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