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