]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
add 'lsi53c810' to the list of scsi controllers
[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",
5b952ff5 237 enum => [qw(lsi lsi53c810 virtio-scsi-pci megasas pvscsi)],
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',
e4c6e0b8 468 'ne2k_isa', 'i82551', 'i82557b', 'i82559er', 'vmxnet3'];
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',
8d87f8aa 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] [,discard=ignore|on]',
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',
8d87f8aa 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] [,discard=ignore|on]',
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',
8d87f8aa 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] [,discard=ignore|on]',
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',
8d87f8aa 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] [,discard=ignore|on]',
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]
8d87f8aa 869# [,aio=native|threads][,discard=ignore|on]
1e3baf05
DM
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
8d87f8aa 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|discard)=(.+)$/) {
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)$/;
8d87f8aa 931 return undef if $res->{discard} && $res->{discard} !~ m/^(ignore|on)$/;
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
8d87f8aa 965my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio discard 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') {
5b952ff5 1053 $maxdev = ($conf->{scsihw} && ($conf->{scsihw} !~ m/^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
5b952ff5
DM
1080 if (!$conf->{scsihw} || ($conf->{scsihw} =~ m/^lsi/)){
1081 $device = "scsi-$devicetype,bus=scsihw$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
cdd20088
AD
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 1222
e4c6e0b8 1223 if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er|vmxnet3)(=([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
4dc339e7
AD
2454 push @$cpuFlags , '+lahf_lm' if $cpu eq 'kvm64';
2455
6b9d84cf
AD
2456 push @$cpuFlags , '+x2apic' if !$nokvm && $conf->{ostype} ne 'solaris';
2457
2458 push @$cpuFlags , '-x2apic' if $conf->{ostype} eq 'solaris';
519ed28c 2459
2e1a5389
AD
2460 push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32';
2461
be190583 2462 $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags);
519ed28c
AD
2463
2464 push @$cmd, '-cpu', $cpu;
2465
1e3baf05
DM
2466 push @$cmd, '-S' if $conf->{freeze};
2467
2468 # set keyboard layout
2469 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2470 push @$cmd, '-k', $kb if $kb;
2471
2472 # enable sound
2473 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2474 #push @$cmd, '-soundhw', 'es1370';
2475 #push @$cmd, '-soundhw', $soundhw if $soundhw;
ab6a046f 2476
bc84dcca 2477 if($conf->{agent}) {
ab6a046f
AD
2478 my $qgasocket = qga_socket($vmid);
2479 my $pciaddr = print_pci_addr("qga0", $bridges);
2480 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2481 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2482 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2483 }
2484
1d794448 2485 my $spice_port;
2fa3151e 2486
590e698c
DM
2487 if ($qxlnum) {
2488 if ($qxlnum > 1) {
2489 if ($conf->{ostype} && $conf->{ostype} =~ m/^w/){
2490 for(my $i = 1; $i < $qxlnum; $i++){
2491 my $pciaddr = print_pci_addr("vga$i", $bridges);
2492 push @$cmd, '-device', "qxl,id=vga$i,ram_size=67108864,vram_size=33554432$pciaddr";
2493 }
2494 } else {
2495 # assume other OS works like Linux
2496 push @$cmd, '-global', 'qxl-vga.ram_size=134217728';
2497 push @$cmd, '-global', 'qxl-vga.vram_size=67108864';
2fa3151e
AD
2498 }
2499 }
2500
1011b570 2501 my $pciaddr = print_pci_addr("spice", $bridges);
95a4b4a9 2502
1d794448 2503 $spice_port = PVE::Tools::next_unused_port(61000, 61099);
943340a6 2504
1d794448 2505 push @$cmd, '-spice', "tls-port=${spice_port},addr=127.0.0.1,tls-ciphers=DES-CBC3-SHA,seamless-migration=on";
1011b570 2506
1011b570
DM
2507 push @$cmd, '-device', "virtio-serial,id=spice$pciaddr";
2508 push @$cmd, '-chardev', "spicevmc,id=vdagent,name=vdagent";
2509 push @$cmd, '-device', "virtserialport,chardev=vdagent,name=com.redhat.spice.0";
2510 }
2511
8d9ae0d2
DM
2512 # enable balloon by default, unless explicitly disabled
2513 if (!defined($conf->{balloon}) || $conf->{balloon}) {
2514 $pciaddr = print_pci_addr("balloon0", $bridges);
2515 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr";
2516 }
1e3baf05 2517
0ea9541d
DM
2518 if ($conf->{watchdog}) {
2519 my $wdopts = parse_watchdog($conf->{watchdog});
5bdcf937 2520 $pciaddr = print_pci_addr("watchdog", $bridges);
0a40e8ea 2521 my $watchdog = $wdopts->{model} || 'i6300esb';
5bdcf937
AD
2522 push @$devices, '-device', "$watchdog$pciaddr";
2523 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
0ea9541d
DM
2524 }
2525
1e3baf05 2526 my $vollist = [];
941e0c42 2527 my $scsicontroller = {};
26ee04b6 2528 my $ahcicontroller = {};
cdd20088 2529 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
1e3baf05
DM
2530
2531 foreach_drive($conf, sub {
2532 my ($ds, $drive) = @_;
2533
ff1a2432 2534 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 2535 push @$vollist, $drive->{file};
ff1a2432 2536 }
afdb31d5 2537
1e3baf05 2538 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
2539
2540 if (drive_is_cdrom ($drive)) {
2541 if ($bootindex_hash->{d}) {
2542 $drive->{bootindex} = $bootindex_hash->{d};
2543 $bootindex_hash->{d} += 1;
2544 }
2545 } else {
2546 if ($bootindex_hash->{c}) {
2547 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
2548 $bootindex_hash->{c} += 1;
2549 }
2550 }
2551
941e0c42 2552 if ($drive->{interface} eq 'scsi') {
cdd20088 2553
5b952ff5 2554 my $maxdev = ($scsihw !~ m/^lsi/) ? 256 : 7;
cdd20088 2555 my $controller = int($drive->{index} / $maxdev);
5bdcf937
AD
2556 $pciaddr = print_pci_addr("scsihw$controller", $bridges);
2557 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
cdd20088 2558 $scsicontroller->{$controller}=1;
941e0c42 2559 }
3b408e82 2560
26ee04b6
DA
2561 if ($drive->{interface} eq 'sata') {
2562 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
5bdcf937
AD
2563 $pciaddr = print_pci_addr("ahci$controller", $bridges);
2564 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
26ee04b6
DA
2565 $ahcicontroller->{$controller}=1;
2566 }
2567
5bdcf937
AD
2568 push @$devices, '-drive',print_drive_full($storecfg, $vmid, $drive);
2569 push @$devices, '-device',print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
1e3baf05
DM
2570 });
2571
2572 push @$cmd, '-m', $conf->{memory} || $defaults->{memory};
19672434 2573
cc4d6182 2574 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 2575 next if !$conf->{"net$i"};
cc4d6182
DA
2576 my $d = parse_net($conf->{"net$i"});
2577 next if !$d;
1e3baf05 2578
cc4d6182 2579 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 2580
cc4d6182
DA
2581 if ($bootindex_hash->{n}) {
2582 $d->{bootindex} = $bootindex_hash->{n};
2583 $bootindex_hash->{n} += 1;
2584 }
1e3baf05 2585
cc4d6182 2586 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
5bdcf937
AD
2587 push @$devices, '-netdev', $netdevfull;
2588
2589 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i",$bridges);
2590 push @$devices, '-device', $netdevicefull;
2591 }
1e3baf05 2592
5bdcf937
AD
2593 #bridges
2594 while (my ($k, $v) = each %$bridges) {
2595 $pciaddr = print_pci_addr("pci.$k");
2596 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
19672434
DM
2597 }
2598
1e3baf05
DM
2599
2600 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2601 # when the VM uses virtio devices.
19672434
DM
2602 if (!$use_virtio && $have_ovz) {
2603
6b64503e 2604 my $cpuunits = defined($conf->{cpuunits}) ?
1e3baf05
DM
2605 $conf->{cpuunits} : $defaults->{cpuunits};
2606
2607 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2608
2609 # fixme: cpulimit is currently ignored
2610 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2611 }
2612
2613 # add custom args
2614 if ($conf->{args}) {
3ada46c9 2615 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
2616 push @$cmd, @$aa;
2617 }
2618
5bdcf937 2619 push @$cmd, @$devices;
be190583 2620 push @$cmd, '-rtc', join(',', @$rtcFlags)
8c559505 2621 if scalar(@$rtcFlags);
be190583 2622 push @$cmd, '-machine', join(',', @$machineFlags)
8c559505
DM
2623 if scalar(@$machineFlags);
2624 push @$cmd, '-global', join(',', @$globalFlags)
2625 if scalar(@$globalFlags);
2626
1d794448 2627 return wantarray ? ($cmd, $vollist, $spice_port) : $cmd;
1e3baf05 2628}
19672434 2629
1e3baf05
DM
2630sub vnc_socket {
2631 my ($vmid) = @_;
2632 return "${var_run_tmpdir}/$vmid.vnc";
2633}
2634
943340a6 2635sub spice_port {
1011b570 2636 my ($vmid) = @_;
943340a6 2637
1d794448 2638 my $res = vm_mon_cmd($vmid, 'query-spice');
943340a6
DM
2639
2640 return $res->{'tls-port'} || $res->{'port'} || die "no spice port\n";
1011b570
DM
2641}
2642
c971c4f2
AD
2643sub qmp_socket {
2644 my ($vmid) = @_;
2645 return "${var_run_tmpdir}/$vmid.qmp";
2646}
2647
ab6a046f
AD
2648sub qga_socket {
2649 my ($vmid) = @_;
2650 return "${var_run_tmpdir}/$vmid.qga";
2651}
2652
1e3baf05
DM
2653sub pidfile_name {
2654 my ($vmid) = @_;
2655 return "${var_run_tmpdir}/$vmid.pid";
2656}
2657
86fdcfb2
DA
2658sub vm_devices_list {
2659 my ($vmid) = @_;
2660
ceea9078
DM
2661 my $res = vm_mon_cmd($vmid, 'query-pci');
2662
2663 my $devices = {};
2664 foreach my $pcibus (@$res) {
2665 foreach my $device (@{$pcibus->{devices}}) {
2666 next if !$device->{'qdev_id'};
2667 $devices->{$device->{'qdev_id'}} = $device;
1dc4f496
DM
2668 }
2669 }
86fdcfb2 2670
1dc4f496 2671 return $devices;
86fdcfb2
DA
2672}
2673
ec21aa11 2674sub vm_deviceplug {
f19d1c47 2675 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 2676
cd6ecb89
AD
2677 return 1 if !check_running($vmid);
2678
2679 if ($deviceid eq 'tablet') {
0ecf8463 2680 my $devicefull = "usb-tablet,id=tablet,bus=uhci.0,port=1";
cd6ecb89
AD
2681 qemu_deviceadd($vmid, $devicefull);
2682 return 1;
2683 }
2684
2dbe827e 2685 return 1 if !$conf->{hotplug};
afdb31d5 2686
95d6343b
DA
2687 my $devices_list = vm_devices_list($vmid);
2688 return 1 if defined($devices_list->{$deviceid});
2689
40f28a9f
AD
2690 qemu_bridgeadd($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2691
5e5dcb73
DA
2692 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2693 return undef if !qemu_driveadd($storecfg, $vmid, $device);
cdd20088 2694 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
5e5dcb73
DA
2695 qemu_deviceadd($vmid, $devicefull);
2696 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2697 qemu_drivedel($vmid, $deviceid);
2698 return undef;
2699 }
f19d1c47 2700 }
cfc817c7 2701
cdd20088
AD
2702 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2703 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
cfc817c7 2704 my $pciaddr = print_pci_addr($deviceid);
cdd20088 2705 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
cfc817c7
DA
2706 qemu_deviceadd($vmid, $devicefull);
2707 return undef if(!qemu_deviceaddverify($vmid, $deviceid));
2708 }
2709
a4f091a0 2710 if ($deviceid =~ m/^(scsi)(\d+)$/) {
5b952ff5 2711 return 1 if ($conf->{scsihw} && ($conf->{scsihw} !~ m/^lsi/)); #virtio-scsi not yet support hotplug
cdd20088 2712 return undef if !qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
a4f091a0 2713 return undef if !qemu_driveadd($storecfg, $vmid, $device);
cdd20088 2714 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
a4f091a0
DA
2715 if(!qemu_deviceadd($vmid, $devicefull)) {
2716 qemu_drivedel($vmid, $deviceid);
2717 return undef;
2718 }
2719 }
2720
2630d2a9
DA
2721 if ($deviceid =~ m/^(net)(\d+)$/) {
2722 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
2723 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
2724 qemu_deviceadd($vmid, $netdevicefull);
2725 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2726 qemu_netdevdel($vmid, $deviceid);
2727 return undef;
2728 }
2729 }
2730
40f28a9f
AD
2731 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2732 my $bridgeid = $2;
2733 my $pciaddr = print_pci_addr($deviceid);
2734 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2735 qemu_deviceadd($vmid, $devicefull);
2736 return undef if !qemu_deviceaddverify($vmid, $deviceid);
2737 }
2738
5e5dcb73 2739 return 1;
a4dea331
DA
2740}
2741
ec21aa11 2742sub vm_deviceunplug {
f19d1c47 2743 my ($vmid, $conf, $deviceid) = @_;
873c2d69 2744
cd6ecb89
AD
2745 return 1 if !check_running ($vmid);
2746
2747 if ($deviceid eq 'tablet') {
2748 qemu_devicedel($vmid, $deviceid);
2749 return 1;
2750 }
2751
2dbe827e 2752 return 1 if !$conf->{hotplug};
873c2d69 2753
95d6343b
DA
2754 my $devices_list = vm_devices_list($vmid);
2755 return 1 if !defined($devices_list->{$deviceid});
2756
ae57f6b3 2757 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
f19d1c47 2758
5e5dcb73 2759 if ($deviceid =~ m/^(virtio)(\d+)$/) {
5e5dcb73
DA
2760 qemu_devicedel($vmid, $deviceid);
2761 return undef if !qemu_devicedelverify($vmid, $deviceid);
1f219ef5 2762 return undef if !qemu_drivedel($vmid, $deviceid);
5e5dcb73 2763 }
cfc817c7
DA
2764
2765 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2766 return undef if !qemu_devicedel($vmid, $deviceid);
2767 }
2768
a4f091a0
DA
2769 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2770 return undef if !qemu_devicedel($vmid, $deviceid);
2771 return undef if !qemu_drivedel($vmid, $deviceid);
2772 }
2773
2630d2a9 2774 if ($deviceid =~ m/^(net)(\d+)$/) {
2630d2a9
DA
2775 qemu_devicedel($vmid, $deviceid);
2776 return undef if !qemu_devicedelverify($vmid, $deviceid);
750886f8 2777 return undef if !qemu_netdevdel($vmid, $deviceid);
2630d2a9
DA
2778 }
2779
5e5dcb73
DA
2780 return 1;
2781}
2782
2783sub qemu_deviceadd {
2784 my ($vmid, $devicefull) = @_;
873c2d69 2785
d695b5b7
AD
2786 $devicefull = "driver=".$devicefull;
2787 my %options = split(/[=,]/, $devicefull);
f19d1c47 2788
d695b5b7
AD
2789 vm_mon_cmd($vmid, "device_add" , %options);
2790 return 1;
5e5dcb73 2791}
afdb31d5 2792
5e5dcb73
DA
2793sub qemu_devicedel {
2794 my($vmid, $deviceid) = @_;
5a77d8c1
AD
2795 my $ret = vm_mon_cmd($vmid, "device_del", id => $deviceid);
2796 return 1;
5e5dcb73
DA
2797}
2798
2799sub qemu_driveadd {
2800 my($storecfg, $vmid, $device) = @_;
2801
2802 my $drive = print_drive_full($storecfg, $vmid, $device);
7b7c6d1b 2803 my $ret = vm_human_monitor_command($vmid, "drive_add auto $drive");
5e5dcb73
DA
2804 # If the command succeeds qemu prints: "OK"
2805 if ($ret !~ m/OK/s) {
2806 syslog("err", "adding drive failed: $ret");
2807 return undef;
f19d1c47 2808 }
5e5dcb73
DA
2809 return 1;
2810}
afdb31d5 2811
5e5dcb73
DA
2812sub qemu_drivedel {
2813 my($vmid, $deviceid) = @_;
873c2d69 2814
7b7c6d1b 2815 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
5e5dcb73
DA
2816 $ret =~ s/^\s+//;
2817 if ($ret =~ m/Device \'.*?\' not found/s) {
afdb31d5 2818 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
5e5dcb73
DA
2819 }
2820 elsif ($ret ne "") {
2821 syslog("err", "deleting drive $deviceid failed : $ret");
2822 return undef;
873c2d69 2823 }
5e5dcb73
DA
2824 return 1;
2825}
f19d1c47 2826
5e5dcb73
DA
2827sub qemu_deviceaddverify {
2828 my ($vmid,$deviceid) = @_;
873c2d69 2829
5e5dcb73
DA
2830 for (my $i = 0; $i <= 5; $i++) {
2831 my $devices_list = vm_devices_list($vmid);
2832 return 1 if defined($devices_list->{$deviceid});
2833 sleep 1;
afdb31d5 2834 }
5e5dcb73
DA
2835 syslog("err", "error on hotplug device $deviceid");
2836 return undef;
2837}
afdb31d5 2838
5e5dcb73
DA
2839
2840sub qemu_devicedelverify {
2841 my ($vmid,$deviceid) = @_;
2842
2843 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2844 for (my $i = 0; $i <= 5; $i++) {
2845 my $devices_list = vm_devices_list($vmid);
2846 return 1 if !defined($devices_list->{$deviceid});
2847 sleep 1;
afdb31d5 2848 }
5e5dcb73
DA
2849 syslog("err", "error on hot-unplugging device $deviceid");
2850 return undef;
873c2d69
DA
2851}
2852
cdd20088 2853sub qemu_findorcreatescsihw {
cfc817c7
DA
2854 my ($storecfg, $conf, $vmid, $device) = @_;
2855
5b952ff5 2856 my $maxdev = ($conf->{scsihw} && ($conf->{scsihw} !~ m/^lsi/)) ? 256 : 7;
cfc817c7 2857 my $controller = int($device->{index} / $maxdev);
cdd20088 2858 my $scsihwid="scsihw$controller";
cfc817c7
DA
2859 my $devices_list = vm_devices_list($vmid);
2860
cdd20088
AD
2861 if(!defined($devices_list->{$scsihwid})) {
2862 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $scsihwid);
cfc817c7
DA
2863 }
2864 return 1;
2865}
2866
40f28a9f
AD
2867sub qemu_bridgeadd {
2868 my ($storecfg, $conf, $vmid, $device) = @_;
2869
2870 my $bridges = {};
2871 my $bridgeid = undef;
2872 print_pci_addr($device, $bridges);
2873
2874 while (my ($k, $v) = each %$bridges) {
2875 $bridgeid = $k;
2876 }
0e616534 2877 return if !$bridgeid || $bridgeid < 1;
40f28a9f
AD
2878 my $bridge = "pci.$bridgeid";
2879 my $devices_list = vm_devices_list($vmid);
2880
2881 if(!defined($devices_list->{$bridge})) {
2882 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $bridge);
2883 }
2884 return 1;
2885}
2886
2630d2a9
DA
2887sub qemu_netdevadd {
2888 my ($vmid, $conf, $device, $deviceid) = @_;
2889
2890 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
73aa03b8 2891 my %options = split(/[=,]/, $netdev);
2630d2a9 2892
73aa03b8
AD
2893 vm_mon_cmd($vmid, "netdev_add", %options);
2894 return 1;
2630d2a9
DA
2895}
2896
2897sub qemu_netdevdel {
2898 my ($vmid, $deviceid) = @_;
2899
89c1e0f4
AD
2900 vm_mon_cmd($vmid, "netdev_del", id => $deviceid);
2901 return 1;
2630d2a9
DA
2902}
2903
affd2f88
AD
2904sub qemu_block_set_io_throttle {
2905 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2906
f3f323a3
AD
2907 return if !check_running($vmid) ;
2908
f3f323a3
AD
2909 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));
2910
affd2f88
AD
2911}
2912
f5eb281a 2913# old code, only used to shutdown old VM after update
dab36e1e
DM
2914sub __read_avail {
2915 my ($fh, $timeout) = @_;
2916
2917 my $sel = new IO::Select;
2918 $sel->add($fh);
2919
2920 my $res = '';
2921 my $buf;
2922
2923 my @ready;
2924 while (scalar (@ready = $sel->can_read($timeout))) {
2925 my $count;
2926 if ($count = $fh->sysread($buf, 8192)) {
2927 if ($buf =~ /^(.*)\(qemu\) $/s) {
2928 $res .= $1;
2929 last;
2930 } else {
2931 $res .= $buf;
2932 }
2933 } else {
2934 if (!defined($count)) {
2935 die "$!\n";
2936 }
2937 last;
2938 }
2939 }
2940
2941 die "monitor read timeout\n" if !scalar(@ready);
f5eb281a 2942
dab36e1e
DM
2943 return $res;
2944}
2945
f5eb281a 2946# old code, only used to shutdown old VM after update
dab36e1e
DM
2947sub vm_monitor_command {
2948 my ($vmid, $cmdstr, $nocheck) = @_;
f5eb281a 2949
dab36e1e
DM
2950 my $res;
2951
2952 eval {
2953 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
2954
2955 my $sname = "${var_run_tmpdir}/$vmid.mon";
2956
2957 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
2958 die "unable to connect to VM $vmid socket - $!\n";
2959
2960 my $timeout = 3;
2961
2962 # hack: migrate sometime blocks the monitor (when migrate_downtime
2963 # is set)
2964 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2965 $timeout = 60*60; # 1 hour
2966 }
2967
2968 # read banner;
2969 my $data = __read_avail($sock, $timeout);
2970
2971 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2972 die "got unexpected qemu monitor banner\n";
2973 }
2974
2975 my $sel = new IO::Select;
2976 $sel->add($sock);
2977
2978 if (!scalar(my @ready = $sel->can_write($timeout))) {
2979 die "monitor write error - timeout";
2980 }
2981
2982 my $fullcmd = "$cmdstr\r";
2983
2984 # syslog('info', "VM $vmid monitor command: $cmdstr");
2985
2986 my $b;
2987 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2988 die "monitor write error - $!";
2989 }
2990
2991 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2992
2993 $timeout = 20;
2994
2995 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2996 $timeout = 60*60; # 1 hour
2997 } elsif ($cmdstr =~ m/^(eject|change)/) {
2998 $timeout = 60; # note: cdrom mount command is slow
2999 }
3000 if ($res = __read_avail($sock, $timeout)) {
3001
3002 my @lines = split("\r?\n", $res);
f5eb281a 3003
dab36e1e 3004 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
f5eb281a 3005
dab36e1e
DM
3006 $res = join("\n", @lines);
3007 $res .= "\n";
3008 }
3009 };
3010
3011 my $err = $@;
3012
3013 if ($err) {
3014 syslog("err", "VM $vmid monitor command failed - $err");
3015 die $err;
3016 }
f5eb281a 3017
dab36e1e
DM
3018 return $res;
3019}
3020
c1175c92
AD
3021sub qemu_block_resize {
3022 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
3023
ed221350 3024 my $running = check_running($vmid);
c1175c92
AD
3025
3026 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
3027
3028 return if !$running;
3029
3030 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
3031
3032}
3033
1ab0057c
AD
3034sub qemu_volume_snapshot {
3035 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3036
ed221350 3037 my $running = check_running($vmid);
1ab0057c
AD
3038
3039 return if !PVE::Storage::volume_snapshot($storecfg, $volid, $snap, $running);
3040
3041 return if !$running;
3042
3043 vm_mon_cmd($vmid, "snapshot-drive", device => $deviceid, name => $snap);
3044
3045}
3046
fc46aff9
AD
3047sub qemu_volume_snapshot_delete {
3048 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3049
ed221350 3050 my $running = check_running($vmid);
fc46aff9
AD
3051
3052 return if !PVE::Storage::volume_snapshot_delete($storecfg, $volid, $snap, $running);
3053
3054 return if !$running;
3055
18bfb361 3056 vm_mon_cmd($vmid, "delete-drive-snapshot", device => $deviceid, name => $snap);
fc46aff9
AD
3057}
3058
3d5149c9
AD
3059sub qga_freezefs {
3060 my ($vmid) = @_;
3061
3062 #need to impplement call to qemu-ga
3063}
3064
e8f3f18e
AD
3065sub qga_unfreezefs {
3066 my ($vmid) = @_;
3067
3068 #need to impplement call to qemu-ga
3069}
3070
1e3baf05 3071sub vm_start {
1d794448 3072 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
1e3baf05 3073
6b64503e 3074 lock_config($vmid, sub {
7e8dcf2c 3075 my $conf = load_config($vmid, $migratedfrom);
1e3baf05 3076
8b43bc11 3077 die "you can't start a vm if it's a template\n" if is_template($conf);
3dcb98d5 3078
6b64503e 3079 check_lock($conf) if !$skiplock;
1e3baf05 3080
7e8dcf2c 3081 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
1e3baf05 3082
6c47d546
DM
3083 my $defaults = load_defaults();
3084
3085 # set environment variable useful inside network script
3086 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
3087
1d794448 3088 my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
6c47d546 3089
1e3baf05 3090 my $migrate_port = 0;
5bc1e039 3091 my $migrate_uri;
1e3baf05
DM
3092 if ($statefile) {
3093 if ($statefile eq 'tcp') {
5bc1e039
SP
3094 my $localip = "localhost";
3095 my $datacenterconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
3096 if ($datacenterconf->{migration_unsecure}) {
3097 my $nodename = PVE::INotify::nodename();
3098 $localip = PVE::Cluster::remote_node_ip($nodename, 1);
3099 }
f9a971e0 3100 $migrate_port = PVE::Tools::next_migrate_port();
5bc1e039 3101 $migrate_uri = "tcp:${localip}:${migrate_port}";
6c47d546
DM
3102 push @$cmd, '-incoming', $migrate_uri;
3103 push @$cmd, '-S';
1e3baf05 3104 } else {
6c47d546 3105 push @$cmd, '-loadstate', $statefile;
1e3baf05 3106 }
91bd6c90
DM
3107 } elsif ($paused) {
3108 push @$cmd, '-S';
1e3baf05
DM
3109 }
3110
1e3baf05 3111 # host pci devices
040b06b7
DA
3112 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
3113 my $d = parse_hostpci($conf->{"hostpci$i"});
3114 next if !$d;
3115 my $info = pci_device_info("0000:$d->{pciid}");
3116 die "IOMMU not present\n" if !check_iommu_support();
3117 die "no pci device info for device '$d->{pciid}'\n" if !$info;
3118 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub($info);
3119 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset($info);
3120 }
1e3baf05
DM
3121
3122 PVE::Storage::activate_volumes($storecfg, $vollist);
3123
585b6e28
DM
3124 eval { run_command($cmd, timeout => $statefile ? undef : 30,
3125 umask => 0077); };
1e3baf05 3126 my $err = $@;
ff1a2432 3127 die "start failed: $err" if $err;
1e3baf05 3128
5bc1e039 3129 print "migration listens on $migrate_uri\n" if $migrate_uri;
afdb31d5 3130
8c609afd 3131 if ($statefile && $statefile ne 'tcp') {
95381ce0 3132 eval { vm_mon_cmd_nocheck($vmid, "cont"); };
8c609afd 3133 warn $@ if $@;
62de2cbd
DM
3134 }
3135
1d794448 3136 if ($migratedfrom) {
e18b0b99
AD
3137 my $capabilities = {};
3138 $capabilities->{capability} = "xbzrle";
3139 $capabilities->{state} = JSON::true;
ed221350 3140 eval { vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => [$capabilities]); };
1d794448
DM
3141 warn $@ if $@;
3142
3143 if ($spice_port) {
3144 print "spice listens on port $spice_port\n";
3145 if ($spice_ticket) {
3146 PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "set_password", protocol => 'spice', password => $spice_ticket);
3147 PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "expire_password", protocol => 'spice', time => "+30");
95a4b4a9
AD
3148 }
3149 }
3150
1d794448 3151 } else {
4ec05c4c 3152
15b1fc93 3153 if (!$statefile && (!defined($conf->{balloon}) || $conf->{balloon})) {
be190583 3154 vm_mon_cmd_nocheck($vmid, "balloon", value => $conf->{balloon}*1024*1024)
4ec05c4c 3155 if $conf->{balloon};
be190583
DM
3156 vm_mon_cmd_nocheck($vmid, 'qom-set',
3157 path => "machine/peripheral/balloon0",
3158 property => "guest-stats-polling-interval",
4ec05c4c
AD
3159 value => 2);
3160 }
e18b0b99 3161 }
1e3baf05
DM
3162 });
3163}
3164
0eedc444
AD
3165sub vm_mon_cmd {
3166 my ($vmid, $execute, %params) = @_;
3167
26f11676
DM
3168 my $cmd = { execute => $execute, arguments => \%params };
3169 vm_qmp_command($vmid, $cmd);
0eedc444
AD
3170}
3171
3172sub vm_mon_cmd_nocheck {
3173 my ($vmid, $execute, %params) = @_;
3174
26f11676
DM
3175 my $cmd = { execute => $execute, arguments => \%params };
3176 vm_qmp_command($vmid, $cmd, 1);
0eedc444
AD
3177}
3178
c971c4f2 3179sub vm_qmp_command {
d967756b 3180 my ($vmid, $cmd, $nocheck) = @_;
97d62eb7 3181
c971c4f2 3182 my $res;
26f11676 3183
14db5366
DM
3184 my $timeout;
3185 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
3186 $timeout = $cmd->{arguments}->{timeout};
3187 delete $cmd->{arguments}->{timeout};
3188 }
be190583 3189
c971c4f2
AD
3190 eval {
3191 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
ed221350 3192 my $sname = qmp_socket($vmid);
f5eb281a 3193 if (-e $sname) {
dab36e1e
DM
3194 my $qmpclient = PVE::QMPClient->new();
3195
14db5366 3196 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
dab36e1e
DM
3197 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
3198 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
3199 if scalar(%{$cmd->{arguments}});
3200 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
3201 } else {
3202 die "unable to open monitor socket\n";
3203 }
c971c4f2 3204 };
26f11676 3205 if (my $err = $@) {
c971c4f2
AD
3206 syslog("err", "VM $vmid qmp command failed - $err");
3207 die $err;
3208 }
3209
3210 return $res;
3211}
3212
9df5cbcc
DM
3213sub vm_human_monitor_command {
3214 my ($vmid, $cmdline) = @_;
3215
3216 my $res;
3217
f5eb281a 3218 my $cmd = {
9df5cbcc
DM
3219 execute => 'human-monitor-command',
3220 arguments => { 'command-line' => $cmdline},
3221 };
3222
3223 return vm_qmp_command($vmid, $cmd);
3224}
3225
1e3baf05
DM
3226sub vm_commandline {
3227 my ($storecfg, $vmid) = @_;
3228
6b64503e 3229 my $conf = load_config($vmid);
1e3baf05
DM
3230
3231 my $defaults = load_defaults();
3232
6b64503e 3233 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 3234
6b64503e 3235 return join(' ', @$cmd);
1e3baf05
DM
3236}
3237
3238sub vm_reset {
3239 my ($vmid, $skiplock) = @_;
3240
6b64503e 3241 lock_config($vmid, sub {
1e3baf05 3242
6b64503e 3243 my $conf = load_config($vmid);
1e3baf05 3244
6b64503e 3245 check_lock($conf) if !$skiplock;
1e3baf05 3246
816e2c4a 3247 vm_mon_cmd($vmid, "system_reset");
ff1a2432
DM
3248 });
3249}
3250
3251sub get_vm_volumes {
3252 my ($conf) = @_;
1e3baf05 3253
ff1a2432 3254 my $vollist = [];
d5769dc2
DM
3255 foreach_volid($conf, sub {
3256 my ($volid, $is_cdrom) = @_;
ff1a2432 3257
d5769dc2 3258 return if $volid =~ m|^/|;
ff1a2432 3259
d5769dc2
DM
3260 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
3261 return if !$sid;
ff1a2432
DM
3262
3263 push @$vollist, $volid;
1e3baf05 3264 });
ff1a2432
DM
3265
3266 return $vollist;
3267}
3268
3269sub vm_stop_cleanup {
254575e9 3270 my ($storecfg, $vmid, $conf, $keepActive) = @_;
ff1a2432 3271
745fed70
DM
3272 eval {
3273 fairsched_rmnod($vmid); # try to destroy group
ff1a2432 3274
254575e9
DM
3275 if (!$keepActive) {
3276 my $vollist = get_vm_volumes($conf);
3277 PVE::Storage::deactivate_volumes($storecfg, $vollist);
3278 }
961bfcb2 3279
ab6a046f 3280 foreach my $ext (qw(mon qmp pid vnc qga)) {
961bfcb2
DM
3281 unlink "/var/run/qemu-server/${vmid}.$ext";
3282 }
745fed70
DM
3283 };
3284 warn $@ if $@; # avoid errors - just warn
1e3baf05
DM
3285}
3286
e6c3b671 3287# Note: use $nockeck to skip tests if VM configuration file exists.
254575e9
DM
3288# We need that when migration VMs to other nodes (files already moved)
3289# Note: we set $keepActive in vzdump stop mode - volumes need to stay active
1e3baf05 3290sub vm_stop {
af30308f 3291 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
9269013a 3292
9269013a 3293 $force = 1 if !defined($force) && !$shutdown;
1e3baf05 3294
af30308f
DM
3295 if ($migratedfrom){
3296 my $pid = check_running($vmid, $nocheck, $migratedfrom);
3297 kill 15, $pid if $pid;
3298 my $conf = load_config($vmid, $migratedfrom);
3299 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive);
3300 return;
3301 }
3302
e6c3b671 3303 lock_config($vmid, sub {
1e3baf05 3304
e6c3b671 3305 my $pid = check_running($vmid, $nocheck);
ff1a2432 3306 return if !$pid;
1e3baf05 3307
ff1a2432 3308 my $conf;
e6c3b671 3309 if (!$nocheck) {
ff1a2432 3310 $conf = load_config($vmid);
e6c3b671 3311 check_lock($conf) if !$skiplock;
7f4a5b5a
DM
3312 if (!defined($timeout) && $shutdown && $conf->{startup}) {
3313 my $opts = parse_startup($conf->{startup});
3314 $timeout = $opts->{down} if $opts->{down};
3315 }
e6c3b671 3316 }
19672434 3317
7f4a5b5a
DM
3318 $timeout = 60 if !defined($timeout);
3319
9269013a
DM
3320 eval {
3321 if ($shutdown) {
988903ca 3322 $nocheck ? vm_mon_cmd_nocheck($vmid, "system_powerdown") : vm_mon_cmd($vmid, "system_powerdown");
bcb7c9cf 3323
9269013a 3324 } else {
988903ca 3325 $nocheck ? vm_mon_cmd_nocheck($vmid, "quit") : vm_mon_cmd($vmid, "quit");
afdb31d5 3326 }
9269013a 3327 };
1e3baf05
DM
3328 my $err = $@;
3329
3330 if (!$err) {
1e3baf05 3331 my $count = 0;
e6c3b671 3332 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
3333 $count++;
3334 sleep 1;
3335 }
3336
3337 if ($count >= $timeout) {
9269013a
DM
3338 if ($force) {
3339 warn "VM still running - terminating now with SIGTERM\n";
3340 kill 15, $pid;
3341 } else {
3342 die "VM quit/powerdown failed - got timeout\n";
3343 }
3344 } else {
254575e9 3345 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
9269013a 3346 return;
1e3baf05
DM
3347 }
3348 } else {
9269013a
DM
3349 if ($force) {
3350 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3351 kill 15, $pid;
3352 } else {
afdb31d5 3353 die "VM quit/powerdown failed\n";
9269013a 3354 }
1e3baf05
DM
3355 }
3356
3357 # wait again
ff1a2432 3358 $timeout = 10;
1e3baf05
DM
3359
3360 my $count = 0;
e6c3b671 3361 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
3362 $count++;
3363 sleep 1;
3364 }
3365
3366 if ($count >= $timeout) {
ff1a2432 3367 warn "VM still running - terminating now with SIGKILL\n";
1e3baf05 3368 kill 9, $pid;
ff1a2432 3369 sleep 1;
1e3baf05
DM
3370 }
3371
254575e9 3372 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
ff1a2432 3373 });
1e3baf05
DM
3374}
3375
3376sub vm_suspend {
3377 my ($vmid, $skiplock) = @_;
3378
6b64503e 3379 lock_config($vmid, sub {
1e3baf05 3380
6b64503e 3381 my $conf = load_config($vmid);
1e3baf05 3382
051347aa 3383 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
bcb7c9cf 3384
f77f91f3 3385 vm_mon_cmd($vmid, "stop");
1e3baf05
DM
3386 });
3387}
3388
3389sub vm_resume {
3390 my ($vmid, $skiplock) = @_;
3391
6b64503e 3392 lock_config($vmid, sub {
1e3baf05 3393
6b64503e 3394 my $conf = load_config($vmid);
1e3baf05 3395
051347aa 3396 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
1e3baf05 3397
12060fe8 3398 vm_mon_cmd($vmid, "cont");
1e3baf05
DM
3399 });
3400}
3401
5fdbe4f0
DM
3402sub vm_sendkey {
3403 my ($vmid, $skiplock, $key) = @_;
1e3baf05 3404
6b64503e 3405 lock_config($vmid, sub {
1e3baf05 3406
6b64503e 3407 my $conf = load_config($vmid);
f5eb281a 3408
7b7c6d1b
DM
3409 # there is no qmp command, so we use the human monitor command
3410 vm_human_monitor_command($vmid, "sendkey $key");
1e3baf05
DM
3411 });
3412}
3413
3414sub vm_destroy {
3415 my ($storecfg, $vmid, $skiplock) = @_;
3416
6b64503e 3417 lock_config($vmid, sub {
1e3baf05 3418
6b64503e 3419 my $conf = load_config($vmid);
1e3baf05 3420
6b64503e 3421 check_lock($conf) if !$skiplock;
1e3baf05 3422
ff1a2432
DM
3423 if (!check_running($vmid)) {
3424 fairsched_rmnod($vmid); # try to destroy group
3425 destroy_vm($storecfg, $vmid);
3426 } else {
3427 die "VM $vmid is running - destroy failed\n";
1e3baf05
DM
3428 }
3429 });
3430}
3431
1e3baf05
DM
3432# pci helpers
3433
3434sub file_write {
3435 my ($filename, $buf) = @_;
3436
6b64503e 3437 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
3438 return undef if !$fh;
3439
3440 my $res = print $fh $buf;
3441
3442 $fh->close();
3443
3444 return $res;
3445}
3446
3447sub pci_device_info {
3448 my ($name) = @_;
3449
3450 my $res;
3451
3452 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3453 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3454
3455 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
3456 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3457
3458 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
3459 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3460
3461 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
3462 return undef if !defined($product) || $product !~ s/^0x//;
3463
3464 $res = {
3465 name => $name,
3466 vendor => $vendor,
3467 product => $product,
3468 domain => $domain,
3469 bus => $bus,
3470 slot => $slot,
3471 func => $func,
3472 irq => $irq,
3473 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
3474 };
3475
3476 return $res;
3477}
3478
3479sub pci_dev_reset {
3480 my ($dev) = @_;
3481
3482 my $name = $dev->{name};
3483
3484 my $fn = "$pcisysfs/devices/$name/reset";
3485
6b64503e 3486 return file_write($fn, "1");
1e3baf05
DM
3487}
3488
3489sub pci_dev_bind_to_stub {
3490 my ($dev) = @_;
3491
3492 my $name = $dev->{name};
3493
3494 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3495 return 1 if -d $testdir;
3496
3497 my $data = "$dev->{vendor} $dev->{product}";
6b64503e 3498 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
1e3baf05
DM
3499
3500 my $fn = "$pcisysfs/devices/$name/driver/unbind";
6b64503e 3501 if (!file_write($fn, $name)) {
1e3baf05
DM
3502 return undef if -f $fn;
3503 }
3504
3505 $fn = "$pcisysfs/drivers/pci-stub/bind";
3506 if (! -d $testdir) {
6b64503e 3507 return undef if !file_write($fn, $name);
1e3baf05
DM
3508 }
3509
3510 return -d $testdir;
3511}
3512
afdb31d5 3513sub print_pci_addr {
5bdcf937 3514 my ($id, $bridges) = @_;
6b64503e 3515
72a063e4 3516 my $res = '';
6b64503e 3517 my $devices = {
24f0d39a 3518 piix3 => { bus => 0, addr => 1 },
e5f7f8ed 3519 #addr2 : first videocard
13b5a753 3520 balloon0 => { bus => 0, addr => 3 },
0a40e8ea 3521 watchdog => { bus => 0, addr => 4 },
cdd20088
AD
3522 scsihw0 => { bus => 0, addr => 5 },
3523 scsihw1 => { bus => 0, addr => 6 },
26ee04b6 3524 ahci0 => { bus => 0, addr => 7 },
ab6a046f 3525 qga0 => { bus => 0, addr => 8 },
1011b570 3526 spice => { bus => 0, addr => 9 },
6b64503e
DM
3527 virtio0 => { bus => 0, addr => 10 },
3528 virtio1 => { bus => 0, addr => 11 },
3529 virtio2 => { bus => 0, addr => 12 },
3530 virtio3 => { bus => 0, addr => 13 },
3531 virtio4 => { bus => 0, addr => 14 },
3532 virtio5 => { bus => 0, addr => 15 },
b78ebef7
DA
3533 hostpci0 => { bus => 0, addr => 16 },
3534 hostpci1 => { bus => 0, addr => 17 },
f290f8d9
DA
3535 net0 => { bus => 0, addr => 18 },
3536 net1 => { bus => 0, addr => 19 },
3537 net2 => { bus => 0, addr => 20 },
3538 net3 => { bus => 0, addr => 21 },
3539 net4 => { bus => 0, addr => 22 },
3540 net5 => { bus => 0, addr => 23 },
2fa3151e
AD
3541 vga1 => { bus => 0, addr => 24 },
3542 vga2 => { bus => 0, addr => 25 },
3543 vga3 => { bus => 0, addr => 26 },
e5f7f8ed 3544 #addr29 : usb-host (pve-usb.cfg)
5bdcf937
AD
3545 'pci.1' => { bus => 0, addr => 30 },
3546 'pci.2' => { bus => 0, addr => 31 },
3547 'net6' => { bus => 1, addr => 1 },
3548 'net7' => { bus => 1, addr => 2 },
3549 'net8' => { bus => 1, addr => 3 },
3550 'net9' => { bus => 1, addr => 4 },
3551 'net10' => { bus => 1, addr => 5 },
3552 'net11' => { bus => 1, addr => 6 },
3553 'net12' => { bus => 1, addr => 7 },
3554 'net13' => { bus => 1, addr => 8 },
3555 'net14' => { bus => 1, addr => 9 },
3556 'net15' => { bus => 1, addr => 10 },
3557 'net16' => { bus => 1, addr => 11 },
3558 'net17' => { bus => 1, addr => 12 },
3559 'net18' => { bus => 1, addr => 13 },
3560 'net19' => { bus => 1, addr => 14 },
3561 'net20' => { bus => 1, addr => 15 },
3562 'net21' => { bus => 1, addr => 16 },
3563 'net22' => { bus => 1, addr => 17 },
3564 'net23' => { bus => 1, addr => 18 },
3565 'net24' => { bus => 1, addr => 19 },
3566 'net25' => { bus => 1, addr => 20 },
3567 'net26' => { bus => 1, addr => 21 },
3568 'net27' => { bus => 1, addr => 22 },
3569 'net28' => { bus => 1, addr => 23 },
3570 'net29' => { bus => 1, addr => 24 },
3571 'net30' => { bus => 1, addr => 25 },
3572 'net31' => { bus => 1, addr => 26 },
3573 'virtio6' => { bus => 2, addr => 1 },
3574 'virtio7' => { bus => 2, addr => 2 },
3575 'virtio8' => { bus => 2, addr => 3 },
3576 'virtio9' => { bus => 2, addr => 4 },
3577 'virtio10' => { bus => 2, addr => 5 },
3578 'virtio11' => { bus => 2, addr => 6 },
3579 'virtio12' => { bus => 2, addr => 7 },
3580 'virtio13' => { bus => 2, addr => 8 },
3581 'virtio14' => { bus => 2, addr => 9 },
3582 'virtio15' => { bus => 2, addr => 10 },
6b64503e
DM
3583 };
3584
3585 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
72a063e4 3586 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
5bdcf937
AD
3587 my $bus = $devices->{$id}->{bus};
3588 $res = ",bus=pci.$bus,addr=$addr";
98627641 3589 $bridges->{$bus} = 1 if $bridges;
72a063e4
DA
3590 }
3591 return $res;
3592
3593}
3594
3e16d5fc
DM
3595# vzdump restore implementaion
3596
ed221350 3597sub tar_archive_read_firstfile {
3e16d5fc 3598 my $archive = shift;
afdb31d5 3599
3e16d5fc
DM
3600 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
3601
3602 # try to detect archive type first
3603 my $pid = open (TMP, "tar tf '$archive'|") ||
3604 die "unable to open file '$archive'\n";
3605 my $firstfile = <TMP>;
3606 kill 15, $pid;
3607 close TMP;
3608
3609 die "ERROR: archive contaions no data\n" if !$firstfile;
3610 chomp $firstfile;
3611
3612 return $firstfile;
3613}
3614
ed221350
DM
3615sub tar_restore_cleanup {
3616 my ($storecfg, $statfile) = @_;
3e16d5fc
DM
3617
3618 print STDERR "starting cleanup\n";
3619
3620 if (my $fd = IO::File->new($statfile, "r")) {
3621 while (defined(my $line = <$fd>)) {
3622 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3623 my $volid = $2;
3624 eval {
3625 if ($volid =~ m|^/|) {
3626 unlink $volid || die 'unlink failed\n';
3627 } else {
ed221350 3628 PVE::Storage::vdisk_free($storecfg, $volid);
3e16d5fc 3629 }
afdb31d5 3630 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3e16d5fc
DM
3631 };
3632 print STDERR "unable to cleanup '$volid' - $@" if $@;
3633 } else {
3634 print STDERR "unable to parse line in statfile - $line";
afdb31d5 3635 }
3e16d5fc
DM
3636 }
3637 $fd->close();
3638 }
3639}
3640
3641sub restore_archive {
a0d1b1a2 3642 my ($archive, $vmid, $user, $opts) = @_;
3e16d5fc 3643
91bd6c90
DM
3644 my $format = $opts->{format};
3645 my $comp;
3646
3647 if ($archive =~ m/\.tgz$/ || $archive =~ m/\.tar\.gz$/) {
3648 $format = 'tar' if !$format;
3649 $comp = 'gzip';
3650 } elsif ($archive =~ m/\.tar$/) {
3651 $format = 'tar' if !$format;
3652 } elsif ($archive =~ m/.tar.lzo$/) {
3653 $format = 'tar' if !$format;
3654 $comp = 'lzop';
3655 } elsif ($archive =~ m/\.vma$/) {
3656 $format = 'vma' if !$format;
3657 } elsif ($archive =~ m/\.vma\.gz$/) {
3658 $format = 'vma' if !$format;
3659 $comp = 'gzip';
3660 } elsif ($archive =~ m/\.vma\.lzo$/) {
3661 $format = 'vma' if !$format;
3662 $comp = 'lzop';
3663 } else {
3664 $format = 'vma' if !$format; # default
3665 }
3666
3667 # try to detect archive format
3668 if ($format eq 'tar') {
3669 return restore_tar_archive($archive, $vmid, $user, $opts);
3670 } else {
3671 return restore_vma_archive($archive, $vmid, $user, $opts, $comp);
3672 }
3673}
3674
3675sub restore_update_config_line {
3676 my ($outfd, $cookie, $vmid, $map, $line, $unique) = @_;
3677
3678 return if $line =~ m/^\#qmdump\#/;
3679 return if $line =~ m/^\#vzdump\#/;
3680 return if $line =~ m/^lock:/;
3681 return if $line =~ m/^unused\d+:/;
3682 return if $line =~ m/^parent:/;
ca3e4fa4 3683 return if $line =~ m/^template:/; # restored VM is never a template
91bd6c90
DM
3684
3685 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3686 # try to convert old 1.X settings
3687 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3688 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
3689 my ($model, $macaddr) = split(/\=/, $devconfig);
3690 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $unique;
3691 my $net = {
3692 model => $model,
3693 bridge => "vmbr$ind",
3694 macaddr => $macaddr,
3695 };
3696 my $netstr = print_net($net);
3697
3698 print $outfd "net$cookie->{netcount}: $netstr\n";
3699 $cookie->{netcount}++;
3700 }
3701 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && $unique) {
3702 my ($id, $netstr) = ($1, $2);
3703 my $net = parse_net($netstr);
3704 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
3705 $netstr = print_net($net);
3706 print $outfd "$id: $netstr\n";
3707 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
3708 my $virtdev = $1;
907ea891 3709 my $value = $3;
91bd6c90
DM
3710 if ($line =~ m/backup=no/) {
3711 print $outfd "#$line";
3712 } elsif ($virtdev && $map->{$virtdev}) {
ed221350 3713 my $di = parse_drive($virtdev, $value);
8fd57431 3714 delete $di->{format}; # format can change on restore
91bd6c90 3715 $di->{file} = $map->{$virtdev};
ed221350 3716 $value = print_drive($vmid, $di);
91bd6c90
DM
3717 print $outfd "$virtdev: $value\n";
3718 } else {
3719 print $outfd $line;
3720 }
3721 } else {
3722 print $outfd $line;
3723 }
3724}
3725
3726sub scan_volids {
3727 my ($cfg, $vmid) = @_;
3728
3729 my $info = PVE::Storage::vdisk_list($cfg, undef, $vmid);
3730
3731 my $volid_hash = {};
3732 foreach my $storeid (keys %$info) {
3733 foreach my $item (@{$info->{$storeid}}) {
3734 next if !($item->{volid} && $item->{size});
5996a936 3735 $item->{path} = PVE::Storage::path($cfg, $item->{volid});
91bd6c90
DM
3736 $volid_hash->{$item->{volid}} = $item;
3737 }
3738 }
3739
3740 return $volid_hash;
3741}
3742
a8e2f942
DM
3743sub get_used_paths {
3744 my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
3745
3746 my $used_path = {};
3747
3748 my $scan_config = sub {
3749 my ($cref, $snapname) = @_;
3750
3751 foreach my $key (keys %$cref) {
3752 my $value = $cref->{$key};
3753 if (valid_drivename($key)) {
3754 next if $skip_drive && $key eq $skip_drive;
3755 my $drive = parse_drive($key, $value);
3756 next if !$drive || !$drive->{file} || drive_is_cdrom($drive);
3757 if ($drive->{file} =~ m!^/!) {
3758 $used_path->{$drive->{file}}++; # = 1;
3759 } else {
3760 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
3761 next if !$storeid;
3762 my $scfg = PVE::Storage::storage_config($storecfg, $storeid, 1);
3763 next if !$scfg;
3764 my $path = PVE::Storage::path($storecfg, $drive->{file}, $snapname);
3765 $used_path->{$path}++; # = 1;
3766 }
3767 }
3768 }
3769 };
3770
3771 &$scan_config($conf);
3772
3773 undef $skip_drive;
3774
3775 if ($scan_snapshots) {
3776 foreach my $snapname (keys %{$conf->{snapshots}}) {
3777 &$scan_config($conf->{snapshots}->{$snapname}, $snapname);
3778 }
3779 }
3780
3781 return $used_path;
3782}
3783
91bd6c90
DM
3784sub update_disksize {
3785 my ($vmid, $conf, $volid_hash) = @_;
be190583 3786
91bd6c90
DM
3787 my $changes;
3788
3789 my $used = {};
3790
5996a936
DM
3791 # Note: it is allowed to define multiple storages with same path (alias), so
3792 # we need to check both 'volid' and real 'path' (two different volid can point
3793 # to the same path).
3794
3795 my $usedpath = {};
be190583 3796
91bd6c90
DM
3797 # update size info
3798 foreach my $opt (keys %$conf) {
ed221350
DM
3799 if (valid_drivename($opt)) {
3800 my $drive = parse_drive($opt, $conf->{$opt});
91bd6c90
DM
3801 my $volid = $drive->{file};
3802 next if !$volid;
3803
3804 $used->{$volid} = 1;
be190583 3805 if ($volid_hash->{$volid} &&
5996a936
DM
3806 (my $path = $volid_hash->{$volid}->{path})) {
3807 $usedpath->{$path} = 1;
3808 }
91bd6c90 3809
ed221350 3810 next if drive_is_cdrom($drive);
91bd6c90
DM
3811 next if !$volid_hash->{$volid};
3812
3813 $drive->{size} = $volid_hash->{$volid}->{size};
7a907ce6
DM
3814 my $new = print_drive($vmid, $drive);
3815 if ($new ne $conf->{$opt}) {
3816 $changes = 1;
3817 $conf->{$opt} = $new;
3818 }
91bd6c90
DM
3819 }
3820 }
3821
5996a936
DM
3822 # remove 'unusedX' entry if volume is used
3823 foreach my $opt (keys %$conf) {
3824 next if $opt !~ m/^unused\d+$/;
3825 my $volid = $conf->{$opt};
3826 my $path = $volid_hash->{$volid}->{path} if $volid_hash->{$volid};
be190583 3827 if ($used->{$volid} || ($path && $usedpath->{$path})) {
5996a936
DM
3828 $changes = 1;
3829 delete $conf->{$opt};
3830 }
3831 }
3832
91bd6c90
DM
3833 foreach my $volid (sort keys %$volid_hash) {
3834 next if $volid =~ m/vm-$vmid-state-/;
3835 next if $used->{$volid};
5996a936
DM
3836 my $path = $volid_hash->{$volid}->{path};
3837 next if !$path; # just to be sure
3838 next if $usedpath->{$path};
91bd6c90 3839 $changes = 1;
ed221350 3840 add_unused_volume($conf, $volid);
05937a14 3841 $usedpath->{$path} = 1; # avoid to add more than once (aliases)
91bd6c90
DM
3842 }
3843
3844 return $changes;
3845}
3846
3847sub rescan {
3848 my ($vmid, $nolock) = @_;
3849
3850 my $cfg = PVE::Cluster::cfs_read_file("storage.cfg");
3851
3852 my $volid_hash = scan_volids($cfg, $vmid);
3853
3854 my $updatefn = sub {
3855 my ($vmid) = @_;
3856
ed221350 3857 my $conf = load_config($vmid);
be190583 3858
ed221350 3859 check_lock($conf);
91bd6c90 3860
03da3f0d
DM
3861 my $vm_volids = {};
3862 foreach my $volid (keys %$volid_hash) {
3863 my $info = $volid_hash->{$volid};
3864 $vm_volids->{$volid} = $info if $info->{vmid} && $info->{vmid} == $vmid;
3865 }
3866
3867 my $changes = update_disksize($vmid, $conf, $vm_volids);
91bd6c90 3868
ed221350 3869 update_config_nolock($vmid, $conf, 1) if $changes;
91bd6c90
DM
3870 };
3871
3872 if (defined($vmid)) {
3873 if ($nolock) {
3874 &$updatefn($vmid);
3875 } else {
ed221350 3876 lock_config($vmid, $updatefn, $vmid);
91bd6c90
DM
3877 }
3878 } else {
3879 my $vmlist = config_list();
3880 foreach my $vmid (keys %$vmlist) {
3881 if ($nolock) {
3882 &$updatefn($vmid);
3883 } else {
ed221350 3884 lock_config($vmid, $updatefn, $vmid);
be190583 3885 }
91bd6c90
DM
3886 }
3887 }
3888}
3889
3890sub restore_vma_archive {
3891 my ($archive, $vmid, $user, $opts, $comp) = @_;
3892
3893 my $input = $archive eq '-' ? "<&STDIN" : undef;
3894 my $readfrom = $archive;
3895
3896 my $uncomp = '';
3897 if ($comp) {
3898 $readfrom = '-';
3899 my $qarchive = PVE::Tools::shellquote($archive);
3900 if ($comp eq 'gzip') {
3901 $uncomp = "zcat $qarchive|";
3902 } elsif ($comp eq 'lzop') {
3903 $uncomp = "lzop -d -c $qarchive|";
3904 } else {
3905 die "unknown compression method '$comp'\n";
3906 }
be190583 3907
91bd6c90
DM
3908 }
3909
3910 my $tmpdir = "/var/tmp/vzdumptmp$$";
3911 rmtree $tmpdir;
3912
3913 # disable interrupts (always do cleanups)
3914 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
3915 warn "got interrupt - ignored\n";
3916 };
3917
3918 my $mapfifo = "/var/tmp/vzdumptmp$$.fifo";
3919 POSIX::mkfifo($mapfifo, 0600);
3920 my $fifofh;
3921
3922 my $openfifo = sub {
3923 open($fifofh, '>', $mapfifo) || die $!;
3924 };
3925
3926 my $cmd = "${uncomp}vma extract -v -r $mapfifo $readfrom $tmpdir";
3927
3928 my $oldtimeout;
3929 my $timeout = 5;
3930
3931 my $devinfo = {};
3932
3933 my $rpcenv = PVE::RPCEnvironment::get();
3934
ed221350 3935 my $conffile = config_file($vmid);
91bd6c90
DM
3936 my $tmpfn = "$conffile.$$.tmp";
3937
ed221350
DM
3938 # Note: $oldconf is undef if VM does not exists
3939 my $oldconf = PVE::Cluster::cfs_read_file(cfs_config_path($vmid));
3940
91bd6c90
DM
3941 my $print_devmap = sub {
3942 my $virtdev_hash = {};
3943
3944 my $cfgfn = "$tmpdir/qemu-server.conf";
3945
3946 # we can read the config - that is already extracted
3947 my $fh = IO::File->new($cfgfn, "r") ||
3948 "unable to read qemu-server.conf - $!\n";
3949
3950 while (defined(my $line = <$fh>)) {
3951 if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
3952 my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
3953 die "archive does not contain data for drive '$virtdev'\n"
3954 if !$devinfo->{$devname};
3955 if (defined($opts->{storage})) {
3956 $storeid = $opts->{storage} || 'local';
3957 } elsif (!$storeid) {
3958 $storeid = 'local';
3959 }
3960 $format = 'raw' if !$format;
3961 $devinfo->{$devname}->{devname} = $devname;
3962 $devinfo->{$devname}->{virtdev} = $virtdev;
3963 $devinfo->{$devname}->{format} = $format;
3964 $devinfo->{$devname}->{storeid} = $storeid;
3965
be190583 3966 # check permission on storage
91bd6c90
DM
3967 my $pool = $opts->{pool}; # todo: do we need that?
3968 if ($user ne 'root@pam') {
3969 $rpcenv->check($user, "/storage/$storeid", ['Datastore.AllocateSpace']);
3970 }
3971
3972 $virtdev_hash->{$virtdev} = $devinfo->{$devname};
3973 }
3974 }
3975
3976 foreach my $devname (keys %$devinfo) {
be190583
DM
3977 die "found no device mapping information for device '$devname'\n"
3978 if !$devinfo->{$devname}->{virtdev};
91bd6c90
DM
3979 }
3980
91bd6c90 3981 my $cfg = cfs_read_file('storage.cfg');
ed221350
DM
3982
3983 # create empty/temp config
be190583 3984 if ($oldconf) {
ed221350
DM
3985 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
3986 foreach_drive($oldconf, sub {
3987 my ($ds, $drive) = @_;
3988
3989 return if drive_is_cdrom($drive);
3990
3991 my $volid = $drive->{file};
3992
3993 return if !$volid || $volid =~ m|^/|;
3994
3995 my ($path, $owner) = PVE::Storage::path($cfg, $volid);
3996 return if !$path || !$owner || ($owner != $vmid);
3997
3998 # Note: only delete disk we want to restore
3999 # other volumes will become unused
4000 if ($virtdev_hash->{$ds}) {
4001 PVE::Storage::vdisk_free($cfg, $volid);
4002 }
4003 });
4004 }
4005
4006 my $map = {};
91bd6c90
DM
4007 foreach my $virtdev (sort keys %$virtdev_hash) {
4008 my $d = $virtdev_hash->{$virtdev};
4009 my $alloc_size = int(($d->{size} + 1024 - 1)/1024);
4010 my $scfg = PVE::Storage::storage_config($cfg, $d->{storeid});
8fd57431
DM
4011
4012 # test if requested format is supported
4013 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($cfg, $d->{storeid});
4014 my $supported = grep { $_ eq $d->{format} } @$validFormats;
4015 $d->{format} = $defFormat if !$supported;
4016
91bd6c90
DM
4017 my $volid = PVE::Storage::vdisk_alloc($cfg, $d->{storeid}, $vmid,
4018 $d->{format}, undef, $alloc_size);
4019 print STDERR "new volume ID is '$volid'\n";
4020 $d->{volid} = $volid;
4021 my $path = PVE::Storage::path($cfg, $volid);
4022
4023 my $write_zeros = 1;
4024 # fixme: what other storages types initialize volumes with zero?
244f2577 4025 if ($scfg->{type} eq 'dir' || $scfg->{type} eq 'nfs' || $scfg->{type} eq 'glusterfs' ||
013d5275 4026 $scfg->{type} eq 'sheepdog' || $scfg->{type} eq 'rbd') {
91bd6c90
DM
4027 $write_zeros = 0;
4028 }
4029
4030 print $fifofh "${write_zeros}:$d->{devname}=$path\n";
4031
4032 print "map '$d->{devname}' to '$path' (write zeros = ${write_zeros})\n";
4033 $map->{$virtdev} = $volid;
4034 }
4035
4036 $fh->seek(0, 0) || die "seek failed - $!\n";
4037
4038 my $outfd = new IO::File ($tmpfn, "w") ||
4039 die "unable to write config for VM $vmid\n";
4040
4041 my $cookie = { netcount => 0 };
4042 while (defined(my $line = <$fh>)) {
be190583 4043 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
91bd6c90
DM
4044 }
4045
4046 $fh->close();
4047 $outfd->close();
4048 };
4049
4050 eval {
4051 # enable interrupts
4052 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
4053 die "interrupted by signal\n";
4054 };
4055 local $SIG{ALRM} = sub { die "got timeout\n"; };
4056
4057 $oldtimeout = alarm($timeout);
4058
4059 my $parser = sub {
4060 my $line = shift;
4061
4062 print "$line\n";
4063
4064 if ($line =~ m/^DEV:\sdev_id=(\d+)\ssize:\s(\d+)\sdevname:\s(\S+)$/) {
4065 my ($dev_id, $size, $devname) = ($1, $2, $3);
4066 $devinfo->{$devname} = { size => $size, dev_id => $dev_id };
4067 } elsif ($line =~ m/^CTIME: /) {
4068 &$print_devmap();
4069 print $fifofh "done\n";
4070 my $tmp = $oldtimeout || 0;
4071 $oldtimeout = undef;
4072 alarm($tmp);
4073 close($fifofh);
4074 }
4075 };
be190583 4076
91bd6c90
DM
4077 print "restore vma archive: $cmd\n";
4078 run_command($cmd, input => $input, outfunc => $parser, afterfork => $openfifo);
4079 };
4080 my $err = $@;
4081
4082 alarm($oldtimeout) if $oldtimeout;
4083
4084 unlink $mapfifo;
4085
4086 if ($err) {
4087 rmtree $tmpdir;
4088 unlink $tmpfn;
4089
4090 my $cfg = cfs_read_file('storage.cfg');
4091 foreach my $devname (keys %$devinfo) {
4092 my $volid = $devinfo->{$devname}->{volid};
4093 next if !$volid;
4094 eval {
4095 if ($volid =~ m|^/|) {
4096 unlink $volid || die 'unlink failed\n';
4097 } else {
4098 PVE::Storage::vdisk_free($cfg, $volid);
4099 }
4100 print STDERR "temporary volume '$volid' sucessfuly removed\n";
4101 };
4102 print STDERR "unable to cleanup '$volid' - $@" if $@;
4103 }
4104 die $err;
4105 }
4106
4107 rmtree $tmpdir;
ed221350
DM
4108
4109 rename($tmpfn, $conffile) ||
91bd6c90
DM
4110 die "unable to commit configuration file '$conffile'\n";
4111
ed221350
DM
4112 PVE::Cluster::cfs_update(); # make sure we read new file
4113
91bd6c90
DM
4114 eval { rescan($vmid, 1); };
4115 warn $@ if $@;
4116}
4117
4118sub restore_tar_archive {
4119 my ($archive, $vmid, $user, $opts) = @_;
4120
9c502e26 4121 if ($archive ne '-') {
ed221350 4122 my $firstfile = tar_archive_read_firstfile($archive);
9c502e26
DM
4123 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
4124 if $firstfile ne 'qemu-server.conf';
4125 }
3e16d5fc 4126
ed221350 4127 my $storecfg = cfs_read_file('storage.cfg');
ebb55558 4128
ed221350 4129 # destroy existing data - keep empty config
ebb55558
DM
4130 my $vmcfgfn = PVE::QemuServer::config_file($vmid);
4131 destroy_vm($storecfg, $vmid, 1) if -f $vmcfgfn;
ed221350 4132
3e16d5fc
DM
4133 my $tocmd = "/usr/lib/qemu-server/qmextract";
4134
2415a446 4135 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 4136 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
4137 $tocmd .= ' --prealloc' if $opts->{prealloc};
4138 $tocmd .= ' --info' if $opts->{info};
4139
a0d1b1a2 4140 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 4141 # so we pipe to zcat
2415a446
DM
4142 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
4143 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
4144
4145 my $tmpdir = "/var/tmp/vzdumptmp$$";
4146 mkpath $tmpdir;
4147
4148 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
4149 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 4150 local $ENV{VZDUMP_USER} = $user;
3e16d5fc 4151
ed221350 4152 my $conffile = config_file($vmid);
3e16d5fc
DM
4153 my $tmpfn = "$conffile.$$.tmp";
4154
4155 # disable interrupts (always do cleanups)
4156 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
4157 print STDERR "got interrupt - ignored\n";
4158 };
4159
afdb31d5 4160 eval {
3e16d5fc
DM
4161 # enable interrupts
4162 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
4163 die "interrupted by signal\n";
4164 };
4165
9c502e26
DM
4166 if ($archive eq '-') {
4167 print "extracting archive from STDIN\n";
4168 run_command($cmd, input => "<&STDIN");
4169 } else {
4170 print "extracting archive '$archive'\n";
4171 run_command($cmd);
4172 }
3e16d5fc
DM
4173
4174 return if $opts->{info};
4175
4176 # read new mapping
4177 my $map = {};
4178 my $statfile = "$tmpdir/qmrestore.stat";
4179 if (my $fd = IO::File->new($statfile, "r")) {
4180 while (defined (my $line = <$fd>)) {
4181 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
4182 $map->{$1} = $2 if $1;
4183 } else {
4184 print STDERR "unable to parse line in statfile - $line\n";
4185 }
4186 }
4187 $fd->close();
4188 }
4189
4190 my $confsrc = "$tmpdir/qemu-server.conf";
4191
4192 my $srcfd = new IO::File($confsrc, "r") ||
4193 die "unable to open file '$confsrc'\n";
4194
4195 my $outfd = new IO::File ($tmpfn, "w") ||
4196 die "unable to write config for VM $vmid\n";
4197
91bd6c90 4198 my $cookie = { netcount => 0 };
3e16d5fc 4199 while (defined (my $line = <$srcfd>)) {
be190583 4200 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
3e16d5fc
DM
4201 }
4202
4203 $srcfd->close();
4204 $outfd->close();
4205 };
4206 my $err = $@;
4207
afdb31d5 4208 if ($err) {
3e16d5fc
DM
4209
4210 unlink $tmpfn;
4211
ed221350 4212 tar_restore_cleanup($storecfg, "$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 4213
3e16d5fc 4214 die $err;
afdb31d5 4215 }
3e16d5fc
DM
4216
4217 rmtree $tmpdir;
4218
4219 rename $tmpfn, $conffile ||
4220 die "unable to commit configuration file '$conffile'\n";
91bd6c90 4221
ed221350
DM
4222 PVE::Cluster::cfs_update(); # make sure we read new file
4223
91bd6c90
DM
4224 eval { rescan($vmid, 1); };
4225 warn $@ if $@;
3e16d5fc
DM
4226};
4227
0d18dcfc
DM
4228
4229# Internal snapshots
4230
4231# NOTE: Snapshot create/delete involves several non-atomic
4232# action, and can take a long time.
4233# So we try to avoid locking the file and use 'lock' variable
4234# inside the config file instead.
4235
ef59d1ca
DM
4236my $snapshot_copy_config = sub {
4237 my ($source, $dest) = @_;
4238
4239 foreach my $k (keys %$source) {
4240 next if $k eq 'snapshots';
982c7f12
DM
4241 next if $k eq 'snapstate';
4242 next if $k eq 'snaptime';
18bfb361 4243 next if $k eq 'vmstate';
ef59d1ca
DM
4244 next if $k eq 'lock';
4245 next if $k eq 'digest';
db7c26e5 4246 next if $k eq 'description';
ef59d1ca 4247 next if $k =~ m/^unused\d+$/;
be190583 4248
ef59d1ca
DM
4249 $dest->{$k} = $source->{$k};
4250 }
4251};
4252
4253my $snapshot_apply_config = sub {
4254 my ($conf, $snap) = @_;
4255
4256 # copy snapshot list
4257 my $newconf = {
4258 snapshots => $conf->{snapshots},
4259 };
4260
db7c26e5 4261 # keep description and list of unused disks
ef59d1ca 4262 foreach my $k (keys %$conf) {
db7c26e5 4263 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
ef59d1ca
DM
4264 $newconf->{$k} = $conf->{$k};
4265 }
4266
4267 &$snapshot_copy_config($snap, $newconf);
4268
4269 return $newconf;
4270};
4271
18bfb361
DM
4272sub foreach_writable_storage {
4273 my ($conf, $func) = @_;
4274
4275 my $sidhash = {};
4276
4277 foreach my $ds (keys %$conf) {
4278 next if !valid_drivename($ds);
4279
4280 my $drive = parse_drive($ds, $conf->{$ds});
4281 next if !$drive;
4282 next if drive_is_cdrom($drive);
4283
4284 my $volid = $drive->{file};
4285
4286 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
be190583 4287 $sidhash->{$sid} = $sid if $sid;
18bfb361
DM
4288 }
4289
4290 foreach my $sid (sort keys %$sidhash) {
4291 &$func($sid);
4292 }
4293}
4294
4295my $alloc_vmstate_volid = sub {
4296 my ($storecfg, $vmid, $conf, $snapname) = @_;
be190583 4297
18bfb361
DM
4298 # Note: we try to be smart when selecting a $target storage
4299
4300 my $target;
4301
4302 # search shared storage first
4303 foreach_writable_storage($conf, sub {
4304 my ($sid) = @_;
4305 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
4306 return if !$scfg->{shared};
4307
4308 $target = $sid if !$target || $scfg->{path}; # prefer file based storage
4309 });
4310
4311 if (!$target) {
4312 # now search local storage
4313 foreach_writable_storage($conf, sub {
4314 my ($sid) = @_;
4315 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
4316 return if $scfg->{shared};
4317
4318 $target = $sid if !$target || $scfg->{path}; # prefer file based storage;
4319 });
4320 }
4321
4322 $target = 'local' if !$target;
4323
fe6249f4
DM
4324 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
4325 # we abort live save after $conf->{memory}, so we need at max twice that space
4326 my $size = $conf->{memory}*2 + $driver_state_size;
18bfb361
DM
4327
4328 my $name = "vm-$vmid-state-$snapname";
4329 my $scfg = PVE::Storage::storage_config($storecfg, $target);
4330 $name .= ".raw" if $scfg->{path}; # add filename extension for file base storage
4331 my $volid = PVE::Storage::vdisk_alloc($storecfg, $target, $vmid, 'raw', $name, $size*1024);
4332
4333 return $volid;
4334};
4335
0d18dcfc 4336my $snapshot_prepare = sub {
18bfb361 4337 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
22c377f0
DM
4338
4339 my $snap;
0d18dcfc
DM
4340
4341 my $updatefn = sub {
4342
4343 my $conf = load_config($vmid);
4344
be190583 4345 die "you can't take a snapshot if it's a template\n"
5295b23d
DM
4346 if is_template($conf);
4347
0d18dcfc
DM
4348 check_lock($conf);
4349
22c377f0
DM
4350 $conf->{lock} = 'snapshot';
4351
be190583
DM
4352 die "snapshot name '$snapname' already used\n"
4353 if defined($conf->{snapshots}->{$snapname});
0d18dcfc 4354
ee2f90b1 4355 my $storecfg = PVE::Storage::config();
7ea975ef 4356 die "snapshot feature is not available" if !has_feature('snapshot', $conf, $storecfg);
18bfb361 4357
782f4f75 4358 $snap = $conf->{snapshots}->{$snapname} = {};
0d18dcfc 4359
18bfb361
DM
4360 if ($save_vmstate && check_running($vmid)) {
4361 $snap->{vmstate} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
4362 }
4363
ef59d1ca 4364 &$snapshot_copy_config($conf, $snap);
0d18dcfc 4365
782f4f75
DM
4366 $snap->{snapstate} = "prepare";
4367 $snap->{snaptime} = time();
4368 $snap->{description} = $comment if $comment;
4369
4b15803d
DM
4370 # always overwrite machine if we save vmstate. This makes sure we
4371 # can restore it later using correct machine type
4372 $snap->{machine} = get_current_qemu_machine($vmid) if $snap->{vmstate};
4373
0d18dcfc
DM
4374 update_config_nolock($vmid, $conf, 1);
4375 };
4376
4377 lock_config($vmid, $updatefn);
22c377f0
DM
4378
4379 return $snap;
0d18dcfc
DM
4380};
4381
4382my $snapshot_commit = sub {
4383 my ($vmid, $snapname) = @_;
4384
4385 my $updatefn = sub {
4386
4387 my $conf = load_config($vmid);
4388
be190583
DM
4389 die "missing snapshot lock\n"
4390 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
0d18dcfc
DM
4391
4392 my $snap = $conf->{snapshots}->{$snapname};
4393
be190583
DM
4394 die "snapshot '$snapname' does not exist\n" if !defined($snap);
4395
4396 die "wrong snapshot state\n"
4397 if !($snap->{snapstate} && $snap->{snapstate} eq "prepare");
0d18dcfc 4398
0d18dcfc 4399 delete $snap->{snapstate};
ee2f90b1 4400 delete $conf->{lock};
0d18dcfc 4401
ef59d1ca 4402 my $newconf = &$snapshot_apply_config($conf, $snap);
0d18dcfc 4403
05e5ad3f
DM
4404 $newconf->{parent} = $snapname;
4405
0d18dcfc
DM
4406 update_config_nolock($vmid, $newconf, 1);
4407 };
4408
4409 lock_config($vmid, $updatefn);
4410};
4411
22c377f0
DM
4412sub snapshot_rollback {
4413 my ($vmid, $snapname) = @_;
4414
4415 my $snap;
4416
4417 my $prepare = 1;
4418
a3222b91 4419 my $storecfg = PVE::Storage::config();
be190583 4420
22c377f0
DM
4421 my $updatefn = sub {
4422
4423 my $conf = load_config($vmid);
4424
8b43bc11 4425 die "you can't rollback if vm is a template\n" if is_template($conf);
90b0c6b3 4426
ab33a7c2
DM
4427 $snap = $conf->{snapshots}->{$snapname};
4428
be190583 4429 die "snapshot '$snapname' does not exist\n" if !defined($snap);
ab33a7c2 4430
be190583 4431 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
ab33a7c2
DM
4432 if $snap->{snapstate};
4433
a3222b91
DM
4434 if ($prepare) {
4435 check_lock($conf);
4436 vm_stop($storecfg, $vmid, undef, undef, 5, undef, undef);
4437 }
22c377f0
DM
4438
4439 die "unable to rollback vm $vmid: vm is running\n"
4440 if check_running($vmid);
4441
4442 if ($prepare) {
4443 $conf->{lock} = 'rollback';
4444 } else {
4445 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
4446 delete $conf->{lock};
4447 }
4448
4b15803d
DM
4449 my $forcemachine;
4450
22c377f0 4451 if (!$prepare) {
4b15803d
DM
4452 my $has_machine_config = defined($conf->{machine});
4453
22c377f0 4454 # copy snapshot config to current config
ef59d1ca
DM
4455 $conf = &$snapshot_apply_config($conf, $snap);
4456 $conf->{parent} = $snapname;
4b15803d 4457
d8b916fd
DM
4458 # Note: old code did not store 'machine', so we try to be smart
4459 # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
4460 $forcemachine = $conf->{machine} || 'pc-i440fx-1.4';
be190583 4461 # we remove the 'machine' configuration if not explicitly specified
4b15803d
DM
4462 # in the original config.
4463 delete $conf->{machine} if $snap->{vmstate} && !$has_machine_config;
22c377f0
DM
4464 }
4465
4466 update_config_nolock($vmid, $conf, 1);
a3222b91
DM
4467
4468 if (!$prepare && $snap->{vmstate}) {
4469 my $statefile = PVE::Storage::path($storecfg, $snap->{vmstate});
4b15803d 4470 vm_start($storecfg, $vmid, $statefile, undef, undef, undef, $forcemachine);
a3222b91 4471 }
22c377f0
DM
4472 };
4473
4474 lock_config($vmid, $updatefn);
be190583 4475
22c377f0
DM
4476 foreach_drive($snap, sub {
4477 my ($ds, $drive) = @_;
4478
4479 return if drive_is_cdrom($drive);
4480
4481 my $volid = $drive->{file};
4482 my $device = "drive-$ds";
4483
79e57b29 4484 PVE::Storage::volume_snapshot_rollback($storecfg, $volid, $snapname);
22c377f0
DM
4485 });
4486
4487 $prepare = 0;
4488 lock_config($vmid, $updatefn);
4489}
4490
9dcf4909
DM
4491my $savevm_wait = sub {
4492 my ($vmid) = @_;
4493
4494 for(;;) {
ed221350 4495 my $stat = vm_mon_cmd_nocheck($vmid, "query-savevm");
9dcf4909
DM
4496 if (!$stat->{status}) {
4497 die "savevm not active\n";
4498 } elsif ($stat->{status} eq 'active') {
4499 sleep(1);
4500 next;
4501 } elsif ($stat->{status} eq 'completed') {
4502 last;
4503 } else {
4504 die "query-savevm returned status '$stat->{status}'\n";
4505 }
4506 }
4507};
4508
0d18dcfc 4509sub snapshot_create {
18bfb361 4510 my ($vmid, $snapname, $save_vmstate, $freezefs, $comment) = @_;
0d18dcfc 4511
18bfb361 4512 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
0d18dcfc 4513
18bfb361 4514 $freezefs = $save_vmstate = 0 if !$snap->{vmstate}; # vm is not running
030dd626 4515
3ee28e38
DM
4516 my $drivehash = {};
4517
18bfb361
DM
4518 my $running = check_running($vmid);
4519
0d18dcfc
DM
4520 eval {
4521 # create internal snapshots of all drives
22c377f0
DM
4522
4523 my $storecfg = PVE::Storage::config();
a3222b91
DM
4524
4525 if ($running) {
4526 if ($snap->{vmstate}) {
be190583 4527 my $path = PVE::Storage::path($storecfg, $snap->{vmstate});
9dcf4909
DM
4528 vm_mon_cmd($vmid, "savevm-start", statefile => $path);
4529 &$savevm_wait($vmid);
a3222b91 4530 } else {
9dcf4909 4531 vm_mon_cmd($vmid, "savevm-start");
a3222b91
DM
4532 }
4533 };
4534
4535 qga_freezefs($vmid) if $running && $freezefs;
be190583 4536
22c377f0
DM
4537 foreach_drive($snap, sub {
4538 my ($ds, $drive) = @_;
4539
4540 return if drive_is_cdrom($drive);
0d18dcfc 4541
22c377f0
DM
4542 my $volid = $drive->{file};
4543 my $device = "drive-$ds";
4544
4545 qemu_volume_snapshot($vmid, $device, $storecfg, $volid, $snapname);
3ee28e38 4546 $drivehash->{$ds} = 1;
22c377f0 4547 });
0d18dcfc 4548 };
22c377f0
DM
4549 my $err = $@;
4550
1a71fa73 4551 eval { qga_unfreezefs($vmid) if $running && $freezefs; };
22c377f0
DM
4552 warn $@ if $@;
4553
9dcf4909 4554 eval { vm_mon_cmd($vmid, "savevm-end") if $running; };
22c377f0
DM
4555 warn $@ if $@;
4556
4557 if ($err) {
0d18dcfc 4558 warn "snapshot create failed: starting cleanup\n";
3ee28e38 4559 eval { snapshot_delete($vmid, $snapname, 0, $drivehash); };
0d18dcfc
DM
4560 warn $@ if $@;
4561 die $err;
4562 }
4563
4564 &$snapshot_commit($vmid, $snapname);
4565}
4566
3ee28e38 4567# Note: $drivehash is only set when called from snapshot_create.
0d18dcfc 4568sub snapshot_delete {
3ee28e38 4569 my ($vmid, $snapname, $force, $drivehash) = @_;
0d18dcfc
DM
4570
4571 my $prepare = 1;
4572
22c377f0 4573 my $snap;
ee2f90b1 4574 my $unused = [];
0d18dcfc 4575
6cb1a8cf
DM
4576 my $unlink_parent = sub {
4577 my ($confref, $new_parent) = @_;
4578
4579 if ($confref->{parent} && $confref->{parent} eq $snapname) {
4580 if ($new_parent) {
4581 $confref->{parent} = $new_parent;
4582 } else {
4583 delete $confref->{parent};
4584 }
4585 }
4586 };
be190583 4587
0d18dcfc 4588 my $updatefn = sub {
2009f324 4589 my ($remove_drive) = @_;
0d18dcfc 4590
22c377f0 4591 my $conf = load_config($vmid);
0d18dcfc 4592
5295b23d
DM
4593 if (!$drivehash) {
4594 check_lock($conf);
be190583 4595 die "you can't delete a snapshot if vm is a template\n"
5295b23d
DM
4596 if is_template($conf);
4597 }
0d18dcfc 4598
22c377f0 4599 $snap = $conf->{snapshots}->{$snapname};
0d18dcfc 4600
be190583 4601 die "snapshot '$snapname' does not exist\n" if !defined($snap);
0d18dcfc
DM
4602
4603 # remove parent refs
6cb1a8cf 4604 &$unlink_parent($conf, $snap->{parent});
0d18dcfc
DM
4605 foreach my $sn (keys %{$conf->{snapshots}}) {
4606 next if $sn eq $snapname;
6cb1a8cf 4607 &$unlink_parent($conf->{snapshots}->{$sn}, $snap->{parent});
0d18dcfc
DM
4608 }
4609
2009f324 4610 if ($remove_drive) {
18bfb361
DM
4611 if ($remove_drive eq 'vmstate') {
4612 delete $snap->{$remove_drive};
4613 } else {
4614 my $drive = parse_drive($remove_drive, $snap->{$remove_drive});
4615 my $volid = $drive->{file};
4616 delete $snap->{$remove_drive};
4617 add_unused_volume($conf, $volid);
4618 }
2009f324
DM
4619 }
4620
0d18dcfc
DM
4621 if ($prepare) {
4622 $snap->{snapstate} = 'delete';
4623 } else {
4624 delete $conf->{snapshots}->{$snapname};
3ee28e38 4625 delete $conf->{lock} if $drivehash;
ee2f90b1
DM
4626 foreach my $volid (@$unused) {
4627 add_unused_volume($conf, $volid);
4628 }
0d18dcfc
DM
4629 }
4630
4631 update_config_nolock($vmid, $conf, 1);
4632 };
4633
4634 lock_config($vmid, $updatefn);
4635
18bfb361 4636 # now remove vmstate file
0d18dcfc 4637
22c377f0
DM
4638 my $storecfg = PVE::Storage::config();
4639
18bfb361
DM
4640 if ($snap->{vmstate}) {
4641 eval { PVE::Storage::vdisk_free($storecfg, $snap->{vmstate}); };
4642 if (my $err = $@) {
4643 die $err if !$force;
4644 warn $err;
4645 }
4646 # save changes (remove vmstate from snapshot)
4647 lock_config($vmid, $updatefn, 'vmstate') if !$force;
4648 };
4649
4650 # now remove all internal snapshots
4651 foreach_drive($snap, sub {
22c377f0
DM
4652 my ($ds, $drive) = @_;
4653
4654 return if drive_is_cdrom($drive);
3ee28e38 4655
22c377f0
DM
4656 my $volid = $drive->{file};
4657 my $device = "drive-$ds";
4658
2009f324
DM
4659 if (!$drivehash || $drivehash->{$ds}) {
4660 eval { qemu_volume_snapshot_delete($vmid, $device, $storecfg, $volid, $snapname); };
4661 if (my $err = $@) {
4662 die $err if !$force;
4663 warn $err;
4664 }
3ee28e38 4665 }
2009f324
DM
4666
4667 # save changes (remove drive fron snapshot)
4668 lock_config($vmid, $updatefn, $ds) if !$force;
ee2f90b1 4669 push @$unused, $volid;
22c377f0 4670 });
0d18dcfc
DM
4671
4672 # now cleanup config
4673 $prepare = 0;
4674 lock_config($vmid, $updatefn);
4675}
4676
9cd07842 4677sub has_feature {
7ea975ef
AD
4678 my ($feature, $conf, $storecfg, $snapname, $running) = @_;
4679
719893a9 4680 my $err;
7ea975ef
AD
4681 foreach_drive($conf, sub {
4682 my ($ds, $drive) = @_;
4683
4684 return if drive_is_cdrom($drive);
4685 my $volid = $drive->{file};
4686 $err = 1 if !PVE::Storage::volume_has_feature($storecfg, $feature, $volid, $snapname, $running);
4687 });
4688
719893a9 4689 return $err ? 0 : 1;
7ea975ef 4690}
04a69bb4
AD
4691
4692sub template_create {
4693 my ($vmid, $conf, $disk) = @_;
4694
04a69bb4 4695 my $storecfg = PVE::Storage::config();
04a69bb4 4696
9cd07842
DM
4697 foreach_drive($conf, sub {
4698 my ($ds, $drive) = @_;
4699
4700 return if drive_is_cdrom($drive);
4701 return if $disk && $ds ne $disk;
4702
4703 my $volid = $drive->{file};
bbd56097 4704 return if !PVE::Storage::volume_has_feature($storecfg, 'template', $volid);
9cd07842 4705
04a69bb4
AD
4706 my $voliddst = PVE::Storage::vdisk_create_base($storecfg, $volid);
4707 $drive->{file} = $voliddst;
152fe752
DM
4708 $conf->{$ds} = print_drive($vmid, $drive);
4709 update_config_nolock($vmid, $conf, 1);
04a69bb4 4710 });
04a69bb4
AD
4711}
4712
624361b3
AD
4713sub is_template {
4714 my ($conf) = @_;
4715
96d695c0 4716 return 1 if defined $conf->{template} && $conf->{template} == 1;
624361b3
AD
4717}
4718
5133de42
AD
4719sub qemu_img_convert {
4720 my ($src_volid, $dst_volid, $size, $snapname) = @_;
4721
4722 my $storecfg = PVE::Storage::config();
4723 my ($src_storeid, $src_volname) = PVE::Storage::parse_volume_id($src_volid, 1);
4724 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid, 1);
4725
4726 if ($src_storeid && $dst_storeid) {
4727 my $src_scfg = PVE::Storage::storage_config($storecfg, $src_storeid);
4728 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
4729
4730 my $src_format = qemu_img_format($src_scfg, $src_volname);
4731 my $dst_format = qemu_img_format($dst_scfg, $dst_volname);
4732
4733 my $src_path = PVE::Storage::path($storecfg, $src_volid, $snapname);
4734 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
4735
4736 my $cmd = [];
71ddbff9 4737 push @$cmd, '/usr/bin/qemu-img', 'convert', '-t', 'writeback', '-p', '-n';
5133de42
AD
4738 push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
4739 push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path, $dst_path;
4740
4741 my $parser = sub {
4742 my $line = shift;
4743 if($line =~ m/\((\S+)\/100\%\)/){
4744 my $percent = $1;
4745 my $transferred = int($size * $percent / 100);
4746 my $remaining = $size - $transferred;
4747
4748 print "transferred: $transferred bytes remaining: $remaining bytes total: $size bytes progression: $percent %\n";
4749 }
4750
4751 };
4752
4753 eval { run_command($cmd, timeout => undef, outfunc => $parser); };
4754 my $err = $@;
4755 die "copy failed: $err" if $err;
4756 }
4757}
4758
4759sub qemu_img_format {
4760 my ($scfg, $volname) = @_;
4761
ccb5c001 4762 if ($scfg->{path} && $volname =~ m/\.(raw|qcow2|qed|vmdk)$/) {
5133de42 4763 return $1;
ccb5c001 4764 } elsif ($scfg->{type} eq 'iscsi') {
5133de42 4765 return "host_device";
be190583 4766 } else {
5133de42 4767 return "raw";
5133de42
AD
4768 }
4769}
4770
cfad42af
AD
4771sub qemu_drive_mirror {
4772 my ($vmid, $drive, $dst_volid, $vmiddst, $maxwait) = @_;
4773
4774 my $count = 1;
4775 my $old_len = 0;
4776 my $frozen = undef;
4777
4778 my $storecfg = PVE::Storage::config();
4779 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid, 1);
4780
4781 if ($dst_storeid) {
4782 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
4783
152fe752 4784 my $format;
cfad42af
AD
4785 if ($dst_volname =~ m/\.(raw|qcow2)$/){
4786 $format = $1;
4787 }
4788
4789 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
4790
152fe752 4791 if ($format) {
be190583 4792 #fixme : sometime drive-mirror timeout, but works fine after.
152fe752 4793 # (I have see the problem with big volume > 200GB), so we need to eval
be190583 4794 eval { vm_mon_cmd($vmid, "drive-mirror", timeout => 10, device => "drive-$drive", mode => "existing",
152fe752
DM
4795 sync => "full", target => $dst_path, format => $format); };
4796 } else {
be190583 4797 eval { vm_mon_cmd($vmid, "drive-mirror", timeout => 10, device => "drive-$drive", mode => "existing",
152fe752 4798 sync => "full", target => $dst_path); };
cfad42af 4799 }
152fe752
DM
4800
4801 eval {
cfad42af 4802 while (1) {
152fe752 4803 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
cfad42af 4804 my $stat = @$stats[0];
f6ab3bdb
AD
4805 die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
4806 die "error job is not mirroring" if $stat->{type} ne "mirror";
4807
cfad42af
AD
4808 my $transferred = $stat->{offset};
4809 my $total = $stat->{len};
4810 my $remaining = $total - $transferred;
4811 my $percent = sprintf "%.2f", ($transferred * 100 / $total);
cfad42af
AD
4812
4813 print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent %\n";
4814
4815 last if ($stat->{len} == $stat->{offset});
4816 if ($old_len == $stat->{offset}) {
4817 if ($maxwait && $count > $maxwait) {
4818 # if writes to disk occurs the disk needs to be freezed
4819 # to be able to complete the migration
4820 vm_suspend($vmid,1);
4821 $count = 0;
4822 $frozen = 1;
152fe752 4823 } else {
cfad42af
AD
4824 $count++ unless $frozen;
4825 }
152fe752
DM
4826 } elsif ($frozen) {
4827 vm_resume($vmid,1);
4828 $count = 0;
cfad42af
AD
4829 }
4830 $old_len = $stat->{offset};
4831 sleep 1;
4832 }
be190583 4833
2fc6bc17 4834 if ($vmiddst == $vmid) {
be190583 4835 # switch the disk if source and destination are on the same guest
2fc6bc17
DM
4836 vm_mon_cmd($vmid, "block-job-complete", device => "drive-$drive");
4837 }
cfad42af 4838 };
4fca0153 4839 if (my $err = $@) {
152fe752 4840 eval { vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive"); };
4fca0153 4841 die "mirroring error: $err";
cfad42af
AD
4842 }
4843
2fc6bc17
DM
4844 if ($vmiddst != $vmid) {
4845 # if we clone a disk for a new target vm, we don't switch the disk
152fe752 4846 vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive");
cfad42af
AD
4847 }
4848 }
4849}
4850
152fe752 4851sub clone_disk {
be190583 4852 my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
152fe752
DM
4853 $newvmid, $storage, $format, $full, $newvollist) = @_;
4854
4855 my $newvolid;
4856
4857 if (!$full) {
4858 print "create linked clone of drive $drivename ($drive->{file})\n";
4859 $newvolid = PVE::Storage::vdisk_clone($storecfg, $drive->{file}, $newvmid);
4860 push @$newvollist, $newvolid;
4861 } else {
4862 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file});
4863 $storeid = $storage if $storage;
4864
1377d7b0
DM
4865 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($storecfg, $storeid);
4866 if (!$format) {
4867 $format = $drive->{format} || $defFormat;
152fe752
DM
4868 }
4869
1377d7b0
DM
4870 # test if requested format is supported - else use default
4871 my $supported = grep { $_ eq $format } @$validFormats;
4872 $format = $defFormat if !$supported;
4873
152fe752
DM
4874 my ($size) = PVE::Storage::volume_size_info($storecfg, $drive->{file}, 3);
4875
4876 print "create full clone of drive $drivename ($drive->{file})\n";
4877 $newvolid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $newvmid, $format, undef, ($size/1024));
4878 push @$newvollist, $newvolid;
4879
4880 if (!$running || $snapname) {
4881 qemu_img_convert($drive->{file}, $newvolid, $size, $snapname);
4882 } else {
4883 qemu_drive_mirror($vmid, $drivename, $newvolid, $newvmid);
be190583 4884 }
152fe752
DM
4885 }
4886
4887 my ($size) = PVE::Storage::volume_size_info($storecfg, $newvolid, 3);
4888
4889 my $disk = $drive;
4890 $disk->{format} = undef;
4891 $disk->{file} = $newvolid;
4892 $disk->{size} = $size;
4893
4894 return $disk;
4895}
4896
ff556cf2
DM
4897# this only works if VM is running
4898sub get_current_qemu_machine {
4899 my ($vmid) = @_;
4900
4901 my $cmd = { execute => 'query-machines', arguments => {} };
be190583 4902 my $res = PVE::QemuServer::vm_qmp_command($vmid, $cmd);
ff556cf2
DM
4903
4904 my ($current, $default);
4905 foreach my $e (@$res) {
4906 $default = $e->{name} if $e->{'is-default'};
4907 $current = $e->{name} if $e->{'is-current'};
4908 }
4909
4910 # fallback to the default machine if current is not supported by qemu
4911 return $current || $default || 'pc';
4912}
4913
1481f3f2
AD
4914sub read_x509_subject_spice {
4915 my ($filename) = @_;
4916
4917 # read x509 subject
4918 my $bio = Net::SSLeay::BIO_new_file($filename, 'r');
4919 my $x509 = Net::SSLeay::PEM_read_bio_X509($bio);
4920 Net::SSLeay::BIO_free($bio);
4921 my $nameobj = Net::SSLeay::X509_get_subject_name($x509);
4922 my $subject = Net::SSLeay::X509_NAME_oneline($nameobj);
4923 Net::SSLeay::X509_free($x509);
4924
4925 # remote-viewer wants comma as seperator (not '/')
4926 $subject =~ s!^/!!;
4927 $subject =~ s!/(\w+=)!,$1!g;
4928
4929 return $subject;
4930}
1e3baf05 49311;