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