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