]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
cleanup: split out parse_size
[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.",
03e480fc 261 pattern => '(ide|sata|scsi|virtio)\d+',
1e3baf05
DM
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
f36ed4f4
DM
777my $parse_size = sub {
778 my ($value) = @_;
779
780 return undef if $value !~ m/^([1-9]\d*(\.\d+)?)([KMG])?$/;
781 my ($size, $unit) = ($1, $3);
782 if ($unit) {
783 if ($unit eq 'K') {
784 $size = $size * 1024;
785 } elsif ($unit eq 'M') {
786 $size = $size * 1024 * 1024;
787 } elsif ($unit eq 'G') {
788 $size = $size * 1024 * 1024 * 1024;
789 }
790 }
791 return int($size);
792};
793
794my $format_size = sub {
795 my ($size) = @_;
796
797 $size = int($size);
798
799 my $kb = int($size/1024);
800 return $size if $kb*1024 != $size;
801
802 my $mb = int($kb/1024);
803 return "${kb}K" if $mb*1024 != $kb;
804
805 my $gb = int($mb/1024);
806 return "${mb}M" if $gb*1024 != $mb;
807
808 return "${gb}G";
809};
810
1e3baf05
DM
811# ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
812# [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
036e0e2b 813# [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
1e3baf05
DM
814# [,aio=native|threads]
815
816sub parse_drive {
817 my ($key, $data) = @_;
818
819 my $res = {};
19672434 820
1e3baf05
DM
821 # $key may be undefined - used to verify JSON parameters
822 if (!defined($key)) {
823 $res->{interface} = 'unknown'; # should not harm when used to verify parameters
824 $res->{index} = 0;
825 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
826 $res->{interface} = $1;
827 $res->{index} = $2;
828 } else {
829 return undef;
830 }
831
832 foreach my $p (split (/,/, $data)) {
833 next if $p =~ m/^\s*$/;
834
24afaca0 835 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
836 my ($k, $v) = ($1, $2);
837
838 $k = 'file' if $k eq 'volume';
839
840 return undef if defined $res->{$k};
19672434 841
1e3baf05
DM
842 $res->{$k} = $v;
843 } else {
844 if (!$res->{file} && $p !~ m/=/) {
845 $res->{file} = $p;
846 } else {
847 return undef;
848 }
849 }
850 }
851
852 return undef if !$res->{file};
853
19672434 854 return undef if $res->{cache} &&
e482cec3 855 $res->{cache} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
1e3baf05
DM
856 return undef if $res->{snapshot} && $res->{snapshot} !~ m/^(on|off)$/;
857 return undef if $res->{cyls} && $res->{cyls} !~ m/^\d+$/;
858 return undef if $res->{heads} && $res->{heads} !~ m/^\d+$/;
859 return undef if $res->{secs} && $res->{secs} !~ m/^\d+$/;
860 return undef if $res->{media} && $res->{media} !~ m/^(disk|cdrom)$/;
861 return undef if $res->{trans} && $res->{trans} !~ m/^(none|lba|auto)$/;
862 return undef if $res->{format} && $res->{format} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
863 return undef if $res->{rerror} && $res->{rerror} !~ m/^(ignore|report|stop)$/;
864 return undef if $res->{werror} && $res->{werror} !~ m/^(enospc|ignore|report|stop)$/;
865 return undef if $res->{backup} && $res->{backup} !~ m/^(yes|no)$/;
866 return undef if $res->{aio} && $res->{aio} !~ m/^(native|threads)$/;
867
affd2f88
AD
868 return undef if $res->{bps_rd} && $res->{bps};
869 return undef if $res->{bps_wr} && $res->{bps};
870 return undef if $res->{iops_rd} && $res->{iops};
871 return undef if $res->{iops_wr} && $res->{iops};
872
873 return undef if $res->{bps} && $res->{bps} !~ m/^\d+$/;
874 return undef if $res->{bps_rd} && $res->{bps_rd} !~ m/^\d+$/;
875 return undef if $res->{bps_wr} && $res->{bps_wr} !~ m/^\d+$/;
876 return undef if $res->{iops} && $res->{iops} !~ m/^\d+$/;
877 return undef if $res->{iops_rd} && $res->{iops_rd} !~ m/^\d+$/;
878 return undef if $res->{iops_wr} && $res->{iops_wr} !~ m/^\d+$/;
879
880
24afaca0 881 if ($res->{size}) {
f36ed4f4 882 return undef if !defined($res->{size} = &$parse_size($res->{size}));
24afaca0
DM
883 }
884
1e3baf05
DM
885 if ($res->{media} && ($res->{media} eq 'cdrom')) {
886 return undef if $res->{snapshot} || $res->{trans} || $res->{format};
19672434 887 return undef if $res->{heads} || $res->{secs} || $res->{cyls};
1e3baf05
DM
888 return undef if $res->{interface} eq 'virtio';
889 }
890
891 # rerror does not work with scsi drives
892 if ($res->{rerror}) {
893 return undef if $res->{interface} eq 'scsi';
894 }
895
896 return $res;
897}
898
affd2f88 899my @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
DM
900
901sub print_drive {
902 my ($vmid, $drive) = @_;
903
904 my $opts = '';
905 foreach my $o (@qemu_drive_options, 'backup') {
906 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
907 }
908
24afaca0
DM
909 if ($drive->{size}) {
910 $opts .= ",size=" . &$format_size($drive->{size});
911 }
912
1e3baf05
DM
913 return "$drive->{file}$opts";
914}
915
28ef82d3
DM
916sub scsi_inquiry {
917 my($fh, $noerr) = @_;
918
919 my $SG_IO = 0x2285;
920 my $SG_GET_VERSION_NUM = 0x2282;
921
922 my $versionbuf = "\x00" x 8;
923 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
924 if (!$ret) {
925 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
926 return undef;
927 }
97d62eb7 928 my $version = unpack("I", $versionbuf);
28ef82d3
DM
929 if ($version < 30000) {
930 die "scsi generic interface too old\n" if !$noerr;
931 return undef;
932 }
97d62eb7 933
28ef82d3
DM
934 my $buf = "\x00" x 36;
935 my $sensebuf = "\x00" x 8;
936 my $cmd = pack("C x3 C x11", 0x12, 36);
97d62eb7 937
28ef82d3
DM
938 # see /usr/include/scsi/sg.h
939 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";
940
97d62eb7
DM
941 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
942 length($sensebuf), 0, length($buf), $buf,
28ef82d3
DM
943 $cmd, $sensebuf, 6000);
944
945 $ret = ioctl($fh, $SG_IO, $packet);
946 if (!$ret) {
947 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
948 return undef;
949 }
97d62eb7 950
28ef82d3
DM
951 my @res = unpack($sg_io_hdr_t, $packet);
952 if ($res[17] || $res[18]) {
953 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
954 return undef;
955 }
956
957 my $res = {};
958 ($res->{device}, $res->{removable}, $res->{venodor},
959 $res->{product}, $res->{revision}) = unpack("C C x6 A8 A16 A4", $buf);
960
961 return $res;
962}
963
964sub path_is_scsi {
965 my ($path) = @_;
966
967 my $fh = IO::File->new("+<$path") || return undef;
968 my $res = scsi_inquiry($fh, 1);
969 close($fh);
970
971 return $res;
972}
973
ca916ecc 974sub print_drivedevice_full {
5bdcf937 975 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
ca916ecc
DA
976
977 my $device = '';
978 my $maxdev = 0;
19672434 979
ca916ecc 980 if ($drive->{interface} eq 'virtio') {
5bdcf937 981 my $pciaddr = print_pci_addr("$drive->{interface}$drive->{index}", $bridges);
2ed36a41
DM
982 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
983 } elsif ($drive->{interface} eq 'scsi') {
cdd20088 984 $maxdev = ($conf->{scsihw} && $conf->{scsihw} ne 'lsi') ? 256 : 7;
2ed36a41
DM
985 my $controller = int($drive->{index} / $maxdev);
986 my $unit = $drive->{index} % $maxdev;
987 my $devicetype = 'hd';
231f2e13
DA
988 my $path = '';
989 if (drive_is_cdrom($drive)) {
990 $devicetype = 'cd';
991 } else {
992 if ($drive->{file} =~ m|^/|) {
993 $path = $drive->{file};
994 } else {
995 $path = PVE::Storage::path($storecfg, $drive->{file});
996 }
d454d040
AD
997
998 if($path =~ m/^iscsi\:\/\//){
999 $devicetype = 'generic';
1000 }
1001 else {
1002 $devicetype = 'block' if path_is_scsi($path);
1003 }
231f2e13 1004 }
ca916ecc 1005
cdd20088
AD
1006 if (!$conf->{scsihw} || $conf->{scsihw} eq 'lsi'){
1007 $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';
1008 } else {
1009 $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}";
1010 }
1011
2ed36a41
DM
1012 } elsif ($drive->{interface} eq 'ide'){
1013 $maxdev = 2;
1014 my $controller = int($drive->{index} / $maxdev);
1015 my $unit = $drive->{index} % $maxdev;
1016 my $devicetype = ($drive->{media} && $drive->{media} eq 'cdrom') ? "cd" : "hd";
1017
7ebe888a 1018 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
cdb0931f
DA
1019 } elsif ($drive->{interface} eq 'sata'){
1020 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1021 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1022 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
2ed36a41
DM
1023 } elsif ($drive->{interface} eq 'usb') {
1024 die "implement me";
1025 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1026 } else {
1027 die "unsupported interface type";
ca916ecc
DA
1028 }
1029
3b408e82
DM
1030 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex};
1031
ca916ecc
DA
1032 return $device;
1033}
1034
1e3baf05
DM
1035sub print_drive_full {
1036 my ($storecfg, $vmid, $drive) = @_;
1037
1038 my $opts = '';
1039 foreach my $o (@qemu_drive_options) {
3b408e82 1040 next if $o eq 'bootindex';
1e3baf05 1041 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
19672434 1042 }
1e3baf05
DM
1043
1044 # use linux-aio by default (qemu default is threads)
19672434 1045 $opts .= ",aio=native" if !$drive->{aio};
1e3baf05
DM
1046
1047 my $path;
1048 my $volid = $drive->{file};
6b64503e
DM
1049 if (drive_is_cdrom($drive)) {
1050 $path = get_iso_path($storecfg, $vmid, $volid);
1e3baf05
DM
1051 } else {
1052 if ($volid =~ m|^/|) {
1053 $path = $volid;
1054 } else {
6b64503e 1055 $path = PVE::Storage::path($storecfg, $volid);
1e3baf05 1056 }
2b556977
DM
1057 if (!$drive->{cache} && ($path =~ m|^/dev/| || $path =~ m|\.raw$|)) {
1058 $opts .= ",cache=none";
1059 }
1e3baf05
DM
1060 }
1061
1062 my $pathinfo = $path ? "file=$path," : '';
1063
3ebfcc86 1064 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1e3baf05
DM
1065}
1066
cc4d6182 1067sub print_netdevice_full {
5bdcf937 1068 my ($vmid, $conf, $net, $netid, $bridges) = @_;
cc4d6182
DA
1069
1070 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
1071
1072 my $device = $net->{model};
1073 if ($net->{model} eq 'virtio') {
1074 $device = 'virtio-net-pci';
1075 };
1076
1077 # qemu > 0.15 always try to boot from network - we disable that by
1078 # not loading the pxe rom file
1079 my $extra = ($bootorder !~ m/n/) ? "romfile=," : '';
5bdcf937 1080 my $pciaddr = print_pci_addr("$netid", $bridges);
cc4d6182
DA
1081 my $tmpstr = "$device,${extra}mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1082 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex} ;
1083 return $tmpstr;
1084}
1085
1086sub print_netdev_full {
1087 my ($vmid, $conf, $net, $netid) = @_;
1088
1089 my $i = '';
1090 if ($netid =~ m/^net(\d+)$/) {
1091 $i = int($1);
1092 }
1093
1094 die "got strange net id '$i'\n" if $i >= ${MAX_NETS};
1095
1096 my $ifname = "tap${vmid}i$i";
1097
1098 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1099 die "interface name '$ifname' is too long (max 15 character)\n"
1100 if length($ifname) >= 16;
1101
1102 my $vhostparam = '';
1103 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model} eq 'virtio';
1104
1105 my $vmname = $conf->{name} || "vm$vmid";
1106
1107 if ($net->{bridge}) {
1108 return "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
1109 } else {
1110 return "type=user,id=$netid,hostname=$vmname";
1111 }
1112}
1e3baf05
DM
1113
1114sub drive_is_cdrom {
1115 my ($drive) = @_;
1116
1117 return $drive && $drive->{media} && ($drive->{media} eq 'cdrom');
1118
1119}
1120
040b06b7
DA
1121sub parse_hostpci {
1122 my ($value) = @_;
1123
1124 return undef if !$value;
1125
1126 my $res = {};
1127
1128 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
1129 $res->{pciid} = $value;
1130 } else {
1131 return undef;
1132 }
1133
1134 return $res;
1135}
1136
1e3baf05
DM
1137# netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1138sub parse_net {
1139 my ($data) = @_;
1140
1141 my $res = {};
1142
6b64503e 1143 foreach my $kvp (split(/,/, $data)) {
1e3baf05
DM
1144
1145 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 1146 my $model = lc($1);
9f91ff02 1147 my $mac = uc($3) || PVE::Tools::random_ether_addr();
1e3baf05
DM
1148 $res->{model} = $model;
1149 $res->{macaddr} = $mac;
1150 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1151 $res->{bridge} = $1;
1152 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1153 $res->{rate} = $1;
5070f384
DA
1154 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1155 $res->{tag} = $1;
1e3baf05
DM
1156 } else {
1157 return undef;
1158 }
19672434 1159
1e3baf05
DM
1160 }
1161
1162 return undef if !$res->{model};
1163
1164 return $res;
1165}
1166
1167sub print_net {
1168 my $net = shift;
1169
1170 my $res = "$net->{model}";
1171 $res .= "=$net->{macaddr}" if $net->{macaddr};
1172 $res .= ",bridge=$net->{bridge}" if $net->{bridge};
1173 $res .= ",rate=$net->{rate}" if $net->{rate};
18744ba3 1174 $res .= ",tag=$net->{tag}" if $net->{tag};
1e3baf05
DM
1175
1176 return $res;
1177}
1178
1179sub add_random_macs {
1180 my ($settings) = @_;
1181
1182 foreach my $opt (keys %$settings) {
1183 next if $opt !~ m/^net(\d+)$/;
1184 my $net = parse_net($settings->{$opt});
1185 next if !$net;
1186 $settings->{$opt} = print_net($net);
1187 }
1188}
1189
1190sub add_unused_volume {
1858638f 1191 my ($config, $volid) = @_;
1e3baf05
DM
1192
1193 my $key;
1194 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1195 my $test = "unused$ind";
1196 if (my $vid = $config->{$test}) {
1197 return if $vid eq $volid; # do not add duplicates
1198 } else {
1199 $key = $test;
19672434 1200 }
1e3baf05
DM
1201 }
1202
1203 die "To many unused volume - please delete them first.\n" if !$key;
97d62eb7 1204
1858638f 1205 $config->{$key} = $volid;
1e3baf05 1206
1858638f 1207 return $key;
1e3baf05
DM
1208}
1209
1210# fixme: remove all thos $noerr parameters?
1211
1212PVE::JSONSchema::register_format('pve-qm-bootdisk', \&verify_bootdisk);
1213sub verify_bootdisk {
1214 my ($value, $noerr) = @_;
1215
19672434 1216 return $value if valid_drivename($value);
1e3baf05
DM
1217
1218 return undef if $noerr;
1219
1220 die "invalid boot disk '$value'\n";
1221}
1222
1223PVE::JSONSchema::register_format('pve-qm-net', \&verify_net);
1224sub verify_net {
1225 my ($value, $noerr) = @_;
1226
1227 return $value if parse_net($value);
1228
1229 return undef if $noerr;
19672434 1230
1e3baf05
DM
1231 die "unable to parse network options\n";
1232}
1233
1234PVE::JSONSchema::register_format('pve-qm-drive', \&verify_drive);
1235sub verify_drive {
1236 my ($value, $noerr) = @_;
1237
6b64503e 1238 return $value if parse_drive(undef, $value);
1e3baf05
DM
1239
1240 return undef if $noerr;
19672434 1241
1e3baf05
DM
1242 die "unable to parse drive options\n";
1243}
1244
1245PVE::JSONSchema::register_format('pve-qm-hostpci', \&verify_hostpci);
1246sub verify_hostpci {
1247 my ($value, $noerr) = @_;
1248
040b06b7
DA
1249 return $value if parse_hostpci($value);
1250
1251 return undef if $noerr;
1252
1253 die "unable to parse pci id\n";
1e3baf05
DM
1254}
1255
0ea9541d
DM
1256PVE::JSONSchema::register_format('pve-qm-watchdog', \&verify_watchdog);
1257sub verify_watchdog {
1258 my ($value, $noerr) = @_;
1259
1260 return $value if parse_watchdog($value);
1261
1262 return undef if $noerr;
19672434 1263
0ea9541d
DM
1264 die "unable to parse watchdog options\n";
1265}
1266
1267sub parse_watchdog {
1268 my ($value) = @_;
1269
1270 return undef if !$value;
1271
1272 my $res = {};
1273
6b64503e 1274 foreach my $p (split(/,/, $value)) {
0ea9541d
DM
1275 next if $p =~ m/^\s*$/;
1276
1277 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1278 $res->{model} = $2;
1279 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1280 $res->{action} = $2;
1281 } else {
1282 return undef;
1283 }
1284 }
1285
1286 return $res;
1287}
1288
59411c4e
DM
1289PVE::JSONSchema::register_format('pve-qm-startup', \&verify_startup);
1290sub verify_startup {
1291 my ($value, $noerr) = @_;
1292
1293 return $value if parse_startup($value);
1294
1295 return undef if $noerr;
1296
1297 die "unable to parse startup options\n";
1298}
1299
1300sub parse_startup {
1301 my ($value) = @_;
1302
1303 return undef if !$value;
1304
1305 my $res = {};
1306
1307 foreach my $p (split(/,/, $value)) {
1308 next if $p =~ m/^\s*$/;
1309
1310 if ($p =~ m/^(order=)?(\d+)$/) {
1311 $res->{order} = $2;
1312 } elsif ($p =~ m/^up=(\d+)$/) {
1313 $res->{up} = $1;
1314 } elsif ($p =~ m/^down=(\d+)$/) {
1315 $res->{down} = $1;
1316 } else {
1317 return undef;
1318 }
1319 }
1320
1321 return $res;
1322}
1323
1e3baf05
DM
1324sub parse_usb_device {
1325 my ($value) = @_;
1326
1327 return undef if !$value;
1328
6b64503e 1329 my @dl = split(/,/, $value);
1e3baf05
DM
1330 my $found;
1331
1332 my $res = {};
1333 foreach my $v (@dl) {
036e0e2b 1334 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1e3baf05 1335 $found = 1;
036e0e2b
DM
1336 $res->{vendorid} = $2;
1337 $res->{productid} = $4;
1e3baf05
DM
1338 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1339 $found = 1;
1340 $res->{hostbus} = $1;
1341 $res->{hostport} = $2;
1342 } else {
1343 return undef;
1344 }
1345 }
1346 return undef if !$found;
1347
1348 return $res;
1349}
19672434 1350
1e3baf05
DM
1351PVE::JSONSchema::register_format('pve-qm-usb-device', \&verify_usb_device);
1352sub verify_usb_device {
1353 my ($value, $noerr) = @_;
1354
1355 return $value if parse_usb_device($value);
1356
1357 return undef if $noerr;
19672434 1358
1e3baf05
DM
1359 die "unable to parse usb device\n";
1360}
1361
1e3baf05
DM
1362# add JSON properties for create and set function
1363sub json_config_properties {
1364 my $prop = shift;
1365
1366 foreach my $opt (keys %$confdesc) {
1367 $prop->{$opt} = $confdesc->{$opt};
1368 }
1369
1370 return $prop;
1371}
1372
1373sub check_type {
1374 my ($key, $value) = @_;
1375
1376 die "unknown setting '$key'\n" if !$confdesc->{$key};
1377
1378 my $type = $confdesc->{$key}->{type};
1379
6b64503e 1380 if (!defined($value)) {
1e3baf05
DM
1381 die "got undefined value\n";
1382 }
1383
1384 if ($value =~ m/[\n\r]/) {
1385 die "property contains a line feed\n";
1386 }
1387
1388 if ($type eq 'boolean') {
19672434
DM
1389 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1390 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1391 die "type check ('boolean') failed - got '$value'\n";
1e3baf05
DM
1392 } elsif ($type eq 'integer') {
1393 return int($1) if $value =~ m/^(\d+)$/;
1394 die "type check ('integer') failed - got '$value'\n";
1395 } elsif ($type eq 'string') {
1396 if (my $fmt = $confdesc->{$key}->{format}) {
1397 if ($fmt eq 'pve-qm-drive') {
1398 # special case - we need to pass $key to parse_drive()
6b64503e 1399 my $drive = parse_drive($key, $value);
1e3baf05
DM
1400 return $value if $drive;
1401 die "unable to parse drive options\n";
1402 }
1403 PVE::JSONSchema::check_format($fmt, $value);
19672434
DM
1404 return $value;
1405 }
1e3baf05 1406 $value =~ s/^\"(.*)\"$/$1/;
19672434 1407 return $value;
1e3baf05
DM
1408 } else {
1409 die "internal error"
1410 }
1411}
1412
191435c6
DM
1413sub lock_config_full {
1414 my ($vmid, $timeout, $code, @param) = @_;
1e3baf05 1415
6b64503e 1416 my $filename = config_file_lock($vmid);
1e3baf05 1417
191435c6 1418 my $res = lock_file($filename, $timeout, $code, @param);
1e3baf05
DM
1419
1420 die $@ if $@;
5fdbe4f0
DM
1421
1422 return $res;
1e3baf05
DM
1423}
1424
191435c6
DM
1425sub lock_config {
1426 my ($vmid, $code, @param) = @_;
1427
1428 return lock_config_full($vmid, 10, $code, @param);
1429}
1430
1e3baf05 1431sub cfs_config_path {
a78ccf26 1432 my ($vmid, $node) = @_;
1e3baf05 1433
a78ccf26
DM
1434 $node = $nodename if !$node;
1435 return "nodes/$node/qemu-server/$vmid.conf";
1e3baf05
DM
1436}
1437
040b06b7
DA
1438sub check_iommu_support{
1439 #fixme : need to check IOMMU support
1440 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1441
1442 my $iommu=1;
1443 return $iommu;
1444
1445}
1446
1e3baf05 1447sub config_file {
a78ccf26 1448 my ($vmid, $node) = @_;
1e3baf05 1449
a78ccf26 1450 my $cfspath = cfs_config_path($vmid, $node);
1e3baf05
DM
1451 return "/etc/pve/$cfspath";
1452}
1453
1454sub config_file_lock {
1455 my ($vmid) = @_;
1456
1457 return "$lock_dir/lock-$vmid.conf";
1458}
1459
1460sub touch_config {
1461 my ($vmid) = @_;
1462
6b64503e 1463 my $conf = config_file($vmid);
1e3baf05
DM
1464 utime undef, undef, $conf;
1465}
1466
1e3baf05 1467sub destroy_vm {
a6af7b3e 1468 my ($storecfg, $vmid, $keep_empty_config) = @_;
1e3baf05 1469
6b64503e 1470 my $conffile = config_file($vmid);
1e3baf05 1471
6b64503e 1472 my $conf = load_config($vmid);
1e3baf05 1473
6b64503e 1474 check_lock($conf);
1e3baf05 1475
19672434 1476 # only remove disks owned by this VM
1e3baf05
DM
1477 foreach_drive($conf, sub {
1478 my ($ds, $drive) = @_;
1479
6b64503e 1480 return if drive_is_cdrom($drive);
1e3baf05
DM
1481
1482 my $volid = $drive->{file};
ff1a2432 1483 return if !$volid || $volid =~ m|^/|;
1e3baf05 1484
6b64503e 1485 my ($path, $owner) = PVE::Storage::path($storecfg, $volid);
ff1a2432 1486 return if !$path || !$owner || ($owner != $vmid);
1e3baf05 1487
6b64503e 1488 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05 1489 });
19672434 1490
a6af7b3e 1491 if ($keep_empty_config) {
9c502e26 1492 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
a6af7b3e
DM
1493 } else {
1494 unlink $conffile;
1495 }
1e3baf05
DM
1496
1497 # also remove unused disk
1498 eval {
6b64503e 1499 my $dl = PVE::Storage::vdisk_list($storecfg, undef, $vmid);
1e3baf05
DM
1500
1501 eval {
6b64503e 1502 PVE::Storage::foreach_volid($dl, sub {
1e3baf05 1503 my ($volid, $sid, $volname, $d) = @_;
6b64503e 1504 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05
DM
1505 });
1506 };
1507 warn $@ if $@;
1508
1509 };
1510 warn $@ if $@;
1511}
1512
1e3baf05 1513sub load_config {
7e8dcf2c 1514 my ($vmid, $node) = @_;
1e3baf05 1515
7e8dcf2c 1516 my $cfspath = cfs_config_path($vmid, $node);
1e3baf05
DM
1517
1518 my $conf = PVE::Cluster::cfs_read_file($cfspath);
1519
1520 die "no such VM ('$vmid')\n" if !defined($conf);
1521
1522 return $conf;
19672434 1523}
1e3baf05
DM
1524
1525sub parse_vm_config {
1526 my ($filename, $raw) = @_;
1527
1528 return undef if !defined($raw);
1529
554ac7e7 1530 my $res = {
fc1ddcdc 1531 digest => Digest::SHA::sha1_hex($raw),
554ac7e7 1532 };
1e3baf05 1533
19672434 1534 $filename =~ m|/qemu-server/(\d+)\.conf$|
1e3baf05
DM
1535 || die "got strange filename '$filename'";
1536
1537 my $vmid = $1;
1538
0581fe4f
DM
1539 my $descr = '';
1540
1e3baf05
DM
1541 while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
1542 my $line = $1;
19672434 1543
1e3baf05
DM
1544 next if $line =~ m/^\s*$/;
1545
0581fe4f
DM
1546 if ($line =~ m/^\#(.*)\s*$/) {
1547 $descr .= PVE::Tools::decode_text($1) . "\n";
1548 next;
1549 }
1550
1e3baf05 1551 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
0581fe4f 1552 $descr .= PVE::Tools::decode_text($2);
1e3baf05
DM
1553 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1554 my $key = $1;
1555 my $value = $2;
1556 $res->{$key} = $value;
1557 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1558 my $key = $1;
1559 my $value = $2;
1560 eval { $value = check_type($key, $value); };
1561 if ($@) {
1562 warn "vm $vmid - unable to parse value of '$key' - $@";
1563 } else {
1564 my $fmt = $confdesc->{$key}->{format};
1565 if ($fmt && $fmt eq 'pve-qm-drive') {
1566 my $v = parse_drive($key, $value);
1567 if (my $volid = filename_to_volume_id($vmid, $v->{file}, $v->{media})) {
1568 $v->{file} = $volid;
6b64503e 1569 $value = print_drive($vmid, $v);
1e3baf05
DM
1570 } else {
1571 warn "vm $vmid - unable to parse value of '$key'\n";
1572 next;
1573 }
1574 }
1575
1576 if ($key eq 'cdrom') {
1577 $res->{ide2} = $value;
1578 } else {
1579 $res->{$key} = $value;
1580 }
1581 }
1582 }
1583 }
1584
0581fe4f
DM
1585 $res->{description} = $descr if $descr;
1586
1e3baf05
DM
1587 # convert old smp to sockets
1588 if ($res->{smp} && !$res->{sockets}) {
1589 $res->{sockets} = $res->{smp};
19672434 1590 }
1e3baf05
DM
1591 delete $res->{smp};
1592
1593 return $res;
1594}
1595
1858638f
DM
1596sub write_vm_config {
1597 my ($filename, $conf) = @_;
1e3baf05 1598
1858638f
DM
1599 if ($conf->{cdrom}) {
1600 die "option ide2 conflicts with cdrom\n" if $conf->{ide2};
1601 $conf->{ide2} = $conf->{cdrom};
1602 delete $conf->{cdrom};
1603 }
1e3baf05
DM
1604
1605 # we do not use 'smp' any longer
1858638f
DM
1606 if ($conf->{sockets}) {
1607 delete $conf->{smp};
1608 } elsif ($conf->{smp}) {
1609 $conf->{sockets} = $conf->{smp};
1610 delete $conf->{cores};
1611 delete $conf->{smp};
1e3baf05
DM
1612 }
1613
1614 my $new_volids = {};
1858638f 1615 foreach my $key (keys %$conf) {
0581fe4f 1616 next if $key eq 'digest' || $key eq 'description';
1858638f 1617 my $value = $conf->{$key};
1e3baf05
DM
1618 eval { $value = check_type($key, $value); };
1619 die "unable to parse value of '$key' - $@" if $@;
1858638f
DM
1620
1621 $conf->{$key} = $value;
1622
1e3baf05
DM
1623 if (valid_drivename($key)) {
1624 my $drive = PVE::QemuServer::parse_drive($key, $value);
1625 $new_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
1626 }
1627 }
1628
1858638f
DM
1629 # remove 'unusedX' settings if we re-add a volume
1630 foreach my $key (keys %$conf) {
1631 my $value = $conf->{$key};
1632 if ($key =~ m/^unused/ && $new_volids->{$value}) {
1633 delete $conf->{$key};
1e3baf05 1634 }
1858638f 1635 }
1e3baf05 1636
1858638f
DM
1637 # gererate RAW data
1638 my $raw = '';
0581fe4f
DM
1639
1640 # add description as comment to top of file
1641 my $descr = $conf->{description} || '';
1642 foreach my $cl (split(/\n/, $descr)) {
1643 $raw .= '#' . PVE::Tools::encode_text($cl) . "\n";
1644 }
1645
1858638f 1646 foreach my $key (sort keys %$conf) {
0581fe4f 1647 next if $key eq 'digest' || $key eq 'description';
1858638f
DM
1648 $raw .= "$key: $conf->{$key}\n";
1649 }
1e3baf05 1650
1858638f
DM
1651 return $raw;
1652}
1e3baf05 1653
1858638f
DM
1654sub update_config_nolock {
1655 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 1656
1858638f 1657 check_lock($conf) if !$skiplock;
97d62eb7 1658
1858638f 1659 my $cfspath = cfs_config_path($vmid);
1e3baf05 1660
1858638f
DM
1661 PVE::Cluster::cfs_write_file($cfspath, $conf);
1662}
1e3baf05 1663
1858638f
DM
1664sub update_config {
1665 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 1666
1858638f 1667 lock_config($vmid, &update_config_nolock, $conf, $skiplock);
1e3baf05
DM
1668}
1669
19672434 1670sub load_defaults {
1e3baf05
DM
1671
1672 my $res = {};
1673
1674 # we use static defaults from our JSON schema configuration
1675 foreach my $key (keys %$confdesc) {
1676 if (defined(my $default = $confdesc->{$key}->{default})) {
1677 $res->{$key} = $default;
1678 }
1679 }
19672434 1680
1e3baf05
DM
1681 my $conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
1682 $res->{keyboard} = $conf->{keyboard} if $conf->{keyboard};
1683
1684 return $res;
1685}
1686
1687sub config_list {
1688 my $vmlist = PVE::Cluster::get_vmlist();
1689 my $res = {};
1690 return $res if !$vmlist || !$vmlist->{ids};
1691 my $ids = $vmlist->{ids};
1692
1e3baf05
DM
1693 foreach my $vmid (keys %$ids) {
1694 my $d = $ids->{$vmid};
1695 next if !$d->{node} || $d->{node} ne $nodename;
5ee957cc 1696 next if !$d->{type} || $d->{type} ne 'qemu';
1e3baf05
DM
1697 $res->{$vmid}->{exists} = 1;
1698 }
1699 return $res;
1700}
1701
64e13401
DM
1702# test if VM uses local resources (to prevent migration)
1703sub check_local_resources {
1704 my ($conf, $noerr) = @_;
1705
1706 my $loc_res = 0;
19672434 1707
e0ab7331
DM
1708 $loc_res = 1 if $conf->{hostusb}; # old syntax
1709 $loc_res = 1 if $conf->{hostpci}; # old syntax
64e13401 1710
0d29ab3b 1711 foreach my $k (keys %$conf) {
2fe1a152 1712 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
64e13401
DM
1713 }
1714
1715 die "VM uses local resources\n" if $loc_res && !$noerr;
1716
1717 return $loc_res;
1718}
1719
47152e2e
DM
1720# check is used storages are available on all nodes (use by migrate)
1721sub check_storage_availability {
1722 my ($storecfg, $conf, $node) = @_;
1723
1724 foreach_drive($conf, sub {
1725 my ($ds, $drive) = @_;
1726
1727 my $volid = $drive->{file};
1728 return if !$volid;
1729
1730 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
1731 return if !$sid;
1732
1733 # check if storage is available on both nodes
1734 my $scfg = PVE::Storage::storage_check_node($storecfg, $sid);
1735 PVE::Storage::storage_check_node($storecfg, $sid, $node);
1736 });
1737}
1738
1e3baf05
DM
1739sub check_lock {
1740 my ($conf) = @_;
1741
1742 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1743}
1744
1745sub check_cmdline {
1746 my ($pidfile, $pid) = @_;
1747
6b64503e
DM
1748 my $fh = IO::File->new("/proc/$pid/cmdline", "r");
1749 if (defined($fh)) {
1e3baf05
DM
1750 my $line = <$fh>;
1751 $fh->close;
1752 return undef if !$line;
6b64503e 1753 my @param = split(/\0/, $line);
1e3baf05
DM
1754
1755 my $cmd = $param[0];
1756 return if !$cmd || ($cmd !~ m|kvm$|);
1757
1758 for (my $i = 0; $i < scalar (@param); $i++) {
1759 my $p = $param[$i];
1760 next if !$p;
1761 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1762 my $p = $param[$i+1];
1763 return 1 if $p && ($p eq $pidfile);
1764 return undef;
1765 }
1766 }
1767 }
1768 return undef;
1769}
1770
1771sub check_running {
7e8dcf2c 1772 my ($vmid, $nocheck, $node) = @_;
1e3baf05 1773
7e8dcf2c 1774 my $filename = config_file($vmid, $node);
1e3baf05
DM
1775
1776 die "unable to find configuration file for VM $vmid - no such machine\n"
e6c3b671 1777 if !$nocheck && ! -f $filename;
1e3baf05 1778
e6c3b671 1779 my $pidfile = pidfile_name($vmid);
1e3baf05 1780
e6c3b671
DM
1781 if (my $fd = IO::File->new("<$pidfile")) {
1782 my $st = stat($fd);
1e3baf05 1783 my $line = <$fd>;
6b64503e 1784 close($fd);
1e3baf05
DM
1785
1786 my $mtime = $st->mtime;
1787 if ($mtime > time()) {
1788 warn "file '$filename' modified in future\n";
1789 }
1790
1791 if ($line =~ m/^(\d+)$/) {
1792 my $pid = $1;
e6c3b671
DM
1793 if (check_cmdline($pidfile, $pid)) {
1794 if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
1795 return $pid;
1796 }
1797 }
1e3baf05
DM
1798 }
1799 }
1800
1801 return undef;
1802}
1803
1804sub vzlist {
19672434 1805
1e3baf05
DM
1806 my $vzlist = config_list();
1807
6b64503e 1808 my $fd = IO::Dir->new($var_run_tmpdir) || return $vzlist;
1e3baf05 1809
19672434 1810 while (defined(my $de = $fd->read)) {
1e3baf05
DM
1811 next if $de !~ m/^(\d+)\.pid$/;
1812 my $vmid = $1;
6b64503e
DM
1813 next if !defined($vzlist->{$vmid});
1814 if (my $pid = check_running($vmid)) {
1e3baf05
DM
1815 $vzlist->{$vmid}->{pid} = $pid;
1816 }
1817 }
1818
1819 return $vzlist;
1820}
1821
1e3baf05
DM
1822sub disksize {
1823 my ($storecfg, $conf) = @_;
1824
1825 my $bootdisk = $conf->{bootdisk};
1826 return undef if !$bootdisk;
1827 return undef if !valid_drivename($bootdisk);
1828
1829 return undef if !$conf->{$bootdisk};
1830
1831 my $drive = parse_drive($bootdisk, $conf->{$bootdisk});
1832 return undef if !defined($drive);
1833
1834 return undef if drive_is_cdrom($drive);
1835
1836 my $volid = $drive->{file};
1837 return undef if !$volid;
1838
24afaca0 1839 return $drive->{size};
1e3baf05
DM
1840}
1841
1842my $last_proc_pid_stat;
1843
03a33f30
DM
1844# get VM status information
1845# This must be fast and should not block ($full == false)
1846# We only query KVM using QMP if $full == true (this can be slow)
1e3baf05 1847sub vmstatus {
03a33f30 1848 my ($opt_vmid, $full) = @_;
1e3baf05
DM
1849
1850 my $res = {};
1851
19672434 1852 my $storecfg = PVE::Storage::config();
1e3baf05
DM
1853
1854 my $list = vzlist();
694fcad4 1855 my ($uptime) = PVE::ProcFSTools::read_proc_uptime(1);
1e3baf05 1856
ae4915a2
DM
1857 my $cpucount = $cpuinfo->{cpus} || 1;
1858
1e3baf05
DM
1859 foreach my $vmid (keys %$list) {
1860 next if $opt_vmid && ($vmid ne $opt_vmid);
1861
1862 my $cfspath = cfs_config_path($vmid);
1863 my $conf = PVE::Cluster::cfs_read_file($cfspath) || {};
1864
1865 my $d = {};
1866 $d->{pid} = $list->{$vmid}->{pid};
1867
1868 # fixme: better status?
1869 $d->{status} = $list->{$vmid}->{pid} ? 'running' : 'stopped';
1870
af990afe
DM
1871 my $size = disksize($storecfg, $conf);
1872 if (defined($size)) {
1873 $d->{disk} = 0; # no info available
1e3baf05
DM
1874 $d->{maxdisk} = $size;
1875 } else {
1876 $d->{disk} = 0;
1877 $d->{maxdisk} = 0;
1878 }
1879
1880 $d->{cpus} = ($conf->{sockets} || 1) * ($conf->{cores} || 1);
ae4915a2
DM
1881 $d->{cpus} = $cpucount if $d->{cpus} > $cpucount;
1882
1e3baf05 1883 $d->{name} = $conf->{name} || "VM $vmid";
19672434 1884 $d->{maxmem} = $conf->{memory} ? $conf->{memory}*(1024*1024) : 0;
1e3baf05 1885
1e3baf05
DM
1886 $d->{uptime} = 0;
1887 $d->{cpu} = 0;
1e3baf05
DM
1888 $d->{mem} = 0;
1889
1890 $d->{netout} = 0;
1891 $d->{netin} = 0;
1892
1893 $d->{diskread} = 0;
1894 $d->{diskwrite} = 0;
1895
1896 $res->{$vmid} = $d;
1897 }
1898
1899 my $netdev = PVE::ProcFSTools::read_proc_net_dev();
1900 foreach my $dev (keys %$netdev) {
1901 next if $dev !~ m/^tap([1-9]\d*)i/;
1902 my $vmid = $1;
1903 my $d = $res->{$vmid};
1904 next if !$d;
19672434 1905
1e3baf05
DM
1906 $d->{netout} += $netdev->{$dev}->{receive};
1907 $d->{netin} += $netdev->{$dev}->{transmit};
1908 }
1909
1e3baf05
DM
1910 my $ctime = gettimeofday;
1911
1912 foreach my $vmid (keys %$list) {
1913
1914 my $d = $res->{$vmid};
1915 my $pid = $d->{pid};
1916 next if !$pid;
1917
694fcad4
DM
1918 my $pstat = PVE::ProcFSTools::read_proc_pid_stat($pid);
1919 next if !$pstat; # not running
19672434 1920
694fcad4 1921 my $used = $pstat->{utime} + $pstat->{stime};
1e3baf05 1922
694fcad4 1923 $d->{uptime} = int(($uptime - $pstat->{starttime})/$cpuinfo->{user_hz});
1e3baf05 1924
694fcad4 1925 if ($pstat->{vsize}) {
6b64503e 1926 $d->{mem} = int(($pstat->{rss}/$pstat->{vsize})*$d->{maxmem});
1e3baf05
DM
1927 }
1928
1929 my $old = $last_proc_pid_stat->{$pid};
1930 if (!$old) {
19672434
DM
1931 $last_proc_pid_stat->{$pid} = {
1932 time => $ctime,
1e3baf05
DM
1933 used => $used,
1934 cpu => 0,
1e3baf05
DM
1935 };
1936 next;
1937 }
1938
7f0b5beb 1939 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz};
1e3baf05
DM
1940
1941 if ($dtime > 1000) {
1942 my $dutime = $used - $old->{used};
1943
ae4915a2 1944 $d->{cpu} = (($dutime/$dtime)* $cpucount) / $d->{cpus};
1e3baf05 1945 $last_proc_pid_stat->{$pid} = {
19672434 1946 time => $ctime,
1e3baf05
DM
1947 used => $used,
1948 cpu => $d->{cpu},
1e3baf05
DM
1949 };
1950 } else {
1951 $d->{cpu} = $old->{cpu};
1e3baf05
DM
1952 }
1953 }
1954
f5eb281a 1955 return $res if !$full;
03a33f30
DM
1956
1957 my $qmpclient = PVE::QMPClient->new();
1958
1959 my $blockstatscb = sub {
1960 my ($vmid, $resp) = @_;
1961 my $data = $resp->{'return'} || [];
1962 my $totalrdbytes = 0;
1963 my $totalwrbytes = 0;
1964 for my $blockstat (@$data) {
1965 $totalrdbytes = $totalrdbytes + $blockstat->{stats}->{rd_bytes};
1966 $totalwrbytes = $totalwrbytes + $blockstat->{stats}->{wr_bytes};
1967 }
1968 $res->{$vmid}->{diskread} = $totalrdbytes;
1969 $res->{$vmid}->{diskwrite} = $totalwrbytes;
1970 };
1971
1972 my $statuscb = sub {
1973 my ($vmid, $resp) = @_;
1974 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
1975
1976 my $status = 'unknown';
1977 if (!defined($status = $resp->{'return'}->{status})) {
1978 warn "unable to get VM status\n";
1979 return;
1980 }
1981
1982 $res->{$vmid}->{qmpstatus} = $resp->{'return'}->{status};
1983 };
1984
1985 foreach my $vmid (keys %$list) {
1986 next if $opt_vmid && ($vmid ne $opt_vmid);
1987 next if !$res->{$vmid}->{pid}; # not running
1988 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
1989 }
1990
1991 $qmpclient->queue_execute();
1992
1993 foreach my $vmid (keys %$list) {
1994 next if $opt_vmid && ($vmid ne $opt_vmid);
1995 $res->{$vmid}->{qmpstatus} = $res->{$vmid}->{status} if !$res->{$vmid}->{qmpstatus};
1996 }
1997
1e3baf05
DM
1998 return $res;
1999}
2000
2001sub foreach_drive {
2002 my ($conf, $func) = @_;
2003
2004 foreach my $ds (keys %$conf) {
2005 next if !valid_drivename($ds);
2006
6b64503e 2007 my $drive = parse_drive($ds, $conf->{$ds});
1e3baf05
DM
2008 next if !$drive;
2009
2010 &$func($ds, $drive);
2011 }
2012}
2013
2014sub config_to_command {
2015 my ($storecfg, $vmid, $conf, $defaults, $migrate_uri) = @_;
2016
2017 my $cmd = [];
5bdcf937 2018 my $devices = [];
b78ebef7 2019 my $pciaddr = '';
5bdcf937 2020 my $bridges = {};
1e3baf05
DM
2021 my $kvmver = kvm_user_version();
2022 my $vernum = 0; # unknown
a3c52213
DM
2023 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2024 $vernum = $1*1000000+$2*1000;
2025 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
1e3baf05
DM
2026 $vernum = $1*1000000+$2*1000+$3;
2027 }
2028
a3c52213 2029 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
1e3baf05
DM
2030
2031 my $have_ovz = -f '/proc/vz/vestat';
2032
2033 push @$cmd, '/usr/bin/kvm';
2034
2035 push @$cmd, '-id', $vmid;
2036
2037 my $use_virtio = 0;
2038
c971c4f2
AD
2039 my $qmpsocket = qmp_socket($vmid);
2040 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2041 push @$cmd, '-mon', "chardev=qmp,mode=control";
2042
7b7c6d1b 2043 my $socket = vnc_socket($vmid);
1e3baf05
DM
2044 push @$cmd, '-vnc', "unix:$socket,x509,password";
2045
6b64503e 2046 push @$cmd, '-pidfile' , pidfile_name($vmid);
19672434 2047
1e3baf05
DM
2048 push @$cmd, '-daemonize';
2049
2050 push @$cmd, '-incoming', $migrate_uri if $migrate_uri;
2051
b67900f1
AD
2052 push @$cmd, '-S' if $migrate_uri;
2053
1c060867
DM
2054 my $use_usb2 = 0;
2055 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2056 next if !$conf->{"usb$i"};
2057 $use_usb2 = 1;
2058 }
1e3baf05 2059 # include usb device config
5bdcf937 2060 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
19672434 2061
1e3baf05 2062 # enable absolute mouse coordinates (needed by vnc)
6b64503e 2063 my $tablet = defined($conf->{tablet}) ? $conf->{tablet} : $defaults->{tablet};
1c060867
DM
2064 if ($tablet) {
2065 if ($use_usb2) {
5bdcf937 2066 push @$devices, '-device', 'usb-tablet,bus=ehci.0,port=6';
1c060867 2067 } else {
5bdcf937 2068 push @$devices, '-usbdevice', 'tablet';
1c060867
DM
2069 }
2070 }
1e3baf05
DM
2071
2072 # host pci devices
040b06b7
DA
2073 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2074 my $d = parse_hostpci($conf->{"hostpci$i"});
2075 next if !$d;
5bdcf937
AD
2076 $pciaddr = print_pci_addr("hostpci$i", $bridges);
2077 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
1e3baf05
DM
2078 }
2079
2080 # usb devices
2081 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2082 my $d = parse_usb_device($conf->{"usb$i"});
2083 next if !$d;
2084 if ($d->{vendorid} && $d->{productid}) {
5bdcf937 2085 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
1e3baf05 2086 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
5bdcf937 2087 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
1e3baf05
DM
2088 }
2089 }
2090
1e3baf05 2091 # serial devices
bae179aa 2092 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2093 if (my $path = $conf->{"serial$i"}) {
19672434 2094 die "no such serial device\n" if ! -c $path;
5bdcf937
AD
2095 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2096 push @$devices, '-device', "isa-serial,chardev=serial$i";
34978be3 2097 }
1e3baf05
DM
2098 }
2099
2100 # parallel devices
1989a89c 2101 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2102 if (my $path = $conf->{"parallel$i"}) {
19672434 2103 die "no such parallel device\n" if ! -c $path;
5bdcf937
AD
2104 push @$devices, '-chardev', "parport,id=parallel$i,path=$path";
2105 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
34978be3 2106 }
1e3baf05
DM
2107 }
2108
2109 my $vmname = $conf->{name} || "vm$vmid";
2110
2111 push @$cmd, '-name', $vmname;
19672434 2112
1e3baf05
DM
2113 my $sockets = 1;
2114 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2115 $sockets = $conf->{sockets} if $conf->{sockets};
2116
2117 my $cores = $conf->{cores} || 1;
2118
1e3baf05
DM
2119 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2120
2121 push @$cmd, '-cpu', $conf->{cpu} if $conf->{cpu};
2122
1e3baf05
DM
2123 push @$cmd, '-nodefaults';
2124
32baffb4 2125 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
3b408e82 2126
0888fdce
DM
2127 my $bootindex_hash = {};
2128 my $i = 1;
2129 foreach my $o (split(//, $bootorder)) {
2130 $bootindex_hash->{$o} = $i*100;
2131 $i++;
afdb31d5 2132 }
3b408e82
DM
2133
2134 push @$cmd, '-boot', "menu=on";
1e3baf05 2135
6b64503e 2136 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2137
6b64503e 2138 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05
DM
2139
2140 my $vga = $conf->{vga};
2141 if (!$vga) {
2142 if ($conf->{ostype} && ($conf->{ostype} eq 'win7' || $conf->{ostype} eq 'w2k8')) {
2143 $vga = 'std';
2144 } else {
2145 $vga = 'cirrus';
2146 }
2147 }
19672434 2148
1e3baf05
DM
2149 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2150
2151 # time drift fix
6b64503e 2152 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
da21653b
DM
2153 # ignore - no longer supported by newer kvm
2154 # push @$cmd, '-tdf' if $tdf;
1e3baf05 2155
6b64503e 2156 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
1e3baf05
DM
2157
2158 if (my $ost = $conf->{ostype}) {
2159 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2160
2161 if ($ost =~ m/^w/) { # windows
6b64503e 2162 push @$cmd, '-localtime' if !defined($conf->{localtime});
1e3baf05
DM
2163
2164 # use rtc-td-hack when acpi is enabled
6b64503e 2165 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
1e3baf05
DM
2166 push @$cmd, '-rtc-td-hack';
2167 }
2168 }
2169
b7e0c8bf
DM
2170 if ($ost eq 'win7' || $ost eq 'w2k8' || $ost eq 'wvista') {
2171 push @$cmd, '-no-kvm-pit-reinjection';
2172 push @$cmd, '-no-hpet';
2173 }
2174
1e3baf05 2175 # -tdf ?
19672434
DM
2176 # -no-acpi
2177 # -no-kvm
1e3baf05
DM
2178 # -win2k-hack ?
2179 }
2180
7f0b5beb
DM
2181 if ($nokvm) {
2182 push @$cmd, '-no-kvm';
2183 } else {
2184 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2185 }
1e3baf05
DM
2186
2187 push @$cmd, '-localtime' if $conf->{localtime};
2188
2189 push @$cmd, '-startdate', $conf->{startdate} if $conf->{startdate};
2190
2191 push @$cmd, '-S' if $conf->{freeze};
2192
2193 # set keyboard layout
2194 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2195 push @$cmd, '-k', $kb if $kb;
2196
2197 # enable sound
2198 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2199 #push @$cmd, '-soundhw', 'es1370';
2200 #push @$cmd, '-soundhw', $soundhw if $soundhw;
5bdcf937
AD
2201 $pciaddr = print_pci_addr("balloon0", $bridges);
2202 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon};
1e3baf05 2203
0ea9541d
DM
2204 if ($conf->{watchdog}) {
2205 my $wdopts = parse_watchdog($conf->{watchdog});
5bdcf937 2206 $pciaddr = print_pci_addr("watchdog", $bridges);
0a40e8ea 2207 my $watchdog = $wdopts->{model} || 'i6300esb';
5bdcf937
AD
2208 push @$devices, '-device', "$watchdog$pciaddr";
2209 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
0ea9541d
DM
2210 }
2211
1e3baf05 2212 my $vollist = [];
941e0c42 2213 my $scsicontroller = {};
26ee04b6 2214 my $ahcicontroller = {};
cdd20088 2215 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
1e3baf05
DM
2216
2217 foreach_drive($conf, sub {
2218 my ($ds, $drive) = @_;
2219
ff1a2432 2220 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 2221 push @$vollist, $drive->{file};
ff1a2432 2222 }
afdb31d5 2223
1e3baf05 2224 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
2225
2226 if (drive_is_cdrom ($drive)) {
2227 if ($bootindex_hash->{d}) {
2228 $drive->{bootindex} = $bootindex_hash->{d};
2229 $bootindex_hash->{d} += 1;
2230 }
2231 } else {
2232 if ($bootindex_hash->{c}) {
2233 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
2234 $bootindex_hash->{c} += 1;
2235 }
2236 }
2237
941e0c42 2238 if ($drive->{interface} eq 'scsi') {
cdd20088
AD
2239
2240 my $maxdev = ($scsihw ne 'lsi') ? 256 : 7;
2241 my $controller = int($drive->{index} / $maxdev);
5bdcf937
AD
2242 $pciaddr = print_pci_addr("scsihw$controller", $bridges);
2243 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
cdd20088 2244 $scsicontroller->{$controller}=1;
941e0c42 2245 }
3b408e82 2246
26ee04b6
DA
2247 if ($drive->{interface} eq 'sata') {
2248 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
5bdcf937
AD
2249 $pciaddr = print_pci_addr("ahci$controller", $bridges);
2250 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
26ee04b6
DA
2251 $ahcicontroller->{$controller}=1;
2252 }
2253
5bdcf937
AD
2254 push @$devices, '-drive',print_drive_full($storecfg, $vmid, $drive);
2255 push @$devices, '-device',print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
1e3baf05
DM
2256 });
2257
2258 push @$cmd, '-m', $conf->{memory} || $defaults->{memory};
19672434 2259
cc4d6182 2260 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 2261 next if !$conf->{"net$i"};
cc4d6182
DA
2262 my $d = parse_net($conf->{"net$i"});
2263 next if !$d;
1e3baf05 2264
cc4d6182 2265 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 2266
cc4d6182
DA
2267 if ($bootindex_hash->{n}) {
2268 $d->{bootindex} = $bootindex_hash->{n};
2269 $bootindex_hash->{n} += 1;
2270 }
1e3baf05 2271
cc4d6182 2272 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
5bdcf937
AD
2273 push @$devices, '-netdev', $netdevfull;
2274
2275 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i",$bridges);
2276 push @$devices, '-device', $netdevicefull;
2277 }
1e3baf05 2278
5bdcf937
AD
2279 #bridges
2280 while (my ($k, $v) = each %$bridges) {
2281 $pciaddr = print_pci_addr("pci.$k");
2282 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
19672434
DM
2283 }
2284
1e3baf05
DM
2285
2286 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2287 # when the VM uses virtio devices.
19672434
DM
2288 if (!$use_virtio && $have_ovz) {
2289
6b64503e 2290 my $cpuunits = defined($conf->{cpuunits}) ?
1e3baf05
DM
2291 $conf->{cpuunits} : $defaults->{cpuunits};
2292
2293 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2294
2295 # fixme: cpulimit is currently ignored
2296 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2297 }
2298
2299 # add custom args
2300 if ($conf->{args}) {
3ada46c9 2301 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
2302 push @$cmd, @$aa;
2303 }
2304
5bdcf937 2305 push @$cmd, @$devices;
1e3baf05
DM
2306 return wantarray ? ($cmd, $vollist) : $cmd;
2307}
19672434 2308
1e3baf05
DM
2309sub vnc_socket {
2310 my ($vmid) = @_;
2311 return "${var_run_tmpdir}/$vmid.vnc";
2312}
2313
c971c4f2
AD
2314sub qmp_socket {
2315 my ($vmid) = @_;
2316 return "${var_run_tmpdir}/$vmid.qmp";
2317}
2318
1e3baf05
DM
2319sub pidfile_name {
2320 my ($vmid) = @_;
2321 return "${var_run_tmpdir}/$vmid.pid";
2322}
2323
1e3baf05
DM
2324sub next_migrate_port {
2325
2326 for (my $p = 60000; $p < 60010; $p++) {
2327
6b64503e
DM
2328 my $sock = IO::Socket::INET->new(Listen => 5,
2329 LocalAddr => 'localhost',
2330 LocalPort => $p,
2331 ReuseAddr => 1,
2332 Proto => 0);
1e3baf05
DM
2333
2334 if ($sock) {
6b64503e 2335 close($sock);
1e3baf05
DM
2336 return $p;
2337 }
2338 }
2339
2340 die "unable to find free migration port";
2341}
2342
86fdcfb2
DA
2343sub vm_devices_list {
2344 my ($vmid) = @_;
2345
ceea9078
DM
2346 my $res = vm_mon_cmd($vmid, 'query-pci');
2347
2348 my $devices = {};
2349 foreach my $pcibus (@$res) {
2350 foreach my $device (@{$pcibus->{devices}}) {
2351 next if !$device->{'qdev_id'};
2352 $devices->{$device->{'qdev_id'}} = $device;
1dc4f496
DM
2353 }
2354 }
86fdcfb2 2355
1dc4f496 2356 return $devices;
86fdcfb2
DA
2357}
2358
ec21aa11 2359sub vm_deviceplug {
f19d1c47 2360 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 2361
2630d2a9 2362 return 1 if !check_running($vmid) || !$conf->{hotplug};
afdb31d5 2363
95d6343b
DA
2364 my $devices_list = vm_devices_list($vmid);
2365 return 1 if defined($devices_list->{$deviceid});
2366
40f28a9f
AD
2367 qemu_bridgeadd($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2368
5e5dcb73
DA
2369 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2370 return undef if !qemu_driveadd($storecfg, $vmid, $device);
cdd20088 2371 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
5e5dcb73
DA
2372 qemu_deviceadd($vmid, $devicefull);
2373 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2374 qemu_drivedel($vmid, $deviceid);
2375 return undef;
2376 }
f19d1c47 2377 }
cfc817c7 2378
cdd20088
AD
2379 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2380 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
cfc817c7 2381 my $pciaddr = print_pci_addr($deviceid);
cdd20088 2382 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
cfc817c7
DA
2383 qemu_deviceadd($vmid, $devicefull);
2384 return undef if(!qemu_deviceaddverify($vmid, $deviceid));
2385 }
2386
a4f091a0 2387 if ($deviceid =~ m/^(scsi)(\d+)$/) {
cdd20088
AD
2388 return 1 if ($conf->{scsihw} && $conf->{scsihw} ne 'lsi'); #virtio-scsi not yet support hotplug
2389 return undef if !qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
a4f091a0 2390 return undef if !qemu_driveadd($storecfg, $vmid, $device);
cdd20088 2391 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
a4f091a0
DA
2392 if(!qemu_deviceadd($vmid, $devicefull)) {
2393 qemu_drivedel($vmid, $deviceid);
2394 return undef;
2395 }
2396 }
2397
2630d2a9
DA
2398 if ($deviceid =~ m/^(net)(\d+)$/) {
2399 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
2400 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
2401 qemu_deviceadd($vmid, $netdevicefull);
2402 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2403 qemu_netdevdel($vmid, $deviceid);
2404 return undef;
2405 }
2406 }
2407
40f28a9f
AD
2408 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2409 my $bridgeid = $2;
2410 my $pciaddr = print_pci_addr($deviceid);
2411 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2412 qemu_deviceadd($vmid, $devicefull);
2413 return undef if !qemu_deviceaddverify($vmid, $deviceid);
2414 }
2415
5e5dcb73 2416 return 1;
a4dea331
DA
2417}
2418
ec21aa11 2419sub vm_deviceunplug {
f19d1c47 2420 my ($vmid, $conf, $deviceid) = @_;
873c2d69 2421
5e5dcb73 2422 return 1 if !check_running ($vmid) || !$conf->{hotplug};
873c2d69 2423
95d6343b
DA
2424 my $devices_list = vm_devices_list($vmid);
2425 return 1 if !defined($devices_list->{$deviceid});
2426
ae57f6b3 2427 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
f19d1c47 2428
5e5dcb73
DA
2429 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2430 return undef if !qemu_drivedel($vmid, $deviceid);
2431 qemu_devicedel($vmid, $deviceid);
2432 return undef if !qemu_devicedelverify($vmid, $deviceid);
2433 }
cfc817c7
DA
2434
2435 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2436 return undef if !qemu_devicedel($vmid, $deviceid);
2437 }
2438
a4f091a0
DA
2439 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2440 return undef if !qemu_devicedel($vmid, $deviceid);
2441 return undef if !qemu_drivedel($vmid, $deviceid);
2442 }
2443
2630d2a9
DA
2444 if ($deviceid =~ m/^(net)(\d+)$/) {
2445 return undef if !qemu_netdevdel($vmid, $deviceid);
2446 qemu_devicedel($vmid, $deviceid);
2447 return undef if !qemu_devicedelverify($vmid, $deviceid);
2448 }
2449
5e5dcb73
DA
2450 return 1;
2451}
2452
2453sub qemu_deviceadd {
2454 my ($vmid, $devicefull) = @_;
873c2d69 2455
7b7c6d1b 2456 my $ret = vm_human_monitor_command($vmid, "device_add $devicefull");
5e5dcb73 2457 $ret =~ s/^\s+//;
afdb31d5 2458 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
5e5dcb73
DA
2459 return 1 if $ret eq "";
2460 syslog("err", "error on hotplug device : $ret");
2461 return undef;
f19d1c47 2462
5e5dcb73 2463}
afdb31d5 2464
5e5dcb73
DA
2465sub qemu_devicedel {
2466 my($vmid, $deviceid) = @_;
f19d1c47 2467
7b7c6d1b 2468 my $ret = vm_human_monitor_command($vmid, "device_del $deviceid");
5e5dcb73
DA
2469 $ret =~ s/^\s+//;
2470 return 1 if $ret eq "";
2471 syslog("err", "detaching device $deviceid failed : $ret");
2472 return undef;
2473}
2474
2475sub qemu_driveadd {
2476 my($storecfg, $vmid, $device) = @_;
2477
2478 my $drive = print_drive_full($storecfg, $vmid, $device);
7b7c6d1b 2479 my $ret = vm_human_monitor_command($vmid, "drive_add auto $drive");
5e5dcb73
DA
2480 # If the command succeeds qemu prints: "OK"
2481 if ($ret !~ m/OK/s) {
2482 syslog("err", "adding drive failed: $ret");
2483 return undef;
f19d1c47 2484 }
5e5dcb73
DA
2485 return 1;
2486}
afdb31d5 2487
5e5dcb73
DA
2488sub qemu_drivedel {
2489 my($vmid, $deviceid) = @_;
873c2d69 2490
7b7c6d1b 2491 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
5e5dcb73
DA
2492 $ret =~ s/^\s+//;
2493 if ($ret =~ m/Device \'.*?\' not found/s) {
afdb31d5 2494 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
5e5dcb73
DA
2495 }
2496 elsif ($ret ne "") {
2497 syslog("err", "deleting drive $deviceid failed : $ret");
2498 return undef;
873c2d69 2499 }
5e5dcb73
DA
2500 return 1;
2501}
f19d1c47 2502
5e5dcb73
DA
2503sub qemu_deviceaddverify {
2504 my ($vmid,$deviceid) = @_;
873c2d69 2505
5e5dcb73
DA
2506 for (my $i = 0; $i <= 5; $i++) {
2507 my $devices_list = vm_devices_list($vmid);
2508 return 1 if defined($devices_list->{$deviceid});
2509 sleep 1;
afdb31d5 2510 }
5e5dcb73
DA
2511 syslog("err", "error on hotplug device $deviceid");
2512 return undef;
2513}
afdb31d5 2514
5e5dcb73
DA
2515
2516sub qemu_devicedelverify {
2517 my ($vmid,$deviceid) = @_;
2518
2519 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2520 for (my $i = 0; $i <= 5; $i++) {
2521 my $devices_list = vm_devices_list($vmid);
2522 return 1 if !defined($devices_list->{$deviceid});
2523 sleep 1;
afdb31d5 2524 }
5e5dcb73
DA
2525 syslog("err", "error on hot-unplugging device $deviceid");
2526 return undef;
873c2d69
DA
2527}
2528
cdd20088 2529sub qemu_findorcreatescsihw {
cfc817c7
DA
2530 my ($storecfg, $conf, $vmid, $device) = @_;
2531
cdd20088 2532 my $maxdev = ($conf->{scsihw} && $conf->{scsihw} ne 'lsi') ? 256 : 7;
cfc817c7 2533 my $controller = int($device->{index} / $maxdev);
cdd20088 2534 my $scsihwid="scsihw$controller";
cfc817c7
DA
2535 my $devices_list = vm_devices_list($vmid);
2536
cdd20088
AD
2537 if(!defined($devices_list->{$scsihwid})) {
2538 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $scsihwid);
cfc817c7
DA
2539 }
2540 return 1;
2541}
2542
40f28a9f
AD
2543sub qemu_bridgeadd {
2544 my ($storecfg, $conf, $vmid, $device) = @_;
2545
2546 my $bridges = {};
2547 my $bridgeid = undef;
2548 print_pci_addr($device, $bridges);
2549
2550 while (my ($k, $v) = each %$bridges) {
2551 $bridgeid = $k;
2552 }
2553 return if $bridgeid < 1;
2554 my $bridge = "pci.$bridgeid";
2555 my $devices_list = vm_devices_list($vmid);
2556
2557 if(!defined($devices_list->{$bridge})) {
2558 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $bridge);
2559 }
2560 return 1;
2561}
2562
2630d2a9
DA
2563sub qemu_netdevadd {
2564 my ($vmid, $conf, $device, $deviceid) = @_;
2565
2566 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
7b7c6d1b 2567 my $ret = vm_human_monitor_command($vmid, "netdev_add $netdev");
2630d2a9
DA
2568 $ret =~ s/^\s+//;
2569
97d62eb7 2570 #if the command succeeds, no output is sent. So any non-empty string shows an error
2630d2a9
DA
2571 return 1 if $ret eq "";
2572 syslog("err", "adding netdev failed: $ret");
2573 return undef;
2574}
2575
2576sub qemu_netdevdel {
2577 my ($vmid, $deviceid) = @_;
2578
7b7c6d1b 2579 my $ret = vm_human_monitor_command($vmid, "netdev_del $deviceid");
2630d2a9 2580 $ret =~ s/^\s+//;
97d62eb7 2581 #if the command succeeds, no output is sent. So any non-empty string shows an error
2630d2a9
DA
2582 return 1 if $ret eq "";
2583 syslog("err", "deleting netdev failed: $ret");
2584 return undef;
2585}
2586
affd2f88
AD
2587sub qemu_block_set_io_throttle {
2588 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2589
f3f323a3
AD
2590 return if !check_running($vmid) ;
2591
affd2f88
AD
2592 $bps = 0 if !$bps;
2593 $bps_rd = 0 if !$bps_rd;
2594 $bps_wr = 0 if !$bps_wr;
2595 $iops = 0 if !$iops;
2596 $iops_rd = 0 if !$iops_rd;
2597 $iops_wr = 0 if !$iops_wr;
2598
f3f323a3
AD
2599 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));
2600
affd2f88
AD
2601}
2602
f5eb281a 2603# old code, only used to shutdown old VM after update
dab36e1e
DM
2604sub __read_avail {
2605 my ($fh, $timeout) = @_;
2606
2607 my $sel = new IO::Select;
2608 $sel->add($fh);
2609
2610 my $res = '';
2611 my $buf;
2612
2613 my @ready;
2614 while (scalar (@ready = $sel->can_read($timeout))) {
2615 my $count;
2616 if ($count = $fh->sysread($buf, 8192)) {
2617 if ($buf =~ /^(.*)\(qemu\) $/s) {
2618 $res .= $1;
2619 last;
2620 } else {
2621 $res .= $buf;
2622 }
2623 } else {
2624 if (!defined($count)) {
2625 die "$!\n";
2626 }
2627 last;
2628 }
2629 }
2630
2631 die "monitor read timeout\n" if !scalar(@ready);
f5eb281a 2632
dab36e1e
DM
2633 return $res;
2634}
2635
f5eb281a 2636# old code, only used to shutdown old VM after update
dab36e1e
DM
2637sub vm_monitor_command {
2638 my ($vmid, $cmdstr, $nocheck) = @_;
f5eb281a 2639
dab36e1e
DM
2640 my $res;
2641
2642 eval {
2643 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
2644
2645 my $sname = "${var_run_tmpdir}/$vmid.mon";
2646
2647 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
2648 die "unable to connect to VM $vmid socket - $!\n";
2649
2650 my $timeout = 3;
2651
2652 # hack: migrate sometime blocks the monitor (when migrate_downtime
2653 # is set)
2654 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2655 $timeout = 60*60; # 1 hour
2656 }
2657
2658 # read banner;
2659 my $data = __read_avail($sock, $timeout);
2660
2661 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2662 die "got unexpected qemu monitor banner\n";
2663 }
2664
2665 my $sel = new IO::Select;
2666 $sel->add($sock);
2667
2668 if (!scalar(my @ready = $sel->can_write($timeout))) {
2669 die "monitor write error - timeout";
2670 }
2671
2672 my $fullcmd = "$cmdstr\r";
2673
2674 # syslog('info', "VM $vmid monitor command: $cmdstr");
2675
2676 my $b;
2677 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2678 die "monitor write error - $!";
2679 }
2680
2681 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2682
2683 $timeout = 20;
2684
2685 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2686 $timeout = 60*60; # 1 hour
2687 } elsif ($cmdstr =~ m/^(eject|change)/) {
2688 $timeout = 60; # note: cdrom mount command is slow
2689 }
2690 if ($res = __read_avail($sock, $timeout)) {
2691
2692 my @lines = split("\r?\n", $res);
f5eb281a 2693
dab36e1e 2694 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
f5eb281a 2695
dab36e1e
DM
2696 $res = join("\n", @lines);
2697 $res .= "\n";
2698 }
2699 };
2700
2701 my $err = $@;
2702
2703 if ($err) {
2704 syslog("err", "VM $vmid monitor command failed - $err");
2705 die $err;
2706 }
f5eb281a 2707
dab36e1e
DM
2708 return $res;
2709}
2710
c1175c92
AD
2711sub qemu_block_resize {
2712 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2713
2714 my $running = PVE::QemuServer::check_running($vmid);
2715
2716 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
2717
2718 return if !$running;
2719
2720 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
2721
2722}
2723
1e3baf05 2724sub vm_start {
7e8dcf2c 2725 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom) = @_;
1e3baf05 2726
6b64503e 2727 lock_config($vmid, sub {
7e8dcf2c 2728 my $conf = load_config($vmid, $migratedfrom);
1e3baf05 2729
6b64503e 2730 check_lock($conf) if !$skiplock;
1e3baf05 2731
7e8dcf2c 2732 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
1e3baf05
DM
2733
2734 my $migrate_uri;
2735 my $migrate_port = 0;
2736
2737 if ($statefile) {
2738 if ($statefile eq 'tcp') {
2739 $migrate_port = next_migrate_port();
2740 $migrate_uri = "tcp:localhost:${migrate_port}";
2741 } else {
2742 if (-f $statefile) {
2743 $migrate_uri = "exec:cat $statefile";
2744 } else {
2745 warn "state file '$statefile' does not exist - doing normal startup\n";
2746 }
2747 }
2748 }
2749
2750 my $defaults = load_defaults();
2751
d691e6d3
DM
2752 # set environment variable useful inside network script
2753 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
2754
e6c3b671 2755 my ($cmd, $vollist) = config_to_command($storecfg, $vmid, $conf, $defaults, $migrate_uri);
1e3baf05 2756 # host pci devices
040b06b7
DA
2757 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2758 my $d = parse_hostpci($conf->{"hostpci$i"});
2759 next if !$d;
2760 my $info = pci_device_info("0000:$d->{pciid}");
2761 die "IOMMU not present\n" if !check_iommu_support();
2762 die "no pci device info for device '$d->{pciid}'\n" if !$info;
2763 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub($info);
2764 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset($info);
2765 }
1e3baf05
DM
2766
2767 PVE::Storage::activate_volumes($storecfg, $vollist);
2768
6b64503e 2769 eval { run_command($cmd, timeout => $migrate_uri ? undef : 30); };
1e3baf05 2770 my $err = $@;
ff1a2432 2771 die "start failed: $err" if $err;
1e3baf05
DM
2772
2773 if ($statefile) {
2774
2775 if ($statefile eq 'tcp') {
2776 print "migration listens on port $migrate_port\n";
2777 } else {
2778 unlink $statefile;
2779 # fixme: send resume - is that necessary ?
60816474 2780 eval { vm_mon_cmd($vmid, "cont"); };
1e3baf05
DM
2781 }
2782 }
afdb31d5 2783
48e1a963
DM
2784 # always set migrate speed (overwrite kvm default of 32m)
2785 # we set a very hight default of 8192m which is basically unlimited
2786 my $migrate_speed = $defaults->{migrate_speed} || 8192;
2787 $migrate_speed = $conf->{migrate_speed} || $migrate_speed;
2f674c7a 2788 $migrate_speed = $migrate_speed * 1048576;
afdb31d5 2789 eval {
2f674c7a 2790 vm_mon_cmd($vmid, "migrate_set_speed", value => $migrate_speed);
48e1a963 2791 };
1e3baf05 2792
71c11a83
DM
2793 my $migrate_downtime = $defaults->{migrate_downtime};
2794 $migrate_downtime = $conf->{migrate_downtime} if defined($conf->{migrate_downtime});
2795 if (defined($migrate_downtime)) {
bcb7c9cf 2796 eval { vm_mon_cmd($vmid, "migrate_set_downtime", value => $migrate_downtime); };
1e3baf05 2797 }
e6c3b671 2798
e18b0b99
AD
2799 if($migratedfrom) {
2800 my $capabilities = {};
2801 $capabilities->{capability} = "xbzrle";
2802 $capabilities->{state} = JSON::true;
2803 eval { PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => [$capabilities]); };
2804 }
2805
7878afeb 2806 vm_balloonset($vmid, $conf->{balloon}) if $conf->{balloon};
ce332eeb 2807
1e3baf05
DM
2808 });
2809}
2810
0eedc444
AD
2811sub vm_mon_cmd {
2812 my ($vmid, $execute, %params) = @_;
2813
26f11676
DM
2814 my $cmd = { execute => $execute, arguments => \%params };
2815 vm_qmp_command($vmid, $cmd);
0eedc444
AD
2816}
2817
2818sub vm_mon_cmd_nocheck {
2819 my ($vmid, $execute, %params) = @_;
2820
26f11676
DM
2821 my $cmd = { execute => $execute, arguments => \%params };
2822 vm_qmp_command($vmid, $cmd, 1);
0eedc444
AD
2823}
2824
c971c4f2 2825sub vm_qmp_command {
d967756b 2826 my ($vmid, $cmd, $nocheck) = @_;
97d62eb7 2827
c971c4f2 2828 my $res;
26f11676 2829
14db5366
DM
2830 my $timeout;
2831 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
2832 $timeout = $cmd->{arguments}->{timeout};
2833 delete $cmd->{arguments}->{timeout};
2834 }
2835
c971c4f2
AD
2836 eval {
2837 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
dab36e1e 2838 my $sname = PVE::QemuServer::qmp_socket($vmid);
f5eb281a 2839 if (-e $sname) {
dab36e1e
DM
2840 my $qmpclient = PVE::QMPClient->new();
2841
14db5366 2842 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
dab36e1e
DM
2843 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
2844 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
2845 if scalar(%{$cmd->{arguments}});
2846 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
2847 } else {
2848 die "unable to open monitor socket\n";
2849 }
c971c4f2 2850 };
26f11676 2851 if (my $err = $@) {
c971c4f2
AD
2852 syslog("err", "VM $vmid qmp command failed - $err");
2853 die $err;
2854 }
2855
2856 return $res;
2857}
2858
9df5cbcc
DM
2859sub vm_human_monitor_command {
2860 my ($vmid, $cmdline) = @_;
2861
2862 my $res;
2863
f5eb281a 2864 my $cmd = {
9df5cbcc
DM
2865 execute => 'human-monitor-command',
2866 arguments => { 'command-line' => $cmdline},
2867 };
2868
2869 return vm_qmp_command($vmid, $cmd);
2870}
2871
1e3baf05
DM
2872sub vm_commandline {
2873 my ($storecfg, $vmid) = @_;
2874
6b64503e 2875 my $conf = load_config($vmid);
1e3baf05
DM
2876
2877 my $defaults = load_defaults();
2878
6b64503e 2879 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 2880
6b64503e 2881 return join(' ', @$cmd);
1e3baf05
DM
2882}
2883
2884sub vm_reset {
2885 my ($vmid, $skiplock) = @_;
2886
6b64503e 2887 lock_config($vmid, sub {
1e3baf05 2888
6b64503e 2889 my $conf = load_config($vmid);
1e3baf05 2890
6b64503e 2891 check_lock($conf) if !$skiplock;
1e3baf05 2892
816e2c4a 2893 vm_mon_cmd($vmid, "system_reset");
ff1a2432
DM
2894 });
2895}
2896
2897sub get_vm_volumes {
2898 my ($conf) = @_;
1e3baf05 2899
ff1a2432
DM
2900 my $vollist = [];
2901 foreach_drive($conf, sub {
2902 my ($ds, $drive) = @_;
2903
2904 my ($sid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
2905 return if !$sid;
2906
2907 my $volid = $drive->{file};
2908 return if !$volid || $volid =~ m|^/|;
2909
2910 push @$vollist, $volid;
1e3baf05 2911 });
ff1a2432
DM
2912
2913 return $vollist;
2914}
2915
2916sub vm_stop_cleanup {
254575e9 2917 my ($storecfg, $vmid, $conf, $keepActive) = @_;
ff1a2432 2918
745fed70
DM
2919 eval {
2920 fairsched_rmnod($vmid); # try to destroy group
ff1a2432 2921
254575e9
DM
2922 if (!$keepActive) {
2923 my $vollist = get_vm_volumes($conf);
2924 PVE::Storage::deactivate_volumes($storecfg, $vollist);
2925 }
961bfcb2 2926
eb26097e 2927 foreach my $ext (qw(mon qmp pid vnc)) {
961bfcb2
DM
2928 unlink "/var/run/qemu-server/${vmid}.$ext";
2929 }
745fed70
DM
2930 };
2931 warn $@ if $@; # avoid errors - just warn
1e3baf05
DM
2932}
2933
e6c3b671 2934# Note: use $nockeck to skip tests if VM configuration file exists.
254575e9
DM
2935# We need that when migration VMs to other nodes (files already moved)
2936# Note: we set $keepActive in vzdump stop mode - volumes need to stay active
1e3baf05 2937sub vm_stop {
af30308f 2938 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
9269013a 2939
9269013a 2940 $force = 1 if !defined($force) && !$shutdown;
1e3baf05 2941
af30308f
DM
2942 if ($migratedfrom){
2943 my $pid = check_running($vmid, $nocheck, $migratedfrom);
2944 kill 15, $pid if $pid;
2945 my $conf = load_config($vmid, $migratedfrom);
2946 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive);
2947 return;
2948 }
2949
e6c3b671 2950 lock_config($vmid, sub {
1e3baf05 2951
e6c3b671 2952 my $pid = check_running($vmid, $nocheck);
ff1a2432 2953 return if !$pid;
1e3baf05 2954
ff1a2432 2955 my $conf;
e6c3b671 2956 if (!$nocheck) {
ff1a2432 2957 $conf = load_config($vmid);
e6c3b671 2958 check_lock($conf) if !$skiplock;
7f4a5b5a
DM
2959 if (!defined($timeout) && $shutdown && $conf->{startup}) {
2960 my $opts = parse_startup($conf->{startup});
2961 $timeout = $opts->{down} if $opts->{down};
2962 }
e6c3b671 2963 }
19672434 2964
7f4a5b5a
DM
2965 $timeout = 60 if !defined($timeout);
2966
9269013a
DM
2967 eval {
2968 if ($shutdown) {
988903ca 2969 $nocheck ? vm_mon_cmd_nocheck($vmid, "system_powerdown") : vm_mon_cmd($vmid, "system_powerdown");
bcb7c9cf 2970
9269013a 2971 } else {
988903ca 2972 $nocheck ? vm_mon_cmd_nocheck($vmid, "quit") : vm_mon_cmd($vmid, "quit");
afdb31d5 2973 }
9269013a 2974 };
1e3baf05
DM
2975 my $err = $@;
2976
2977 if (!$err) {
1e3baf05 2978 my $count = 0;
e6c3b671 2979 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
2980 $count++;
2981 sleep 1;
2982 }
2983
2984 if ($count >= $timeout) {
9269013a
DM
2985 if ($force) {
2986 warn "VM still running - terminating now with SIGTERM\n";
2987 kill 15, $pid;
2988 } else {
2989 die "VM quit/powerdown failed - got timeout\n";
2990 }
2991 } else {
254575e9 2992 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
9269013a 2993 return;
1e3baf05
DM
2994 }
2995 } else {
9269013a
DM
2996 if ($force) {
2997 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
2998 kill 15, $pid;
2999 } else {
afdb31d5 3000 die "VM quit/powerdown failed\n";
9269013a 3001 }
1e3baf05
DM
3002 }
3003
3004 # wait again
ff1a2432 3005 $timeout = 10;
1e3baf05
DM
3006
3007 my $count = 0;
e6c3b671 3008 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
3009 $count++;
3010 sleep 1;
3011 }
3012
3013 if ($count >= $timeout) {
ff1a2432 3014 warn "VM still running - terminating now with SIGKILL\n";
1e3baf05 3015 kill 9, $pid;
ff1a2432 3016 sleep 1;
1e3baf05
DM
3017 }
3018
254575e9 3019 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
ff1a2432 3020 });
1e3baf05
DM
3021}
3022
3023sub vm_suspend {
3024 my ($vmid, $skiplock) = @_;
3025
6b64503e 3026 lock_config($vmid, sub {
1e3baf05 3027
6b64503e 3028 my $conf = load_config($vmid);
1e3baf05 3029
6b64503e 3030 check_lock($conf) if !$skiplock;
bcb7c9cf 3031
f77f91f3 3032 vm_mon_cmd($vmid, "stop");
1e3baf05
DM
3033 });
3034}
3035
3036sub vm_resume {
3037 my ($vmid, $skiplock) = @_;
3038
6b64503e 3039 lock_config($vmid, sub {
1e3baf05 3040
6b64503e 3041 my $conf = load_config($vmid);
1e3baf05 3042
6b64503e 3043 check_lock($conf) if !$skiplock;
1e3baf05 3044
12060fe8 3045 vm_mon_cmd($vmid, "cont");
1e3baf05
DM
3046 });
3047}
3048
5fdbe4f0
DM
3049sub vm_sendkey {
3050 my ($vmid, $skiplock, $key) = @_;
1e3baf05 3051
6b64503e 3052 lock_config($vmid, sub {
1e3baf05 3053
6b64503e 3054 my $conf = load_config($vmid);
f5eb281a 3055
7b7c6d1b
DM
3056 # there is no qmp command, so we use the human monitor command
3057 vm_human_monitor_command($vmid, "sendkey $key");
1e3baf05
DM
3058 });
3059}
3060
3061sub vm_destroy {
3062 my ($storecfg, $vmid, $skiplock) = @_;
3063
6b64503e 3064 lock_config($vmid, sub {
1e3baf05 3065
6b64503e 3066 my $conf = load_config($vmid);
1e3baf05 3067
6b64503e 3068 check_lock($conf) if !$skiplock;
1e3baf05 3069
ff1a2432
DM
3070 if (!check_running($vmid)) {
3071 fairsched_rmnod($vmid); # try to destroy group
3072 destroy_vm($storecfg, $vmid);
3073 } else {
3074 die "VM $vmid is running - destroy failed\n";
1e3baf05
DM
3075 }
3076 });
3077}
3078
1e3baf05
DM
3079# pci helpers
3080
3081sub file_write {
3082 my ($filename, $buf) = @_;
3083
6b64503e 3084 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
3085 return undef if !$fh;
3086
3087 my $res = print $fh $buf;
3088
3089 $fh->close();
3090
3091 return $res;
3092}
3093
3094sub pci_device_info {
3095 my ($name) = @_;
3096
3097 my $res;
3098
3099 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3100 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3101
3102 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
3103 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3104
3105 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
3106 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3107
3108 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
3109 return undef if !defined($product) || $product !~ s/^0x//;
3110
3111 $res = {
3112 name => $name,
3113 vendor => $vendor,
3114 product => $product,
3115 domain => $domain,
3116 bus => $bus,
3117 slot => $slot,
3118 func => $func,
3119 irq => $irq,
3120 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
3121 };
3122
3123 return $res;
3124}
3125
3126sub pci_dev_reset {
3127 my ($dev) = @_;
3128
3129 my $name = $dev->{name};
3130
3131 my $fn = "$pcisysfs/devices/$name/reset";
3132
6b64503e 3133 return file_write($fn, "1");
1e3baf05
DM
3134}
3135
3136sub pci_dev_bind_to_stub {
3137 my ($dev) = @_;
3138
3139 my $name = $dev->{name};
3140
3141 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3142 return 1 if -d $testdir;
3143
3144 my $data = "$dev->{vendor} $dev->{product}";
6b64503e 3145 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
1e3baf05
DM
3146
3147 my $fn = "$pcisysfs/devices/$name/driver/unbind";
6b64503e 3148 if (!file_write($fn, $name)) {
1e3baf05
DM
3149 return undef if -f $fn;
3150 }
3151
3152 $fn = "$pcisysfs/drivers/pci-stub/bind";
3153 if (! -d $testdir) {
6b64503e 3154 return undef if !file_write($fn, $name);
1e3baf05
DM
3155 }
3156
3157 return -d $testdir;
3158}
3159
afdb31d5 3160sub print_pci_addr {
5bdcf937 3161 my ($id, $bridges) = @_;
6b64503e 3162
72a063e4 3163 my $res = '';
6b64503e 3164 my $devices = {
e5f7f8ed
DA
3165 #addr1 : ide,parallel,serial (motherboard)
3166 #addr2 : first videocard
13b5a753 3167 balloon0 => { bus => 0, addr => 3 },
0a40e8ea 3168 watchdog => { bus => 0, addr => 4 },
cdd20088
AD
3169 scsihw0 => { bus => 0, addr => 5 },
3170 scsihw1 => { bus => 0, addr => 6 },
26ee04b6 3171 ahci0 => { bus => 0, addr => 7 },
6b64503e
DM
3172 virtio0 => { bus => 0, addr => 10 },
3173 virtio1 => { bus => 0, addr => 11 },
3174 virtio2 => { bus => 0, addr => 12 },
3175 virtio3 => { bus => 0, addr => 13 },
3176 virtio4 => { bus => 0, addr => 14 },
3177 virtio5 => { bus => 0, addr => 15 },
b78ebef7
DA
3178 hostpci0 => { bus => 0, addr => 16 },
3179 hostpci1 => { bus => 0, addr => 17 },
f290f8d9
DA
3180 net0 => { bus => 0, addr => 18 },
3181 net1 => { bus => 0, addr => 19 },
3182 net2 => { bus => 0, addr => 20 },
3183 net3 => { bus => 0, addr => 21 },
3184 net4 => { bus => 0, addr => 22 },
3185 net5 => { bus => 0, addr => 23 },
e5f7f8ed 3186 #addr29 : usb-host (pve-usb.cfg)
5bdcf937
AD
3187 'pci.1' => { bus => 0, addr => 30 },
3188 'pci.2' => { bus => 0, addr => 31 },
3189 'net6' => { bus => 1, addr => 1 },
3190 'net7' => { bus => 1, addr => 2 },
3191 'net8' => { bus => 1, addr => 3 },
3192 'net9' => { bus => 1, addr => 4 },
3193 'net10' => { bus => 1, addr => 5 },
3194 'net11' => { bus => 1, addr => 6 },
3195 'net12' => { bus => 1, addr => 7 },
3196 'net13' => { bus => 1, addr => 8 },
3197 'net14' => { bus => 1, addr => 9 },
3198 'net15' => { bus => 1, addr => 10 },
3199 'net16' => { bus => 1, addr => 11 },
3200 'net17' => { bus => 1, addr => 12 },
3201 'net18' => { bus => 1, addr => 13 },
3202 'net19' => { bus => 1, addr => 14 },
3203 'net20' => { bus => 1, addr => 15 },
3204 'net21' => { bus => 1, addr => 16 },
3205 'net22' => { bus => 1, addr => 17 },
3206 'net23' => { bus => 1, addr => 18 },
3207 'net24' => { bus => 1, addr => 19 },
3208 'net25' => { bus => 1, addr => 20 },
3209 'net26' => { bus => 1, addr => 21 },
3210 'net27' => { bus => 1, addr => 22 },
3211 'net28' => { bus => 1, addr => 23 },
3212 'net29' => { bus => 1, addr => 24 },
3213 'net30' => { bus => 1, addr => 25 },
3214 'net31' => { bus => 1, addr => 26 },
3215 'virtio6' => { bus => 2, addr => 1 },
3216 'virtio7' => { bus => 2, addr => 2 },
3217 'virtio8' => { bus => 2, addr => 3 },
3218 'virtio9' => { bus => 2, addr => 4 },
3219 'virtio10' => { bus => 2, addr => 5 },
3220 'virtio11' => { bus => 2, addr => 6 },
3221 'virtio12' => { bus => 2, addr => 7 },
3222 'virtio13' => { bus => 2, addr => 8 },
3223 'virtio14' => { bus => 2, addr => 9 },
3224 'virtio15' => { bus => 2, addr => 10 },
6b64503e
DM
3225 };
3226
3227 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
72a063e4 3228 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
5bdcf937
AD
3229 my $bus = $devices->{$id}->{bus};
3230 $res = ",bus=pci.$bus,addr=$addr";
98627641 3231 $bridges->{$bus} = 1 if $bridges;
72a063e4
DA
3232 }
3233 return $res;
3234
3235}
3236
13a48620 3237sub vm_balloonset {
7878afeb 3238 my ($vmid, $value) = @_;
13a48620 3239
2d23ddc5 3240 vm_mon_cmd($vmid, "balloon", value => $value);
13a48620
DA
3241}
3242
3e16d5fc
DM
3243# vzdump restore implementaion
3244
3245sub archive_read_firstfile {
3246 my $archive = shift;
afdb31d5 3247
3e16d5fc
DM
3248 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
3249
3250 # try to detect archive type first
3251 my $pid = open (TMP, "tar tf '$archive'|") ||
3252 die "unable to open file '$archive'\n";
3253 my $firstfile = <TMP>;
3254 kill 15, $pid;
3255 close TMP;
3256
3257 die "ERROR: archive contaions no data\n" if !$firstfile;
3258 chomp $firstfile;
3259
3260 return $firstfile;
3261}
3262
3263sub restore_cleanup {
3264 my $statfile = shift;
3265
3266 print STDERR "starting cleanup\n";
3267
3268 if (my $fd = IO::File->new($statfile, "r")) {
3269 while (defined(my $line = <$fd>)) {
3270 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3271 my $volid = $2;
3272 eval {
3273 if ($volid =~ m|^/|) {
3274 unlink $volid || die 'unlink failed\n';
3275 } else {
3276 my $cfg = cfs_read_file('storage.cfg');
3277 PVE::Storage::vdisk_free($cfg, $volid);
3278 }
afdb31d5 3279 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3e16d5fc
DM
3280 };
3281 print STDERR "unable to cleanup '$volid' - $@" if $@;
3282 } else {
3283 print STDERR "unable to parse line in statfile - $line";
afdb31d5 3284 }
3e16d5fc
DM
3285 }
3286 $fd->close();
3287 }
3288}
3289
3290sub restore_archive {
a0d1b1a2 3291 my ($archive, $vmid, $user, $opts) = @_;
3e16d5fc 3292
9c502e26
DM
3293 if ($archive ne '-') {
3294 my $firstfile = archive_read_firstfile($archive);
3295 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
3296 if $firstfile ne 'qemu-server.conf';
3297 }
3e16d5fc
DM
3298
3299 my $tocmd = "/usr/lib/qemu-server/qmextract";
3300
2415a446 3301 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 3302 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
3303 $tocmd .= ' --prealloc' if $opts->{prealloc};
3304 $tocmd .= ' --info' if $opts->{info};
3305
a0d1b1a2 3306 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 3307 # so we pipe to zcat
2415a446
DM
3308 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
3309 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
3310
3311 my $tmpdir = "/var/tmp/vzdumptmp$$";
3312 mkpath $tmpdir;
3313
3314 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
3315 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 3316 local $ENV{VZDUMP_USER} = $user;
3e16d5fc
DM
3317
3318 my $conffile = PVE::QemuServer::config_file($vmid);
3319 my $tmpfn = "$conffile.$$.tmp";
3320
3321 # disable interrupts (always do cleanups)
3322 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
3323 print STDERR "got interrupt - ignored\n";
3324 };
3325
afdb31d5 3326 eval {
3e16d5fc
DM
3327 # enable interrupts
3328 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
3329 die "interrupted by signal\n";
3330 };
3331
9c502e26
DM
3332 if ($archive eq '-') {
3333 print "extracting archive from STDIN\n";
3334 run_command($cmd, input => "<&STDIN");
3335 } else {
3336 print "extracting archive '$archive'\n";
3337 run_command($cmd);
3338 }
3e16d5fc
DM
3339
3340 return if $opts->{info};
3341
3342 # read new mapping
3343 my $map = {};
3344 my $statfile = "$tmpdir/qmrestore.stat";
3345 if (my $fd = IO::File->new($statfile, "r")) {
3346 while (defined (my $line = <$fd>)) {
3347 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3348 $map->{$1} = $2 if $1;
3349 } else {
3350 print STDERR "unable to parse line in statfile - $line\n";
3351 }
3352 }
3353 $fd->close();
3354 }
3355
3356 my $confsrc = "$tmpdir/qemu-server.conf";
3357
3358 my $srcfd = new IO::File($confsrc, "r") ||
3359 die "unable to open file '$confsrc'\n";
3360
3361 my $outfd = new IO::File ($tmpfn, "w") ||
3362 die "unable to write config for VM $vmid\n";
3363
51586c3a
DM
3364 my $netcount = 0;
3365
3e16d5fc
DM
3366 while (defined (my $line = <$srcfd>)) {
3367 next if $line =~ m/^\#vzdump\#/;
3368 next if $line =~ m/^lock:/;
3369 next if $line =~ m/^unused\d+:/;
3370
51586c3a
DM
3371 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3372 # try to convert old 1.X settings
3373 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3374 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
3375 my ($model, $macaddr) = split(/\=/, $devconfig);
3376 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $opts->{unique};
3377 my $net = {
3378 model => $model,
3379 bridge => "vmbr$ind",
3380 macaddr => $macaddr,
3381 };
3382 my $netstr = print_net($net);
3383 print $outfd "net${netcount}: $netstr\n";
3384 $netcount++;
3385 }
3386 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && ($opts->{unique})) {
3387 my ($id, $netstr) = ($1, $2);
3388 my $net = parse_net($netstr);
3389 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
3390 $netstr = print_net($net);
afdb31d5 3391 print $outfd "$id: $netstr\n";
51586c3a 3392 } elsif ($line =~ m/^((ide|scsi|virtio)\d+):\s*(\S+)\s*$/) {
3e16d5fc
DM
3393 my $virtdev = $1;
3394 my $value = $2;
3395 if ($line =~ m/backup=no/) {
3396 print $outfd "#$line";
3397 } elsif ($virtdev && $map->{$virtdev}) {
3398 my $di = PVE::QemuServer::parse_drive($virtdev, $value);
3399 $di->{file} = $map->{$virtdev};
3400 $value = PVE::QemuServer::print_drive($vmid, $di);
3401 print $outfd "$virtdev: $value\n";
3402 } else {
3403 print $outfd $line;
3404 }
3405 } else {
3406 print $outfd $line;
3407 }
3408 }
3409
3410 $srcfd->close();
3411 $outfd->close();
3412 };
3413 my $err = $@;
3414
afdb31d5 3415 if ($err) {
3e16d5fc
DM
3416
3417 unlink $tmpfn;
3418
3419 restore_cleanup("$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 3420
3e16d5fc 3421 die $err;
afdb31d5 3422 }
3e16d5fc
DM
3423
3424 rmtree $tmpdir;
3425
3426 rename $tmpfn, $conffile ||
3427 die "unable to commit configuration file '$conffile'\n";
3428};
3429
1e3baf05 34301;