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