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