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