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