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