]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
correctly handle empty description in pending section
[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;
4543ecf0 25use PVE::Tools qw(run_command lock_file lock_file_full file_read_firstline dir_glob_foreach);
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
e5eaa028
WL
34my $qemu_snap_storage = {rbd => 1, sheepdog => 1};
35
7f0b5beb 36my $cpuinfo = PVE::ProcFSTools::read_cpuinfo();
1e3baf05 37
19672434 38# Note about locking: we use flock on the config file protect
1e3baf05
DM
39# against concurent actions.
40# Aditionaly, we have a 'lock' setting in the config file. This
22c377f0 41# can be set to 'migrate', 'backup', 'snapshot' or 'rollback'. Most actions are not
1e3baf05
DM
42# allowed when such lock is set. But you can ignore this kind of
43# lock with the --skiplock flag.
44
97d62eb7 45cfs_register_file('/qemu-server/',
1858638f
DM
46 \&parse_vm_config,
47 \&write_vm_config);
1e3baf05 48
3ea94c60
DM
49PVE::JSONSchema::register_standard_option('skiplock', {
50 description => "Ignore locks - only root is allowed to use this option.",
afdb31d5 51 type => 'boolean',
3ea94c60
DM
52 optional => 1,
53});
54
55PVE::JSONSchema::register_standard_option('pve-qm-stateuri', {
56 description => "Some command save/restore state from this location.",
57 type => 'string',
58 maxLength => 128,
59 optional => 1,
60});
61
8abd398b
DM
62PVE::JSONSchema::register_standard_option('pve-snapshot-name', {
63 description => "The name of the snapshot.",
64 type => 'string', format => 'pve-configid',
65 maxLength => 40,
66});
67
1e3baf05
DM
68#no warnings 'redefine';
69
c8effec3
AD
70sub cgroups_write {
71 my ($controller, $vmid, $option, $value) = @_;
72
3a515a88
DM
73 my $path = "/sys/fs/cgroup/$controller/qemu.slice/$vmid.scope/$option";
74 PVE::ProcFSTools::write_proc_entry($path, $value);
c8effec3
AD
75
76}
77
1e3baf05
DM
78my $nodename = PVE::INotify::nodename();
79
80mkdir "/etc/pve/nodes/$nodename";
81my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
82mkdir $confdir;
83
84my $var_run_tmpdir = "/var/run/qemu-server";
85mkdir $var_run_tmpdir;
86
87my $lock_dir = "/var/lock/qemu-server";
88mkdir $lock_dir;
89
90my $pcisysfs = "/sys/bus/pci";
91
1e3baf05
DM
92my $confdesc = {
93 onboot => {
94 optional => 1,
95 type => 'boolean',
96 description => "Specifies whether a VM will be started during system bootup.",
97 default => 0,
98 },
99 autostart => {
100 optional => 1,
101 type => 'boolean',
102 description => "Automatic restart after crash (currently ignored).",
103 default => 0,
104 },
2ff09f52
DA
105 hotplug => {
106 optional => 1,
b3c2bdd1
DM
107 type => 'string', format => 'pve-hotplug-features',
108 description => "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.",
109 default => 'network,disk,usb',
2ff09f52 110 },
1e3baf05
DM
111 reboot => {
112 optional => 1,
113 type => 'boolean',
114 description => "Allow reboot. If set to '0' the VM exit on reboot.",
115 default => 1,
116 },
117 lock => {
118 optional => 1,
119 type => 'string',
120 description => "Lock/unlock the VM.",
22c377f0 121 enum => [qw(migrate backup snapshot rollback)],
1e3baf05
DM
122 },
123 cpulimit => {
124 optional => 1,
c6f773b8
DM
125 type => 'number',
126 description => "Limit of CPU usage. Note if the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit.",
1e3baf05 127 minimum => 0,
c6f773b8 128 maximum => 128,
1e3baf05
DM
129 default => 0,
130 },
131 cpuunits => {
132 optional => 1,
133 type => 'integer',
134 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.",
135 minimum => 0,
136 maximum => 500000,
137 default => 1000,
138 },
139 memory => {
140 optional => 1,
141 type => 'integer',
7878afeb 142 description => "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
1e3baf05
DM
143 minimum => 16,
144 default => 512,
145 },
13a48620
DA
146 balloon => {
147 optional => 1,
148 type => 'integer',
8b1accf7
DM
149 description => "Amount of target RAM for the VM in MB. Using zero disables the ballon driver.",
150 minimum => 0,
151 },
152 shares => {
153 optional => 1,
154 type => 'integer',
155 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",
156 minimum => 0,
157 maximum => 50000,
158 default => 1000,
13a48620 159 },
1e3baf05
DM
160 keyboard => {
161 optional => 1,
162 type => 'string',
163 description => "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
e95fe75f 164 enum => PVE::Tools::kvmkeymaplist(),
1e3baf05
DM
165 default => 'en-us',
166 },
167 name => {
168 optional => 1,
7fabe17d 169 type => 'string', format => 'dns-name',
1e3baf05
DM
170 description => "Set a name for the VM. Only used on the configuration web interface.",
171 },
cdd20088
AD
172 scsihw => {
173 optional => 1,
174 type => 'string',
175 description => "scsi controller model",
6731a4cf 176 enum => [qw(lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi)],
cdd20088
AD
177 default => 'lsi',
178 },
1e3baf05
DM
179 description => {
180 optional => 1,
181 type => 'string',
0581fe4f 182 description => "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
1e3baf05
DM
183 },
184 ostype => {
185 optional => 1,
186 type => 'string',
6b9d84cf 187 enum => [qw(other wxp w2k w2k3 w2k8 wvista win7 win8 l24 l26 solaris)],
1e3baf05
DM
188 description => <<EODESC,
189Used to enable special optimization/features for specific
190operating systems:
191
192other => unspecified OS
193wxp => Microsoft Windows XP
194w2k => Microsoft Windows 2000
195w2k3 => Microsoft Windows 2003
196w2k8 => Microsoft Windows 2008
197wvista => Microsoft Windows Vista
198win7 => Microsoft Windows 7
a70ebde3 199win8 => Microsoft Windows 8/2012
1e3baf05
DM
200l24 => Linux 2.4 Kernel
201l26 => Linux 2.6/3.X Kernel
6b9d84cf 202solaris => solaris/opensolaris/openindiania kernel
1e3baf05 203
6b9d84cf 204other|l24|l26|solaris ... no special behaviour
a70ebde3 205wxp|w2k|w2k3|w2k8|wvista|win7|win8 ... use --localtime switch
1e3baf05
DM
206EODESC
207 },
208 boot => {
209 optional => 1,
210 type => 'string',
211 description => "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
212 pattern => '[acdn]{1,4}',
32baffb4 213 default => 'cdn',
1e3baf05
DM
214 },
215 bootdisk => {
216 optional => 1,
217 type => 'string', format => 'pve-qm-bootdisk',
218 description => "Enable booting from specified disk.",
03e480fc 219 pattern => '(ide|sata|scsi|virtio)\d+',
1e3baf05
DM
220 },
221 smp => {
222 optional => 1,
223 type => 'integer',
224 description => "The number of CPUs. Please use option -sockets instead.",
225 minimum => 1,
226 default => 1,
227 },
228 sockets => {
229 optional => 1,
230 type => 'integer',
231 description => "The number of CPU sockets.",
232 minimum => 1,
233 default => 1,
234 },
235 cores => {
236 optional => 1,
237 type => 'integer',
238 description => "The number of cores per socket.",
239 minimum => 1,
240 default => 1,
241 },
8a010eae
AD
242 numa => {
243 optional => 1,
244 type => 'boolean',
245 description => "Enable/disable Numa.",
246 default => 0,
247 },
de9d1e55 248 vcpus => {
3bd18e48
AD
249 optional => 1,
250 type => 'integer',
de9d1e55 251 description => "Number of hotplugged vcpus.",
3bd18e48 252 minimum => 1,
de9d1e55 253 default => 0,
3bd18e48 254 },
1e3baf05
DM
255 acpi => {
256 optional => 1,
257 type => 'boolean',
258 description => "Enable/disable ACPI.",
259 default => 1,
260 },
bc84dcca 261 agent => {
ab6a046f
AD
262 optional => 1,
263 type => 'boolean',
264 description => "Enable/disable Qemu GuestAgent.",
be79c214 265 default => 0,
ab6a046f 266 },
1e3baf05
DM
267 kvm => {
268 optional => 1,
269 type => 'boolean',
270 description => "Enable/disable KVM hardware virtualization.",
271 default => 1,
272 },
273 tdf => {
274 optional => 1,
275 type => 'boolean',
8c559505
DM
276 description => "Enable/disable time drift fix.",
277 default => 0,
1e3baf05 278 },
19672434 279 localtime => {
1e3baf05
DM
280 optional => 1,
281 type => 'boolean',
282 description => "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
283 },
284 freeze => {
285 optional => 1,
286 type => 'boolean',
287 description => "Freeze CPU at startup (use 'c' monitor command to start execution).",
288 },
289 vga => {
290 optional => 1,
291 type => 'string',
ef5e2be2 292 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 293 enum => [qw(std cirrus vmware qxl serial0 serial1 serial2 serial3 qxl2 qxl3 qxl4)],
1e3baf05 294 },
0ea9541d
DM
295 watchdog => {
296 optional => 1,
297 type => 'string', format => 'pve-qm-watchdog',
298 typetext => '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
299 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)",
300 },
1e3baf05
DM
301 startdate => {
302 optional => 1,
19672434 303 type => 'string',
1e3baf05
DM
304 typetext => "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
305 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'.",
306 pattern => '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
307 default => 'now',
308 },
43574f73 309 startup => get_standard_option('pve-startup-order'),
68eda3ab
AD
310 template => {
311 optional => 1,
312 type => 'boolean',
313 description => "Enable/disable Template.",
314 default => 0,
315 },
1e3baf05
DM
316 args => {
317 optional => 1,
318 type => 'string',
319 description => <<EODESCR,
320Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
321
322args: -no-reboot -no-hpet
323EODESCR
324 },
325 tablet => {
326 optional => 1,
327 type => 'boolean',
328 default => 1,
5acbfe9e 329 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
330 },
331 migrate_speed => {
332 optional => 1,
333 type => 'integer',
334 description => "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
335 minimum => 0,
336 default => 0,
337 },
338 migrate_downtime => {
339 optional => 1,
04432191 340 type => 'number',
1e3baf05
DM
341 description => "Set maximum tolerated downtime (in seconds) for migrations.",
342 minimum => 0,
04432191 343 default => 0.1,
1e3baf05
DM
344 },
345 cdrom => {
346 optional => 1,
347 type => 'string', format => 'pve-qm-drive',
348 typetext => 'volume',
349 description => "This is an alias for option -ide2",
350 },
351 cpu => {
352 optional => 1,
353 description => "Emulated CPU type.",
354 type => 'string',
8bb5e28d 355 enum => [ qw(486 athlon pentium pentium2 pentium3 coreduo core2duo kvm32 kvm64 qemu32 qemu64 phenom Conroe Penryn Nehalem Westmere SandyBridge IvyBridge Haswell Broadwell Opteron_G1 Opteron_G2 Opteron_G3 Opteron_G4 Opteron_G5 host) ],
eac6899d 356 default => 'kvm64',
1e3baf05 357 },
b7ba6b79
DM
358 parent => get_standard_option('pve-snapshot-name', {
359 optional => 1,
360 description => "Parent snapshot name. This is used internally, and should not be modified.",
361 }),
982c7f12
DM
362 snaptime => {
363 optional => 1,
364 description => "Timestamp for snapshots.",
365 type => 'integer',
366 minimum => 0,
367 },
18bfb361
DM
368 vmstate => {
369 optional => 1,
370 type => 'string', format => 'pve-volume-id',
371 description => "Reference to a volume which stores the VM state. This is used internally for snapshots.",
372 },
3bafc510
DM
373 machine => {
374 description => "Specific the Qemu machine type.",
375 type => 'string',
376 pattern => '(pc|pc(-i440fx)?-\d+\.\d+|q35|pc-q35-\d+\.\d+)',
377 maxLength => 40,
378 optional => 1,
379 },
2796e7d5
DM
380 smbios1 => {
381 description => "Specify SMBIOS type 1 fields.",
382 type => 'string', format => 'pve-qm-smbios1',
383 typetext => "[manufacturer=str][,product=str][,version=str][,serial=str] [,uuid=uuid][,sku=str][,family=str]",
384 maxLength => 256,
385 optional => 1,
386 },
1e3baf05
DM
387};
388
389# what about other qemu settings ?
390#cpu => 'string',
391#machine => 'string',
392#fda => 'file',
393#fdb => 'file',
394#mtdblock => 'file',
395#sd => 'file',
396#pflash => 'file',
397#snapshot => 'bool',
398#bootp => 'file',
399##tftp => 'dir',
400##smb => 'dir',
401#kernel => 'file',
402#append => 'string',
403#initrd => 'file',
404##soundhw => 'string',
405
406while (my ($k, $v) = each %$confdesc) {
407 PVE::JSONSchema::register_standard_option("pve-qm-$k", $v);
408}
409
410my $MAX_IDE_DISKS = 4;
f62db2a4 411my $MAX_SCSI_DISKS = 14;
a2650619 412my $MAX_VIRTIO_DISKS = 16;
cdb0931f 413my $MAX_SATA_DISKS = 6;
1e3baf05 414my $MAX_USB_DEVICES = 5;
5bdcf937 415my $MAX_NETS = 32;
1e3baf05 416my $MAX_UNUSED_DISKS = 8;
5cffb2d2 417my $MAX_HOSTPCI_DEVICES = 4;
bae179aa 418my $MAX_SERIAL_PORTS = 4;
1989a89c 419my $MAX_PARALLEL_PORTS = 3;
2ed5d572 420my $MAX_NUMA = 8;
4d3f29ed
AD
421my $MAX_MEM = 4194304;
422my $STATICMEM = 1024;
2ed5d572
AD
423
424my $numadesc = {
425 optional => 1,
426 type => 'string', format => 'pve-qm-numanode',
25088687 427 typetext => "cpus=<id[-id],memory=<mb>[[,hostnodes=<id[-id]>] [,policy=<preferred|bind|interleave>]]",
2ed5d572
AD
428 description => "numa topology",
429};
430PVE::JSONSchema::register_standard_option("pve-qm-numanode", $numadesc);
431
432for (my $i = 0; $i < $MAX_NUMA; $i++) {
433 $confdesc->{"numa$i"} = $numadesc;
434}
1e3baf05
DM
435
436my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
55034103
KT
437 'ne2k_isa', 'i82551', 'i82557b', 'i82559er', 'vmxnet3',
438 'e1000-82540em', 'e1000-82544gc', 'e1000-82545em'];
6b64503e 439my $nic_model_list_txt = join(' ', sort @$nic_model_list);
1e3baf05 440
1e3baf05
DM
441my $netdesc = {
442 optional => 1,
443 type => 'string', format => 'pve-qm-net',
25088687 444 typetext => "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,queues=<nbqueues>][,rate=<mbps>] [,tag=<vlanid>][,firewall=0|1],link_down=0|1]",
1e3baf05 445 description => <<EODESCR,
19672434 446Specify network devices.
1e3baf05
DM
447
448MODEL is one of: $nic_model_list_txt
449
19672434 450XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
1e3baf05
DM
451automatically generated if not specified.
452
453The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
454
455Option 'rate' is used to limit traffic bandwidth from and to this interface. It is specified as floating point number, unit is 'Megabytes per second'.
456
457If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
458
45910.0.2.2 Gateway
46010.0.2.3 DNS Server
46110.0.2.4 SMB Server
462
463The DHCP server assign addresses to the guest starting from 10.0.2.15.
464
465EODESCR
466};
467PVE::JSONSchema::register_standard_option("pve-qm-net", $netdesc);
468
469for (my $i = 0; $i < $MAX_NETS; $i++) {
470 $confdesc->{"net$i"} = $netdesc;
471}
472
473my $drivename_hash;
19672434 474
1e3baf05
DM
475my $idedesc = {
476 optional => 1,
477 type => 'string', format => 'pve-qm-drive',
8d87f8aa 478 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 479 description => "Use volume as IDE hard disk or CD-ROM (n is 0 to " .($MAX_IDE_DISKS -1) . ").",
1e3baf05
DM
480};
481PVE::JSONSchema::register_standard_option("pve-qm-ide", $idedesc);
482
483my $scsidesc = {
484 optional => 1,
485 type => 'string', format => 'pve-qm-drive',
6e11f143 486 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] [,iothread=on] [,queues=<nbqueues>]',
3c770faa 487 description => "Use volume as SCSI hard disk or CD-ROM (n is 0 to " . ($MAX_SCSI_DISKS - 1) . ").",
1e3baf05
DM
488};
489PVE::JSONSchema::register_standard_option("pve-qm-scsi", $scsidesc);
490
cdb0931f
DA
491my $satadesc = {
492 optional => 1,
493 type => 'string', format => 'pve-qm-drive',
8d87f8aa 494 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 495 description => "Use volume as SATA hard disk or CD-ROM (n is 0 to " . ($MAX_SATA_DISKS - 1). ").",
cdb0931f
DA
496};
497PVE::JSONSchema::register_standard_option("pve-qm-sata", $satadesc);
498
1e3baf05
DM
499my $virtiodesc = {
500 optional => 1,
501 type => 'string', format => 'pve-qm-drive',
51f492cd 502 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] [,iothread=on]',
3c770faa 503 description => "Use volume as VIRTIO hard disk (n is 0 to " . ($MAX_VIRTIO_DISKS - 1) . ").",
1e3baf05
DM
504};
505PVE::JSONSchema::register_standard_option("pve-qm-virtio", $virtiodesc);
506
507my $usbdesc = {
508 optional => 1,
509 type => 'string', format => 'pve-qm-usb-device',
80401dd8 510 typetext => 'host=HOSTUSBDEVICE|spice',
1e3baf05 511 description => <<EODESCR,
2fe1a152 512Configure an USB device (n is 0 to 4). This can be used to
1e3baf05
DM
513pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
514
19672434 515'bus-port(.port)*' (decimal numbers) or
1e3baf05
DM
516'vendor_id:product_id' (hexadeciaml numbers)
517
19672434 518You can use the 'lsusb -t' command to list existing usb devices.
1e3baf05
DM
519
520Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
521
80401dd8
DM
522The value 'spice' can be used to add a usb redirection devices for spice.
523
1e3baf05
DM
524EODESCR
525};
526PVE::JSONSchema::register_standard_option("pve-qm-usb", $usbdesc);
527
040b06b7
DA
528my $hostpcidesc = {
529 optional => 1,
530 type => 'string', format => 'pve-qm-hostpci',
2e3b7e2a 531 typetext => "[host=]HOSTPCIDEVICE [,driver=kvm|vfio] [,rombar=on|off] [,pcie=0|1] [,x-vga=on|off]",
040b06b7
DA
532 description => <<EODESCR,
533Map host pci devices. HOSTPCIDEVICE syntax is:
534
535'bus:dev.func' (hexadecimal numbers)
536
537You can us the 'lspci' command to list existing pci devices.
538
0cea6a01
DM
539The 'rombar' option determines whether or not the device's ROM will be visible in the guest's memory map (default is 'on').
540
040b06b7
DA
541Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
542
543Experimental: user reported problems with this option.
544EODESCR
545};
546PVE::JSONSchema::register_standard_option("pve-qm-hostpci", $hostpcidesc);
547
bae179aa
DA
548my $serialdesc = {
549 optional => 1,
ca0cef26 550 type => 'string',
1b0b51ed 551 pattern => '(/dev/.+|socket)',
bae179aa 552 description => <<EODESCR,
1b0b51ed 553Create a serial device inside the VM (n is 0 to 3), and pass through a host serial device (i.e. /dev/ttyS0), or create a unix socket on the host side (use 'qm terminal' to open a terminal connection).
bae179aa
DA
554
555Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
556
557Experimental: user reported problems with this option.
558EODESCR
559};
bae179aa 560
1989a89c
DA
561my $paralleldesc= {
562 optional => 1,
ca0cef26 563 type => 'string',
9ecc8431 564 pattern => '/dev/parport\d+|/dev/usb/lp\d+',
1989a89c 565 description => <<EODESCR,
19672434 566Map host parallel devices (n is 0 to 2).
1989a89c
DA
567
568Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
569
570Experimental: user reported problems with this option.
571EODESCR
572};
1989a89c
DA
573
574for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
575 $confdesc->{"parallel$i"} = $paralleldesc;
576}
577
bae179aa
DA
578for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
579 $confdesc->{"serial$i"} = $serialdesc;
580}
581
040b06b7
DA
582for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
583 $confdesc->{"hostpci$i"} = $hostpcidesc;
584}
1e3baf05
DM
585
586for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
587 $drivename_hash->{"ide$i"} = 1;
588 $confdesc->{"ide$i"} = $idedesc;
589}
590
cdb0931f
DA
591for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
592 $drivename_hash->{"sata$i"} = 1;
593 $confdesc->{"sata$i"} = $satadesc;
594}
595
1e3baf05
DM
596for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
597 $drivename_hash->{"scsi$i"} = 1;
598 $confdesc->{"scsi$i"} = $scsidesc ;
599}
600
601for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
602 $drivename_hash->{"virtio$i"} = 1;
603 $confdesc->{"virtio$i"} = $virtiodesc;
604}
605
606for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
607 $confdesc->{"usb$i"} = $usbdesc;
608}
609
610my $unuseddesc = {
611 optional => 1,
612 type => 'string', format => 'pve-volume-id',
613 description => "Reference to unused volumes.",
614};
615
616for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
617 $confdesc->{"unused$i"} = $unuseddesc;
618}
619
620my $kvm_api_version = 0;
621
622sub kvm_version {
623
624 return $kvm_api_version if $kvm_api_version;
625
6b64503e 626 my $fh = IO::File->new("</dev/kvm") ||
1e3baf05
DM
627 return 0;
628
6b64503e 629 if (my $v = $fh->ioctl(KVM_GET_API_VERSION(), 0)) {
1e3baf05
DM
630 $kvm_api_version = $v;
631 }
632
633 $fh->close();
634
635 return $kvm_api_version;
636}
637
638my $kvm_user_version;
639
640sub kvm_user_version {
641
642 return $kvm_user_version if $kvm_user_version;
643
644 $kvm_user_version = 'unknown';
645
646 my $tmp = `kvm -help 2>/dev/null`;
19672434 647
fa7ae705 648 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?)[,\s]/) {
1e3baf05
DM
649 $kvm_user_version = $2;
650 }
651
652 return $kvm_user_version;
653
654}
655
656my $kernel_has_vhost_net = -c '/dev/vhost-net';
657
658sub disknames {
659 # order is important - used to autoselect boot disk
19672434 660 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
1e3baf05 661 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
cdb0931f
DA
662 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
663 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
1e3baf05
DM
664}
665
666sub valid_drivename {
667 my $dev = shift;
668
6b64503e 669 return defined($drivename_hash->{$dev});
1e3baf05
DM
670}
671
672sub option_exists {
673 my $key = shift;
674 return defined($confdesc->{$key});
19672434 675}
1e3baf05
DM
676
677sub nic_models {
678 return $nic_model_list;
679}
680
681sub os_list_description {
682
683 return {
684 other => 'Other',
685 wxp => 'Windows XP',
686 w2k => 'Windows 2000',
687 w2k3 =>, 'Windows 2003',
688 w2k8 => 'Windows 2008',
689 wvista => 'Windows Vista',
690 win7 => 'Windows 7',
a70ebde3 691 win8 => 'Windows 8/2012',
1e3baf05
DM
692 l24 => 'Linux 2.4',
693 l26 => 'Linux 2.6',
19672434 694 };
1e3baf05
DM
695}
696
1e3baf05
DM
697my $cdrom_path;
698
699sub get_cdrom_path {
700
701 return $cdrom_path if $cdrom_path;
702
703 return $cdrom_path = "/dev/cdrom" if -l "/dev/cdrom";
704 return $cdrom_path = "/dev/cdrom1" if -l "/dev/cdrom1";
705 return $cdrom_path = "/dev/cdrom2" if -l "/dev/cdrom2";
706}
707
708sub get_iso_path {
709 my ($storecfg, $vmid, $cdrom) = @_;
710
711 if ($cdrom eq 'cdrom') {
712 return get_cdrom_path();
713 } elsif ($cdrom eq 'none') {
714 return '';
715 } elsif ($cdrom =~ m|^/|) {
716 return $cdrom;
717 } else {
6b64503e 718 return PVE::Storage::path($storecfg, $cdrom);
1e3baf05
DM
719 }
720}
721
722# try to convert old style file names to volume IDs
723sub filename_to_volume_id {
724 my ($vmid, $file, $media) = @_;
725
726 if (!($file eq 'none' || $file eq 'cdrom' ||
727 $file =~ m|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
19672434 728
1e3baf05 729 return undef if $file =~ m|/|;
19672434 730
1e3baf05
DM
731 if ($media && $media eq 'cdrom') {
732 $file = "local:iso/$file";
733 } else {
734 $file = "local:$vmid/$file";
735 }
736 }
737
738 return $file;
739}
740
741sub verify_media_type {
742 my ($opt, $vtype, $media) = @_;
743
744 return if !$media;
745
746 my $etype;
747 if ($media eq 'disk') {
a125592c 748 $etype = 'images';
1e3baf05
DM
749 } elsif ($media eq 'cdrom') {
750 $etype = 'iso';
751 } else {
752 die "internal error";
753 }
754
755 return if ($vtype eq $etype);
19672434 756
1e3baf05
DM
757 raise_param_exc({ $opt => "unexpected media type ($vtype != $etype)" });
758}
759
760sub cleanup_drive_path {
761 my ($opt, $storecfg, $drive) = @_;
762
763 # try to convert filesystem paths to volume IDs
764
765 if (($drive->{file} !~ m/^(cdrom|none)$/) &&
766 ($drive->{file} !~ m|^/dev/.+|) &&
767 ($drive->{file} !~ m/^([^:]+):(.+)$/) &&
19672434 768 ($drive->{file} !~ m/^\d+$/)) {
1e3baf05
DM
769 my ($vtype, $volid) = PVE::Storage::path_to_volume_id($storecfg, $drive->{file});
770 raise_param_exc({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
771 $drive->{media} = 'cdrom' if !$drive->{media} && $vtype eq 'iso';
772 verify_media_type($opt, $vtype, $drive->{media});
773 $drive->{file} = $volid;
774 }
775
776 $drive->{media} = 'cdrom' if !$drive->{media} && $drive->{file} =~ m/^(cdrom|none)$/;
777}
778
779sub create_conf_nolock {
780 my ($vmid, $settings) = @_;
781
6b64503e 782 my $filename = config_file($vmid);
1e3baf05
DM
783
784 die "configuration file '$filename' already exists\n" if -f $filename;
19672434 785
1e3baf05
DM
786 my $defaults = load_defaults();
787
788 $settings->{name} = "vm$vmid" if !$settings->{name};
789 $settings->{memory} = $defaults->{memory} if !$settings->{memory};
790
791 my $data = '';
792 foreach my $opt (keys %$settings) {
793 next if !$confdesc->{$opt};
794
795 my $value = $settings->{$opt};
796 next if !$value;
797
798 $data .= "$opt: $value\n";
799 }
800
801 PVE::Tools::file_set_contents($filename, $data);
802}
803
b3c2bdd1
DM
804sub parse_hotplug_features {
805 my ($data) = @_;
806
807 my $res = {};
808
809 return $res if $data eq '0';
a1b7d579 810
b3c2bdd1
DM
811 $data = $confdesc->{hotplug}->{default} if $data eq '1';
812
45827685 813 foreach my $feature (PVE::Tools::split_list($data)) {
b3c2bdd1
DM
814 if ($feature =~ m/^(network|disk|cpu|memory|usb)$/) {
815 $res->{$1} = 1;
816 } else {
817 warn "ignoring unknown hotplug feature '$feature'\n";
818 }
819 }
820 return $res;
821}
822
823PVE::JSONSchema::register_format('pve-hotplug-features', \&pve_verify_hotplug_features);
824sub pve_verify_hotplug_features {
825 my ($value, $noerr) = @_;
826
827 return $value if parse_hotplug_features($value);
828
829 return undef if $noerr;
830
831 die "unable to parse hotplug option\n";
832}
833
f36ed4f4
DM
834my $parse_size = sub {
835 my ($value) = @_;
836
9bf371a6 837 return undef if $value !~ m/^(\d+(\.\d+)?)([KMG])?$/;
f36ed4f4
DM
838 my ($size, $unit) = ($1, $3);
839 if ($unit) {
840 if ($unit eq 'K') {
841 $size = $size * 1024;
842 } elsif ($unit eq 'M') {
843 $size = $size * 1024 * 1024;
844 } elsif ($unit eq 'G') {
845 $size = $size * 1024 * 1024 * 1024;
846 }
847 }
848 return int($size);
849};
850
851my $format_size = sub {
852 my ($size) = @_;
853
854 $size = int($size);
855
856 my $kb = int($size/1024);
857 return $size if $kb*1024 != $size;
858
859 my $mb = int($kb/1024);
860 return "${kb}K" if $mb*1024 != $kb;
861
862 my $gb = int($mb/1024);
863 return "${mb}M" if $gb*1024 != $mb;
864
865 return "${gb}G";
866};
867
1e3baf05
DM
868# ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
869# [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
036e0e2b 870# [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
51f492cd 871# [,aio=native|threads][,discard=ignore|on][,iothread=on]
1e3baf05
DM
872
873sub parse_drive {
874 my ($key, $data) = @_;
875
876 my $res = {};
19672434 877
1e3baf05
DM
878 # $key may be undefined - used to verify JSON parameters
879 if (!defined($key)) {
880 $res->{interface} = 'unknown'; # should not harm when used to verify parameters
881 $res->{index} = 0;
882 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
883 $res->{interface} = $1;
884 $res->{index} = $2;
885 } else {
886 return undef;
887 }
888
889 foreach my $p (split (/,/, $data)) {
890 next if $p =~ m/^\s*$/;
891
6e11f143 892 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|iothread|queues)=(.+)$/) {
1e3baf05
DM
893 my ($k, $v) = ($1, $2);
894
895 $k = 'file' if $k eq 'volume';
896
897 return undef if defined $res->{$k};
19672434 898
9bf371a6
DM
899 if ($k eq 'bps' || $k eq 'bps_rd' || $k eq 'bps_wr') {
900 return undef if !$v || $v !~ m/^\d+/;
901 $k = "m$k";
902 $v = sprintf("%.3f", $v / (1024*1024));
903 }
1e3baf05
DM
904 $res->{$k} = $v;
905 } else {
906 if (!$res->{file} && $p !~ m/=/) {
907 $res->{file} = $p;
908 } else {
909 return undef;
910 }
911 }
912 }
913
914 return undef if !$res->{file};
915
19672434 916 return undef if $res->{cache} &&
e482cec3 917 $res->{cache} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
1e3baf05
DM
918 return undef if $res->{snapshot} && $res->{snapshot} !~ m/^(on|off)$/;
919 return undef if $res->{cyls} && $res->{cyls} !~ m/^\d+$/;
920 return undef if $res->{heads} && $res->{heads} !~ m/^\d+$/;
921 return undef if $res->{secs} && $res->{secs} !~ m/^\d+$/;
922 return undef if $res->{media} && $res->{media} !~ m/^(disk|cdrom)$/;
923 return undef if $res->{trans} && $res->{trans} !~ m/^(none|lba|auto)$/;
d81f0f09 924 return undef if $res->{format} && $res->{format} !~ m/^(raw|cow|qcow|qed|qcow2|vmdk|cloop)$/;
1e3baf05
DM
925 return undef if $res->{rerror} && $res->{rerror} !~ m/^(ignore|report|stop)$/;
926 return undef if $res->{werror} && $res->{werror} !~ m/^(enospc|ignore|report|stop)$/;
927 return undef if $res->{backup} && $res->{backup} !~ m/^(yes|no)$/;
928 return undef if $res->{aio} && $res->{aio} !~ m/^(native|threads)$/;
8d87f8aa 929 return undef if $res->{discard} && $res->{discard} !~ m/^(ignore|on)$/;
51f492cd 930 return undef if $res->{iothread} && $res->{iothread} !~ m/^(on)$/;
6e11f143 931 return undef if $res->{queues} && ($res->{queues} !~ m/^\d+$/ || $res->{queues} < 2);
be190583 932
9bf371a6
DM
933 return undef if $res->{mbps_rd} && $res->{mbps};
934 return undef if $res->{mbps_wr} && $res->{mbps};
935
936 return undef if $res->{mbps} && $res->{mbps} !~ m/^\d+(\.\d+)?$/;
74edd76b 937 return undef if $res->{mbps_max} && $res->{mbps_max} !~ m/^\d+(\.\d+)?$/;
9bf371a6 938 return undef if $res->{mbps_rd} && $res->{mbps_rd} !~ m/^\d+(\.\d+)?$/;
74edd76b 939 return undef if $res->{mbps_rd_max} && $res->{mbps_rd_max} !~ m/^\d+(\.\d+)?$/;
9bf371a6 940 return undef if $res->{mbps_wr} && $res->{mbps_wr} !~ m/^\d+(\.\d+)?$/;
74edd76b 941 return undef if $res->{mbps_wr_max} && $res->{mbps_wr_max} !~ m/^\d+(\.\d+)?$/;
9bf371a6 942
affd2f88
AD
943 return undef if $res->{iops_rd} && $res->{iops};
944 return undef if $res->{iops_wr} && $res->{iops};
74edd76b
AD
945
946
affd2f88 947 return undef if $res->{iops} && $res->{iops} !~ m/^\d+$/;
74edd76b 948 return undef if $res->{iops_max} && $res->{iops_max} !~ m/^\d+$/;
affd2f88 949 return undef if $res->{iops_rd} && $res->{iops_rd} !~ m/^\d+$/;
74edd76b 950 return undef if $res->{iops_rd_max} && $res->{iops_rd_max} !~ m/^\d+$/;
affd2f88 951 return undef if $res->{iops_wr} && $res->{iops_wr} !~ m/^\d+$/;
74edd76b 952 return undef if $res->{iops_wr_max} && $res->{iops_wr_max} !~ m/^\d+$/;
affd2f88
AD
953
954
24afaca0 955 if ($res->{size}) {
be190583 956 return undef if !defined($res->{size} = &$parse_size($res->{size}));
24afaca0
DM
957 }
958
1e3baf05
DM
959 if ($res->{media} && ($res->{media} eq 'cdrom')) {
960 return undef if $res->{snapshot} || $res->{trans} || $res->{format};
19672434 961 return undef if $res->{heads} || $res->{secs} || $res->{cyls};
1e3baf05
DM
962 return undef if $res->{interface} eq 'virtio';
963 }
964
965 # rerror does not work with scsi drives
966 if ($res->{rerror}) {
967 return undef if $res->{interface} eq 'scsi';
968 }
969
970 return $res;
971}
972
74edd76b 973my @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
974
975sub print_drive {
976 my ($vmid, $drive) = @_;
977
978 my $opts = '';
6e11f143 979 foreach my $o (@qemu_drive_options, 'mbps', 'mbps_rd', 'mbps_wr', 'mbps_max', 'mbps_rd_max', 'mbps_wr_max', 'backup', 'iothread', 'queues') {
1e3baf05
DM
980 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
981 }
982
24afaca0
DM
983 if ($drive->{size}) {
984 $opts .= ",size=" . &$format_size($drive->{size});
985 }
986
1e3baf05
DM
987 return "$drive->{file}$opts";
988}
989
28ef82d3
DM
990sub scsi_inquiry {
991 my($fh, $noerr) = @_;
992
993 my $SG_IO = 0x2285;
994 my $SG_GET_VERSION_NUM = 0x2282;
995
996 my $versionbuf = "\x00" x 8;
997 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
998 if (!$ret) {
999 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
1000 return undef;
1001 }
97d62eb7 1002 my $version = unpack("I", $versionbuf);
28ef82d3
DM
1003 if ($version < 30000) {
1004 die "scsi generic interface too old\n" if !$noerr;
1005 return undef;
1006 }
97d62eb7 1007
28ef82d3
DM
1008 my $buf = "\x00" x 36;
1009 my $sensebuf = "\x00" x 8;
f334aa3e 1010 my $cmd = pack("C x3 C x1", 0x12, 36);
97d62eb7 1011
28ef82d3
DM
1012 # see /usr/include/scsi/sg.h
1013 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";
1014
97d62eb7
DM
1015 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
1016 length($sensebuf), 0, length($buf), $buf,
28ef82d3
DM
1017 $cmd, $sensebuf, 6000);
1018
1019 $ret = ioctl($fh, $SG_IO, $packet);
1020 if (!$ret) {
1021 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
1022 return undef;
1023 }
97d62eb7 1024
28ef82d3
DM
1025 my @res = unpack($sg_io_hdr_t, $packet);
1026 if ($res[17] || $res[18]) {
1027 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
1028 return undef;
1029 }
1030
1031 my $res = {};
09984754 1032 (my $byte0, my $byte1, $res->{vendor},
28ef82d3
DM
1033 $res->{product}, $res->{revision}) = unpack("C C x6 A8 A16 A4", $buf);
1034
09984754
DM
1035 $res->{removable} = $byte1 & 128 ? 1 : 0;
1036 $res->{type} = $byte0 & 31;
1037
28ef82d3
DM
1038 return $res;
1039}
1040
1041sub path_is_scsi {
1042 my ($path) = @_;
1043
1044 my $fh = IO::File->new("+<$path") || return undef;
1045 my $res = scsi_inquiry($fh, 1);
1046 close($fh);
1047
1048 return $res;
1049}
1050
db656e5f
DM
1051sub machine_type_is_q35 {
1052 my ($conf) = @_;
b467f79a 1053
db656e5f
DM
1054 return $conf->{machine} && ($conf->{machine} =~ m/q35/) ? 1 : 0;
1055}
1056
1057sub print_tabletdevice_full {
1058 my ($conf) = @_;
b467f79a 1059
db656e5f
DM
1060 my $q35 = machine_type_is_q35($conf);
1061
1062 # we use uhci for old VMs because tablet driver was buggy in older qemu
1063 my $usbbus = $q35 ? "ehci" : "uhci";
b467f79a 1064
db656e5f
DM
1065 return "usb-tablet,id=tablet,bus=$usbbus.0,port=1";
1066}
1067
ca916ecc 1068sub print_drivedevice_full {
5bdcf937 1069 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
ca916ecc
DA
1070
1071 my $device = '';
1072 my $maxdev = 0;
19672434 1073
ca916ecc 1074 if ($drive->{interface} eq 'virtio') {
5bdcf937 1075 my $pciaddr = print_pci_addr("$drive->{interface}$drive->{index}", $bridges);
2ed36a41 1076 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
51f492cd 1077 $device .= ",iothread=iothread-$drive->{interface}$drive->{index}" if $drive->{iothread};
2ed36a41 1078 } elsif ($drive->{interface} eq 'scsi') {
6731a4cf 1079
ee034f5c 1080 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $drive);
2ed36a41
DM
1081 my $unit = $drive->{index} % $maxdev;
1082 my $devicetype = 'hd';
231f2e13
DA
1083 my $path = '';
1084 if (drive_is_cdrom($drive)) {
1085 $devicetype = 'cd';
29b19529 1086 } else {
231f2e13
DA
1087 if ($drive->{file} =~ m|^/|) {
1088 $path = $drive->{file};
1089 } else {
1090 $path = PVE::Storage::path($storecfg, $drive->{file});
1091 }
d454d040
AD
1092
1093 if($path =~ m/^iscsi\:\/\//){
29b19529
DM
1094 $devicetype = 'generic';
1095 } else {
09984754
DM
1096 if (my $info = path_is_scsi($path)) {
1097 if ($info->{type} == 0) {
1098 $devicetype = 'block';
1099 } elsif ($info->{type} == 1) { # tape
1100 $devicetype = 'generic';
1101 }
1102 }
d454d040 1103 }
231f2e13 1104 }
ca916ecc 1105
5b952ff5 1106 if (!$conf->{scsihw} || ($conf->{scsihw} =~ m/^lsi/)){
6731a4cf 1107 $device = "scsi-$devicetype,bus=$controller_prefix$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
cdd20088 1108 } else {
6731a4cf 1109 $device = "scsi-$devicetype,bus=$controller_prefix$controller.0,channel=0,scsi-id=0,lun=$drive->{index},drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
cdd20088
AD
1110 }
1111
2ed36a41
DM
1112 } elsif ($drive->{interface} eq 'ide'){
1113 $maxdev = 2;
1114 my $controller = int($drive->{index} / $maxdev);
1115 my $unit = $drive->{index} % $maxdev;
1116 my $devicetype = ($drive->{media} && $drive->{media} eq 'cdrom') ? "cd" : "hd";
1117
7ebe888a 1118 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
cdb0931f
DA
1119 } elsif ($drive->{interface} eq 'sata'){
1120 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1121 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1122 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
2ed36a41
DM
1123 } elsif ($drive->{interface} eq 'usb') {
1124 die "implement me";
1125 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1126 } else {
1127 die "unsupported interface type";
ca916ecc
DA
1128 }
1129
3b408e82
DM
1130 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex};
1131
ca916ecc
DA
1132 return $device;
1133}
1134
15b21acc 1135sub get_initiator_name {
46f58b5f 1136 my $initiator;
15b21acc 1137
46f58b5f
DM
1138 my $fh = IO::File->new('/etc/iscsi/initiatorname.iscsi') || return undef;
1139 while (defined(my $line = <$fh>)) {
1140 next if $line !~ m/^\s*InitiatorName\s*=\s*([\.\-:\w]+)/;
15b21acc
MR
1141 $initiator = $1;
1142 last;
1143 }
46f58b5f
DM
1144 $fh->close();
1145
15b21acc
MR
1146 return $initiator;
1147}
1148
1e3baf05
DM
1149sub print_drive_full {
1150 my ($storecfg, $vmid, $drive) = @_;
1151
d81f0f09
DM
1152 my $path;
1153 my $volid = $drive->{file};
1154 my $format;
1155
1156 if (drive_is_cdrom($drive)) {
1157 $path = get_iso_path($storecfg, $vmid, $volid);
1158 } else {
1159 my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
1160 if ($storeid) {
1161 $path = PVE::Storage::path($storecfg, $volid);
1162 my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
1163 $format = qemu_img_format($scfg, $volname);
1164 } else {
1165 $path = $volid;
1166 }
1167 }
1168
1e3baf05
DM
1169 my $opts = '';
1170 foreach my $o (@qemu_drive_options) {
3b408e82 1171 next if $o eq 'bootindex';
1e3baf05 1172 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
19672434 1173 }
1e3baf05 1174
d81f0f09
DM
1175 $opts .= ",format=$format" if $format && !$drive->{format};
1176
9bf371a6
DM
1177 foreach my $o (qw(bps bps_rd bps_wr)) {
1178 my $v = $drive->{"m$o"};
1179 $opts .= ",$o=" . int($v*1024*1024) if $v;
1180 }
1181
b2ee900e
WB
1182 my $cache_direct = 0;
1183
1184 if (my $cache = $drive->{cache}) {
1185 $cache_direct = $cache =~ /^(?:off|none|directsync)$/;
1186 } elsif (!drive_is_cdrom($drive)) {
1187 $opts .= ",cache=none";
1188 $cache_direct = 1;
1189 }
1190
1191 # aio native works only with O_DIRECT
1192 if (!$drive->{aio}) {
1193 if($cache_direct) {
1194 $opts .= ",aio=native";
1195 } else {
1196 $opts .= ",aio=threads";
1197 }
1198 }
11490cf2 1199
f1e05305
AD
1200 my $detectzeroes = $drive->{discard} ? "unmap" : "on";
1201 $opts .= ",detect-zeroes=$detectzeroes" if !drive_is_cdrom($drive);
1202
1e3baf05
DM
1203 my $pathinfo = $path ? "file=$path," : '';
1204
3ebfcc86 1205 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1e3baf05
DM
1206}
1207
cc4d6182 1208sub print_netdevice_full {
5bdcf937 1209 my ($vmid, $conf, $net, $netid, $bridges) = @_;
cc4d6182
DA
1210
1211 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
1212
1213 my $device = $net->{model};
1214 if ($net->{model} eq 'virtio') {
1215 $device = 'virtio-net-pci';
1216 };
1217
5bdcf937 1218 my $pciaddr = print_pci_addr("$netid", $bridges);
5e2068d2 1219 my $tmpstr = "$device,mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
a9410357
AD
1220 if ($net->{queues} && $net->{queues} > 1 && $net->{model} eq 'virtio'){
1221 #Consider we have N queues, the number of vectors needed is 2*N + 2 (plus one config interrupt and control vq)
1222 my $vectors = $net->{queues} * 2 + 2;
1223 $tmpstr .= ",vectors=$vectors,mq=on";
1224 }
cc4d6182
DA
1225 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex} ;
1226 return $tmpstr;
1227}
1228
1229sub print_netdev_full {
1230 my ($vmid, $conf, $net, $netid) = @_;
1231
1232 my $i = '';
1233 if ($netid =~ m/^net(\d+)$/) {
1234 $i = int($1);
1235 }
1236
1237 die "got strange net id '$i'\n" if $i >= ${MAX_NETS};
1238
1239 my $ifname = "tap${vmid}i$i";
1240
1241 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1242 die "interface name '$ifname' is too long (max 15 character)\n"
1243 if length($ifname) >= 16;
1244
1245 my $vhostparam = '';
1246 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model} eq 'virtio';
1247
1248 my $vmname = $conf->{name} || "vm$vmid";
1249
a9410357
AD
1250 my $netdev = "";
1251
cc4d6182 1252 if ($net->{bridge}) {
a9410357 1253 $netdev = "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown$vhostparam";
cc4d6182 1254 } else {
a9410357 1255 $netdev = "type=user,id=$netid,hostname=$vmname";
cc4d6182 1256 }
a9410357
AD
1257
1258 $netdev .= ",queues=$net->{queues}" if ($net->{queues} && $net->{model} eq 'virtio');
1259
1260 return $netdev;
cc4d6182 1261}
1e3baf05
DM
1262
1263sub drive_is_cdrom {
1264 my ($drive) = @_;
1265
1266 return $drive && $drive->{media} && ($drive->{media} eq 'cdrom');
1267
1268}
1269
2ed5d572
AD
1270sub parse_numa {
1271 my ($data) = @_;
1272
1273 my $res = {};
1274
1275 foreach my $kvp (split(/,/, $data)) {
1276
1277 if ($kvp =~ m/^memory=(\S+)$/) {
1278 $res->{memory} = $1;
1279 } elsif ($kvp =~ m/^policy=(preferred|bind|interleave)$/) {
1280 $res->{policy} = $1;
1281 } elsif ($kvp =~ m/^cpus=(\d+)(-(\d+))?$/) {
1282 $res->{cpus}->{start} = $1;
1283 $res->{cpus}->{end} = $3;
1284 } elsif ($kvp =~ m/^hostnodes=(\d+)(-(\d+))?$/) {
1285 $res->{hostnodes}->{start} = $1;
1286 $res->{hostnodes}->{end} = $3;
1287 } else {
1288 return undef;
1289 }
1290 }
1291
1292 return $res;
1293}
1294
040b06b7
DA
1295sub parse_hostpci {
1296 my ($value) = @_;
1297
1298 return undef if !$value;
1299
0cea6a01
DM
1300
1301 my @list = split(/,/, $value);
1302 my $found;
1303
040b06b7 1304 my $res = {};
0cea6a01 1305 foreach my $kv (@list) {
040b06b7 1306
4543ecf0 1307 if ($kv =~ m/^(host=)?([a-f0-9]{2}:[a-f0-9]{2})(\.([a-f0-9]))?$/) {
0cea6a01 1308 $found = 1;
4543ecf0
AD
1309 if(defined($4)){
1310 push @{$res->{pciid}}, { id => $2 , function => $4};
1311
1312 }else{
1313 my $pcidevices = lspci($2);
1314 $res->{pciid} = $pcidevices->{$2};
1315 }
0cea6a01
DM
1316 } elsif ($kv =~ m/^driver=(kvm|vfio)$/) {
1317 $res->{driver} = $1;
1318 } elsif ($kv =~ m/^rombar=(on|off)$/) {
1319 $res->{rombar} = $1;
2e3b7e2a
AD
1320 } elsif ($kv =~ m/^x-vga=(on|off)$/) {
1321 $res->{'x-vga'} = $1;
1322 } elsif ($kv =~ m/^pcie=(\d+)$/) {
1323 $res->{pcie} = 1 if $1 == 1;
0cea6a01
DM
1324 } else {
1325 warn "unknown hostpci setting '$kv'\n";
1326 }
040b06b7
DA
1327 }
1328
0cea6a01
DM
1329 return undef if !$found;
1330
040b06b7
DA
1331 return $res;
1332}
1333
1e3baf05
DM
1334# netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1335sub parse_net {
1336 my ($data) = @_;
1337
1338 my $res = {};
1339
6b64503e 1340 foreach my $kvp (split(/,/, $data)) {
1e3baf05 1341
55034103 1342 if ($kvp =~ m/^(ne2k_pci|e1000|e1000-82540em|e1000-82544gc|e1000-82545em|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er|vmxnet3)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
6b64503e 1343 my $model = lc($1);
92f0fedc 1344 my $mac = defined($3) ? uc($3) : PVE::Tools::random_ether_addr();
1e3baf05
DM
1345 $res->{model} = $model;
1346 $res->{macaddr} = $mac;
1347 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1348 $res->{bridge} = $1;
a9410357
AD
1349 } elsif ($kvp =~ m/^queues=(\d+)$/) {
1350 $res->{queues} = $1;
1e3baf05
DM
1351 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1352 $res->{rate} = $1;
5070f384
DA
1353 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1354 $res->{tag} = $1;
25088687 1355 } elsif ($kvp =~ m/^firewall=([01])$/) {
2dd4aa4c 1356 $res->{firewall} = $1;
25088687
DM
1357 } elsif ($kvp =~ m/^link_down=([01])$/) {
1358 $res->{link_down} = $1;
1e3baf05
DM
1359 } else {
1360 return undef;
1361 }
19672434 1362
1e3baf05
DM
1363 }
1364
1365 return undef if !$res->{model};
1366
1367 return $res;
1368}
1369
1370sub print_net {
1371 my $net = shift;
1372
1373 my $res = "$net->{model}";
1374 $res .= "=$net->{macaddr}" if $net->{macaddr};
1375 $res .= ",bridge=$net->{bridge}" if $net->{bridge};
1376 $res .= ",rate=$net->{rate}" if $net->{rate};
18744ba3 1377 $res .= ",tag=$net->{tag}" if $net->{tag};
25088687
DM
1378 $res .= ",firewall=1" if $net->{firewall};
1379 $res .= ",link_down=1" if $net->{link_down};
8b6c5579 1380 $res .= ",queues=$net->{queues}" if $net->{queues};
1e3baf05
DM
1381
1382 return $res;
1383}
1384
1385sub add_random_macs {
1386 my ($settings) = @_;
1387
1388 foreach my $opt (keys %$settings) {
1389 next if $opt !~ m/^net(\d+)$/;
1390 my $net = parse_net($settings->{$opt});
1391 next if !$net;
1392 $settings->{$opt} = print_net($net);
1393 }
1394}
1395
1396sub add_unused_volume {
1858638f 1397 my ($config, $volid) = @_;
1e3baf05
DM
1398
1399 my $key;
1400 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1401 my $test = "unused$ind";
1402 if (my $vid = $config->{$test}) {
1403 return if $vid eq $volid; # do not add duplicates
1404 } else {
1405 $key = $test;
19672434 1406 }
1e3baf05
DM
1407 }
1408
1409 die "To many unused volume - please delete them first.\n" if !$key;
97d62eb7 1410
1858638f 1411 $config->{$key} = $volid;
1e3baf05 1412
1858638f 1413 return $key;
1e3baf05
DM
1414}
1415
055d554d
DM
1416sub vm_is_volid_owner {
1417 my ($storecfg, $vmid, $volid) = @_;
1418
1419 if ($volid !~ m|^/|) {
1420 my ($path, $owner);
1421 eval { ($path, $owner) = PVE::Storage::path($storecfg, $volid); };
1422 if ($owner && ($owner == $vmid)) {
1423 return 1;
1424 }
1425 }
1426
1427 return undef;
1428}
1429
1430sub vmconfig_delete_pending_option {
1431 my ($conf, $key) = @_;
1432
1433 delete $conf->{pending}->{$key};
1434 my $pending_delete_hash = { $key => 1 };
1435 foreach my $opt (PVE::Tools::split_list($conf->{pending}->{delete})) {
1436 $pending_delete_hash->{$opt} = 1;
1437 }
1438 $conf->{pending}->{delete} = join(',', keys %$pending_delete_hash);
1439}
1440
1441sub vmconfig_undelete_pending_option {
1442 my ($conf, $key) = @_;
1443
1444 my $pending_delete_hash = {};
1445 foreach my $opt (PVE::Tools::split_list($conf->{pending}->{delete})) {
1446 $pending_delete_hash->{$opt} = 1;
1447 }
1448 delete $pending_delete_hash->{$key};
1449
1450 my @keylist = keys %$pending_delete_hash;
1451 if (scalar(@keylist)) {
1452 $conf->{pending}->{delete} = join(',', @keylist);
1453 } else {
1454 delete $conf->{pending}->{delete};
1455 }
1456}
1457
1458sub vmconfig_register_unused_drive {
1459 my ($storecfg, $vmid, $conf, $drive) = @_;
1460
1461 if (!drive_is_cdrom($drive)) {
1462 my $volid = $drive->{file};
1463 if (vm_is_volid_owner($storecfg, $vmid, $volid)) {
1464 add_unused_volume($conf, $volid, $vmid);
1465 }
1466 }
1467}
1468
c750e90a
DM
1469sub vmconfig_cleanup_pending {
1470 my ($conf) = @_;
1471
1472 # remove pending changes when nothing changed
1473 my $changes;
1474 foreach my $opt (keys %{$conf->{pending}}) {
1475 if (defined($conf->{$opt}) && ($conf->{pending}->{$opt} eq $conf->{$opt})) {
1476 $changes = 1;
1477 delete $conf->{pending}->{$opt};
1478 }
1479 }
1480
1481 # remove delete if option is not set
1482 my $pending_delete_hash = {};
1483 foreach my $opt (PVE::Tools::split_list($conf->{pending}->{delete})) {
1484 if (defined($conf->{$opt})) {
1485 $pending_delete_hash->{$opt} = 1;
1486 } else {
1487 $changes = 1;
1488 }
1489 }
1490
1491 my @keylist = keys %$pending_delete_hash;
1492 if (scalar(@keylist)) {
1493 $conf->{pending}->{delete} = join(',', @keylist);
1494 } else {
1495 delete $conf->{pending}->{delete};
1496 }
1497
1498 return $changes;
1499}
1500
2796e7d5
DM
1501my $valid_smbios1_options = {
1502 manufacturer => '\S+',
1503 product => '\S+',
1504 version => '\S+',
1505 serial => '\S+',
1506 uuid => '[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}',
1507 sku => '\S+',
1508 family => '\S+',
1509};
1510
1511# smbios: [manufacturer=str][,product=str][,version=str][,serial=str][,uuid=uuid][,sku=str][,family=str]
1512sub parse_smbios1 {
1513 my ($data) = @_;
1514
1515 my $res = {};
1516
1517 foreach my $kvp (split(/,/, $data)) {
1518 return undef if $kvp !~ m/^(\S+)=(.+)$/;
1519 my ($k, $v) = split(/=/, $kvp);
1520 return undef if !defined($k) || !defined($v);
1521 return undef if !$valid_smbios1_options->{$k};
1522 return undef if $v !~ m/^$valid_smbios1_options->{$k}$/;
1523 $res->{$k} = $v;
1524 }
1525
1526 return $res;
1527}
1528
cd11416f
DM
1529sub print_smbios1 {
1530 my ($smbios1) = @_;
1531
1532 my $data = '';
1533 foreach my $k (keys %$smbios1) {
1534 next if !defined($smbios1->{$k});
1535 next if !$valid_smbios1_options->{$k};
1536 $data .= ',' if $data;
1537 $data .= "$k=$smbios1->{$k}";
1538 }
1539 return $data;
1540}
1541
2796e7d5
DM
1542PVE::JSONSchema::register_format('pve-qm-smbios1', \&verify_smbios1);
1543sub verify_smbios1 {
1544 my ($value, $noerr) = @_;
1545
1546 return $value if parse_smbios1($value);
1547
1548 return undef if $noerr;
1549
1550 die "unable to parse smbios (type 1) options\n";
1551}
1552
1e3baf05
DM
1553PVE::JSONSchema::register_format('pve-qm-bootdisk', \&verify_bootdisk);
1554sub verify_bootdisk {
1555 my ($value, $noerr) = @_;
1556
19672434 1557 return $value if valid_drivename($value);
1e3baf05
DM
1558
1559 return undef if $noerr;
1560
1561 die "invalid boot disk '$value'\n";
1562}
1563
2ed5d572
AD
1564PVE::JSONSchema::register_format('pve-qm-numanode', \&verify_numa);
1565sub verify_numa {
1566 my ($value, $noerr) = @_;
1567
1568 return $value if parse_numa($value);
1569
1570 return undef if $noerr;
1571
1572 die "unable to parse numa options\n";
1573}
1574
1e3baf05
DM
1575PVE::JSONSchema::register_format('pve-qm-net', \&verify_net);
1576sub verify_net {
1577 my ($value, $noerr) = @_;
1578
1579 return $value if parse_net($value);
1580
1581 return undef if $noerr;
19672434 1582
1e3baf05
DM
1583 die "unable to parse network options\n";
1584}
1585
1586PVE::JSONSchema::register_format('pve-qm-drive', \&verify_drive);
1587sub verify_drive {
1588 my ($value, $noerr) = @_;
1589
6b64503e 1590 return $value if parse_drive(undef, $value);
1e3baf05
DM
1591
1592 return undef if $noerr;
19672434 1593
1e3baf05
DM
1594 die "unable to parse drive options\n";
1595}
1596
1597PVE::JSONSchema::register_format('pve-qm-hostpci', \&verify_hostpci);
1598sub verify_hostpci {
1599 my ($value, $noerr) = @_;
1600
040b06b7
DA
1601 return $value if parse_hostpci($value);
1602
1603 return undef if $noerr;
1604
1605 die "unable to parse pci id\n";
1e3baf05
DM
1606}
1607
0ea9541d
DM
1608PVE::JSONSchema::register_format('pve-qm-watchdog', \&verify_watchdog);
1609sub verify_watchdog {
1610 my ($value, $noerr) = @_;
1611
1612 return $value if parse_watchdog($value);
1613
1614 return undef if $noerr;
19672434 1615
0ea9541d
DM
1616 die "unable to parse watchdog options\n";
1617}
1618
1619sub parse_watchdog {
1620 my ($value) = @_;
1621
1622 return undef if !$value;
1623
1624 my $res = {};
1625
6b64503e 1626 foreach my $p (split(/,/, $value)) {
0ea9541d
DM
1627 next if $p =~ m/^\s*$/;
1628
1629 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1630 $res->{model} = $2;
1631 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1632 $res->{action} = $2;
1633 } else {
1634 return undef;
1635 }
1636 }
1637
1638 return $res;
1639}
1640
1e3baf05
DM
1641sub parse_usb_device {
1642 my ($value) = @_;
1643
1644 return undef if !$value;
1645
6b64503e 1646 my @dl = split(/,/, $value);
1e3baf05
DM
1647 my $found;
1648
1649 my $res = {};
1650 foreach my $v (@dl) {
036e0e2b 1651 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1e3baf05 1652 $found = 1;
036e0e2b
DM
1653 $res->{vendorid} = $2;
1654 $res->{productid} = $4;
1e3baf05
DM
1655 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1656 $found = 1;
1657 $res->{hostbus} = $1;
1658 $res->{hostport} = $2;
80401dd8
DM
1659 } elsif ($v =~ m/^spice$/) {
1660 $found = 1;
1661 $res->{spice} = 1;
1e3baf05
DM
1662 } else {
1663 return undef;
1664 }
1665 }
1666 return undef if !$found;
1667
1668 return $res;
1669}
19672434 1670
1e3baf05
DM
1671PVE::JSONSchema::register_format('pve-qm-usb-device', \&verify_usb_device);
1672sub verify_usb_device {
1673 my ($value, $noerr) = @_;
1674
1675 return $value if parse_usb_device($value);
1676
1677 return undef if $noerr;
19672434 1678
1e3baf05
DM
1679 die "unable to parse usb device\n";
1680}
1681
1e3baf05
DM
1682# add JSON properties for create and set function
1683sub json_config_properties {
1684 my $prop = shift;
1685
1686 foreach my $opt (keys %$confdesc) {
18bfb361 1687 next if $opt eq 'parent' || $opt eq 'snaptime' || $opt eq 'vmstate';
1e3baf05
DM
1688 $prop->{$opt} = $confdesc->{$opt};
1689 }
1690
1691 return $prop;
1692}
1693
1694sub check_type {
1695 my ($key, $value) = @_;
1696
1697 die "unknown setting '$key'\n" if !$confdesc->{$key};
1698
1699 my $type = $confdesc->{$key}->{type};
1700
6b64503e 1701 if (!defined($value)) {
1e3baf05
DM
1702 die "got undefined value\n";
1703 }
1704
1705 if ($value =~ m/[\n\r]/) {
1706 die "property contains a line feed\n";
1707 }
1708
1709 if ($type eq 'boolean') {
19672434
DM
1710 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1711 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1712 die "type check ('boolean') failed - got '$value'\n";
1e3baf05
DM
1713 } elsif ($type eq 'integer') {
1714 return int($1) if $value =~ m/^(\d+)$/;
1715 die "type check ('integer') failed - got '$value'\n";
04432191
AD
1716 } elsif ($type eq 'number') {
1717 return $value if $value =~ m/^(\d+)(\.\d+)?$/;
1718 die "type check ('number') failed - got '$value'\n";
1e3baf05
DM
1719 } elsif ($type eq 'string') {
1720 if (my $fmt = $confdesc->{$key}->{format}) {
1721 if ($fmt eq 'pve-qm-drive') {
1722 # special case - we need to pass $key to parse_drive()
6b64503e 1723 my $drive = parse_drive($key, $value);
1e3baf05
DM
1724 return $value if $drive;
1725 die "unable to parse drive options\n";
1726 }
1727 PVE::JSONSchema::check_format($fmt, $value);
19672434
DM
1728 return $value;
1729 }
1e3baf05 1730 $value =~ s/^\"(.*)\"$/$1/;
19672434 1731 return $value;
1e3baf05
DM
1732 } else {
1733 die "internal error"
1734 }
1735}
1736
191435c6
DM
1737sub lock_config_full {
1738 my ($vmid, $timeout, $code, @param) = @_;
1e3baf05 1739
6b64503e 1740 my $filename = config_file_lock($vmid);
1e3baf05 1741
191435c6 1742 my $res = lock_file($filename, $timeout, $code, @param);
1e3baf05
DM
1743
1744 die $@ if $@;
5fdbe4f0
DM
1745
1746 return $res;
1e3baf05
DM
1747}
1748
4e4f83fe
DM
1749sub lock_config_mode {
1750 my ($vmid, $timeout, $shared, $code, @param) = @_;
6116f729
DM
1751
1752 my $filename = config_file_lock($vmid);
1753
4e4f83fe 1754 my $res = lock_file_full($filename, $timeout, $shared, $code, @param);
6116f729
DM
1755
1756 die $@ if $@;
1757
1758 return $res;
1759}
1760
191435c6
DM
1761sub lock_config {
1762 my ($vmid, $code, @param) = @_;
1763
1764 return lock_config_full($vmid, 10, $code, @param);
1765}
1766
1e3baf05 1767sub cfs_config_path {
a78ccf26 1768 my ($vmid, $node) = @_;
1e3baf05 1769
a78ccf26
DM
1770 $node = $nodename if !$node;
1771 return "nodes/$node/qemu-server/$vmid.conf";
1e3baf05
DM
1772}
1773
040b06b7
DA
1774sub check_iommu_support{
1775 #fixme : need to check IOMMU support
1776 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1777
1778 my $iommu=1;
1779 return $iommu;
1780
1781}
1782
1e3baf05 1783sub config_file {
a78ccf26 1784 my ($vmid, $node) = @_;
1e3baf05 1785
a78ccf26 1786 my $cfspath = cfs_config_path($vmid, $node);
1e3baf05
DM
1787 return "/etc/pve/$cfspath";
1788}
1789
1790sub config_file_lock {
1791 my ($vmid) = @_;
1792
1793 return "$lock_dir/lock-$vmid.conf";
1794}
1795
1796sub touch_config {
1797 my ($vmid) = @_;
1798
6b64503e 1799 my $conf = config_file($vmid);
1e3baf05
DM
1800 utime undef, undef, $conf;
1801}
1802
1e3baf05 1803sub destroy_vm {
a6af7b3e 1804 my ($storecfg, $vmid, $keep_empty_config) = @_;
1e3baf05 1805
6b64503e 1806 my $conffile = config_file($vmid);
1e3baf05 1807
6b64503e 1808 my $conf = load_config($vmid);
1e3baf05 1809
6b64503e 1810 check_lock($conf);
1e3baf05 1811
19672434 1812 # only remove disks owned by this VM
1e3baf05
DM
1813 foreach_drive($conf, sub {
1814 my ($ds, $drive) = @_;
1815
6b64503e 1816 return if drive_is_cdrom($drive);
1e3baf05
DM
1817
1818 my $volid = $drive->{file};
ed221350 1819
ff1a2432 1820 return if !$volid || $volid =~ m|^/|;
1e3baf05 1821
6b64503e 1822 my ($path, $owner) = PVE::Storage::path($storecfg, $volid);
ff1a2432 1823 return if !$path || !$owner || ($owner != $vmid);
1e3baf05 1824
6b64503e 1825 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05 1826 });
19672434 1827
a6af7b3e 1828 if ($keep_empty_config) {
9c502e26 1829 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
a6af7b3e
DM
1830 } else {
1831 unlink $conffile;
1832 }
1e3baf05
DM
1833
1834 # also remove unused disk
1835 eval {
6b64503e 1836 my $dl = PVE::Storage::vdisk_list($storecfg, undef, $vmid);
1e3baf05
DM
1837
1838 eval {
6b64503e 1839 PVE::Storage::foreach_volid($dl, sub {
1e3baf05 1840 my ($volid, $sid, $volname, $d) = @_;
6b64503e 1841 PVE::Storage::vdisk_free($storecfg, $volid);
1e3baf05
DM
1842 });
1843 };
1844 warn $@ if $@;
1845
1846 };
1847 warn $@ if $@;
1848}
1849
1e3baf05 1850sub load_config {
7e8dcf2c 1851 my ($vmid, $node) = @_;
1e3baf05 1852
7e8dcf2c 1853 my $cfspath = cfs_config_path($vmid, $node);
1e3baf05
DM
1854
1855 my $conf = PVE::Cluster::cfs_read_file($cfspath);
1856
1857 die "no such VM ('$vmid')\n" if !defined($conf);
1858
1859 return $conf;
19672434 1860}
1e3baf05
DM
1861
1862sub parse_vm_config {
1863 my ($filename, $raw) = @_;
1864
1865 return undef if !defined($raw);
1866
554ac7e7 1867 my $res = {
fc1ddcdc 1868 digest => Digest::SHA::sha1_hex($raw),
0d18dcfc 1869 snapshots => {},
0d732d16 1870 pending => {},
554ac7e7 1871 };
1e3baf05 1872
19672434 1873 $filename =~ m|/qemu-server/(\d+)\.conf$|
1e3baf05
DM
1874 || die "got strange filename '$filename'";
1875
1876 my $vmid = $1;
1877
0d18dcfc 1878 my $conf = $res;
b0ec896e 1879 my $descr;
e297c490 1880 my $section = '';
0581fe4f 1881
0d18dcfc
DM
1882 my @lines = split(/\n/, $raw);
1883 foreach my $line (@lines) {
1e3baf05 1884 next if $line =~ m/^\s*$/;
be190583 1885
eab09f4e 1886 if ($line =~ m/^\[PENDING\]\s*$/i) {
e297c490 1887 $section = 'pending';
b0ec896e
DM
1888 if (defined($descr)) {
1889 $descr =~ s/\s+$//;
1890 $conf->{description} = $descr;
1891 }
1892 $descr = undef;
e297c490 1893 $conf = $res->{$section} = {};
eab09f4e
AD
1894 next;
1895
0d732d16 1896 } elsif ($line =~ m/^\[([a-z][a-z0-9_\-]+)\]\s*$/i) {
e297c490 1897 $section = $1;
b0ec896e
DM
1898 if (defined($descr)) {
1899 $descr =~ s/\s+$//;
1900 $conf->{description} = $descr;
1901 }
1902 $descr = undef;
e297c490 1903 $conf = $res->{snapshots}->{$section} = {};
0d18dcfc
DM
1904 next;
1905 }
1e3baf05 1906
0581fe4f 1907 if ($line =~ m/^\#(.*)\s*$/) {
b0ec896e 1908 $descr = '' if !defined($descr);
0581fe4f
DM
1909 $descr .= PVE::Tools::decode_text($1) . "\n";
1910 next;
1911 }
1912
1e3baf05 1913 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
b0ec896e 1914 $descr = '' if !defined($descr);
0581fe4f 1915 $descr .= PVE::Tools::decode_text($2);
0d18dcfc
DM
1916 } elsif ($line =~ m/snapstate:\s*(prepare|delete)\s*$/) {
1917 $conf->{snapstate} = $1;
1e3baf05
DM
1918 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1919 my $key = $1;
1920 my $value = $2;
0d18dcfc 1921 $conf->{$key} = $value;
ef824322 1922 } elsif ($line =~ m/^delete:\s*(.*\S)\s*$/) {
e297c490 1923 my $value = $1;
ef824322
DM
1924 if ($section eq 'pending') {
1925 $conf->{delete} = $value; # we parse this later
1926 } else {
1927 warn "vm $vmid - propertry 'delete' is only allowed in [PENDING]\n";
eab09f4e 1928 }
1e3baf05
DM
1929 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1930 my $key = $1;
1931 my $value = $2;
1932 eval { $value = check_type($key, $value); };
1933 if ($@) {
1934 warn "vm $vmid - unable to parse value of '$key' - $@";
1935 } else {
1936 my $fmt = $confdesc->{$key}->{format};
1937 if ($fmt && $fmt eq 'pve-qm-drive') {
1938 my $v = parse_drive($key, $value);
1939 if (my $volid = filename_to_volume_id($vmid, $v->{file}, $v->{media})) {
1940 $v->{file} = $volid;
6b64503e 1941 $value = print_drive($vmid, $v);
1e3baf05
DM
1942 } else {
1943 warn "vm $vmid - unable to parse value of '$key'\n";
1944 next;
1945 }
1946 }
1947
1948 if ($key eq 'cdrom') {
0d18dcfc 1949 $conf->{ide2} = $value;
1e3baf05 1950 } else {
0d18dcfc 1951 $conf->{$key} = $value;
1e3baf05
DM
1952 }
1953 }
1954 }
1955 }
1956
b0ec896e
DM
1957 if (defined($descr)) {
1958 $descr =~ s/\s+$//;
1959 $conf->{description} = $descr;
1960 }
0d18dcfc 1961 delete $res->{snapstate}; # just to be sure
1e3baf05
DM
1962
1963 return $res;
1964}
1965
1858638f
DM
1966sub write_vm_config {
1967 my ($filename, $conf) = @_;
1e3baf05 1968
0d18dcfc
DM
1969 delete $conf->{snapstate}; # just to be sure
1970
1858638f
DM
1971 if ($conf->{cdrom}) {
1972 die "option ide2 conflicts with cdrom\n" if $conf->{ide2};
1973 $conf->{ide2} = $conf->{cdrom};
1974 delete $conf->{cdrom};
1975 }
1e3baf05
DM
1976
1977 # we do not use 'smp' any longer
1858638f
DM
1978 if ($conf->{sockets}) {
1979 delete $conf->{smp};
1980 } elsif ($conf->{smp}) {
1981 $conf->{sockets} = $conf->{smp};
1982 delete $conf->{cores};
1983 delete $conf->{smp};
1e3baf05
DM
1984 }
1985
ee2f90b1 1986 my $used_volids = {};
0d18dcfc 1987
ee2f90b1 1988 my $cleanup_config = sub {
ef824322 1989 my ($cref, $pending, $snapname) = @_;
1858638f 1990
ee2f90b1
DM
1991 foreach my $key (keys %$cref) {
1992 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots' ||
ef824322 1993 $key eq 'snapstate' || $key eq 'pending';
ee2f90b1 1994 my $value = $cref->{$key};
ef824322
DM
1995 if ($key eq 'delete') {
1996 die "propertry 'delete' is only allowed in [PENDING]\n"
1997 if !$pending;
1998 # fixme: check syntax?
1999 next;
2000 }
ee2f90b1
DM
2001 eval { $value = check_type($key, $value); };
2002 die "unable to parse value of '$key' - $@" if $@;
1858638f 2003
ee2f90b1
DM
2004 $cref->{$key} = $value;
2005
a8e2f942 2006 if (!$snapname && valid_drivename($key)) {
ed221350 2007 my $drive = parse_drive($key, $value);
ee2f90b1
DM
2008 $used_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
2009 }
1e3baf05 2010 }
ee2f90b1
DM
2011 };
2012
2013 &$cleanup_config($conf);
ef824322
DM
2014
2015 &$cleanup_config($conf->{pending}, 1);
2016
ee2f90b1 2017 foreach my $snapname (keys %{$conf->{snapshots}}) {
ef824322
DM
2018 die "internal error" if $snapname eq 'pending';
2019 &$cleanup_config($conf->{snapshots}->{$snapname}, undef, $snapname);
1e3baf05
DM
2020 }
2021
1858638f
DM
2022 # remove 'unusedX' settings if we re-add a volume
2023 foreach my $key (keys %$conf) {
2024 my $value = $conf->{$key};
ee2f90b1 2025 if ($key =~ m/^unused/ && $used_volids->{$value}) {
1858638f 2026 delete $conf->{$key};
1e3baf05 2027 }
1858638f 2028 }
be190583 2029
0d18dcfc 2030 my $generate_raw_config = sub {
b0ec896e 2031 my ($conf, $pending) = @_;
0581fe4f 2032
0d18dcfc
DM
2033 my $raw = '';
2034
2035 # add description as comment to top of file
b0ec896e
DM
2036 if (defined(my $descr = $conf->{description})) {
2037 if ($descr) {
2038 foreach my $cl (split(/\n/, $descr)) {
2039 $raw .= '#' . PVE::Tools::encode_text($cl) . "\n";
2040 }
2041 } else {
2042 $raw .= "#\n" if $pending;
2043 }
0d18dcfc
DM
2044 }
2045
2046 foreach my $key (sort keys %$conf) {
ef824322 2047 next if $key eq 'digest' || $key eq 'description' || $key eq 'pending' || $key eq 'snapshots';
0d18dcfc
DM
2048 $raw .= "$key: $conf->{$key}\n";
2049 }
2050 return $raw;
2051 };
0581fe4f 2052
0d18dcfc 2053 my $raw = &$generate_raw_config($conf);
ef824322
DM
2054
2055 if (scalar(keys %{$conf->{pending}})){
2056 $raw .= "\n[PENDING]\n";
b0ec896e 2057 $raw .= &$generate_raw_config($conf->{pending}, 1);
ef824322
DM
2058 }
2059
0d18dcfc
DM
2060 foreach my $snapname (sort keys %{$conf->{snapshots}}) {
2061 $raw .= "\n[$snapname]\n";
2062 $raw .= &$generate_raw_config($conf->{snapshots}->{$snapname});
1858638f 2063 }
1e3baf05 2064
1858638f
DM
2065 return $raw;
2066}
1e3baf05 2067
1858638f
DM
2068sub update_config_nolock {
2069 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 2070
1858638f 2071 check_lock($conf) if !$skiplock;
97d62eb7 2072
1858638f 2073 my $cfspath = cfs_config_path($vmid);
1e3baf05 2074
1858638f
DM
2075 PVE::Cluster::cfs_write_file($cfspath, $conf);
2076}
1e3baf05 2077
1858638f
DM
2078sub update_config {
2079 my ($vmid, $conf, $skiplock) = @_;
1e3baf05 2080
1858638f 2081 lock_config($vmid, &update_config_nolock, $conf, $skiplock);
1e3baf05
DM
2082}
2083
19672434 2084sub load_defaults {
1e3baf05
DM
2085
2086 my $res = {};
2087
2088 # we use static defaults from our JSON schema configuration
2089 foreach my $key (keys %$confdesc) {
2090 if (defined(my $default = $confdesc->{$key}->{default})) {
2091 $res->{$key} = $default;
2092 }
2093 }
19672434 2094
1e3baf05
DM
2095 my $conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
2096 $res->{keyboard} = $conf->{keyboard} if $conf->{keyboard};
2097
2098 return $res;
2099}
2100
2101sub config_list {
2102 my $vmlist = PVE::Cluster::get_vmlist();
2103 my $res = {};
2104 return $res if !$vmlist || !$vmlist->{ids};
2105 my $ids = $vmlist->{ids};
2106
1e3baf05
DM
2107 foreach my $vmid (keys %$ids) {
2108 my $d = $ids->{$vmid};
2109 next if !$d->{node} || $d->{node} ne $nodename;
5ee957cc 2110 next if !$d->{type} || $d->{type} ne 'qemu';
1e3baf05
DM
2111 $res->{$vmid}->{exists} = 1;
2112 }
2113 return $res;
2114}
2115
64e13401
DM
2116# test if VM uses local resources (to prevent migration)
2117sub check_local_resources {
2118 my ($conf, $noerr) = @_;
2119
2120 my $loc_res = 0;
19672434 2121
e0ab7331
DM
2122 $loc_res = 1 if $conf->{hostusb}; # old syntax
2123 $loc_res = 1 if $conf->{hostpci}; # old syntax
64e13401 2124
0d29ab3b 2125 foreach my $k (keys %$conf) {
49ca581d 2126 next if $k =~ m/^usb/ && ($conf->{$k} eq 'spice');
2fe1a152 2127 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
64e13401
DM
2128 }
2129
2130 die "VM uses local resources\n" if $loc_res && !$noerr;
2131
2132 return $loc_res;
2133}
2134
719893a9 2135# check if used storages are available on all nodes (use by migrate)
47152e2e
DM
2136sub check_storage_availability {
2137 my ($storecfg, $conf, $node) = @_;
2138
2139 foreach_drive($conf, sub {
2140 my ($ds, $drive) = @_;
2141
2142 my $volid = $drive->{file};
2143 return if !$volid;
2144
2145 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
2146 return if !$sid;
2147
2148 # check if storage is available on both nodes
2149 my $scfg = PVE::Storage::storage_check_node($storecfg, $sid);
2150 PVE::Storage::storage_check_node($storecfg, $sid, $node);
2151 });
2152}
2153
719893a9
DM
2154# list nodes where all VM images are available (used by has_feature API)
2155sub shared_nodes {
2156 my ($conf, $storecfg) = @_;
2157
2158 my $nodelist = PVE::Cluster::get_nodelist();
2159 my $nodehash = { map { $_ => 1 } @$nodelist };
2160 my $nodename = PVE::INotify::nodename();
be190583 2161
719893a9
DM
2162 foreach_drive($conf, sub {
2163 my ($ds, $drive) = @_;
2164
2165 my $volid = $drive->{file};
2166 return if !$volid;
2167
2168 my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
2169 if ($storeid) {
2170 my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
2171 if ($scfg->{disable}) {
2172 $nodehash = {};
2173 } elsif (my $avail = $scfg->{nodes}) {
2174 foreach my $node (keys %$nodehash) {
2175 delete $nodehash->{$node} if !$avail->{$node};
2176 }
2177 } elsif (!$scfg->{shared}) {
2178 foreach my $node (keys %$nodehash) {
2179 delete $nodehash->{$node} if $node ne $nodename
2180 }
2181 }
2182 }
2183 });
2184
2185 return $nodehash
2186}
2187
1e3baf05
DM
2188sub check_lock {
2189 my ($conf) = @_;
2190
2191 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
2192}
2193
2194sub check_cmdline {
2195 my ($pidfile, $pid) = @_;
2196
6b64503e
DM
2197 my $fh = IO::File->new("/proc/$pid/cmdline", "r");
2198 if (defined($fh)) {
1e3baf05
DM
2199 my $line = <$fh>;
2200 $fh->close;
2201 return undef if !$line;
6b64503e 2202 my @param = split(/\0/, $line);
1e3baf05
DM
2203
2204 my $cmd = $param[0];
06094efd 2205 return if !$cmd || ($cmd !~ m|kvm$| && $cmd !~ m|qemu-system-x86_64$|);
1e3baf05
DM
2206
2207 for (my $i = 0; $i < scalar (@param); $i++) {
2208 my $p = $param[$i];
2209 next if !$p;
2210 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
2211 my $p = $param[$i+1];
2212 return 1 if $p && ($p eq $pidfile);
2213 return undef;
2214 }
2215 }
2216 }
2217 return undef;
2218}
2219
2220sub check_running {
7e8dcf2c 2221 my ($vmid, $nocheck, $node) = @_;
1e3baf05 2222
7e8dcf2c 2223 my $filename = config_file($vmid, $node);
1e3baf05
DM
2224
2225 die "unable to find configuration file for VM $vmid - no such machine\n"
e6c3b671 2226 if !$nocheck && ! -f $filename;
1e3baf05 2227
e6c3b671 2228 my $pidfile = pidfile_name($vmid);
1e3baf05 2229
e6c3b671
DM
2230 if (my $fd = IO::File->new("<$pidfile")) {
2231 my $st = stat($fd);
1e3baf05 2232 my $line = <$fd>;
6b64503e 2233 close($fd);
1e3baf05
DM
2234
2235 my $mtime = $st->mtime;
2236 if ($mtime > time()) {
2237 warn "file '$filename' modified in future\n";
2238 }
2239
2240 if ($line =~ m/^(\d+)$/) {
2241 my $pid = $1;
e6c3b671
DM
2242 if (check_cmdline($pidfile, $pid)) {
2243 if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
2244 return $pid;
2245 }
2246 }
1e3baf05
DM
2247 }
2248 }
2249
2250 return undef;
2251}
2252
2253sub vzlist {
19672434 2254
1e3baf05
DM
2255 my $vzlist = config_list();
2256
6b64503e 2257 my $fd = IO::Dir->new($var_run_tmpdir) || return $vzlist;
1e3baf05 2258
19672434 2259 while (defined(my $de = $fd->read)) {
1e3baf05
DM
2260 next if $de !~ m/^(\d+)\.pid$/;
2261 my $vmid = $1;
6b64503e
DM
2262 next if !defined($vzlist->{$vmid});
2263 if (my $pid = check_running($vmid)) {
1e3baf05
DM
2264 $vzlist->{$vmid}->{pid} = $pid;
2265 }
2266 }
2267
2268 return $vzlist;
2269}
2270
1e3baf05
DM
2271sub disksize {
2272 my ($storecfg, $conf) = @_;
2273
2274 my $bootdisk = $conf->{bootdisk};
2275 return undef if !$bootdisk;
2276 return undef if !valid_drivename($bootdisk);
2277
2278 return undef if !$conf->{$bootdisk};
2279
2280 my $drive = parse_drive($bootdisk, $conf->{$bootdisk});
2281 return undef if !defined($drive);
2282
2283 return undef if drive_is_cdrom($drive);
2284
2285 my $volid = $drive->{file};
2286 return undef if !$volid;
2287
24afaca0 2288 return $drive->{size};
1e3baf05
DM
2289}
2290
2291my $last_proc_pid_stat;
2292
03a33f30
DM
2293# get VM status information
2294# This must be fast and should not block ($full == false)
2295# We only query KVM using QMP if $full == true (this can be slow)
1e3baf05 2296sub vmstatus {
03a33f30 2297 my ($opt_vmid, $full) = @_;
1e3baf05
DM
2298
2299 my $res = {};
2300
19672434 2301 my $storecfg = PVE::Storage::config();
1e3baf05
DM
2302
2303 my $list = vzlist();
694fcad4 2304 my ($uptime) = PVE::ProcFSTools::read_proc_uptime(1);
1e3baf05 2305
ae4915a2
DM
2306 my $cpucount = $cpuinfo->{cpus} || 1;
2307
1e3baf05
DM
2308 foreach my $vmid (keys %$list) {
2309 next if $opt_vmid && ($vmid ne $opt_vmid);
2310
2311 my $cfspath = cfs_config_path($vmid);
2312 my $conf = PVE::Cluster::cfs_read_file($cfspath) || {};
2313
2314 my $d = {};
2315 $d->{pid} = $list->{$vmid}->{pid};
2316
2317 # fixme: better status?
2318 $d->{status} = $list->{$vmid}->{pid} ? 'running' : 'stopped';
2319
af990afe
DM
2320 my $size = disksize($storecfg, $conf);
2321 if (defined($size)) {
2322 $d->{disk} = 0; # no info available
1e3baf05
DM
2323 $d->{maxdisk} = $size;
2324 } else {
2325 $d->{disk} = 0;
2326 $d->{maxdisk} = 0;
2327 }
2328
2329 $d->{cpus} = ($conf->{sockets} || 1) * ($conf->{cores} || 1);
ae4915a2 2330 $d->{cpus} = $cpucount if $d->{cpus} > $cpucount;
d7c8364b 2331 $d->{cpus} = $conf->{vcpus} if $conf->{vcpus};
ae4915a2 2332
1e3baf05 2333 $d->{name} = $conf->{name} || "VM $vmid";
19672434 2334 $d->{maxmem} = $conf->{memory} ? $conf->{memory}*(1024*1024) : 0;
1e3baf05 2335
8b1accf7 2336 if ($conf->{balloon}) {
4bdb0514 2337 $d->{balloon_min} = $conf->{balloon}*(1024*1024);
074e01c8 2338 $d->{shares} = defined($conf->{shares}) ? $conf->{shares} : 1000;
8b1accf7
DM
2339 }
2340
1e3baf05
DM
2341 $d->{uptime} = 0;
2342 $d->{cpu} = 0;
1e3baf05
DM
2343 $d->{mem} = 0;
2344
2345 $d->{netout} = 0;
2346 $d->{netin} = 0;
2347
2348 $d->{diskread} = 0;
2349 $d->{diskwrite} = 0;
2350
4d8c851b
AD
2351 $d->{template} = is_template($conf);
2352
1e3baf05
DM
2353 $res->{$vmid} = $d;
2354 }
2355
2356 my $netdev = PVE::ProcFSTools::read_proc_net_dev();
2357 foreach my $dev (keys %$netdev) {
2358 next if $dev !~ m/^tap([1-9]\d*)i/;
2359 my $vmid = $1;
2360 my $d = $res->{$vmid};
2361 next if !$d;
19672434 2362
1e3baf05
DM
2363 $d->{netout} += $netdev->{$dev}->{receive};
2364 $d->{netin} += $netdev->{$dev}->{transmit};
604ea644
AD
2365
2366 if ($full) {
2367 $d->{nics}->{$dev}->{netout} = $netdev->{$dev}->{receive};
2368 $d->{nics}->{$dev}->{netin} = $netdev->{$dev}->{transmit};
2369 }
2370
1e3baf05
DM
2371 }
2372
1e3baf05
DM
2373 my $ctime = gettimeofday;
2374
2375 foreach my $vmid (keys %$list) {
2376
2377 my $d = $res->{$vmid};
2378 my $pid = $d->{pid};
2379 next if !$pid;
2380
694fcad4
DM
2381 my $pstat = PVE::ProcFSTools::read_proc_pid_stat($pid);
2382 next if !$pstat; # not running
19672434 2383
694fcad4 2384 my $used = $pstat->{utime} + $pstat->{stime};
1e3baf05 2385
694fcad4 2386 $d->{uptime} = int(($uptime - $pstat->{starttime})/$cpuinfo->{user_hz});
1e3baf05 2387
694fcad4 2388 if ($pstat->{vsize}) {
6b64503e 2389 $d->{mem} = int(($pstat->{rss}/$pstat->{vsize})*$d->{maxmem});
1e3baf05
DM
2390 }
2391
2392 my $old = $last_proc_pid_stat->{$pid};
2393 if (!$old) {
19672434
DM
2394 $last_proc_pid_stat->{$pid} = {
2395 time => $ctime,
1e3baf05
DM
2396 used => $used,
2397 cpu => 0,
1e3baf05
DM
2398 };
2399 next;
2400 }
2401
7f0b5beb 2402 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz};
1e3baf05
DM
2403
2404 if ($dtime > 1000) {
2405 my $dutime = $used - $old->{used};
2406
ae4915a2 2407 $d->{cpu} = (($dutime/$dtime)* $cpucount) / $d->{cpus};
1e3baf05 2408 $last_proc_pid_stat->{$pid} = {
19672434 2409 time => $ctime,
1e3baf05
DM
2410 used => $used,
2411 cpu => $d->{cpu},
1e3baf05
DM
2412 };
2413 } else {
2414 $d->{cpu} = $old->{cpu};
1e3baf05
DM
2415 }
2416 }
2417
f5eb281a 2418 return $res if !$full;
03a33f30
DM
2419
2420 my $qmpclient = PVE::QMPClient->new();
2421
64e7fcf2
DM
2422 my $ballooncb = sub {
2423 my ($vmid, $resp) = @_;
2424
2425 my $info = $resp->{'return'};
38babf81
DM
2426 return if !$info->{max_mem};
2427
64e7fcf2
DM
2428 my $d = $res->{$vmid};
2429
38babf81
DM
2430 # use memory assigned to VM
2431 $d->{maxmem} = $info->{max_mem};
2432 $d->{balloon} = $info->{actual};
2433
2434 if (defined($info->{total_mem}) && defined($info->{free_mem})) {
2435 $d->{mem} = $info->{total_mem} - $info->{free_mem};
2436 $d->{freemem} = $info->{free_mem};
64e7fcf2
DM
2437 }
2438
604ea644 2439 $d->{ballooninfo} = $info;
64e7fcf2
DM
2440 };
2441
03a33f30
DM
2442 my $blockstatscb = sub {
2443 my ($vmid, $resp) = @_;
2444 my $data = $resp->{'return'} || [];
2445 my $totalrdbytes = 0;
2446 my $totalwrbytes = 0;
604ea644 2447
03a33f30
DM
2448 for my $blockstat (@$data) {
2449 $totalrdbytes = $totalrdbytes + $blockstat->{stats}->{rd_bytes};
2450 $totalwrbytes = $totalwrbytes + $blockstat->{stats}->{wr_bytes};
604ea644
AD
2451
2452 $blockstat->{device} =~ s/drive-//;
2453 $res->{$vmid}->{blockstat}->{$blockstat->{device}} = $blockstat->{stats};
03a33f30
DM
2454 }
2455 $res->{$vmid}->{diskread} = $totalrdbytes;
2456 $res->{$vmid}->{diskwrite} = $totalwrbytes;
2457 };
2458
2459 my $statuscb = sub {
2460 my ($vmid, $resp) = @_;
64e7fcf2 2461
03a33f30 2462 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
64e7fcf2
DM
2463 # this fails if ballon driver is not loaded, so this must be
2464 # the last commnand (following command are aborted if this fails).
38babf81 2465 $qmpclient->queue_cmd($vmid, $ballooncb, 'query-balloon');
03a33f30
DM
2466
2467 my $status = 'unknown';
2468 if (!defined($status = $resp->{'return'}->{status})) {
2469 warn "unable to get VM status\n";
2470 return;
2471 }
2472
2473 $res->{$vmid}->{qmpstatus} = $resp->{'return'}->{status};
2474 };
2475
2476 foreach my $vmid (keys %$list) {
2477 next if $opt_vmid && ($vmid ne $opt_vmid);
2478 next if !$res->{$vmid}->{pid}; # not running
2479 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2480 }
2481
c8125172 2482 $qmpclient->queue_execute(undef, 1);
03a33f30
DM
2483
2484 foreach my $vmid (keys %$list) {
2485 next if $opt_vmid && ($vmid ne $opt_vmid);
2486 $res->{$vmid}->{qmpstatus} = $res->{$vmid}->{status} if !$res->{$vmid}->{qmpstatus};
2487 }
2488
1e3baf05
DM
2489 return $res;
2490}
2491
e059fb4d
AD
2492sub foreach_dimm {
2493 my ($conf, $vmid, $memory, $sockets, $func) = @_;
2494
2495 my $dimm_id = 0;
2496 my $current_size = 1024;
2497 my $dimm_size = 512;
2498 return if $current_size == $memory;
2499
2500 for (my $j = 0; $j < 8; $j++) {
2501 for (my $i = 0; $i < 32; $i++) {
2502 my $name = "dimm${dimm_id}";
2503 $dimm_id++;
2504 my $numanode = $i % $sockets;
2505 $current_size += $dimm_size;
2506 &$func($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory);
2507 return $current_size if $current_size >= $memory;
2508 }
2509 $dimm_size *= 2;
2510 }
2511}
2512
525814b2
AD
2513sub foreach_reverse_dimm {
2514 my ($conf, $vmid, $memory, $sockets, $func) = @_;
2515
2516 my $dimm_id = 253;
2517 my $current_size = 4177920;
2518 my $dimm_size = 65536;
2519 return if $current_size == $memory;
2520
2521 for (my $j = 0; $j < 8; $j++) {
2522 for (my $i = 0; $i < 32; $i++) {
2523 my $name = "dimm${dimm_id}";
2524 $dimm_id--;
2525 my $numanode = $i % $sockets;
2526 $current_size -= $dimm_size;
2527 &$func($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory);
2528 return $current_size if $current_size <= $memory;
2529 }
2530 $dimm_size /= 2;
2531 }
2532}
2533
1e3baf05
DM
2534sub foreach_drive {
2535 my ($conf, $func) = @_;
2536
2537 foreach my $ds (keys %$conf) {
2538 next if !valid_drivename($ds);
2539
6b64503e 2540 my $drive = parse_drive($ds, $conf->{$ds});
1e3baf05
DM
2541 next if !$drive;
2542
2543 &$func($ds, $drive);
2544 }
2545}
2546
d5769dc2
DM
2547sub foreach_volid {
2548 my ($conf, $func) = @_;
be190583 2549
d5769dc2
DM
2550 my $volhash = {};
2551
2552 my $test_volid = sub {
2553 my ($volid, $is_cdrom) = @_;
2554
2555 return if !$volid;
be190583 2556
d5769dc2
DM
2557 $volhash->{$volid} = $is_cdrom || 0;
2558 };
2559
ed221350 2560 foreach_drive($conf, sub {
d5769dc2
DM
2561 my ($ds, $drive) = @_;
2562 &$test_volid($drive->{file}, drive_is_cdrom($drive));
2563 });
2564
2565 foreach my $snapname (keys %{$conf->{snapshots}}) {
2566 my $snap = $conf->{snapshots}->{$snapname};
2567 &$test_volid($snap->{vmstate}, 0);
ed221350 2568 foreach_drive($snap, sub {
d5769dc2
DM
2569 my ($ds, $drive) = @_;
2570 &$test_volid($drive->{file}, drive_is_cdrom($drive));
2571 });
2572 }
2573
2574 foreach my $volid (keys %$volhash) {
be190583 2575 &$func($volid, $volhash->{$volid});
d5769dc2
DM
2576 }
2577}
2578
86b8228b
DM
2579sub vga_conf_has_spice {
2580 my ($vga) = @_;
2581
590e698c
DM
2582 return 0 if !$vga || $vga !~ m/^qxl([234])?$/;
2583
2584 return $1 || 1;
86b8228b
DM
2585}
2586
1e3baf05 2587sub config_to_command {
952958bc 2588 my ($storecfg, $vmid, $conf, $defaults, $forcemachine) = @_;
1e3baf05
DM
2589
2590 my $cmd = [];
8c559505
DM
2591 my $globalFlags = [];
2592 my $machineFlags = [];
2593 my $rtcFlags = [];
519ed28c 2594 my $cpuFlags = [];
5bdcf937 2595 my $devices = [];
b78ebef7 2596 my $pciaddr = '';
5bdcf937 2597 my $bridges = {};
1e3baf05
DM
2598 my $kvmver = kvm_user_version();
2599 my $vernum = 0; # unknown
a3c52213
DM
2600 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2601 $vernum = $1*1000000+$2*1000;
2602 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
1e3baf05
DM
2603 $vernum = $1*1000000+$2*1000+$3;
2604 }
2605
a3c52213 2606 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
1e3baf05
DM
2607
2608 my $have_ovz = -f '/proc/vz/vestat';
2609
db656e5f 2610 my $q35 = machine_type_is_q35($conf);
4d3f29ed 2611 my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
23f73120 2612 my $machine_type = $forcemachine || $conf->{machine};
db656e5f 2613
f08e17c7
AD
2614 my $cpuunits = defined($conf->{cpuunits}) ?
2615 $conf->{cpuunits} : $defaults->{cpuunits};
2616
2617 push @$cmd, '/usr/bin/systemd-run';
2618 push @$cmd, '--scope';
2619 push @$cmd, '--slice', "qemu";
2620 push @$cmd, '--unit', $vmid;
2621 push @$cmd, '-p', "CPUShares=$cpuunits";
58be00f1 2622 if ($conf->{cpulimit}) {
c6f773b8
DM
2623 my $cpulimit = int($conf->{cpulimit} * 100);
2624 push @$cmd, '-p', "CPUQuota=$cpulimit\%";
58be00f1 2625 }
f08e17c7 2626
1e3baf05
DM
2627 push @$cmd, '/usr/bin/kvm';
2628
2629 push @$cmd, '-id', $vmid;
2630
2631 my $use_virtio = 0;
2632
c971c4f2
AD
2633 my $qmpsocket = qmp_socket($vmid);
2634 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2635 push @$cmd, '-mon', "chardev=qmp,mode=control";
2636
7b7c6d1b 2637 my $socket = vnc_socket($vmid);
1e3baf05
DM
2638 push @$cmd, '-vnc', "unix:$socket,x509,password";
2639
6b64503e 2640 push @$cmd, '-pidfile' , pidfile_name($vmid);
19672434 2641
1e3baf05
DM
2642 push @$cmd, '-daemonize';
2643
2796e7d5
DM
2644 if ($conf->{smbios1}) {
2645 push @$cmd, '-smbios', "type=1,$conf->{smbios1}";
2646 }
2647
db656e5f 2648 if ($q35) {
b467f79a 2649 # the q35 chipset support native usb2, so we enable usb controller
db656e5f 2650 # by default for this machine type
f8e83f05 2651 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-q35.cfg';
db656e5f 2652 } else {
f8e83f05
AD
2653 $pciaddr = print_pci_addr("piix3", $bridges);
2654 push @$devices, '-device', "piix3-usb-uhci,id=uhci$pciaddr.0x2";
24f0d39a 2655
f8e83f05 2656 my $use_usb2 = 0;
db656e5f
DM
2657 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2658 next if !$conf->{"usb$i"};
2659 $use_usb2 = 1;
2660 }
2661 # include usb device config
2662 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
fcc573ab 2663 }
19672434 2664
5acbfe9e 2665 my $vga = $conf->{vga};
2fa3151e 2666
590e698c
DM
2667 my $qxlnum = vga_conf_has_spice($vga);
2668 $vga = 'qxl' if $qxlnum;
2fa3151e 2669
5acbfe9e 2670 if (!$vga) {
264e519f
DM
2671 if ($conf->{ostype} && ($conf->{ostype} eq 'win8' ||
2672 $conf->{ostype} eq 'win7' ||
5acbfe9e
DM
2673 $conf->{ostype} eq 'w2k8')) {
2674 $vga = 'std';
2675 } else {
2676 $vga = 'cirrus';
2677 }
2678 }
2679
1e3baf05 2680 # enable absolute mouse coordinates (needed by vnc)
5acbfe9e
DM
2681 my $tablet;
2682 if (defined($conf->{tablet})) {
2683 $tablet = $conf->{tablet};
2684 } else {
2685 $tablet = $defaults->{tablet};
590e698c 2686 $tablet = 0 if $qxlnum; # disable for spice because it is not needed
ef5e2be2 2687 $tablet = 0 if $vga =~ m/^serial\d+$/; # disable if we use serial terminal (no vga card)
5acbfe9e
DM
2688 }
2689
db656e5f 2690 push @$devices, '-device', print_tabletdevice_full($conf) if $tablet;
b467f79a 2691
1e3baf05 2692 # host pci devices
040b06b7 2693 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2e3b7e2a
AD
2694 my $d = parse_hostpci($conf->{"hostpci$i"});
2695 next if !$d;
2696
2697 my $pcie = $d->{pcie};
2698 if($pcie){
2699 die "q35 machine model is not enabled" if !$q35;
2700 $pciaddr = print_pcie_addr("hostpci$i");
2701 }else{
2702 $pciaddr = print_pci_addr("hostpci$i", $bridges);
2703 }
2704
2705 my $rombar = $d->{rombar} && $d->{rombar} eq 'off' ? ",rombar=0" : "";
2706 my $driver = $d->{driver} && $d->{driver} eq 'vfio' ? "vfio-pci" : "pci-assign";
2707 my $xvga = $d->{'x-vga'} && $d->{'x-vga'} eq 'on' ? ",x-vga=on" : "";
137483c0
AD
2708 if ($xvga && $xvga ne '') {
2709 push @$cpuFlags, 'kvm=off';
2710 $vga = 'none';
2711 }
2e3b7e2a 2712 $driver = "vfio-pci" if $xvga ne '';
4543ecf0
AD
2713 my $pcidevices = $d->{pciid};
2714 my $multifunction = 1 if @$pcidevices > 1;
2e3b7e2a 2715
4543ecf0
AD
2716 my $j=0;
2717 foreach my $pcidevice (@$pcidevices) {
2e3b7e2a 2718
4543ecf0
AD
2719 my $id = "hostpci$i";
2720 $id .= ".$j" if $multifunction;
2721 my $addr = $pciaddr;
2722 $addr .= ".$j" if $multifunction;
2723 my $devicestr = "$driver,host=$pcidevice->{id}.$pcidevice->{function},id=$id$addr";
2724
2725 if($j == 0){
2726 $devicestr .= "$rombar$xvga";
2727 $devicestr .= ",multifunction=on" if $multifunction;
2728 }
2729
2730 push @$devices, '-device', $devicestr;
2731 $j++;
2732 }
1e3baf05
DM
2733 }
2734
2735 # usb devices
2736 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2737 my $d = parse_usb_device($conf->{"usb$i"});
2738 next if !$d;
2739 if ($d->{vendorid} && $d->{productid}) {
5bdcf937 2740 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
1e3baf05 2741 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
5bdcf937 2742 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
80401dd8
DM
2743 } elsif ($d->{spice}) {
2744 # usb redir support for spice
2745 push @$devices, '-chardev', "spicevmc,id=usbredirchardev$i,name=usbredir";
2746 push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=ehci.0";
1e3baf05
DM
2747 }
2748 }
2749
1e3baf05 2750 # serial devices
bae179aa 2751 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2752 if (my $path = $conf->{"serial$i"}) {
9f9d2fb2
DM
2753 if ($path eq 'socket') {
2754 my $socket = "/var/run/qemu-server/${vmid}.serial$i";
2755 push @$devices, '-chardev', "socket,id=serial$i,path=$socket,server,nowait";
2756 push @$devices, '-device', "isa-serial,chardev=serial$i";
2757 } else {
2758 die "no such serial device\n" if ! -c $path;
2759 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2760 push @$devices, '-device', "isa-serial,chardev=serial$i";
2761 }
34978be3 2762 }
1e3baf05
DM
2763 }
2764
2765 # parallel devices
1989a89c 2766 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2767 if (my $path = $conf->{"parallel$i"}) {
19672434 2768 die "no such parallel device\n" if ! -c $path;
32e69805 2769 my $devtype = $path =~ m!^/dev/usb/lp! ? 'tty' : 'parport';
4c5dbaf6 2770 push @$devices, '-chardev', "$devtype,id=parallel$i,path=$path";
5bdcf937 2771 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
34978be3 2772 }
1e3baf05
DM
2773 }
2774
2775 my $vmname = $conf->{name} || "vm$vmid";
2776
2777 push @$cmd, '-name', $vmname;
19672434 2778
1e3baf05
DM
2779 my $sockets = 1;
2780 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2781 $sockets = $conf->{sockets} if $conf->{sockets};
2782
2783 my $cores = $conf->{cores} || 1;
3bd18e48 2784
de9d1e55 2785 my $maxcpus = $sockets * $cores;
76267728 2786
de9d1e55 2787 my $vcpus = $conf->{vcpus} ? $conf->{vcpus} : $maxcpus;
76267728 2788
de9d1e55
AD
2789 my $allowed_vcpus = $cpuinfo->{cpus};
2790
2791 die "MAX $maxcpus vcpus allowed per VM on this node\n"
2792 if ($allowed_vcpus < $maxcpus);
2793
2794 push @$cmd, '-smp', "$vcpus,sockets=$sockets,cores=$cores,maxcpus=$maxcpus";
1e3baf05 2795
1e3baf05
DM
2796 push @$cmd, '-nodefaults';
2797
32baffb4 2798 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
3b408e82 2799
0888fdce
DM
2800 my $bootindex_hash = {};
2801 my $i = 1;
2802 foreach my $o (split(//, $bootorder)) {
2803 $bootindex_hash->{$o} = $i*100;
2804 $i++;
afdb31d5 2805 }
3b408e82 2806
cf71f776 2807 push @$cmd, '-boot', "menu=on,strict=on,reboot-timeout=1000";
1e3baf05 2808
6b64503e 2809 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2810
6b64503e 2811 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05 2812
ef5e2be2 2813 push @$cmd, '-vga', $vga if $vga && $vga !~ m/^serial\d+$/; # for kvm 77 and later
1e3baf05
DM
2814
2815 # time drift fix
6b64503e 2816 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
1e3baf05 2817
6b64503e 2818 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
8c559505 2819 my $useLocaltime = $conf->{localtime};
1e3baf05
DM
2820
2821 if (my $ost = $conf->{ostype}) {
6b9d84cf 2822 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26, solaris
1e3baf05
DM
2823
2824 if ($ost =~ m/^w/) { # windows
8c559505 2825 $useLocaltime = 1 if !defined($conf->{localtime});
1e3baf05 2826
8c559505 2827 # use time drift fix when acpi is enabled
6b64503e 2828 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
8c559505 2829 $tdf = 1 if !defined($conf->{tdf});
1e3baf05
DM
2830 }
2831 }
2832
be190583 2833 if ($ost eq 'win7' || $ost eq 'win8' || $ost eq 'w2k8' ||
a70ebde3 2834 $ost eq 'wvista') {
8c559505 2835 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
b7e0c8bf 2836 push @$cmd, '-no-hpet';
8f3f959d
AD
2837 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
2838 push @$cpuFlags , 'hv_spinlocks=0x1fff' if !$nokvm;
8a054ffd 2839 push @$cpuFlags , 'hv_vapic' if !$nokvm;
cfac0be4 2840 push @$cpuFlags , 'hv_time' if !$nokvm;
8a054ffd 2841
a1b7d579 2842 } else {
8f3f959d
AD
2843 push @$cpuFlags , 'hv_spinlocks=0xffff' if !$nokvm;
2844 }
462e8d19
AD
2845 }
2846
2847 if ($ost eq 'win7' || $ost eq 'win8') {
2848 push @$cpuFlags , 'hv_relaxed' if !$nokvm;
b7e0c8bf 2849 }
1e3baf05
DM
2850 }
2851
8c559505
DM
2852 push @$rtcFlags, 'driftfix=slew' if $tdf;
2853
7f0b5beb 2854 if ($nokvm) {
8c559505 2855 push @$machineFlags, 'accel=tcg';
7f0b5beb
DM
2856 } else {
2857 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2858 }
1e3baf05 2859
952958bc
DM
2860 if ($machine_type) {
2861 push @$machineFlags, "type=${machine_type}";
3bafc510
DM
2862 }
2863
8c559505
DM
2864 if ($conf->{startdate}) {
2865 push @$rtcFlags, "base=$conf->{startdate}";
2866 } elsif ($useLocaltime) {
2867 push @$rtcFlags, 'base=localtime';
2868 }
1e3baf05 2869
519ed28c
AD
2870 my $cpu = $nokvm ? "qemu64" : "kvm64";
2871 $cpu = $conf->{cpu} if $conf->{cpu};
2872
4dc339e7
AD
2873 push @$cpuFlags , '+lahf_lm' if $cpu eq 'kvm64';
2874
6b9d84cf
AD
2875 push @$cpuFlags , '+x2apic' if !$nokvm && $conf->{ostype} ne 'solaris';
2876
2877 push @$cpuFlags , '-x2apic' if $conf->{ostype} eq 'solaris';
519ed28c 2878
2e1a5389
AD
2879 push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32';
2880
0dc48c3d
AD
2881 push @$cpuFlags, '-rdtscp' if $cpu =~ m/^Opteron/;
2882
117a0414
AD
2883 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
2884
2885 push @$cpuFlags , '+kvm_pv_unhalt' if !$nokvm;
0da5a08c 2886 push @$cpuFlags , '+kvm_pv_eoi' if !$nokvm;
117a0414
AD
2887 }
2888
f1f7ea88 2889 push @$cpuFlags, 'enforce' if $cpu ne 'host' && !$nokvm;
dac7c619 2890
be190583 2891 $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags);
519ed28c 2892
dac7c619 2893 push @$cmd, '-cpu', $cpu;
519ed28c 2894
4d3f29ed
AD
2895 my $memory = $conf->{memory} || $defaults->{memory};
2896 my $static_memory = 0;
2897 my $dimm_memory = 0;
2898
2899 if ($hotplug_features->{memory}) {
996635e5
DM
2900 die "Numa need to be enabled for memory hotplug\n" if !$conf->{numa};
2901 die "Total memory is bigger than ${MAX_MEM}MB\n" if $memory > $MAX_MEM;
4d3f29ed 2902 $static_memory = $STATICMEM;
996635e5 2903 die "minimum memory must be ${static_memory}MB\n" if($memory < $static_memory);
4d3f29ed 2904 $dimm_memory = $memory - $static_memory;
996635e5 2905 push @$cmd, '-m', "size=${static_memory},slots=255,maxmem=${MAX_MEM}M";
4d3f29ed
AD
2906
2907 } else {
2908
2909 $static_memory = $memory;
2910 push @$cmd, '-m', $static_memory;
2911 }
8a010eae 2912
67fb9de6 2913 if ($conf->{numa}) {
8a010eae 2914
2ed5d572
AD
2915 my $numa_totalmemory = undef;
2916 for (my $i = 0; $i < $MAX_NUMA; $i++) {
2917 next if !$conf->{"numa$i"};
2918 my $numa = parse_numa($conf->{"numa$i"});
2919 next if !$numa;
67fb9de6
DM
2920 # memory
2921 die "missing numa node$i memory value\n" if !$numa->{memory};
2ed5d572
AD
2922 my $numa_memory = $numa->{memory};
2923 $numa_totalmemory += $numa_memory;
996635e5 2924 my $numa_object = "memory-backend-ram,id=ram-node$i,size=${numa_memory}M";
2ed5d572 2925
67fb9de6 2926 # cpus
2ed5d572 2927 my $cpus_start = $numa->{cpus}->{start};
67fb9de6 2928 die "missing numa node$i cpus\n" if !defined($cpus_start);
2ed5d572
AD
2929 my $cpus_end = $numa->{cpus}->{end} if defined($numa->{cpus}->{end});
2930 my $cpus = $cpus_start;
2931 if (defined($cpus_end)) {
2932 $cpus .= "-$cpus_end";
67fb9de6 2933 die "numa node$i : cpu range $cpus is incorrect\n" if $cpus_end <= $cpus_start;
2ed5d572 2934 }
8a010eae 2935
67fb9de6 2936 # hostnodes
2ed5d572
AD
2937 my $hostnodes_start = $numa->{hostnodes}->{start};
2938 if (defined($hostnodes_start)) {
2939 my $hostnodes_end = $numa->{hostnodes}->{end} if defined($numa->{hostnodes}->{end});
2940 my $hostnodes = $hostnodes_start;
2941 if (defined($hostnodes_end)) {
2942 $hostnodes .= "-$hostnodes_end";
67fb9de6 2943 die "host node $hostnodes range is incorrect\n" if $hostnodes_end <= $hostnodes_start;
2ed5d572 2944 }
8a010eae 2945
2ed5d572
AD
2946 my $hostnodes_end_range = defined($hostnodes_end) ? $hostnodes_end : $hostnodes_start;
2947 for (my $i = $hostnodes_start; $i <= $hostnodes_end_range; $i++ ) {
67fb9de6 2948 die "host numa node$i don't exist\n" if ! -d "/sys/devices/system/node/node$i/";
2ed5d572 2949 }
8a010eae 2950
67fb9de6 2951 # policy
2ed5d572 2952 my $policy = $numa->{policy};
67fb9de6
DM
2953 die "you need to define a policy for hostnode $hostnodes\n" if !$policy;
2954 $numa_object .= ",host-nodes=$hostnodes,policy=$policy";
2ed5d572
AD
2955 }
2956
2957 push @$cmd, '-object', $numa_object;
8a010eae
AD
2958 push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
2959 }
67fb9de6 2960
4d3f29ed
AD
2961 die "total memory for NUMA nodes must be equal to vm static memory\n"
2962 if $numa_totalmemory && $numa_totalmemory != $static_memory;
2ed5d572
AD
2963
2964 #if no custom tology, we split memory and cores across numa nodes
2965 if(!$numa_totalmemory) {
2966
4d3f29ed 2967 my $numa_memory = ($static_memory / $sockets) . "M";
2ed5d572
AD
2968
2969 for (my $i = 0; $i < $sockets; $i++) {
2970
2971 my $cpustart = ($cores * $i);
2972 my $cpuend = ($cpustart + $cores - 1) if $cores && $cores > 1;
2973 my $cpus = $cpustart;
2974 $cpus .= "-$cpuend" if $cpuend;
2975
2976 push @$cmd, '-object', "memory-backend-ram,size=$numa_memory,id=ram-node$i";
2977 push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
2978 }
2979 }
8a010eae
AD
2980 }
2981
4d3f29ed 2982 if ($hotplug_features->{memory}) {
e059fb4d
AD
2983 foreach_dimm($conf, $vmid, $memory, $sockets, sub {
2984 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
996635e5 2985 push @$cmd, "-object" , "memory-backend-ram,id=mem-$name,size=${dimm_size}M";
e059fb4d
AD
2986 push @$cmd, "-device", "pc-dimm,id=$name,memdev=mem-$name,node=$numanode";
2987
2988 #if dimm_memory is not aligned to dimm map
2989 if($current_size > $memory) {
2990 $conf->{memory} = $current_size;
2991 update_config_nolock($vmid, $conf, 1);
2992 }
2993 });
4d3f29ed
AD
2994 }
2995
1e3baf05
DM
2996 push @$cmd, '-S' if $conf->{freeze};
2997
2998 # set keyboard layout
2999 my $kb = $conf->{keyboard} || $defaults->{keyboard};
3000 push @$cmd, '-k', $kb if $kb;
3001
3002 # enable sound
3003 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
3004 #push @$cmd, '-soundhw', 'es1370';
3005 #push @$cmd, '-soundhw', $soundhw if $soundhw;
ab6a046f 3006
bc84dcca 3007 if($conf->{agent}) {
7a6c2150 3008 my $qgasocket = qmp_socket($vmid, 1);
ab6a046f
AD
3009 my $pciaddr = print_pci_addr("qga0", $bridges);
3010 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
3011 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
3012 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
3013 }
3014
1d794448 3015 my $spice_port;
2fa3151e 3016
590e698c
DM
3017 if ($qxlnum) {
3018 if ($qxlnum > 1) {
3019 if ($conf->{ostype} && $conf->{ostype} =~ m/^w/){
3020 for(my $i = 1; $i < $qxlnum; $i++){
3021 my $pciaddr = print_pci_addr("vga$i", $bridges);
3022 push @$cmd, '-device', "qxl,id=vga$i,ram_size=67108864,vram_size=33554432$pciaddr";
3023 }
3024 } else {
3025 # assume other OS works like Linux
3026 push @$cmd, '-global', 'qxl-vga.ram_size=134217728';
3027 push @$cmd, '-global', 'qxl-vga.vram_size=67108864';
2fa3151e
AD
3028 }
3029 }
3030
1011b570 3031 my $pciaddr = print_pci_addr("spice", $bridges);
95a4b4a9 3032
af0eba7e
WB
3033 my $nodename = PVE::INotify::nodename();
3034 my $pfamily = PVE::Tools::get_host_address_family($nodename);
3035 $spice_port = PVE::Tools::next_spice_port($pfamily);
943340a6 3036
fd1f36ac 3037 push @$devices, '-spice', "tls-port=${spice_port},addr=localhost,tls-ciphers=DES-CBC3-SHA,seamless-migration=on";
1011b570 3038
d2da6d9b
AD
3039 push @$devices, '-device', "virtio-serial,id=spice$pciaddr";
3040 push @$devices, '-chardev', "spicevmc,id=vdagent,name=vdagent";
3041 push @$devices, '-device', "virtserialport,chardev=vdagent,name=com.redhat.spice.0";
1011b570
DM
3042 }
3043
8d9ae0d2
DM
3044 # enable balloon by default, unless explicitly disabled
3045 if (!defined($conf->{balloon}) || $conf->{balloon}) {
3046 $pciaddr = print_pci_addr("balloon0", $bridges);
3047 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr";
3048 }
1e3baf05 3049
0ea9541d
DM
3050 if ($conf->{watchdog}) {
3051 my $wdopts = parse_watchdog($conf->{watchdog});
5bdcf937 3052 $pciaddr = print_pci_addr("watchdog", $bridges);
0a40e8ea 3053 my $watchdog = $wdopts->{model} || 'i6300esb';
5bdcf937
AD
3054 push @$devices, '-device', "$watchdog$pciaddr";
3055 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
0ea9541d
DM
3056 }
3057
1e3baf05 3058 my $vollist = [];
941e0c42 3059 my $scsicontroller = {};
26ee04b6 3060 my $ahcicontroller = {};
cdd20088 3061 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
1e3baf05 3062
5881b913
DM
3063 # Add iscsi initiator name if available
3064 if (my $initiator = get_initiator_name()) {
3065 push @$devices, '-iscsi', "initiator-name=$initiator";
3066 }
3067
1e3baf05
DM
3068 foreach_drive($conf, sub {
3069 my ($ds, $drive) = @_;
3070
ff1a2432 3071 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 3072 push @$vollist, $drive->{file};
ff1a2432 3073 }
afdb31d5 3074
1e3baf05 3075 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
3076
3077 if (drive_is_cdrom ($drive)) {
3078 if ($bootindex_hash->{d}) {
3079 $drive->{bootindex} = $bootindex_hash->{d};
3080 $bootindex_hash->{d} += 1;
3081 }
3082 } else {
3083 if ($bootindex_hash->{c}) {
3084 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
3085 $bootindex_hash->{c} += 1;
3086 }
3087 }
3088
51f492cd
AD
3089 if($drive->{interface} eq 'virtio'){
3090 push @$cmd, '-object', "iothread,id=iothread-$ds" if $drive->{iothread};
3091 }
3092
941e0c42 3093 if ($drive->{interface} eq 'scsi') {
cdd20088 3094
ee034f5c 3095 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $drive);
6731a4cf 3096
6731a4cf 3097 $pciaddr = print_pci_addr("$controller_prefix$controller", $bridges);
a1b7d579 3098 my $scsihw_type = $scsihw =~ m/^virtio-scsi-single/ ? "virtio-scsi-pci" : $scsihw;
fc8b40fd
AD
3099
3100 my $iothread = '';
3101 if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{iothread}){
3102 $iothread .= ",iothread=iothread-$controller_prefix$controller";
3103 push @$cmd, '-object', "iothread,id=iothread-$controller_prefix$controller";
3104 }
3105
6e11f143
AD
3106 my $queues = '';
3107 if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{queues}){
3108 $queues = ",num_queues=$drive->{queues}";
3109 }
3110
3111 push @$devices, '-device', "$scsihw_type,id=$controller_prefix$controller$pciaddr$iothread$queues" if !$scsicontroller->{$controller};
cdd20088 3112 $scsicontroller->{$controller}=1;
941e0c42 3113 }
3b408e82 3114
26ee04b6
DA
3115 if ($drive->{interface} eq 'sata') {
3116 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
5bdcf937
AD
3117 $pciaddr = print_pci_addr("ahci$controller", $bridges);
3118 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
26ee04b6
DA
3119 $ahcicontroller->{$controller}=1;
3120 }
46f58b5f 3121
15b21acc
MR
3122 my $drive_cmd = print_drive_full($storecfg, $vmid, $drive);
3123 push @$devices, '-drive',$drive_cmd;
46f58b5f 3124 push @$devices, '-device', print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
1e3baf05
DM
3125 });
3126
cc4d6182 3127 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 3128 next if !$conf->{"net$i"};
cc4d6182
DA
3129 my $d = parse_net($conf->{"net$i"});
3130 next if !$d;
1e3baf05 3131
cc4d6182 3132 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 3133
cc4d6182
DA
3134 if ($bootindex_hash->{n}) {
3135 $d->{bootindex} = $bootindex_hash->{n};
3136 $bootindex_hash->{n} += 1;
3137 }
1e3baf05 3138
cc4d6182 3139 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
5bdcf937
AD
3140 push @$devices, '-netdev', $netdevfull;
3141
3142 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i",$bridges);
3143 push @$devices, '-device', $netdevicefull;
3144 }
1e3baf05 3145
db656e5f
DM
3146 if (!$q35) {
3147 # add pci bridges
fc79e813
AD
3148 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
3149 $bridges->{1} = 1;
3150 $bridges->{2} = 1;
3151 }
3152
6731a4cf
AD
3153 $bridges->{3} = 1 if $scsihw =~ m/^virtio-scsi-single/;
3154
f8e83f05
AD
3155 while (my ($k, $v) = each %$bridges) {
3156 $pciaddr = print_pci_addr("pci.$k");
3157 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
3158 }
19672434
DM
3159 }
3160
1e3baf05
DM
3161 # add custom args
3162 if ($conf->{args}) {
3ada46c9 3163 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
3164 push @$cmd, @$aa;
3165 }
3166
5bdcf937 3167 push @$cmd, @$devices;
be190583 3168 push @$cmd, '-rtc', join(',', @$rtcFlags)
8c559505 3169 if scalar(@$rtcFlags);
be190583 3170 push @$cmd, '-machine', join(',', @$machineFlags)
8c559505
DM
3171 if scalar(@$machineFlags);
3172 push @$cmd, '-global', join(',', @$globalFlags)
3173 if scalar(@$globalFlags);
3174
1d794448 3175 return wantarray ? ($cmd, $vollist, $spice_port) : $cmd;
1e3baf05 3176}
19672434 3177
1e3baf05
DM
3178sub vnc_socket {
3179 my ($vmid) = @_;
3180 return "${var_run_tmpdir}/$vmid.vnc";
3181}
3182
943340a6 3183sub spice_port {
1011b570 3184 my ($vmid) = @_;
943340a6 3185
1d794448 3186 my $res = vm_mon_cmd($vmid, 'query-spice');
943340a6
DM
3187
3188 return $res->{'tls-port'} || $res->{'port'} || die "no spice port\n";
1011b570
DM
3189}
3190
c971c4f2 3191sub qmp_socket {
693d12a2
AD
3192 my ($vmid, $qga) = @_;
3193 my $sockettype = $qga ? 'qga' : 'qmp';
3194 return "${var_run_tmpdir}/$vmid.$sockettype";
c971c4f2
AD
3195}
3196
1e3baf05
DM
3197sub pidfile_name {
3198 my ($vmid) = @_;
3199 return "${var_run_tmpdir}/$vmid.pid";
3200}
3201
86fdcfb2
DA
3202sub vm_devices_list {
3203 my ($vmid) = @_;
3204
ceea9078 3205 my $res = vm_mon_cmd($vmid, 'query-pci');
ceea9078
DM
3206 my $devices = {};
3207 foreach my $pcibus (@$res) {
3208 foreach my $device (@{$pcibus->{devices}}) {
6e62a21f 3209 next if !$device->{'qdev_id'};
200644a7 3210 if ($device->{'pci_bridge'}) {
200644a7
AD
3211 $devices->{$device->{'qdev_id'}} = 1;
3212 foreach my $bridge_device (@{$device->{'pci_bridge'}->{devices}}) {
3213 next if !$bridge_device->{'qdev_id'};
3214 $devices->{$bridge_device->{'qdev_id'}} = 1;
3215 $devices->{$device->{'qdev_id'}}++;
3216 }
3217 } else {
200644a7
AD
3218 $devices->{$device->{'qdev_id'}} = 1;
3219 }
f78cc802
AD
3220 }
3221 }
3222
3223 my $resblock = vm_mon_cmd($vmid, 'query-block');
3224 foreach my $block (@$resblock) {
3225 if($block->{device} =~ m/^drive-(\S+)/){
3226 $devices->{$1} = 1;
1dc4f496
DM
3227 }
3228 }
86fdcfb2 3229
3d7389fe
DM
3230 my $resmice = vm_mon_cmd($vmid, 'query-mice');
3231 foreach my $mice (@$resmice) {
3232 if ($mice->{name} eq 'QEMU HID Tablet') {
3233 $devices->{tablet} = 1;
3234 last;
3235 }
3236 }
3237
1dc4f496 3238 return $devices;
86fdcfb2
DA
3239}
3240
ec21aa11 3241sub vm_deviceplug {
f19d1c47 3242 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 3243
db656e5f
DM
3244 my $q35 = machine_type_is_q35($conf);
3245
95d6343b
DA
3246 my $devices_list = vm_devices_list($vmid);
3247 return 1 if defined($devices_list->{$deviceid});
3248
fee46675
DM
3249 qemu_add_pci_bridge($storecfg, $conf, $vmid, $deviceid); # add PCI bridge if we need it for the device
3250
3d7389fe 3251 if ($deviceid eq 'tablet') {
fee46675 3252
3d7389fe 3253 qemu_deviceadd($vmid, print_tabletdevice_full($conf));
3d7389fe 3254
fee46675 3255 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
40f28a9f 3256
22de899a
AD
3257 qemu_iothread_add($vmid, $deviceid, $device);
3258
fee46675 3259 qemu_driveadd($storecfg, $vmid, $device);
cdd20088 3260 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
fee46675 3261
5e5dcb73 3262 qemu_deviceadd($vmid, $devicefull);
fee46675
DM
3263 eval { qemu_deviceaddverify($vmid, $deviceid); };
3264 if (my $err = $@) {
63c2da2f
DM
3265 eval { qemu_drivedel($vmid, $deviceid); };
3266 warn $@ if $@;
fee46675 3267 die $err;
5e5dcb73 3268 }
cfc817c7 3269
2733141c 3270 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
fee46675 3271
fc8b40fd 3272
cdd20088 3273 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
cfc817c7 3274 my $pciaddr = print_pci_addr($deviceid);
a1b7d579 3275 my $scsihw_type = $scsihw eq 'virtio-scsi-single' ? "virtio-scsi-pci" : $scsihw;
2733141c
AD
3276
3277 my $devicefull = "$scsihw_type,id=$deviceid$pciaddr";
fee46675 3278
fc8b40fd
AD
3279 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{iothread}) {
3280 qemu_iothread_add($vmid, $deviceid, $device);
3281 $devicefull .= ",iothread=iothread-$deviceid";
3282 }
3283
6e11f143
AD
3284 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{queues}) {
3285 $devicefull .= ",num_queues=$device->{queues}";
3286 }
3287
cfc817c7 3288 qemu_deviceadd($vmid, $devicefull);
fee46675 3289 qemu_deviceaddverify($vmid, $deviceid);
cfc817c7 3290
fee46675
DM
3291 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
3292
3293 qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
3294 qemu_driveadd($storecfg, $vmid, $device);
a1b7d579 3295
fee46675
DM
3296 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
3297 eval { qemu_deviceadd($vmid, $devicefull); };
3298 if (my $err = $@) {
63c2da2f
DM
3299 eval { qemu_drivedel($vmid, $deviceid); };
3300 warn $@ if $@;
fee46675 3301 die $err;
a4f091a0 3302 }
a4f091a0 3303
fee46675
DM
3304 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
3305
2630d2a9
DA
3306 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
3307 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
3308 qemu_deviceadd($vmid, $netdevicefull);
fee46675
DM
3309 eval { qemu_deviceaddverify($vmid, $deviceid); };
3310 if (my $err = $@) {
3311 eval { qemu_netdevdel($vmid, $deviceid); };
3312 warn $@ if $@;
3313 die $err;
2630d2a9 3314 }
2630d2a9 3315
fee46675 3316 } elsif (!$q35 && $deviceid =~ m/^(pci\.)(\d+)$/) {
b467f79a 3317
40f28a9f
AD
3318 my $bridgeid = $2;
3319 my $pciaddr = print_pci_addr($deviceid);
3320 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
a1b7d579 3321
40f28a9f 3322 qemu_deviceadd($vmid, $devicefull);
fee46675
DM
3323 qemu_deviceaddverify($vmid, $deviceid);
3324
3325 } else {
a1b7d579 3326 die "can't hotplug device '$deviceid'\n";
40f28a9f
AD
3327 }
3328
5e5dcb73 3329 return 1;
a4dea331
DA
3330}
3331
3eec5767 3332# fixme: this should raise exceptions on error!
ec21aa11 3333sub vm_deviceunplug {
f19d1c47 3334 my ($vmid, $conf, $deviceid) = @_;
873c2d69 3335
95d6343b
DA
3336 my $devices_list = vm_devices_list($vmid);
3337 return 1 if !defined($devices_list->{$deviceid});
3338
63c2da2f
DM
3339 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
3340
3d7389fe 3341 if ($deviceid eq 'tablet') {
63c2da2f 3342
3d7389fe 3343 qemu_devicedel($vmid, $deviceid);
3d7389fe 3344
63c2da2f 3345 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
f19d1c47 3346
5e5dcb73 3347 qemu_devicedel($vmid, $deviceid);
63c2da2f
DM
3348 qemu_devicedelverify($vmid, $deviceid);
3349 qemu_drivedel($vmid, $deviceid);
22de899a
AD
3350 qemu_iothread_del($conf, $vmid, $deviceid);
3351
2733141c 3352 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
a1b7d579 3353
63c2da2f 3354 qemu_devicedel($vmid, $deviceid);
8ce30dde 3355 qemu_devicedelverify($vmid, $deviceid);
fc8b40fd 3356 qemu_iothread_del($conf, $vmid, $deviceid);
a1b7d579 3357
63c2da2f 3358 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
cfc817c7 3359
8bcf3068
AD
3360 #qemu 2.3 segfault on drive_del with virtioscsi + iothread
3361 my $device = parse_drive($deviceid, $conf->{$deviceid});
3362 die "virtioscsi with iothread is not hot-unplugglable currently" if $device->{iothread};
3363
63c2da2f
DM
3364 qemu_devicedel($vmid, $deviceid);
3365 qemu_drivedel($vmid, $deviceid);
a1b7d579 3366 qemu_deletescsihw($conf, $vmid, $deviceid);
8ce30dde 3367
63c2da2f 3368 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
a4f091a0 3369
2630d2a9 3370 qemu_devicedel($vmid, $deviceid);
63c2da2f
DM
3371 qemu_devicedelverify($vmid, $deviceid);
3372 qemu_netdevdel($vmid, $deviceid);
3373
3374 } else {
3375 die "can't unplug device '$deviceid'\n";
2630d2a9
DA
3376 }
3377
5e5dcb73
DA
3378 return 1;
3379}
3380
3381sub qemu_deviceadd {
3382 my ($vmid, $devicefull) = @_;
873c2d69 3383
d695b5b7
AD
3384 $devicefull = "driver=".$devicefull;
3385 my %options = split(/[=,]/, $devicefull);
f19d1c47 3386
d695b5b7 3387 vm_mon_cmd($vmid, "device_add" , %options);
5e5dcb73 3388}
afdb31d5 3389
5e5dcb73 3390sub qemu_devicedel {
fee46675 3391 my ($vmid, $deviceid) = @_;
63c2da2f 3392
5a77d8c1 3393 my $ret = vm_mon_cmd($vmid, "device_del", id => $deviceid);
5e5dcb73
DA
3394}
3395
22de899a
AD
3396sub qemu_iothread_add {
3397 my($vmid, $deviceid, $device) = @_;
3398
3399 if ($device->{iothread}) {
3400 my $iothreads = vm_iothreads_list($vmid);
3401 qemu_objectadd($vmid, "iothread-$deviceid", "iothread") if !$iothreads->{"iothread-$deviceid"};
3402 }
3403}
3404
3405sub qemu_iothread_del {
3406 my($conf, $vmid, $deviceid) = @_;
3407
3408 my $device = parse_drive($deviceid, $conf->{$deviceid});
3409 if ($device->{iothread}) {
3410 my $iothreads = vm_iothreads_list($vmid);
3411 qemu_objectdel($vmid, "iothread-$deviceid") if $iothreads->{"iothread-$deviceid"};
3412 }
3413}
3414
4d3f29ed
AD
3415sub qemu_objectadd {
3416 my($vmid, $objectid, $qomtype) = @_;
3417
3418 vm_mon_cmd($vmid, "object-add", id => $objectid, "qom-type" => $qomtype);
3419
3420 return 1;
3421}
3422
3423sub qemu_objectdel {
3424 my($vmid, $objectid) = @_;
3425
3426 vm_mon_cmd($vmid, "object-del", id => $objectid);
3427
3428 return 1;
3429}
3430
5e5dcb73 3431sub qemu_driveadd {
fee46675 3432 my ($storecfg, $vmid, $device) = @_;
5e5dcb73
DA
3433
3434 my $drive = print_drive_full($storecfg, $vmid, $device);
7a69fc3c 3435 $drive =~ s/\\/\\\\/g;
8ead5ec7 3436 my $ret = vm_human_monitor_command($vmid, "drive_add auto \"$drive\"");
fee46675 3437
5e5dcb73 3438 # If the command succeeds qemu prints: "OK"
fee46675
DM
3439 return 1 if $ret =~ m/OK/s;
3440
3441 die "adding drive failed: $ret\n";
5e5dcb73 3442}
afdb31d5 3443
5e5dcb73
DA
3444sub qemu_drivedel {
3445 my($vmid, $deviceid) = @_;
873c2d69 3446
7b7c6d1b 3447 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
5e5dcb73 3448 $ret =~ s/^\s+//;
a1b7d579 3449
63c2da2f 3450 return 1 if $ret eq "";
a1b7d579 3451
63c2da2f 3452 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
a1b7d579
DM
3453 return 1 if $ret =~ m/Device \'.*?\' not found/s;
3454
63c2da2f 3455 die "deleting drive $deviceid failed : $ret\n";
5e5dcb73 3456}
f19d1c47 3457
5e5dcb73 3458sub qemu_deviceaddverify {
fee46675 3459 my ($vmid, $deviceid) = @_;
873c2d69 3460
5e5dcb73
DA
3461 for (my $i = 0; $i <= 5; $i++) {
3462 my $devices_list = vm_devices_list($vmid);
3463 return 1 if defined($devices_list->{$deviceid});
3464 sleep 1;
afdb31d5 3465 }
fee46675
DM
3466
3467 die "error on hotplug device '$deviceid'\n";
5e5dcb73 3468}
afdb31d5 3469
5e5dcb73
DA
3470
3471sub qemu_devicedelverify {
63c2da2f
DM
3472 my ($vmid, $deviceid) = @_;
3473
a1b7d579 3474 # need to verify that the device is correctly removed as device_del
63c2da2f 3475 # is async and empty return is not reliable
5e5dcb73 3476
5e5dcb73
DA
3477 for (my $i = 0; $i <= 5; $i++) {
3478 my $devices_list = vm_devices_list($vmid);
3479 return 1 if !defined($devices_list->{$deviceid});
3480 sleep 1;
afdb31d5 3481 }
63c2da2f
DM
3482
3483 die "error on hot-unplugging device '$deviceid'\n";
873c2d69
DA
3484}
3485
cdd20088 3486sub qemu_findorcreatescsihw {
cfc817c7
DA
3487 my ($storecfg, $conf, $vmid, $device) = @_;
3488
ee034f5c 3489 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
2733141c
AD
3490
3491 my $scsihwid="$controller_prefix$controller";
cfc817c7
DA
3492 my $devices_list = vm_devices_list($vmid);
3493
cdd20088 3494 if(!defined($devices_list->{$scsihwid})) {
fc8b40fd 3495 vm_deviceplug($storecfg, $conf, $vmid, $scsihwid, $device);
cfc817c7 3496 }
fee46675 3497
cfc817c7
DA
3498 return 1;
3499}
3500
8ce30dde
AD
3501sub qemu_deletescsihw {
3502 my ($conf, $vmid, $opt) = @_;
3503
3504 my $device = parse_drive($opt, $conf->{$opt});
3505
a1511b3c 3506 if ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
2733141c
AD
3507 vm_deviceunplug($vmid, $conf, "virtioscsi$device->{index}");
3508 return 1;
3509 }
3510
ee034f5c 3511 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
8ce30dde
AD
3512
3513 my $devices_list = vm_devices_list($vmid);
3514 foreach my $opt (keys %{$devices_list}) {
3515 if (PVE::QemuServer::valid_drivename($opt)) {
3516 my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
3517 if($drive->{interface} eq 'scsi' && $drive->{index} < (($maxdev-1)*($controller+1))) {
3518 return 1;
3519 }
3520 }
3521 }
3522
3523 my $scsihwid="scsihw$controller";
3524
3525 vm_deviceunplug($vmid, $conf, $scsihwid);
3526
3527 return 1;
3528}
3529
281fedb3 3530sub qemu_add_pci_bridge {
40f28a9f
AD
3531 my ($storecfg, $conf, $vmid, $device) = @_;
3532
3533 my $bridges = {};
281fedb3
DM
3534
3535 my $bridgeid;
3536
40f28a9f
AD
3537 print_pci_addr($device, $bridges);
3538
3539 while (my ($k, $v) = each %$bridges) {
3540 $bridgeid = $k;
3541 }
fee46675 3542 return 1 if !defined($bridgeid) || $bridgeid < 1;
281fedb3 3543
40f28a9f
AD
3544 my $bridge = "pci.$bridgeid";
3545 my $devices_list = vm_devices_list($vmid);
3546
281fedb3 3547 if (!defined($devices_list->{$bridge})) {
fee46675 3548 vm_deviceplug($storecfg, $conf, $vmid, $bridge);
40f28a9f 3549 }
281fedb3 3550
40f28a9f
AD
3551 return 1;
3552}
3553
25088687
DM
3554sub qemu_set_link_status {
3555 my ($vmid, $device, $up) = @_;
3556
a1b7d579 3557 vm_mon_cmd($vmid, "set_link", name => $device,
25088687
DM
3558 up => $up ? JSON::true : JSON::false);
3559}
3560
2630d2a9
DA
3561sub qemu_netdevadd {
3562 my ($vmid, $conf, $device, $deviceid) = @_;
3563
3564 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
73aa03b8 3565 my %options = split(/[=,]/, $netdev);
2630d2a9 3566
73aa03b8
AD
3567 vm_mon_cmd($vmid, "netdev_add", %options);
3568 return 1;
2630d2a9
DA
3569}
3570
3571sub qemu_netdevdel {
3572 my ($vmid, $deviceid) = @_;
3573
89c1e0f4 3574 vm_mon_cmd($vmid, "netdev_del", id => $deviceid);
2630d2a9
DA
3575}
3576
838776ab 3577sub qemu_cpu_hotplug {
8edc9c08 3578 my ($vmid, $conf, $vcpus) = @_;
838776ab 3579
8edc9c08
AD
3580 my $sockets = 1;
3581 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
3582 $sockets = $conf->{sockets} if $conf->{sockets};
3583 my $cores = $conf->{cores} || 1;
3584 my $maxcpus = $sockets * $cores;
838776ab 3585
8edc9c08 3586 $vcpus = $maxcpus if !$vcpus;
3a11fadb 3587
8edc9c08
AD
3588 die "you can't add more vcpus than maxcpus\n"
3589 if $vcpus > $maxcpus;
3a11fadb 3590
8edc9c08 3591 my $currentvcpus = $conf->{vcpus} || $maxcpus;
3a11fadb 3592 die "online cpu unplug is not yet possible\n"
8edc9c08 3593 if $vcpus < $currentvcpus;
838776ab 3594
8edc9c08
AD
3595 my $currentrunningvcpus = vm_mon_cmd($vmid, "query-cpus");
3596 die "vcpus in running vm is different than configuration\n"
3597 if scalar(@{$currentrunningvcpus}) != $currentvcpus;
838776ab 3598
8edc9c08 3599 for (my $i = $currentvcpus; $i < $vcpus; $i++) {
838776ab
AD
3600 vm_mon_cmd($vmid, "cpu-add", id => int($i));
3601 }
3602}
3603
4d3f29ed
AD
3604sub qemu_memory_hotplug {
3605 my ($vmid, $conf, $defaults, $opt, $value) = @_;
3606
3607 return $value if !check_running($vmid);
a1b7d579 3608
4d3f29ed 3609 my $memory = $conf->{memory} || $defaults->{memory};
a1b7d579 3610 $value = $defaults->{memory} if !$value;
4d3f29ed
AD
3611 return $value if $value == $memory;
3612
3613 my $static_memory = $STATICMEM;
3614 my $dimm_memory = $memory - $static_memory;
3615
3616 die "memory can't be lower than $static_memory MB" if $value < $static_memory;
4d3f29ed
AD
3617 die "you cannot add more memory than $MAX_MEM MB!\n" if $memory > $MAX_MEM;
3618
3619
3620 my $sockets = 1;
3621 $sockets = $conf->{sockets} if $conf->{sockets};
3622
525814b2 3623 if($value > $memory) {
e059fb4d 3624
525814b2
AD
3625 foreach_dimm($conf, $vmid, $value, $sockets, sub {
3626 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
4d3f29ed 3627
525814b2 3628 return if $current_size <= $conf->{memory};
4d3f29ed 3629
525814b2
AD
3630 eval { vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-ram", id => "mem-$name", props => { size => int($dimm_size*1024*1024) } ) };
3631 if (my $err = $@) {
3632 eval { qemu_objectdel($vmid, "mem-$name"); };
3633 die $err;
3634 }
3635
3636 eval { vm_mon_cmd($vmid, "device_add", driver => "pc-dimm", id => "$name", memdev => "mem-$name", node => $numanode) };
3637 if (my $err = $@) {
3638 eval { qemu_objectdel($vmid, "mem-$name"); };
3639 die $err;
3640 }
3641 #update conf after each succesful module hotplug
3642 $conf->{memory} = $current_size;
3643 update_config_nolock($vmid, $conf, 1);
3644 });
3645
3646 } else {
3647
3648 foreach_reverse_dimm($conf, $vmid, $value, $sockets, sub {
3649 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
3650
3651 return if $current_size >= $conf->{memory};
3652 print "try to unplug memory dimm $name\n";
3653
3654 my $retry = 0;
3655 while (1) {
3656 eval { qemu_devicedel($vmid, $name) };
3657 sleep 3;
3658 my $dimm_list = qemu_dimm_list($vmid);
3659 last if !$dimm_list->{$name};
3660 raise_param_exc({ $name => "error unplug memory module" }) if $retry > 5;
3661 $retry++;
3662 }
3663
3664 #update conf after each succesful module unplug
3665 $conf->{memory} = $current_size;
3666
3667 eval { qemu_objectdel($vmid, "mem-$name"); };
3668 update_config_nolock($vmid, $conf, 1);
3669 });
3670 }
3671}
3672
3673sub qemu_dimm_list {
3674 my ($vmid) = @_;
3675
3676 my $dimmarray = vm_mon_cmd_nocheck($vmid, "query-memory-devices");
3677 my $dimms = {};
3678
3679 foreach my $dimm (@$dimmarray) {
3680
3681 $dimms->{$dimm->{data}->{id}}->{id} = $dimm->{data}->{id};
3682 $dimms->{$dimm->{data}->{id}}->{node} = $dimm->{data}->{node};
3683 $dimms->{$dimm->{data}->{id}}->{addr} = $dimm->{data}->{addr};
3684 $dimms->{$dimm->{data}->{id}}->{size} = $dimm->{data}->{size};
3685 $dimms->{$dimm->{data}->{id}}->{slot} = $dimm->{data}->{slot};
3686 }
3687 return $dimms;
4d3f29ed
AD
3688}
3689
affd2f88
AD
3690sub qemu_block_set_io_throttle {
3691 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
3692
f3f323a3
AD
3693 return if !check_running($vmid) ;
3694
f3f323a3
AD
3695 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));
3696
affd2f88
AD
3697}
3698
f5eb281a 3699# old code, only used to shutdown old VM after update
dab36e1e
DM
3700sub __read_avail {
3701 my ($fh, $timeout) = @_;
3702
3703 my $sel = new IO::Select;
3704 $sel->add($fh);
3705
3706 my $res = '';
3707 my $buf;
3708
3709 my @ready;
3710 while (scalar (@ready = $sel->can_read($timeout))) {
3711 my $count;
3712 if ($count = $fh->sysread($buf, 8192)) {
3713 if ($buf =~ /^(.*)\(qemu\) $/s) {
3714 $res .= $1;
3715 last;
3716 } else {
3717 $res .= $buf;
3718 }
3719 } else {
3720 if (!defined($count)) {
3721 die "$!\n";
3722 }
3723 last;
3724 }
3725 }
3726
3727 die "monitor read timeout\n" if !scalar(@ready);
f5eb281a 3728
dab36e1e
DM
3729 return $res;
3730}
3731
f5eb281a 3732# old code, only used to shutdown old VM after update
dab36e1e
DM
3733sub vm_monitor_command {
3734 my ($vmid, $cmdstr, $nocheck) = @_;
f5eb281a 3735
dab36e1e
DM
3736 my $res;
3737
3738 eval {
3739 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
3740
3741 my $sname = "${var_run_tmpdir}/$vmid.mon";
3742
3743 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
3744 die "unable to connect to VM $vmid socket - $!\n";
3745
3746 my $timeout = 3;
3747
3748 # hack: migrate sometime blocks the monitor (when migrate_downtime
3749 # is set)
3750 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3751 $timeout = 60*60; # 1 hour
3752 }
3753
3754 # read banner;
3755 my $data = __read_avail($sock, $timeout);
3756
3757 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
3758 die "got unexpected qemu monitor banner\n";
3759 }
3760
3761 my $sel = new IO::Select;
3762 $sel->add($sock);
3763
3764 if (!scalar(my @ready = $sel->can_write($timeout))) {
3765 die "monitor write error - timeout";
3766 }
3767
3768 my $fullcmd = "$cmdstr\r";
3769
3770 # syslog('info', "VM $vmid monitor command: $cmdstr");
3771
3772 my $b;
3773 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
3774 die "monitor write error - $!";
3775 }
3776
3777 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
3778
3779 $timeout = 20;
3780
3781 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3782 $timeout = 60*60; # 1 hour
3783 } elsif ($cmdstr =~ m/^(eject|change)/) {
3784 $timeout = 60; # note: cdrom mount command is slow
3785 }
3786 if ($res = __read_avail($sock, $timeout)) {
3787
3788 my @lines = split("\r?\n", $res);
f5eb281a 3789
dab36e1e 3790 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
f5eb281a 3791
dab36e1e
DM
3792 $res = join("\n", @lines);
3793 $res .= "\n";
3794 }
3795 };
3796
3797 my $err = $@;
3798
3799 if ($err) {
3800 syslog("err", "VM $vmid monitor command failed - $err");
3801 die $err;
3802 }
f5eb281a 3803
dab36e1e
DM
3804 return $res;
3805}
3806
c1175c92
AD
3807sub qemu_block_resize {
3808 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
3809
ed221350 3810 my $running = check_running($vmid);
c1175c92
AD
3811
3812 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
3813
3814 return if !$running;
3815
3816 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
3817
3818}
3819
1ab0057c
AD
3820sub qemu_volume_snapshot {
3821 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3822
ed221350 3823 my $running = check_running($vmid);
1ab0057c 3824
e5eaa028
WL
3825 if ($running && do_snapshots_with_qemu($storecfg, $volid)){
3826 vm_mon_cmd($vmid, "snapshot-drive", device => $deviceid, name => $snap);
3827 } else {
3828 PVE::Storage::volume_snapshot($storecfg, $volid, $snap);
3829 }
1ab0057c
AD
3830}
3831
fc46aff9
AD
3832sub qemu_volume_snapshot_delete {
3833 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3834
ed221350 3835 my $running = check_running($vmid);
fc46aff9
AD
3836
3837 return if !PVE::Storage::volume_snapshot_delete($storecfg, $volid, $snap, $running);
3838
3839 return if !$running;
3840
18bfb361 3841 vm_mon_cmd($vmid, "delete-drive-snapshot", device => $deviceid, name => $snap);
fc46aff9
AD
3842}
3843
264e519f
DM
3844sub set_migration_caps {
3845 my ($vmid) = @_;
a89fded1 3846
8b8345f3 3847 my $cap_ref = [];
a89fded1
AD
3848
3849 my $enabled_cap = {
8b8345f3
DM
3850 "auto-converge" => 1,
3851 "xbzrle" => 0,
3852 "x-rdma-pin-all" => 0,
3853 "zero-blocks" => 0,
a89fded1
AD
3854 };
3855
8b8345f3 3856 my $supported_capabilities = vm_mon_cmd_nocheck($vmid, "query-migrate-capabilities");
a89fded1 3857
8b8345f3 3858 for my $supported_capability (@$supported_capabilities) {
b463a3ce
SP
3859 push @$cap_ref, {
3860 capability => $supported_capability->{capability},
22430fa2
DM
3861 state => $enabled_cap->{$supported_capability->{capability}} ? JSON::true : JSON::false,
3862 };
a89fded1
AD
3863 }
3864
8b8345f3
DM
3865 vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => $cap_ref);
3866}
a89fded1 3867
81d95ae1 3868my $fast_plug_option = {
7498eb64 3869 'lock' => 1,
81d95ae1 3870 'name' => 1,
a1b7d579 3871 'onboot' => 1,
81d95ae1
DM
3872 'shares' => 1,
3873 'startup' => 1,
b0ec896e 3874 'description' => 1,
81d95ae1
DM
3875};
3876
3a11fadb
DM
3877# hotplug changes in [PENDING]
3878# $selection hash can be used to only apply specified options, for
3879# example: { cores => 1 } (only apply changed 'cores')
3880# $errors ref is used to return error messages
c427973b 3881sub vmconfig_hotplug_pending {
3a11fadb 3882 my ($vmid, $conf, $storecfg, $selection, $errors) = @_;
c427973b 3883
8e90138a 3884 my $defaults = load_defaults();
c427973b
DM
3885
3886 # commit values which do not have any impact on running VM first
3a11fadb
DM
3887 # Note: those option cannot raise errors, we we do not care about
3888 # $selection and always apply them.
3889
3890 my $add_error = sub {
3891 my ($opt, $msg) = @_;
3892 $errors->{$opt} = "hotplug problem - $msg";
3893 };
c427973b
DM
3894
3895 my $changes = 0;
3896 foreach my $opt (keys %{$conf->{pending}}) { # add/change
81d95ae1 3897 if ($fast_plug_option->{$opt}) {
c427973b
DM
3898 $conf->{$opt} = $conf->{pending}->{$opt};
3899 delete $conf->{pending}->{$opt};
3900 $changes = 1;
3901 }
3902 }
3903
3904 if ($changes) {
3905 update_config_nolock($vmid, $conf, 1);
3906 $conf = load_config($vmid); # update/reload
3907 }
3908
b3c2bdd1 3909 my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
c427973b 3910
3d7389fe
DM
3911 my @delete = PVE::Tools::split_list($conf->{pending}->{delete});
3912 foreach my $opt (@delete) {
3a11fadb 3913 next if $selection && !$selection->{$opt};
3a11fadb 3914 eval {
51a6f637
AD
3915 if ($opt eq 'hotplug') {
3916 die "skip\n" if ($conf->{hotplug} =~ /memory/);
3917 } elsif ($opt eq 'tablet') {
b3c2bdd1 3918 die "skip\n" if !$hotplug_features->{usb};
3a11fadb
DM
3919 if ($defaults->{tablet}) {
3920 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3921 } else {
3922 vm_deviceunplug($vmid, $conf, $opt);
3923 }
8edc9c08 3924 } elsif ($opt eq 'vcpus') {
b3c2bdd1 3925 die "skip\n" if !$hotplug_features->{cpu};
8edc9c08 3926 qemu_cpu_hotplug($vmid, $conf, undef);
9c2f7069 3927 } elsif ($opt eq 'balloon') {
81d95ae1
DM
3928 # enable balloon device is not hotpluggable
3929 die "skip\n" if !defined($conf->{balloon}) || $conf->{balloon};
3930 } elsif ($fast_plug_option->{$opt}) {
3931 # do nothing
3eec5767 3932 } elsif ($opt =~ m/^net(\d+)$/) {
b3c2bdd1 3933 die "skip\n" if !$hotplug_features->{network};
3eec5767 3934 vm_deviceunplug($vmid, $conf, $opt);
a05cff86 3935 } elsif (valid_drivename($opt)) {
b3c2bdd1 3936 die "skip\n" if !$hotplug_features->{disk} || $opt =~ m/(ide|sata)(\d+)/;
19120f99
AD
3937 vm_deviceunplug($vmid, $conf, $opt);
3938 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}));
4d3f29ed
AD
3939 } elsif ($opt =~ m/^memory$/) {
3940 die "skip\n" if !$hotplug_features->{memory};
3941 qemu_memory_hotplug($vmid, $conf, $defaults, $opt);
c8effec3
AD
3942 } elsif ($opt eq 'cpuunits') {
3943 cgroups_write("cpu", $vmid, "cpu.shares", $defaults->{cpuunits});
58be00f1
AD
3944 } elsif ($opt eq 'cpulimit') {
3945 cgroups_write("cpu", $vmid, "cpu.cfs_quota_us", -1);
3d7389fe 3946 } else {
e56beeda 3947 die "skip\n";
3d7389fe 3948 }
3a11fadb
DM
3949 };
3950 if (my $err = $@) {
e56beeda
DM
3951 &$add_error($opt, $err) if $err ne "skip\n";
3952 } else {
3a11fadb
DM
3953 # save new config if hotplug was successful
3954 delete $conf->{$opt};
3955 vmconfig_undelete_pending_option($conf, $opt);
3956 update_config_nolock($vmid, $conf, 1);
3957 $conf = load_config($vmid); # update/reload
3d7389fe 3958 }
3d7389fe
DM
3959 }
3960
3961 foreach my $opt (keys %{$conf->{pending}}) {
3a11fadb 3962 next if $selection && !$selection->{$opt};
3d7389fe 3963 my $value = $conf->{pending}->{$opt};
3a11fadb 3964 eval {
51a6f637
AD
3965 if ($opt eq 'hotplug') {
3966 die "skip\n" if ($value =~ /memory/) || ($value !~ /memory/ && $conf->{hotplug} =~ /memory/);
3967 } elsif ($opt eq 'tablet') {
b3c2bdd1 3968 die "skip\n" if !$hotplug_features->{usb};
3a11fadb
DM
3969 if ($value == 1) {
3970 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3971 } elsif ($value == 0) {
3972 vm_deviceunplug($vmid, $conf, $opt);
3973 }
8edc9c08 3974 } elsif ($opt eq 'vcpus') {
b3c2bdd1 3975 die "skip\n" if !$hotplug_features->{cpu};
3a11fadb
DM
3976 qemu_cpu_hotplug($vmid, $conf, $value);
3977 } elsif ($opt eq 'balloon') {
81d95ae1 3978 # enable/disable balloning device is not hotpluggable
8fe689e7 3979 my $old_balloon_enabled = !!(!defined($conf->{balloon}) || $conf->{balloon});
a1b7d579 3980 my $new_balloon_enabled = !!(!defined($conf->{pending}->{balloon}) || $conf->{pending}->{balloon});
81d95ae1
DM
3981 die "skip\n" if $old_balloon_enabled != $new_balloon_enabled;
3982
3a11fadb 3983 # allow manual ballooning if shares is set to zero
4cc1efa6 3984 if ((defined($conf->{shares}) && ($conf->{shares} == 0))) {
9c2f7069
AD
3985 my $balloon = $conf->{pending}->{balloon} || $conf->{memory} || $defaults->{memory};
3986 vm_mon_cmd($vmid, "balloon", value => $balloon*1024*1024);
3987 }
a1b7d579 3988 } elsif ($opt =~ m/^net(\d+)$/) {
3eec5767 3989 # some changes can be done without hotplug
a1b7d579 3990 vmconfig_update_net($storecfg, $conf, $hotplug_features->{network},
b3c2bdd1 3991 $vmid, $opt, $value);
a05cff86
DM
3992 } elsif (valid_drivename($opt)) {
3993 # some changes can be done without hotplug
b3c2bdd1
DM
3994 vmconfig_update_disk($storecfg, $conf, $hotplug_features->{disk},
3995 $vmid, $opt, $value, 1);
4d3f29ed
AD
3996 } elsif ($opt =~ m/^memory$/) { #dimms
3997 die "skip\n" if !$hotplug_features->{memory};
3998 $value = qemu_memory_hotplug($vmid, $conf, $defaults, $opt, $value);
c8effec3
AD
3999 } elsif ($opt eq 'cpuunits') {
4000 cgroups_write("cpu", $vmid, "cpu.shares", $conf->{pending}->{$opt});
58be00f1 4001 } elsif ($opt eq 'cpulimit') {
c6f773b8 4002 my $cpulimit = $conf->{pending}->{$opt} == 0 ? -1 : int($conf->{pending}->{$opt} * 100000);
58be00f1 4003 cgroups_write("cpu", $vmid, "cpu.cfs_quota_us", $cpulimit);
3a11fadb 4004 } else {
e56beeda 4005 die "skip\n"; # skip non-hot-pluggable options
3d7389fe 4006 }
3a11fadb
DM
4007 };
4008 if (my $err = $@) {
e56beeda
DM
4009 &$add_error($opt, $err) if $err ne "skip\n";
4010 } else {
3a11fadb
DM
4011 # save new config if hotplug was successful
4012 $conf->{$opt} = $value;
4013 delete $conf->{pending}->{$opt};
4014 update_config_nolock($vmid, $conf, 1);
4015 $conf = load_config($vmid); # update/reload
3d7389fe 4016 }
3d7389fe 4017 }
c427973b 4018}
055d554d
DM
4019
4020sub vmconfig_apply_pending {
3a11fadb 4021 my ($vmid, $conf, $storecfg) = @_;
c427973b
DM
4022
4023 # cold plug
055d554d
DM
4024
4025 my @delete = PVE::Tools::split_list($conf->{pending}->{delete});
4026 foreach my $opt (@delete) { # delete
4027 die "internal error" if $opt =~ m/^unused/;
4028 $conf = load_config($vmid); # update/reload
4029 if (!defined($conf->{$opt})) {
4030 vmconfig_undelete_pending_option($conf, $opt);
4031 update_config_nolock($vmid, $conf, 1);
4032 } elsif (valid_drivename($opt)) {
4033 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}));
4034 vmconfig_undelete_pending_option($conf, $opt);
4035 delete $conf->{$opt};
4036 update_config_nolock($vmid, $conf, 1);
4037 } else {
4038 vmconfig_undelete_pending_option($conf, $opt);
4039 delete $conf->{$opt};
4040 update_config_nolock($vmid, $conf, 1);
4041 }
4042 }
4043
4044 $conf = load_config($vmid); # update/reload
4045
4046 foreach my $opt (keys %{$conf->{pending}}) { # add/change
4047 $conf = load_config($vmid); # update/reload
4048
4049 if (defined($conf->{$opt}) && ($conf->{$opt} eq $conf->{pending}->{$opt})) {
4050 # skip if nothing changed
4051 } elsif (valid_drivename($opt)) {
4052 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}))
4053 if defined($conf->{$opt});
4054 $conf->{$opt} = $conf->{pending}->{$opt};
4055 } else {
4056 $conf->{$opt} = $conf->{pending}->{$opt};
4057 }
4058
4059 delete $conf->{pending}->{$opt};
4060 update_config_nolock($vmid, $conf, 1);
4061 }
4062}
4063
3eec5767
DM
4064my $safe_num_ne = sub {
4065 my ($a, $b) = @_;
4066
4067 return 0 if !defined($a) && !defined($b);
4068 return 1 if !defined($a);
4069 return 1 if !defined($b);
4070
4071 return $a != $b;
4072};
4073
4074my $safe_string_ne = sub {
4075 my ($a, $b) = @_;
4076
4077 return 0 if !defined($a) && !defined($b);
4078 return 1 if !defined($a);
4079 return 1 if !defined($b);
4080
4081 return $a ne $b;
4082};
4083
4084sub vmconfig_update_net {
b3c2bdd1 4085 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value) = @_;
3eec5767
DM
4086
4087 my $newnet = parse_net($value);
4088
4089 if ($conf->{$opt}) {
4090 my $oldnet = parse_net($conf->{$opt});
4091
4092 if (&$safe_string_ne($oldnet->{model}, $newnet->{model}) ||
4093 &$safe_string_ne($oldnet->{macaddr}, $newnet->{macaddr}) ||
4094 &$safe_num_ne($oldnet->{queues}, $newnet->{queues}) ||
4095 !($newnet->{bridge} && $oldnet->{bridge})) { # bridge/nat mode change
4096
4097 # for non online change, we try to hot-unplug
7196b757 4098 die "skip\n" if !$hotplug;
3eec5767
DM
4099 vm_deviceunplug($vmid, $conf, $opt);
4100 } else {
4101
4102 die "internal error" if $opt !~ m/net(\d+)/;
4103 my $iface = "tap${vmid}i$1";
a1b7d579 4104
3eec5767
DM
4105 if (&$safe_num_ne($oldnet->{rate}, $newnet->{rate})) {
4106 PVE::Network::tap_rate_limit($iface, $newnet->{rate});
4107 }
4108
25088687
DM
4109 if (&$safe_string_ne($oldnet->{bridge}, $newnet->{bridge}) ||
4110 &$safe_num_ne($oldnet->{tag}, $newnet->{tag}) ||
4111 &$safe_num_ne($oldnet->{firewall}, $newnet->{firewall})) {
3eec5767
DM
4112 PVE::Network::tap_unplug($iface);
4113 PVE::Network::tap_plug($iface, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall});
4114 }
38c590d9 4115
25088687
DM
4116 if (&$safe_string_ne($oldnet->{link_down}, $newnet->{link_down})) {
4117 qemu_set_link_status($vmid, $opt, !$newnet->{link_down});
4118 }
4119
38c590d9 4120 return 1;
3eec5767
DM
4121 }
4122 }
a1b7d579 4123
7196b757 4124 if ($hotplug) {
38c590d9
DM
4125 vm_deviceplug($storecfg, $conf, $vmid, $opt, $newnet);
4126 } else {
4127 die "skip\n";
4128 }
3eec5767
DM
4129}
4130
a05cff86 4131sub vmconfig_update_disk {
b3c2bdd1 4132 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value, $force) = @_;
a05cff86
DM
4133
4134 # fixme: do we need force?
4135
4136 my $drive = parse_drive($opt, $value);
4137
4138 if ($conf->{$opt}) {
4139
4140 if (my $old_drive = parse_drive($opt, $conf->{$opt})) {
4141
4142 my $media = $drive->{media} || 'disk';
4143 my $oldmedia = $old_drive->{media} || 'disk';
4144 die "unable to change media type\n" if $media ne $oldmedia;
4145
4146 if (!drive_is_cdrom($old_drive)) {
4147
a1b7d579 4148 if ($drive->{file} ne $old_drive->{file}) {
a05cff86 4149
7196b757 4150 die "skip\n" if !$hotplug;
a05cff86
DM
4151
4152 # unplug and register as unused
4153 vm_deviceunplug($vmid, $conf, $opt);
4154 vmconfig_register_unused_drive($storecfg, $vmid, $conf, $old_drive)
a1b7d579 4155
a05cff86
DM
4156 } else {
4157 # update existing disk
4158
4159 # skip non hotpluggable value
a1b7d579 4160 if (&$safe_num_ne($drive->{discard}, $old_drive->{discard}) ||
22de899a 4161 &$safe_string_ne($drive->{iothread}, $old_drive->{iothread}) ||
6e11f143 4162 &$safe_string_ne($drive->{queues}, $old_drive->{queues}) ||
a05cff86
DM
4163 &$safe_string_ne($drive->{cache}, $old_drive->{cache})) {
4164 die "skip\n";
4165 }
4166
4167 # apply throttle
4168 if (&$safe_num_ne($drive->{mbps}, $old_drive->{mbps}) ||
4169 &$safe_num_ne($drive->{mbps_rd}, $old_drive->{mbps_rd}) ||
4170 &$safe_num_ne($drive->{mbps_wr}, $old_drive->{mbps_wr}) ||
4171 &$safe_num_ne($drive->{iops}, $old_drive->{iops}) ||
4172 &$safe_num_ne($drive->{iops_rd}, $old_drive->{iops_rd}) ||
4173 &$safe_num_ne($drive->{iops_wr}, $old_drive->{iops_wr}) ||
4174 &$safe_num_ne($drive->{mbps_max}, $old_drive->{mbps_max}) ||
4175 &$safe_num_ne($drive->{mbps_rd_max}, $old_drive->{mbps_rd_max}) ||
4176 &$safe_num_ne($drive->{mbps_wr_max}, $old_drive->{mbps_wr_max}) ||
4177 &$safe_num_ne($drive->{iops_max}, $old_drive->{iops_max}) ||
4178 &$safe_num_ne($drive->{iops_rd_max}, $old_drive->{iops_rd_max}) ||
4179 &$safe_num_ne($drive->{iops_wr_max}, $old_drive->{iops_wr_max})) {
a1b7d579 4180
a05cff86
DM
4181 qemu_block_set_io_throttle($vmid,"drive-$opt",
4182 ($drive->{mbps} || 0)*1024*1024,
4183 ($drive->{mbps_rd} || 0)*1024*1024,
4184 ($drive->{mbps_wr} || 0)*1024*1024,
4185 $drive->{iops} || 0,
4186 $drive->{iops_rd} || 0,
4187 $drive->{iops_wr} || 0,
4188 ($drive->{mbps_max} || 0)*1024*1024,
4189 ($drive->{mbps_rd_max} || 0)*1024*1024,
4190 ($drive->{mbps_wr_max} || 0)*1024*1024,
4191 $drive->{iops_max} || 0,
4192 $drive->{iops_rd_max} || 0,
4193 $drive->{iops_wr_max} || 0);
4194
4195 }
a1b7d579 4196
a05cff86
DM
4197 return 1;
4198 }
4de1bb25
DM
4199
4200 } else { # cdrom
a1b7d579 4201
4de1bb25
DM
4202 if ($drive->{file} eq 'none') {
4203 vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt");
4204 } else {
4205 my $path = get_iso_path($storecfg, $vmid, $drive->{file});
4206 vm_mon_cmd($vmid, "eject", force => JSON::true,device => "drive-$opt"); # force eject if locked
4207 vm_mon_cmd($vmid, "change", device => "drive-$opt",target => "$path") if $path;
4208 }
a1b7d579 4209
34758d66 4210 return 1;
a05cff86
DM
4211 }
4212 }
4213 }
4214
a1b7d579 4215 die "skip\n" if !$hotplug || $opt =~ m/(ide|sata)(\d+)/;
4de1bb25
DM
4216 # hotplug new disks
4217 vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
a05cff86
DM
4218}
4219
1e3baf05 4220sub vm_start {
1d794448 4221 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
1e3baf05 4222
6b64503e 4223 lock_config($vmid, sub {
7e8dcf2c 4224 my $conf = load_config($vmid, $migratedfrom);
1e3baf05 4225
8b43bc11 4226 die "you can't start a vm if it's a template\n" if is_template($conf);
3dcb98d5 4227
6b64503e 4228 check_lock($conf) if !$skiplock;
1e3baf05 4229
7e8dcf2c 4230 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
1e3baf05 4231
055d554d 4232 if (!$statefile && scalar(keys %{$conf->{pending}})) {
3a11fadb 4233 vmconfig_apply_pending($vmid, $conf, $storecfg);
055d554d
DM
4234 $conf = load_config($vmid); # update/reload
4235 }
4236
6c47d546
DM
4237 my $defaults = load_defaults();
4238
4239 # set environment variable useful inside network script
4240 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
4241
1d794448 4242 my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
6c47d546 4243
1e3baf05 4244 my $migrate_port = 0;
5bc1e039 4245 my $migrate_uri;
1e3baf05
DM
4246 if ($statefile) {
4247 if ($statefile eq 'tcp') {
5bc1e039
SP
4248 my $localip = "localhost";
4249 my $datacenterconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
af0eba7e 4250 my $nodename = PVE::INotify::nodename();
5bc1e039 4251 if ($datacenterconf->{migration_unsecure}) {
5bc1e039
SP
4252 $localip = PVE::Cluster::remote_node_ip($nodename, 1);
4253 }
af0eba7e
WB
4254 my $pfamily = PVE::Tools::get_host_address_family($nodename);
4255 $migrate_port = PVE::Tools::next_migrate_port($pfamily);
2fbd27ea 4256 $migrate_uri = "tcp:[${localip}]:${migrate_port}";
6c47d546
DM
4257 push @$cmd, '-incoming', $migrate_uri;
4258 push @$cmd, '-S';
1e3baf05 4259 } else {
6c47d546 4260 push @$cmd, '-loadstate', $statefile;
1e3baf05 4261 }
91bd6c90
DM
4262 } elsif ($paused) {
4263 push @$cmd, '-S';
1e3baf05
DM
4264 }
4265
1e3baf05 4266 # host pci devices
040b06b7
DA
4267 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
4268 my $d = parse_hostpci($conf->{"hostpci$i"});
4269 next if !$d;
b1f72af6
AD
4270 my $pcidevices = $d->{pciid};
4271 foreach my $pcidevice (@$pcidevices) {
4272 my $pciid = $pcidevice->{id}.".".$pcidevice->{function};
000fc0a2 4273
b1f72af6
AD
4274 my $info = pci_device_info("0000:$pciid");
4275 die "IOMMU not present\n" if !check_iommu_support();
4276 die "no pci device info for device '$pciid'\n" if !$info;
000fc0a2 4277
b1f72af6
AD
4278 if ($d->{driver} && $d->{driver} eq "vfio") {
4279 die "can't unbind/bind pci group to vfio '$pciid'\n" if !pci_dev_group_bind_to_vfio($pciid);
4280 } else {
4281 die "can't unbind/bind to stub pci device '$pciid'\n" if !pci_dev_bind_to_stub($info);
4282 }
4283
8f3e88af 4284 die "can't reset pci device '$pciid'\n" if $info->{has_fl_reset} and !pci_dev_reset($info);
b1f72af6 4285 }
040b06b7 4286 }
1e3baf05
DM
4287
4288 PVE::Storage::activate_volumes($storecfg, $vollist);
4289
585b6e28
DM
4290 eval { run_command($cmd, timeout => $statefile ? undef : 30,
4291 umask => 0077); };
1e3baf05 4292 my $err = $@;
ff1a2432 4293 die "start failed: $err" if $err;
1e3baf05 4294
5bc1e039 4295 print "migration listens on $migrate_uri\n" if $migrate_uri;
afdb31d5 4296
8c609afd 4297 if ($statefile && $statefile ne 'tcp') {
95381ce0 4298 eval { vm_mon_cmd_nocheck($vmid, "cont"); };
8c609afd 4299 warn $@ if $@;
62de2cbd
DM
4300 }
4301
1d794448 4302 if ($migratedfrom) {
a89fded1
AD
4303
4304 eval {
8e90138a 4305 set_migration_caps($vmid);
a89fded1 4306 };
1d794448 4307 warn $@ if $@;
a89fded1 4308
1d794448
DM
4309 if ($spice_port) {
4310 print "spice listens on port $spice_port\n";
4311 if ($spice_ticket) {
8e90138a
DM
4312 vm_mon_cmd_nocheck($vmid, "set_password", protocol => 'spice', password => $spice_ticket);
4313 vm_mon_cmd_nocheck($vmid, "expire_password", protocol => 'spice', time => "+30");
95a4b4a9
AD
4314 }
4315 }
4316
1d794448 4317 } else {
4ec05c4c 4318
15b1fc93 4319 if (!$statefile && (!defined($conf->{balloon}) || $conf->{balloon})) {
be190583 4320 vm_mon_cmd_nocheck($vmid, "balloon", value => $conf->{balloon}*1024*1024)
4ec05c4c 4321 if $conf->{balloon};
4ec05c4c 4322 }
25088687
DM
4323
4324 foreach my $opt (keys %$conf) {
4325 next if $opt !~ m/^net\d+$/;
4326 my $nicconf = parse_net($conf->{$opt});
4327 qemu_set_link_status($vmid, $opt, 0) if $nicconf->{link_down};
4328 }
e18b0b99 4329 }
a1b7d579 4330
eb065317
AD
4331 vm_mon_cmd_nocheck($vmid, 'qom-set',
4332 path => "machine/peripheral/balloon0",
4333 property => "guest-stats-polling-interval",
4334 value => 2) if (!defined($conf->{balloon}) || $conf->{balloon});
4335
1e3baf05
DM
4336 });
4337}
4338
0eedc444
AD
4339sub vm_mon_cmd {
4340 my ($vmid, $execute, %params) = @_;
4341
26f11676
DM
4342 my $cmd = { execute => $execute, arguments => \%params };
4343 vm_qmp_command($vmid, $cmd);
0eedc444
AD
4344}
4345
4346sub vm_mon_cmd_nocheck {
4347 my ($vmid, $execute, %params) = @_;
4348
26f11676
DM
4349 my $cmd = { execute => $execute, arguments => \%params };
4350 vm_qmp_command($vmid, $cmd, 1);
0eedc444
AD
4351}
4352
c971c4f2 4353sub vm_qmp_command {
c5a07de5 4354 my ($vmid, $cmd, $nocheck) = @_;
97d62eb7 4355
c971c4f2 4356 my $res;
26f11676 4357
14db5366
DM
4358 my $timeout;
4359 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
4360 $timeout = $cmd->{arguments}->{timeout};
4361 delete $cmd->{arguments}->{timeout};
4362 }
be190583 4363
c971c4f2
AD
4364 eval {
4365 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
7a6c2150
DM
4366 my $sname = qmp_socket($vmid);
4367 if (-e $sname) { # test if VM is reasonambe new and supports qmp/qga
c5a07de5 4368 my $qmpclient = PVE::QMPClient->new();
dab36e1e 4369
14db5366 4370 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
c5a07de5 4371 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
dab36e1e
DM
4372 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
4373 if scalar(%{$cmd->{arguments}});
4374 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
4375 } else {
4376 die "unable to open monitor socket\n";
4377 }
c971c4f2 4378 };
26f11676 4379 if (my $err = $@) {
c971c4f2
AD
4380 syslog("err", "VM $vmid qmp command failed - $err");
4381 die $err;
4382 }
4383
4384 return $res;
4385}
4386
9df5cbcc
DM
4387sub vm_human_monitor_command {
4388 my ($vmid, $cmdline) = @_;
4389
4390 my $res;
4391
f5eb281a 4392 my $cmd = {
9df5cbcc
DM
4393 execute => 'human-monitor-command',
4394 arguments => { 'command-line' => $cmdline},
4395 };
4396
4397 return vm_qmp_command($vmid, $cmd);
4398}
4399
1e3baf05
DM
4400sub vm_commandline {
4401 my ($storecfg, $vmid) = @_;
4402
6b64503e 4403 my $conf = load_config($vmid);
1e3baf05
DM
4404
4405 my $defaults = load_defaults();
4406
6b64503e 4407 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 4408
6b64503e 4409 return join(' ', @$cmd);
1e3baf05
DM
4410}
4411
4412sub vm_reset {
4413 my ($vmid, $skiplock) = @_;
4414
6b64503e 4415 lock_config($vmid, sub {
1e3baf05 4416
6b64503e 4417 my $conf = load_config($vmid);
1e3baf05 4418
6b64503e 4419 check_lock($conf) if !$skiplock;
1e3baf05 4420
816e2c4a 4421 vm_mon_cmd($vmid, "system_reset");
ff1a2432
DM
4422 });
4423}
4424
4425sub get_vm_volumes {
4426 my ($conf) = @_;
1e3baf05 4427
ff1a2432 4428 my $vollist = [];
d5769dc2
DM
4429 foreach_volid($conf, sub {
4430 my ($volid, $is_cdrom) = @_;
ff1a2432 4431
d5769dc2 4432 return if $volid =~ m|^/|;
ff1a2432 4433
d5769dc2
DM
4434 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
4435 return if !$sid;
ff1a2432
DM
4436
4437 push @$vollist, $volid;
1e3baf05 4438 });
ff1a2432
DM
4439
4440 return $vollist;
4441}
4442
4443sub vm_stop_cleanup {
70b04821 4444 my ($storecfg, $vmid, $conf, $keepActive, $apply_pending_changes) = @_;
ff1a2432 4445
745fed70 4446 eval {
ff1a2432 4447
254575e9
DM
4448 if (!$keepActive) {
4449 my $vollist = get_vm_volumes($conf);
4450 PVE::Storage::deactivate_volumes($storecfg, $vollist);
4451 }
a1b7d579 4452
ab6a046f 4453 foreach my $ext (qw(mon qmp pid vnc qga)) {
961bfcb2
DM
4454 unlink "/var/run/qemu-server/${vmid}.$ext";
4455 }
a1b7d579 4456
70b04821 4457 vmconfig_apply_pending($vmid, $conf, $storecfg) if $apply_pending_changes;
745fed70
DM
4458 };
4459 warn $@ if $@; # avoid errors - just warn
1e3baf05
DM
4460}
4461
e6c3b671 4462# Note: use $nockeck to skip tests if VM configuration file exists.
254575e9
DM
4463# We need that when migration VMs to other nodes (files already moved)
4464# Note: we set $keepActive in vzdump stop mode - volumes need to stay active
1e3baf05 4465sub vm_stop {
af30308f 4466 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
9269013a 4467
9269013a 4468 $force = 1 if !defined($force) && !$shutdown;
1e3baf05 4469
af30308f
DM
4470 if ($migratedfrom){
4471 my $pid = check_running($vmid, $nocheck, $migratedfrom);
4472 kill 15, $pid if $pid;
4473 my $conf = load_config($vmid, $migratedfrom);
70b04821 4474 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 0);
af30308f
DM
4475 return;
4476 }
4477
e6c3b671 4478 lock_config($vmid, sub {
1e3baf05 4479
e6c3b671 4480 my $pid = check_running($vmid, $nocheck);
ff1a2432 4481 return if !$pid;
1e3baf05 4482
ff1a2432 4483 my $conf;
e6c3b671 4484 if (!$nocheck) {
ff1a2432 4485 $conf = load_config($vmid);
e6c3b671 4486 check_lock($conf) if !$skiplock;
7f4a5b5a 4487 if (!defined($timeout) && $shutdown && $conf->{startup}) {
38f7f26c 4488 my $opts = PVE::JSONSchema::pve_parse_startup_order($conf->{startup});
7f4a5b5a
DM
4489 $timeout = $opts->{down} if $opts->{down};
4490 }
e6c3b671 4491 }
19672434 4492
7f4a5b5a 4493 $timeout = 60 if !defined($timeout);
67fb9de6 4494
9269013a
DM
4495 eval {
4496 if ($shutdown) {
fbda7965 4497 if (defined($conf) && $conf->{agent}) {
2ea54503 4498 vm_qmp_command($vmid, { execute => "guest-shutdown" }, $nocheck);
1c0c1c17 4499 } else {
2ea54503 4500 vm_qmp_command($vmid, { execute => "system_powerdown" }, $nocheck);
1c0c1c17 4501 }
9269013a 4502 } else {
2ea54503 4503 vm_qmp_command($vmid, { execute => "quit" }, $nocheck);
afdb31d5 4504 }
9269013a 4505 };
1e3baf05
DM
4506 my $err = $@;
4507
4508 if (!$err) {
1e3baf05 4509 my $count = 0;
e6c3b671 4510 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
4511 $count++;
4512 sleep 1;
4513 }
4514
4515 if ($count >= $timeout) {
9269013a
DM
4516 if ($force) {
4517 warn "VM still running - terminating now with SIGTERM\n";
4518 kill 15, $pid;
4519 } else {
4520 die "VM quit/powerdown failed - got timeout\n";
4521 }
4522 } else {
70b04821 4523 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
9269013a 4524 return;
1e3baf05
DM
4525 }
4526 } else {
9269013a
DM
4527 if ($force) {
4528 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
4529 kill 15, $pid;
4530 } else {
afdb31d5 4531 die "VM quit/powerdown failed\n";
9269013a 4532 }
1e3baf05
DM
4533 }
4534
4535 # wait again
ff1a2432 4536 $timeout = 10;
1e3baf05
DM
4537
4538 my $count = 0;
e6c3b671 4539 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
4540 $count++;
4541 sleep 1;
4542 }
4543
4544 if ($count >= $timeout) {
ff1a2432 4545 warn "VM still running - terminating now with SIGKILL\n";
1e3baf05 4546 kill 9, $pid;
ff1a2432 4547 sleep 1;
1e3baf05
DM
4548 }
4549
70b04821 4550 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
ff1a2432 4551 });
1e3baf05
DM
4552}
4553
4554sub vm_suspend {
4555 my ($vmid, $skiplock) = @_;
4556
6b64503e 4557 lock_config($vmid, sub {
1e3baf05 4558
6b64503e 4559 my $conf = load_config($vmid);
1e3baf05 4560
051347aa 4561 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
bcb7c9cf 4562
f77f91f3 4563 vm_mon_cmd($vmid, "stop");
1e3baf05
DM
4564 });
4565}
4566
4567sub vm_resume {
4568 my ($vmid, $skiplock) = @_;
4569
6b64503e 4570 lock_config($vmid, sub {
1e3baf05 4571
6b64503e 4572 my $conf = load_config($vmid);
1e3baf05 4573
051347aa 4574 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
1e3baf05 4575
12060fe8 4576 vm_mon_cmd($vmid, "cont");
1e3baf05
DM
4577 });
4578}
4579
5fdbe4f0
DM
4580sub vm_sendkey {
4581 my ($vmid, $skiplock, $key) = @_;
1e3baf05 4582
6b64503e 4583 lock_config($vmid, sub {
1e3baf05 4584
6b64503e 4585 my $conf = load_config($vmid);
f5eb281a 4586
7b7c6d1b
DM
4587 # there is no qmp command, so we use the human monitor command
4588 vm_human_monitor_command($vmid, "sendkey $key");
1e3baf05
DM
4589 });
4590}
4591
4592sub vm_destroy {
4593 my ($storecfg, $vmid, $skiplock) = @_;
4594
6b64503e 4595 lock_config($vmid, sub {
1e3baf05 4596
6b64503e 4597 my $conf = load_config($vmid);
1e3baf05 4598
6b64503e 4599 check_lock($conf) if !$skiplock;
1e3baf05 4600
ff1a2432 4601 if (!check_running($vmid)) {
ff1a2432
DM
4602 destroy_vm($storecfg, $vmid);
4603 } else {
4604 die "VM $vmid is running - destroy failed\n";
1e3baf05
DM
4605 }
4606 });
4607}
4608
1e3baf05
DM
4609# pci helpers
4610
4611sub file_write {
4612 my ($filename, $buf) = @_;
4613
6b64503e 4614 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
4615 return undef if !$fh;
4616
4617 my $res = print $fh $buf;
4618
4619 $fh->close();
4620
4621 return $res;
4622}
4623
4624sub pci_device_info {
4625 my ($name) = @_;
4626
4627 my $res;
4628
4629 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
4630 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
4631
4632 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
4633 return undef if !defined($irq) || $irq !~ m/^\d+$/;
4634
4635 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
4636 return undef if !defined($vendor) || $vendor !~ s/^0x//;
4637
4638 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
4639 return undef if !defined($product) || $product !~ s/^0x//;
4640
4641 $res = {
4642 name => $name,
4643 vendor => $vendor,
4644 product => $product,
4645 domain => $domain,
4646 bus => $bus,
4647 slot => $slot,
4648 func => $func,
4649 irq => $irq,
4650 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
4651 };
4652
4653 return $res;
4654}
4655
4656sub pci_dev_reset {
4657 my ($dev) = @_;
4658
4659 my $name = $dev->{name};
4660
4661 my $fn = "$pcisysfs/devices/$name/reset";
4662
6b64503e 4663 return file_write($fn, "1");
1e3baf05
DM
4664}
4665
4666sub pci_dev_bind_to_stub {
4667 my ($dev) = @_;
4668
4669 my $name = $dev->{name};
4670
4671 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
4672 return 1 if -d $testdir;
4673
4674 my $data = "$dev->{vendor} $dev->{product}";
6b64503e 4675 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
1e3baf05
DM
4676
4677 my $fn = "$pcisysfs/devices/$name/driver/unbind";
6b64503e 4678 if (!file_write($fn, $name)) {
1e3baf05
DM
4679 return undef if -f $fn;
4680 }
4681
4682 $fn = "$pcisysfs/drivers/pci-stub/bind";
4683 if (! -d $testdir) {
6b64503e 4684 return undef if !file_write($fn, $name);
1e3baf05
DM
4685 }
4686
4687 return -d $testdir;
4688}
4689
000fc0a2
SP
4690sub pci_dev_bind_to_vfio {
4691 my ($dev) = @_;
4692
4693 my $name = $dev->{name};
4694
4695 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4696
4697 if (!-d $vfio_basedir) {
4698 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4699 }
4700 die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir;
4701
4702 my $testdir = "$vfio_basedir/$name";
4703 return 1 if -d $testdir;
4704
4705 my $data = "$dev->{vendor} $dev->{product}";
4706 return undef if !file_write("$vfio_basedir/new_id", $data);
4707
4708 my $fn = "$pcisysfs/devices/$name/driver/unbind";
4709 if (!file_write($fn, $name)) {
4710 return undef if -f $fn;
4711 }
4712
4713 $fn = "$vfio_basedir/bind";
4714 if (! -d $testdir) {
4715 return undef if !file_write($fn, $name);
4716 }
4717
4718 return -d $testdir;
4719}
4720
4721sub pci_dev_group_bind_to_vfio {
4722 my ($pciid) = @_;
4723
4724 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4725
4726 if (!-d $vfio_basedir) {
4727 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4728 }
4729 die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir;
4730
4731 # get IOMMU group devices
4732 opendir(my $D, "$pcisysfs/devices/0000:$pciid/iommu_group/devices/") || die "Cannot open iommu_group: $!\n";
4733 my @devs = grep /^0000:/, readdir($D);
4734 closedir($D);
4735
4736 foreach my $pciid (@devs) {
4737 $pciid =~ m/^([:\.\da-f]+)$/ or die "PCI ID $pciid not valid!\n";
f8fa2ed7
SP
4738
4739 # pci bridges, switches or root ports are not supported
4740 # they have a pci_bus subdirectory so skip them
4741 next if (-e "$pcisysfs/devices/$pciid/pci_bus");
4742
000fc0a2
SP
4743 my $info = pci_device_info($1);
4744 pci_dev_bind_to_vfio($info) || die "Cannot bind $pciid to vfio\n";
4745 }
4746
4747 return 1;
4748}
4749
afdb31d5 4750sub print_pci_addr {
5bdcf937 4751 my ($id, $bridges) = @_;
6b64503e 4752
72a063e4 4753 my $res = '';
6b64503e 4754 my $devices = {
24f0d39a 4755 piix3 => { bus => 0, addr => 1 },
e5f7f8ed 4756 #addr2 : first videocard
13b5a753 4757 balloon0 => { bus => 0, addr => 3 },
0a40e8ea 4758 watchdog => { bus => 0, addr => 4 },
a1b7d579 4759 scsihw0 => { bus => 0, addr => 5 },
6731a4cf 4760 'pci.3' => { bus => 0, addr => 5 }, #can also be used for virtio-scsi-single bridge
cdd20088 4761 scsihw1 => { bus => 0, addr => 6 },
26ee04b6 4762 ahci0 => { bus => 0, addr => 7 },
ab6a046f 4763 qga0 => { bus => 0, addr => 8 },
1011b570 4764 spice => { bus => 0, addr => 9 },
6b64503e
DM
4765 virtio0 => { bus => 0, addr => 10 },
4766 virtio1 => { bus => 0, addr => 11 },
4767 virtio2 => { bus => 0, addr => 12 },
4768 virtio3 => { bus => 0, addr => 13 },
4769 virtio4 => { bus => 0, addr => 14 },
4770 virtio5 => { bus => 0, addr => 15 },
b78ebef7
DA
4771 hostpci0 => { bus => 0, addr => 16 },
4772 hostpci1 => { bus => 0, addr => 17 },
f290f8d9
DA
4773 net0 => { bus => 0, addr => 18 },
4774 net1 => { bus => 0, addr => 19 },
4775 net2 => { bus => 0, addr => 20 },
4776 net3 => { bus => 0, addr => 21 },
4777 net4 => { bus => 0, addr => 22 },
4778 net5 => { bus => 0, addr => 23 },
2fa3151e
AD
4779 vga1 => { bus => 0, addr => 24 },
4780 vga2 => { bus => 0, addr => 25 },
4781 vga3 => { bus => 0, addr => 26 },
5cffb2d2
AD
4782 hostpci2 => { bus => 0, addr => 27 },
4783 hostpci3 => { bus => 0, addr => 28 },
e5f7f8ed 4784 #addr29 : usb-host (pve-usb.cfg)
5bdcf937
AD
4785 'pci.1' => { bus => 0, addr => 30 },
4786 'pci.2' => { bus => 0, addr => 31 },
4787 'net6' => { bus => 1, addr => 1 },
4788 'net7' => { bus => 1, addr => 2 },
4789 'net8' => { bus => 1, addr => 3 },
4790 'net9' => { bus => 1, addr => 4 },
4791 'net10' => { bus => 1, addr => 5 },
4792 'net11' => { bus => 1, addr => 6 },
4793 'net12' => { bus => 1, addr => 7 },
4794 'net13' => { bus => 1, addr => 8 },
4795 'net14' => { bus => 1, addr => 9 },
4796 'net15' => { bus => 1, addr => 10 },
4797 'net16' => { bus => 1, addr => 11 },
4798 'net17' => { bus => 1, addr => 12 },
4799 'net18' => { bus => 1, addr => 13 },
4800 'net19' => { bus => 1, addr => 14 },
4801 'net20' => { bus => 1, addr => 15 },
4802 'net21' => { bus => 1, addr => 16 },
4803 'net22' => { bus => 1, addr => 17 },
4804 'net23' => { bus => 1, addr => 18 },
4805 'net24' => { bus => 1, addr => 19 },
4806 'net25' => { bus => 1, addr => 20 },
4807 'net26' => { bus => 1, addr => 21 },
4808 'net27' => { bus => 1, addr => 22 },
4809 'net28' => { bus => 1, addr => 23 },
4810 'net29' => { bus => 1, addr => 24 },
4811 'net30' => { bus => 1, addr => 25 },
4812 'net31' => { bus => 1, addr => 26 },
4813 'virtio6' => { bus => 2, addr => 1 },
4814 'virtio7' => { bus => 2, addr => 2 },
4815 'virtio8' => { bus => 2, addr => 3 },
4816 'virtio9' => { bus => 2, addr => 4 },
4817 'virtio10' => { bus => 2, addr => 5 },
4818 'virtio11' => { bus => 2, addr => 6 },
4819 'virtio12' => { bus => 2, addr => 7 },
4820 'virtio13' => { bus => 2, addr => 8 },
4821 'virtio14' => { bus => 2, addr => 9 },
4822 'virtio15' => { bus => 2, addr => 10 },
6731a4cf
AD
4823 'virtioscsi0' => { bus => 3, addr => 1 },
4824 'virtioscsi1' => { bus => 3, addr => 2 },
4825 'virtioscsi2' => { bus => 3, addr => 3 },
4826 'virtioscsi3' => { bus => 3, addr => 4 },
4827 'virtioscsi4' => { bus => 3, addr => 5 },
4828 'virtioscsi5' => { bus => 3, addr => 6 },
4829 'virtioscsi6' => { bus => 3, addr => 7 },
4830 'virtioscsi7' => { bus => 3, addr => 8 },
4831 'virtioscsi8' => { bus => 3, addr => 9 },
4832 'virtioscsi9' => { bus => 3, addr => 10 },
4833 'virtioscsi10' => { bus => 3, addr => 11 },
4834 'virtioscsi11' => { bus => 3, addr => 12 },
4835 'virtioscsi12' => { bus => 3, addr => 13 },
4836 'virtioscsi13' => { bus => 3, addr => 14 },
4837 'virtioscsi14' => { bus => 3, addr => 15 },
4838 'virtioscsi15' => { bus => 3, addr => 16 },
4839 'virtioscsi16' => { bus => 3, addr => 17 },
4840 'virtioscsi17' => { bus => 3, addr => 18 },
4841 'virtioscsi18' => { bus => 3, addr => 19 },
4842 'virtioscsi19' => { bus => 3, addr => 20 },
4843 'virtioscsi20' => { bus => 3, addr => 21 },
4844 'virtioscsi21' => { bus => 3, addr => 22 },
4845 'virtioscsi22' => { bus => 3, addr => 23 },
4846 'virtioscsi23' => { bus => 3, addr => 24 },
4847 'virtioscsi24' => { bus => 3, addr => 25 },
4848 'virtioscsi25' => { bus => 3, addr => 26 },
4849 'virtioscsi26' => { bus => 3, addr => 27 },
4850 'virtioscsi27' => { bus => 3, addr => 28 },
4851 'virtioscsi28' => { bus => 3, addr => 29 },
4852 'virtioscsi29' => { bus => 3, addr => 30 },
4853 'virtioscsi30' => { bus => 3, addr => 31 },
4854
6b64503e
DM
4855 };
4856
4857 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
72a063e4 4858 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
5bdcf937
AD
4859 my $bus = $devices->{$id}->{bus};
4860 $res = ",bus=pci.$bus,addr=$addr";
98627641 4861 $bridges->{$bus} = 1 if $bridges;
72a063e4
DA
4862 }
4863 return $res;
4864
4865}
4866
2e3b7e2a
AD
4867sub print_pcie_addr {
4868 my ($id) = @_;
4869
4870 my $res = '';
4871 my $devices = {
4872 hostpci0 => { bus => "ich9-pcie-port-1", addr => 0 },
4873 hostpci1 => { bus => "ich9-pcie-port-2", addr => 0 },
4874 hostpci2 => { bus => "ich9-pcie-port-3", addr => 0 },
4875 hostpci3 => { bus => "ich9-pcie-port-4", addr => 0 },
4876 };
4877
4878 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
4879 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
4880 my $bus = $devices->{$id}->{bus};
4881 $res = ",bus=$bus,addr=$addr";
4882 }
4883 return $res;
4884
4885}
4886
3e16d5fc
DM
4887# vzdump restore implementaion
4888
ed221350 4889sub tar_archive_read_firstfile {
3e16d5fc 4890 my $archive = shift;
afdb31d5 4891
3e16d5fc
DM
4892 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
4893
4894 # try to detect archive type first
4895 my $pid = open (TMP, "tar tf '$archive'|") ||
4896 die "unable to open file '$archive'\n";
4897 my $firstfile = <TMP>;
4898 kill 15, $pid;
4899 close TMP;
4900
4901 die "ERROR: archive contaions no data\n" if !$firstfile;
4902 chomp $firstfile;
4903
4904 return $firstfile;
4905}
4906
ed221350
DM
4907sub tar_restore_cleanup {
4908 my ($storecfg, $statfile) = @_;
3e16d5fc
DM
4909
4910 print STDERR "starting cleanup\n";
4911
4912 if (my $fd = IO::File->new($statfile, "r")) {
4913 while (defined(my $line = <$fd>)) {
4914 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
4915 my $volid = $2;
4916 eval {
4917 if ($volid =~ m|^/|) {
4918 unlink $volid || die 'unlink failed\n';
4919 } else {
ed221350 4920 PVE::Storage::vdisk_free($storecfg, $volid);
3e16d5fc 4921 }
afdb31d5 4922 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3e16d5fc
DM
4923 };
4924 print STDERR "unable to cleanup '$volid' - $@" if $@;
4925 } else {
4926 print STDERR "unable to parse line in statfile - $line";
afdb31d5 4927 }
3e16d5fc
DM
4928 }
4929 $fd->close();
4930 }
4931}
4932
4933sub restore_archive {
a0d1b1a2 4934 my ($archive, $vmid, $user, $opts) = @_;
3e16d5fc 4935
91bd6c90
DM
4936 my $format = $opts->{format};
4937 my $comp;
4938
4939 if ($archive =~ m/\.tgz$/ || $archive =~ m/\.tar\.gz$/) {
4940 $format = 'tar' if !$format;
4941 $comp = 'gzip';
4942 } elsif ($archive =~ m/\.tar$/) {
4943 $format = 'tar' if !$format;
4944 } elsif ($archive =~ m/.tar.lzo$/) {
4945 $format = 'tar' if !$format;
4946 $comp = 'lzop';
4947 } elsif ($archive =~ m/\.vma$/) {
4948 $format = 'vma' if !$format;
4949 } elsif ($archive =~ m/\.vma\.gz$/) {
4950 $format = 'vma' if !$format;
4951 $comp = 'gzip';
4952 } elsif ($archive =~ m/\.vma\.lzo$/) {
4953 $format = 'vma' if !$format;
4954 $comp = 'lzop';
4955 } else {
4956 $format = 'vma' if !$format; # default
4957 }
4958
4959 # try to detect archive format
4960 if ($format eq 'tar') {
4961 return restore_tar_archive($archive, $vmid, $user, $opts);
4962 } else {
4963 return restore_vma_archive($archive, $vmid, $user, $opts, $comp);
4964 }
4965}
4966
4967sub restore_update_config_line {
4968 my ($outfd, $cookie, $vmid, $map, $line, $unique) = @_;
4969
4970 return if $line =~ m/^\#qmdump\#/;
4971 return if $line =~ m/^\#vzdump\#/;
4972 return if $line =~ m/^lock:/;
4973 return if $line =~ m/^unused\d+:/;
4974 return if $line =~ m/^parent:/;
ca3e4fa4 4975 return if $line =~ m/^template:/; # restored VM is never a template
91bd6c90
DM
4976
4977 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
4978 # try to convert old 1.X settings
4979 my ($id, $ind, $ethcfg) = ($1, $2, $3);
4980 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
4981 my ($model, $macaddr) = split(/\=/, $devconfig);
4982 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $unique;
4983 my $net = {
4984 model => $model,
4985 bridge => "vmbr$ind",
4986 macaddr => $macaddr,
4987 };
4988 my $netstr = print_net($net);
4989
4990 print $outfd "net$cookie->{netcount}: $netstr\n";
4991 $cookie->{netcount}++;
4992 }
4993 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && $unique) {
4994 my ($id, $netstr) = ($1, $2);
4995 my $net = parse_net($netstr);
4996 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
4997 $netstr = print_net($net);
4998 print $outfd "$id: $netstr\n";
4999 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
5000 my $virtdev = $1;
907ea891 5001 my $value = $3;
91bd6c90
DM
5002 if ($line =~ m/backup=no/) {
5003 print $outfd "#$line";
5004 } elsif ($virtdev && $map->{$virtdev}) {
ed221350 5005 my $di = parse_drive($virtdev, $value);
8fd57431 5006 delete $di->{format}; # format can change on restore
91bd6c90 5007 $di->{file} = $map->{$virtdev};
ed221350 5008 $value = print_drive($vmid, $di);
91bd6c90
DM
5009 print $outfd "$virtdev: $value\n";
5010 } else {
5011 print $outfd $line;
5012 }
5013 } else {
5014 print $outfd $line;
5015 }
5016}
5017
5018sub scan_volids {
5019 my ($cfg, $vmid) = @_;
5020
5021 my $info = PVE::Storage::vdisk_list($cfg, undef, $vmid);
5022
5023 my $volid_hash = {};
5024 foreach my $storeid (keys %$info) {
5025 foreach my $item (@{$info->{$storeid}}) {
5026 next if !($item->{volid} && $item->{size});
5996a936 5027 $item->{path} = PVE::Storage::path($cfg, $item->{volid});
91bd6c90
DM
5028 $volid_hash->{$item->{volid}} = $item;
5029 }
5030 }
5031
5032 return $volid_hash;
5033}
5034
a8e2f942
DM
5035sub get_used_paths {
5036 my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
5037
5038 my $used_path = {};
5039
5040 my $scan_config = sub {
5041 my ($cref, $snapname) = @_;
5042
5043 foreach my $key (keys %$cref) {
5044 my $value = $cref->{$key};
5045 if (valid_drivename($key)) {
5046 next if $skip_drive && $key eq $skip_drive;
5047 my $drive = parse_drive($key, $value);
5048 next if !$drive || !$drive->{file} || drive_is_cdrom($drive);
5049 if ($drive->{file} =~ m!^/!) {
5050 $used_path->{$drive->{file}}++; # = 1;
5051 } else {
5052 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
5053 next if !$storeid;
5054 my $scfg = PVE::Storage::storage_config($storecfg, $storeid, 1);
5055 next if !$scfg;
5056 my $path = PVE::Storage::path($storecfg, $drive->{file}, $snapname);
5057 $used_path->{$path}++; # = 1;
5058 }
5059 }
5060 }
5061 };
5062
5063 &$scan_config($conf);
5064
5065 undef $skip_drive;
5066
5067 if ($scan_snapshots) {
5068 foreach my $snapname (keys %{$conf->{snapshots}}) {
5069 &$scan_config($conf->{snapshots}->{$snapname}, $snapname);
5070 }
5071 }
5072
5073 return $used_path;
5074}
5075
91bd6c90
DM
5076sub update_disksize {
5077 my ($vmid, $conf, $volid_hash) = @_;
be190583 5078
91bd6c90
DM
5079 my $changes;
5080
5081 my $used = {};
5082
5996a936
DM
5083 # Note: it is allowed to define multiple storages with same path (alias), so
5084 # we need to check both 'volid' and real 'path' (two different volid can point
5085 # to the same path).
5086
5087 my $usedpath = {};
be190583 5088
91bd6c90
DM
5089 # update size info
5090 foreach my $opt (keys %$conf) {
ed221350
DM
5091 if (valid_drivename($opt)) {
5092 my $drive = parse_drive($opt, $conf->{$opt});
91bd6c90
DM
5093 my $volid = $drive->{file};
5094 next if !$volid;
5095
5096 $used->{$volid} = 1;
be190583 5097 if ($volid_hash->{$volid} &&
5996a936
DM
5098 (my $path = $volid_hash->{$volid}->{path})) {
5099 $usedpath->{$path} = 1;
5100 }
91bd6c90 5101
ed221350 5102 next if drive_is_cdrom($drive);
91bd6c90
DM
5103 next if !$volid_hash->{$volid};
5104
5105 $drive->{size} = $volid_hash->{$volid}->{size};
7a907ce6
DM
5106 my $new = print_drive($vmid, $drive);
5107 if ($new ne $conf->{$opt}) {
5108 $changes = 1;
5109 $conf->{$opt} = $new;
5110 }
91bd6c90
DM
5111 }
5112 }
5113
5996a936
DM
5114 # remove 'unusedX' entry if volume is used
5115 foreach my $opt (keys %$conf) {
5116 next if $opt !~ m/^unused\d+$/;
5117 my $volid = $conf->{$opt};
5118 my $path = $volid_hash->{$volid}->{path} if $volid_hash->{$volid};
be190583 5119 if ($used->{$volid} || ($path && $usedpath->{$path})) {
5996a936
DM
5120 $changes = 1;
5121 delete $conf->{$opt};
5122 }
5123 }
5124
91bd6c90
DM
5125 foreach my $volid (sort keys %$volid_hash) {
5126 next if $volid =~ m/vm-$vmid-state-/;
5127 next if $used->{$volid};
5996a936
DM
5128 my $path = $volid_hash->{$volid}->{path};
5129 next if !$path; # just to be sure
5130 next if $usedpath->{$path};
91bd6c90 5131 $changes = 1;
ed221350 5132 add_unused_volume($conf, $volid);
05937a14 5133 $usedpath->{$path} = 1; # avoid to add more than once (aliases)
91bd6c90
DM
5134 }
5135
5136 return $changes;
5137}
5138
5139sub rescan {
5140 my ($vmid, $nolock) = @_;
5141
5142 my $cfg = PVE::Cluster::cfs_read_file("storage.cfg");
5143
5144 my $volid_hash = scan_volids($cfg, $vmid);
5145
5146 my $updatefn = sub {
5147 my ($vmid) = @_;
5148
ed221350 5149 my $conf = load_config($vmid);
be190583 5150
ed221350 5151 check_lock($conf);
91bd6c90 5152
03da3f0d
DM
5153 my $vm_volids = {};
5154 foreach my $volid (keys %$volid_hash) {
5155 my $info = $volid_hash->{$volid};
5156 $vm_volids->{$volid} = $info if $info->{vmid} && $info->{vmid} == $vmid;
5157 }
5158
5159 my $changes = update_disksize($vmid, $conf, $vm_volids);
91bd6c90 5160
ed221350 5161 update_config_nolock($vmid, $conf, 1) if $changes;
91bd6c90
DM
5162 };
5163
5164 if (defined($vmid)) {
5165 if ($nolock) {
5166 &$updatefn($vmid);
5167 } else {
ed221350 5168 lock_config($vmid, $updatefn, $vmid);
91bd6c90
DM
5169 }
5170 } else {
5171 my $vmlist = config_list();
5172 foreach my $vmid (keys %$vmlist) {
5173 if ($nolock) {
5174 &$updatefn($vmid);
5175 } else {
ed221350 5176 lock_config($vmid, $updatefn, $vmid);
be190583 5177 }
91bd6c90
DM
5178 }
5179 }
5180}
5181
5182sub restore_vma_archive {
5183 my ($archive, $vmid, $user, $opts, $comp) = @_;
5184
5185 my $input = $archive eq '-' ? "<&STDIN" : undef;
5186 my $readfrom = $archive;
5187
5188 my $uncomp = '';
5189 if ($comp) {
5190 $readfrom = '-';
5191 my $qarchive = PVE::Tools::shellquote($archive);
5192 if ($comp eq 'gzip') {
5193 $uncomp = "zcat $qarchive|";
5194 } elsif ($comp eq 'lzop') {
5195 $uncomp = "lzop -d -c $qarchive|";
5196 } else {
5197 die "unknown compression method '$comp'\n";
5198 }
be190583 5199
91bd6c90
DM
5200 }
5201
5202 my $tmpdir = "/var/tmp/vzdumptmp$$";
5203 rmtree $tmpdir;
5204
5205 # disable interrupts (always do cleanups)
5206 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
5207 warn "got interrupt - ignored\n";
5208 };
5209
5210 my $mapfifo = "/var/tmp/vzdumptmp$$.fifo";
5211 POSIX::mkfifo($mapfifo, 0600);
5212 my $fifofh;
5213
5214 my $openfifo = sub {
5215 open($fifofh, '>', $mapfifo) || die $!;
5216 };
5217
5218 my $cmd = "${uncomp}vma extract -v -r $mapfifo $readfrom $tmpdir";
5219
5220 my $oldtimeout;
5221 my $timeout = 5;
5222
5223 my $devinfo = {};
5224
5225 my $rpcenv = PVE::RPCEnvironment::get();
5226
ed221350 5227 my $conffile = config_file($vmid);
91bd6c90
DM
5228 my $tmpfn = "$conffile.$$.tmp";
5229
ed221350
DM
5230 # Note: $oldconf is undef if VM does not exists
5231 my $oldconf = PVE::Cluster::cfs_read_file(cfs_config_path($vmid));
5232
91bd6c90
DM
5233 my $print_devmap = sub {
5234 my $virtdev_hash = {};
5235
5236 my $cfgfn = "$tmpdir/qemu-server.conf";
5237
5238 # we can read the config - that is already extracted
5239 my $fh = IO::File->new($cfgfn, "r") ||
5240 "unable to read qemu-server.conf - $!\n";
5241
5242 while (defined(my $line = <$fh>)) {
5243 if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
5244 my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
5245 die "archive does not contain data for drive '$virtdev'\n"
5246 if !$devinfo->{$devname};
5247 if (defined($opts->{storage})) {
5248 $storeid = $opts->{storage} || 'local';
5249 } elsif (!$storeid) {
5250 $storeid = 'local';
5251 }
5252 $format = 'raw' if !$format;
5253 $devinfo->{$devname}->{devname} = $devname;
5254 $devinfo->{$devname}->{virtdev} = $virtdev;
5255 $devinfo->{$devname}->{format} = $format;
5256 $devinfo->{$devname}->{storeid} = $storeid;
5257
be190583 5258 # check permission on storage
91bd6c90
DM
5259 my $pool = $opts->{pool}; # todo: do we need that?
5260 if ($user ne 'root@pam') {
5261 $rpcenv->check($user, "/storage/$storeid", ['Datastore.AllocateSpace']);
5262 }
5263
5264 $virtdev_hash->{$virtdev} = $devinfo->{$devname};
5265 }
5266 }
5267
5268 foreach my $devname (keys %$devinfo) {
be190583
DM
5269 die "found no device mapping information for device '$devname'\n"
5270 if !$devinfo->{$devname}->{virtdev};
91bd6c90
DM
5271 }
5272
91bd6c90 5273 my $cfg = cfs_read_file('storage.cfg');
ed221350
DM
5274
5275 # create empty/temp config
be190583 5276 if ($oldconf) {
ed221350
DM
5277 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
5278 foreach_drive($oldconf, sub {
5279 my ($ds, $drive) = @_;
5280
5281 return if drive_is_cdrom($drive);
5282
5283 my $volid = $drive->{file};
5284
5285 return if !$volid || $volid =~ m|^/|;
5286
5287 my ($path, $owner) = PVE::Storage::path($cfg, $volid);
5288 return if !$path || !$owner || ($owner != $vmid);
5289
5290 # Note: only delete disk we want to restore
5291 # other volumes will become unused
5292 if ($virtdev_hash->{$ds}) {
5293 PVE::Storage::vdisk_free($cfg, $volid);
5294 }
5295 });
5296 }
5297
5298 my $map = {};
91bd6c90
DM
5299 foreach my $virtdev (sort keys %$virtdev_hash) {
5300 my $d = $virtdev_hash->{$virtdev};
5301 my $alloc_size = int(($d->{size} + 1024 - 1)/1024);
5302 my $scfg = PVE::Storage::storage_config($cfg, $d->{storeid});
8fd57431
DM
5303
5304 # test if requested format is supported
5305 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($cfg, $d->{storeid});
5306 my $supported = grep { $_ eq $d->{format} } @$validFormats;
5307 $d->{format} = $defFormat if !$supported;
5308
91bd6c90
DM
5309 my $volid = PVE::Storage::vdisk_alloc($cfg, $d->{storeid}, $vmid,
5310 $d->{format}, undef, $alloc_size);
5311 print STDERR "new volume ID is '$volid'\n";
5312 $d->{volid} = $volid;
5313 my $path = PVE::Storage::path($cfg, $volid);
5314
5315 my $write_zeros = 1;
5316 # fixme: what other storages types initialize volumes with zero?
244f2577 5317 if ($scfg->{type} eq 'dir' || $scfg->{type} eq 'nfs' || $scfg->{type} eq 'glusterfs' ||
013d5275 5318 $scfg->{type} eq 'sheepdog' || $scfg->{type} eq 'rbd') {
91bd6c90
DM
5319 $write_zeros = 0;
5320 }
5321
5322 print $fifofh "${write_zeros}:$d->{devname}=$path\n";
5323
5324 print "map '$d->{devname}' to '$path' (write zeros = ${write_zeros})\n";
5325 $map->{$virtdev} = $volid;
5326 }
5327
5328 $fh->seek(0, 0) || die "seek failed - $!\n";
5329
5330 my $outfd = new IO::File ($tmpfn, "w") ||
5331 die "unable to write config for VM $vmid\n";
5332
5333 my $cookie = { netcount => 0 };
5334 while (defined(my $line = <$fh>)) {
be190583 5335 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
91bd6c90
DM
5336 }
5337
5338 $fh->close();
5339 $outfd->close();
5340 };
5341
5342 eval {
5343 # enable interrupts
5344 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
5345 die "interrupted by signal\n";
5346 };
5347 local $SIG{ALRM} = sub { die "got timeout\n"; };
5348
5349 $oldtimeout = alarm($timeout);
5350
5351 my $parser = sub {
5352 my $line = shift;
5353
5354 print "$line\n";
5355
5356 if ($line =~ m/^DEV:\sdev_id=(\d+)\ssize:\s(\d+)\sdevname:\s(\S+)$/) {
5357 my ($dev_id, $size, $devname) = ($1, $2, $3);
5358 $devinfo->{$devname} = { size => $size, dev_id => $dev_id };
5359 } elsif ($line =~ m/^CTIME: /) {
46f58b5f 5360 # we correctly received the vma config, so we can disable
3cf90d7a
DM
5361 # the timeout now for disk allocation (set to 10 minutes, so
5362 # that we always timeout if something goes wrong)
5363 alarm(600);
91bd6c90
DM
5364 &$print_devmap();
5365 print $fifofh "done\n";
5366 my $tmp = $oldtimeout || 0;
5367 $oldtimeout = undef;
5368 alarm($tmp);
5369 close($fifofh);
5370 }
5371 };
be190583 5372
91bd6c90
DM
5373 print "restore vma archive: $cmd\n";
5374 run_command($cmd, input => $input, outfunc => $parser, afterfork => $openfifo);
5375 };
5376 my $err = $@;
5377
5378 alarm($oldtimeout) if $oldtimeout;
5379
5380 unlink $mapfifo;
5381
5382 if ($err) {
5383 rmtree $tmpdir;
5384 unlink $tmpfn;
5385
5386 my $cfg = cfs_read_file('storage.cfg');
5387 foreach my $devname (keys %$devinfo) {
5388 my $volid = $devinfo->{$devname}->{volid};
5389 next if !$volid;
5390 eval {
5391 if ($volid =~ m|^/|) {
5392 unlink $volid || die 'unlink failed\n';
5393 } else {
5394 PVE::Storage::vdisk_free($cfg, $volid);
5395 }
5396 print STDERR "temporary volume '$volid' sucessfuly removed\n";
5397 };
5398 print STDERR "unable to cleanup '$volid' - $@" if $@;
5399 }
5400 die $err;
5401 }
5402
5403 rmtree $tmpdir;
ed221350
DM
5404
5405 rename($tmpfn, $conffile) ||
91bd6c90
DM
5406 die "unable to commit configuration file '$conffile'\n";
5407
ed221350
DM
5408 PVE::Cluster::cfs_update(); # make sure we read new file
5409
91bd6c90
DM
5410 eval { rescan($vmid, 1); };
5411 warn $@ if $@;
5412}
5413
5414sub restore_tar_archive {
5415 my ($archive, $vmid, $user, $opts) = @_;
5416
9c502e26 5417 if ($archive ne '-') {
ed221350 5418 my $firstfile = tar_archive_read_firstfile($archive);
9c502e26
DM
5419 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
5420 if $firstfile ne 'qemu-server.conf';
5421 }
3e16d5fc 5422
ed221350 5423 my $storecfg = cfs_read_file('storage.cfg');
ebb55558 5424
ed221350 5425 # destroy existing data - keep empty config
8e90138a 5426 my $vmcfgfn = config_file($vmid);
ebb55558 5427 destroy_vm($storecfg, $vmid, 1) if -f $vmcfgfn;
ed221350 5428
3e16d5fc
DM
5429 my $tocmd = "/usr/lib/qemu-server/qmextract";
5430
2415a446 5431 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 5432 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
5433 $tocmd .= ' --prealloc' if $opts->{prealloc};
5434 $tocmd .= ' --info' if $opts->{info};
5435
a0d1b1a2 5436 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 5437 # so we pipe to zcat
2415a446
DM
5438 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
5439 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
5440
5441 my $tmpdir = "/var/tmp/vzdumptmp$$";
5442 mkpath $tmpdir;
5443
5444 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
5445 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 5446 local $ENV{VZDUMP_USER} = $user;
3e16d5fc 5447
ed221350 5448 my $conffile = config_file($vmid);
3e16d5fc
DM
5449 my $tmpfn = "$conffile.$$.tmp";
5450
5451 # disable interrupts (always do cleanups)
5452 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
5453 print STDERR "got interrupt - ignored\n";
5454 };
5455
afdb31d5 5456 eval {
3e16d5fc
DM
5457 # enable interrupts
5458 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
5459 die "interrupted by signal\n";
5460 };
5461
9c502e26
DM
5462 if ($archive eq '-') {
5463 print "extracting archive from STDIN\n";
5464 run_command($cmd, input => "<&STDIN");
5465 } else {
5466 print "extracting archive '$archive'\n";
5467 run_command($cmd);
5468 }
3e16d5fc
DM
5469
5470 return if $opts->{info};
5471
5472 # read new mapping
5473 my $map = {};
5474 my $statfile = "$tmpdir/qmrestore.stat";
5475 if (my $fd = IO::File->new($statfile, "r")) {
5476 while (defined (my $line = <$fd>)) {
5477 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
5478 $map->{$1} = $2 if $1;
5479 } else {
5480 print STDERR "unable to parse line in statfile - $line\n";
5481 }
5482 }
5483 $fd->close();
5484 }
5485
5486 my $confsrc = "$tmpdir/qemu-server.conf";
5487
5488 my $srcfd = new IO::File($confsrc, "r") ||
5489 die "unable to open file '$confsrc'\n";
5490
5491 my $outfd = new IO::File ($tmpfn, "w") ||
5492 die "unable to write config for VM $vmid\n";
5493
91bd6c90 5494 my $cookie = { netcount => 0 };
3e16d5fc 5495 while (defined (my $line = <$srcfd>)) {
be190583 5496 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
3e16d5fc
DM
5497 }
5498
5499 $srcfd->close();
5500 $outfd->close();
5501 };
5502 my $err = $@;
5503
afdb31d5 5504 if ($err) {
3e16d5fc
DM
5505
5506 unlink $tmpfn;
5507
ed221350 5508 tar_restore_cleanup($storecfg, "$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 5509
3e16d5fc 5510 die $err;
afdb31d5 5511 }
3e16d5fc
DM
5512
5513 rmtree $tmpdir;
5514
5515 rename $tmpfn, $conffile ||
5516 die "unable to commit configuration file '$conffile'\n";
91bd6c90 5517
ed221350
DM
5518 PVE::Cluster::cfs_update(); # make sure we read new file
5519
91bd6c90
DM
5520 eval { rescan($vmid, 1); };
5521 warn $@ if $@;
3e16d5fc
DM
5522};
5523
0d18dcfc
DM
5524
5525# Internal snapshots
5526
5527# NOTE: Snapshot create/delete involves several non-atomic
5528# action, and can take a long time.
5529# So we try to avoid locking the file and use 'lock' variable
5530# inside the config file instead.
5531
ef59d1ca
DM
5532my $snapshot_copy_config = sub {
5533 my ($source, $dest) = @_;
5534
5535 foreach my $k (keys %$source) {
5536 next if $k eq 'snapshots';
982c7f12
DM
5537 next if $k eq 'snapstate';
5538 next if $k eq 'snaptime';
18bfb361 5539 next if $k eq 'vmstate';
ef59d1ca
DM
5540 next if $k eq 'lock';
5541 next if $k eq 'digest';
db7c26e5 5542 next if $k eq 'description';
ef59d1ca 5543 next if $k =~ m/^unused\d+$/;
be190583 5544
ef59d1ca
DM
5545 $dest->{$k} = $source->{$k};
5546 }
5547};
5548
5549my $snapshot_apply_config = sub {
5550 my ($conf, $snap) = @_;
5551
5552 # copy snapshot list
5553 my $newconf = {
5554 snapshots => $conf->{snapshots},
5555 };
5556
db7c26e5 5557 # keep description and list of unused disks
ef59d1ca 5558 foreach my $k (keys %$conf) {
db7c26e5 5559 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
ef59d1ca
DM
5560 $newconf->{$k} = $conf->{$k};
5561 }
5562
5563 &$snapshot_copy_config($snap, $newconf);
5564
5565 return $newconf;
5566};
5567
18bfb361
DM
5568sub foreach_writable_storage {
5569 my ($conf, $func) = @_;
5570
5571 my $sidhash = {};
5572
5573 foreach my $ds (keys %$conf) {
5574 next if !valid_drivename($ds);
5575
5576 my $drive = parse_drive($ds, $conf->{$ds});
5577 next if !$drive;
5578 next if drive_is_cdrom($drive);
5579
5580 my $volid = $drive->{file};
5581
5582 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
be190583 5583 $sidhash->{$sid} = $sid if $sid;
18bfb361
DM
5584 }
5585
5586 foreach my $sid (sort keys %$sidhash) {
5587 &$func($sid);
5588 }
5589}
5590
5591my $alloc_vmstate_volid = sub {
5592 my ($storecfg, $vmid, $conf, $snapname) = @_;
be190583 5593
18bfb361
DM
5594 # Note: we try to be smart when selecting a $target storage
5595
5596 my $target;
5597
5598 # search shared storage first
5599 foreach_writable_storage($conf, sub {
5600 my ($sid) = @_;
5601 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
5602 return if !$scfg->{shared};
5603
5604 $target = $sid if !$target || $scfg->{path}; # prefer file based storage
5605 });
5606
5607 if (!$target) {
5608 # now search local storage
5609 foreach_writable_storage($conf, sub {
5610 my ($sid) = @_;
5611 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
5612 return if $scfg->{shared};
5613
5614 $target = $sid if !$target || $scfg->{path}; # prefer file based storage;
5615 });
5616 }
5617
5618 $target = 'local' if !$target;
5619
fe6249f4
DM
5620 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
5621 # we abort live save after $conf->{memory}, so we need at max twice that space
5622 my $size = $conf->{memory}*2 + $driver_state_size;
18bfb361
DM
5623
5624 my $name = "vm-$vmid-state-$snapname";
5625 my $scfg = PVE::Storage::storage_config($storecfg, $target);
5626 $name .= ".raw" if $scfg->{path}; # add filename extension for file base storage
5627 my $volid = PVE::Storage::vdisk_alloc($storecfg, $target, $vmid, 'raw', $name, $size*1024);
5628
5629 return $volid;
5630};
5631
0d18dcfc 5632my $snapshot_prepare = sub {
18bfb361 5633 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
22c377f0
DM
5634
5635 my $snap;
0d18dcfc
DM
5636
5637 my $updatefn = sub {
5638
5639 my $conf = load_config($vmid);
5640
be190583 5641 die "you can't take a snapshot if it's a template\n"
5295b23d
DM
5642 if is_template($conf);
5643
0d18dcfc
DM
5644 check_lock($conf);
5645
22c377f0
DM
5646 $conf->{lock} = 'snapshot';
5647
be190583
DM
5648 die "snapshot name '$snapname' already used\n"
5649 if defined($conf->{snapshots}->{$snapname});
0d18dcfc 5650
ee2f90b1 5651 my $storecfg = PVE::Storage::config();
7ea975ef 5652 die "snapshot feature is not available" if !has_feature('snapshot', $conf, $storecfg);
18bfb361 5653
782f4f75 5654 $snap = $conf->{snapshots}->{$snapname} = {};
0d18dcfc 5655
18bfb361
DM
5656 if ($save_vmstate && check_running($vmid)) {
5657 $snap->{vmstate} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
5658 }
5659
ef59d1ca 5660 &$snapshot_copy_config($conf, $snap);
0d18dcfc 5661
782f4f75
DM
5662 $snap->{snapstate} = "prepare";
5663 $snap->{snaptime} = time();
5664 $snap->{description} = $comment if $comment;
5665
4b15803d
DM
5666 # always overwrite machine if we save vmstate. This makes sure we
5667 # can restore it later using correct machine type
5668 $snap->{machine} = get_current_qemu_machine($vmid) if $snap->{vmstate};
5669
0d18dcfc
DM
5670 update_config_nolock($vmid, $conf, 1);
5671 };
5672
5673 lock_config($vmid, $updatefn);
22c377f0
DM
5674
5675 return $snap;
0d18dcfc
DM
5676};
5677
5678my $snapshot_commit = sub {
5679 my ($vmid, $snapname) = @_;
5680
5681 my $updatefn = sub {
5682
5683 my $conf = load_config($vmid);
5684
be190583
DM
5685 die "missing snapshot lock\n"
5686 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
0d18dcfc 5687
7946e0fa
DM
5688 my $has_machine_config = defined($conf->{machine});
5689
0d18dcfc
DM
5690 my $snap = $conf->{snapshots}->{$snapname};
5691
be190583
DM
5692 die "snapshot '$snapname' does not exist\n" if !defined($snap);
5693
5694 die "wrong snapshot state\n"
5695 if !($snap->{snapstate} && $snap->{snapstate} eq "prepare");
0d18dcfc 5696
0d18dcfc 5697 delete $snap->{snapstate};
ee2f90b1 5698 delete $conf->{lock};
0d18dcfc 5699
ef59d1ca 5700 my $newconf = &$snapshot_apply_config($conf, $snap);
0d18dcfc 5701
7946e0fa
DM
5702 delete $newconf->{machine} if !$has_machine_config;
5703
05e5ad3f
DM
5704 $newconf->{parent} = $snapname;
5705
0d18dcfc
DM
5706 update_config_nolock($vmid, $newconf, 1);
5707 };
5708
5709 lock_config($vmid, $updatefn);
5710};
5711
22c377f0
DM
5712sub snapshot_rollback {
5713 my ($vmid, $snapname) = @_;
5714
22c377f0
DM
5715 my $prepare = 1;
5716
a3222b91 5717 my $storecfg = PVE::Storage::config();
be190583 5718
ba4eea15 5719 my $conf = load_config($vmid);
22c377f0 5720
ba4eea15 5721 my $get_snapshot_config = sub {
22c377f0 5722
8b43bc11 5723 die "you can't rollback if vm is a template\n" if is_template($conf);
90b0c6b3 5724
ba4eea15 5725 my $res = $conf->{snapshots}->{$snapname};
ab33a7c2 5726
ba4eea15
WL
5727 die "snapshot '$snapname' does not exist\n" if !defined($res);
5728
5729 return $res;
5730 };
5731
5732 my $snap = &$get_snapshot_config();
5733
5734 foreach_drive($snap, sub {
5735 my ($ds, $drive) = @_;
5736
5737 return if drive_is_cdrom($drive);
5738
5739 my $volid = $drive->{file};
5740
5741 PVE::Storage::volume_rollback_is_possible($storecfg, $volid, $snapname);
5742 });
5743
5744 my $updatefn = sub {
5745
5746 $conf = load_config($vmid);
5747
5748 $snap = &$get_snapshot_config();
ab33a7c2 5749
be190583 5750 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
ab33a7c2
DM
5751 if $snap->{snapstate};
5752
a3222b91
DM
5753 if ($prepare) {
5754 check_lock($conf);
5755 vm_stop($storecfg, $vmid, undef, undef, 5, undef, undef);
5756 }
22c377f0
DM
5757
5758 die "unable to rollback vm $vmid: vm is running\n"
5759 if check_running($vmid);
5760
5761 if ($prepare) {
5762 $conf->{lock} = 'rollback';
5763 } else {
5764 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
5765 delete $conf->{lock};
5766 }
5767
4b15803d
DM
5768 my $forcemachine;
5769
22c377f0 5770 if (!$prepare) {
4b15803d
DM
5771 my $has_machine_config = defined($conf->{machine});
5772
22c377f0 5773 # copy snapshot config to current config
ef59d1ca
DM
5774 $conf = &$snapshot_apply_config($conf, $snap);
5775 $conf->{parent} = $snapname;
4b15803d 5776
d8b916fd
DM
5777 # Note: old code did not store 'machine', so we try to be smart
5778 # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
5779 $forcemachine = $conf->{machine} || 'pc-i440fx-1.4';
be190583 5780 # we remove the 'machine' configuration if not explicitly specified
4b15803d
DM
5781 # in the original config.
5782 delete $conf->{machine} if $snap->{vmstate} && !$has_machine_config;
22c377f0
DM
5783 }
5784
5785 update_config_nolock($vmid, $conf, 1);
a3222b91
DM
5786
5787 if (!$prepare && $snap->{vmstate}) {
5788 my $statefile = PVE::Storage::path($storecfg, $snap->{vmstate});
4b15803d 5789 vm_start($storecfg, $vmid, $statefile, undef, undef, undef, $forcemachine);
a3222b91 5790 }
22c377f0
DM
5791 };
5792
5793 lock_config($vmid, $updatefn);
be190583 5794
22c377f0
DM
5795 foreach_drive($snap, sub {
5796 my ($ds, $drive) = @_;
5797
5798 return if drive_is_cdrom($drive);
5799
5800 my $volid = $drive->{file};
5801 my $device = "drive-$ds";
5802
79e57b29 5803 PVE::Storage::volume_snapshot_rollback($storecfg, $volid, $snapname);
22c377f0
DM
5804 });
5805
5806 $prepare = 0;
5807 lock_config($vmid, $updatefn);
5808}
5809
9dcf4909
DM
5810my $savevm_wait = sub {
5811 my ($vmid) = @_;
5812
5813 for(;;) {
ed221350 5814 my $stat = vm_mon_cmd_nocheck($vmid, "query-savevm");
9dcf4909
DM
5815 if (!$stat->{status}) {
5816 die "savevm not active\n";
5817 } elsif ($stat->{status} eq 'active') {
5818 sleep(1);
5819 next;
5820 } elsif ($stat->{status} eq 'completed') {
5821 last;
5822 } else {
5823 die "query-savevm returned status '$stat->{status}'\n";
5824 }
5825 }
5826};
5827
e5eaa028
WL
5828sub do_snapshots_with_qemu {
5829 my ($storecfg, $volid) = @_;
5830
5831 my $storage_name = PVE::Storage::parse_volume_id($volid);
5832
5833 if ($qemu_snap_storage->{$storecfg->{ids}->{$storage_name}->{type}} ){
5834 return 1;
5835 }
5836
5837 if ($volid =~ m/\.(qcow2|qed)$/){
5838 return 1;
5839 }
5840
5841 return undef;
5842}
5843
0d18dcfc 5844sub snapshot_create {
af9110dd 5845 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
0d18dcfc 5846
18bfb361 5847 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
0d18dcfc 5848
af9110dd 5849 $save_vmstate = 0 if !$snap->{vmstate}; # vm is not running
18bfb361 5850
67fb9de6
DM
5851 my $config = load_config($vmid);
5852
af9110dd
WL
5853 my $running = check_running($vmid);
5854
67fb9de6 5855 my $freezefs = $running && $config->{agent};
af9110dd
WL
5856 $freezefs = 0 if $snap->{vmstate}; # not needed if we save RAM
5857
5858 my $drivehash = {};
5859
5860 if ($freezefs) {
65994ad7
WL
5861 eval { vm_mon_cmd($vmid, "guest-fsfreeze-freeze"); };
5862 warn "guest-fsfreeze-freeze problems - $@" if $@;
5863 }
67fb9de6 5864
0d18dcfc
DM
5865 eval {
5866 # create internal snapshots of all drives
22c377f0
DM
5867
5868 my $storecfg = PVE::Storage::config();
a3222b91
DM
5869
5870 if ($running) {
5871 if ($snap->{vmstate}) {
be190583 5872 my $path = PVE::Storage::path($storecfg, $snap->{vmstate});
9dcf4909
DM
5873 vm_mon_cmd($vmid, "savevm-start", statefile => $path);
5874 &$savevm_wait($vmid);
a3222b91 5875 } else {
9dcf4909 5876 vm_mon_cmd($vmid, "savevm-start");
a3222b91
DM
5877 }
5878 };
5879
22c377f0
DM
5880 foreach_drive($snap, sub {
5881 my ($ds, $drive) = @_;
5882
5883 return if drive_is_cdrom($drive);
0d18dcfc 5884
22c377f0
DM
5885 my $volid = $drive->{file};
5886 my $device = "drive-$ds";
5887
5888 qemu_volume_snapshot($vmid, $device, $storecfg, $volid, $snapname);
3ee28e38 5889 $drivehash->{$ds} = 1;
22c377f0 5890 });
0d18dcfc 5891 };
22c377f0
DM
5892 my $err = $@;
5893
65994ad7
WL
5894 if ($running) {
5895 eval { vm_mon_cmd($vmid, "savevm-end") };
5896 warn $@ if $@;
22c377f0 5897
af9110dd 5898 if ($freezefs) {
67fb9de6 5899 eval { vm_mon_cmd($vmid, "guest-fsfreeze-thaw"); };
65994ad7
WL
5900 warn "guest-fsfreeze-thaw problems - $@" if $@;
5901 }
22c377f0 5902
65994ad7 5903 # savevm-end is async, we need to wait
f34ebd52 5904 for (;;) {
2c9e8036
AD
5905 my $stat = vm_mon_cmd_nocheck($vmid, "query-savevm");
5906 if (!$stat->{bytes}) {
5907 last;
5908 } else {
5909 print "savevm not yet finished\n";
5910 sleep(1);
5911 next;
5912 }
5913 }
5914 }
5915
22c377f0 5916 if ($err) {
0d18dcfc 5917 warn "snapshot create failed: starting cleanup\n";
3ee28e38 5918 eval { snapshot_delete($vmid, $snapname, 0, $drivehash); };
0d18dcfc
DM
5919 warn $@ if $@;
5920 die $err;
5921 }
5922
5923 &$snapshot_commit($vmid, $snapname);
5924}
5925
3ee28e38 5926# Note: $drivehash is only set when called from snapshot_create.
0d18dcfc 5927sub snapshot_delete {
3ee28e38 5928 my ($vmid, $snapname, $force, $drivehash) = @_;
0d18dcfc
DM
5929
5930 my $prepare = 1;
5931
22c377f0 5932 my $snap;
ee2f90b1 5933 my $unused = [];
0d18dcfc 5934
6cb1a8cf
DM
5935 my $unlink_parent = sub {
5936 my ($confref, $new_parent) = @_;
5937
5938 if ($confref->{parent} && $confref->{parent} eq $snapname) {
5939 if ($new_parent) {
5940 $confref->{parent} = $new_parent;
5941 } else {
5942 delete $confref->{parent};
5943 }
5944 }
5945 };
be190583 5946
0d18dcfc 5947 my $updatefn = sub {
2009f324 5948 my ($remove_drive) = @_;
0d18dcfc 5949
22c377f0 5950 my $conf = load_config($vmid);
0d18dcfc 5951
5295b23d
DM
5952 if (!$drivehash) {
5953 check_lock($conf);
be190583 5954 die "you can't delete a snapshot if vm is a template\n"
5295b23d
DM
5955 if is_template($conf);
5956 }
0d18dcfc 5957
22c377f0 5958 $snap = $conf->{snapshots}->{$snapname};
0d18dcfc 5959
be190583 5960 die "snapshot '$snapname' does not exist\n" if !defined($snap);
0d18dcfc
DM
5961
5962 # remove parent refs
8fd882a4
SP
5963 if (!$prepare) {
5964 &$unlink_parent($conf, $snap->{parent});
5965 foreach my $sn (keys %{$conf->{snapshots}}) {
5966 next if $sn eq $snapname;
5967 &$unlink_parent($conf->{snapshots}->{$sn}, $snap->{parent});
5968 }
0d18dcfc
DM
5969 }
5970
2009f324 5971 if ($remove_drive) {
18bfb361
DM
5972 if ($remove_drive eq 'vmstate') {
5973 delete $snap->{$remove_drive};
5974 } else {
5975 my $drive = parse_drive($remove_drive, $snap->{$remove_drive});
5976 my $volid = $drive->{file};
5977 delete $snap->{$remove_drive};
5978 add_unused_volume($conf, $volid);
5979 }
2009f324
DM
5980 }
5981
0d18dcfc
DM
5982 if ($prepare) {
5983 $snap->{snapstate} = 'delete';
5984 } else {
5985 delete $conf->{snapshots}->{$snapname};
3ee28e38 5986 delete $conf->{lock} if $drivehash;
ee2f90b1
DM
5987 foreach my $volid (@$unused) {
5988 add_unused_volume($conf, $volid);
5989 }
0d18dcfc
DM
5990 }
5991
5992 update_config_nolock($vmid, $conf, 1);
5993 };
5994
5995 lock_config($vmid, $updatefn);
5996
18bfb361 5997 # now remove vmstate file
0d18dcfc 5998
22c377f0
DM
5999 my $storecfg = PVE::Storage::config();
6000
18bfb361
DM
6001 if ($snap->{vmstate}) {
6002 eval { PVE::Storage::vdisk_free($storecfg, $snap->{vmstate}); };
6003 if (my $err = $@) {
6004 die $err if !$force;
6005 warn $err;
6006 }
6007 # save changes (remove vmstate from snapshot)
6008 lock_config($vmid, $updatefn, 'vmstate') if !$force;
6009 };
6010
6011 # now remove all internal snapshots
6012 foreach_drive($snap, sub {
22c377f0
DM
6013 my ($ds, $drive) = @_;
6014
6015 return if drive_is_cdrom($drive);
3ee28e38 6016
22c377f0
DM
6017 my $volid = $drive->{file};
6018 my $device = "drive-$ds";
6019
2009f324
DM
6020 if (!$drivehash || $drivehash->{$ds}) {
6021 eval { qemu_volume_snapshot_delete($vmid, $device, $storecfg, $volid, $snapname); };
6022 if (my $err = $@) {
6023 die $err if !$force;
6024 warn $err;
6025 }
3ee28e38 6026 }
2009f324
DM
6027
6028 # save changes (remove drive fron snapshot)
6029 lock_config($vmid, $updatefn, $ds) if !$force;
ee2f90b1 6030 push @$unused, $volid;
22c377f0 6031 });
0d18dcfc
DM
6032
6033 # now cleanup config
6034 $prepare = 0;
6035 lock_config($vmid, $updatefn);
6036}
6037
9cd07842 6038sub has_feature {
7ea975ef
AD
6039 my ($feature, $conf, $storecfg, $snapname, $running) = @_;
6040
719893a9 6041 my $err;
7ea975ef
AD
6042 foreach_drive($conf, sub {
6043 my ($ds, $drive) = @_;
6044
6045 return if drive_is_cdrom($drive);
6046 my $volid = $drive->{file};
6047 $err = 1 if !PVE::Storage::volume_has_feature($storecfg, $feature, $volid, $snapname, $running);
6048 });
6049
719893a9 6050 return $err ? 0 : 1;
7ea975ef 6051}
04a69bb4
AD
6052
6053sub template_create {
6054 my ($vmid, $conf, $disk) = @_;
6055
04a69bb4 6056 my $storecfg = PVE::Storage::config();
04a69bb4 6057
9cd07842
DM
6058 foreach_drive($conf, sub {
6059 my ($ds, $drive) = @_;
6060
6061 return if drive_is_cdrom($drive);
6062 return if $disk && $ds ne $disk;
6063
6064 my $volid = $drive->{file};
bbd56097 6065 return if !PVE::Storage::volume_has_feature($storecfg, 'template', $volid);
9cd07842 6066
04a69bb4
AD
6067 my $voliddst = PVE::Storage::vdisk_create_base($storecfg, $volid);
6068 $drive->{file} = $voliddst;
152fe752
DM
6069 $conf->{$ds} = print_drive($vmid, $drive);
6070 update_config_nolock($vmid, $conf, 1);
04a69bb4 6071 });
04a69bb4
AD
6072}
6073
624361b3
AD
6074sub is_template {
6075 my ($conf) = @_;
6076
96d695c0 6077 return 1 if defined $conf->{template} && $conf->{template} == 1;
624361b3
AD
6078}
6079
5133de42
AD
6080sub qemu_img_convert {
6081 my ($src_volid, $dst_volid, $size, $snapname) = @_;
6082
6083 my $storecfg = PVE::Storage::config();
6084 my ($src_storeid, $src_volname) = PVE::Storage::parse_volume_id($src_volid, 1);
6085 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid, 1);
6086
6087 if ($src_storeid && $dst_storeid) {
6088 my $src_scfg = PVE::Storage::storage_config($storecfg, $src_storeid);
6089 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
6090
6091 my $src_format = qemu_img_format($src_scfg, $src_volname);
6092 my $dst_format = qemu_img_format($dst_scfg, $dst_volname);
6093
6094 my $src_path = PVE::Storage::path($storecfg, $src_volid, $snapname);
6095 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
6096
6097 my $cmd = [];
71ddbff9 6098 push @$cmd, '/usr/bin/qemu-img', 'convert', '-t', 'writeback', '-p', '-n';
5133de42
AD
6099 push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
6100 push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path, $dst_path;
6101
6102 my $parser = sub {
6103 my $line = shift;
6104 if($line =~ m/\((\S+)\/100\%\)/){
6105 my $percent = $1;
6106 my $transferred = int($size * $percent / 100);
6107 my $remaining = $size - $transferred;
6108
6109 print "transferred: $transferred bytes remaining: $remaining bytes total: $size bytes progression: $percent %\n";
6110 }
6111
6112 };
6113
6114 eval { run_command($cmd, timeout => undef, outfunc => $parser); };
6115 my $err = $@;
6116 die "copy failed: $err" if $err;
6117 }
6118}
6119
6120sub qemu_img_format {
6121 my ($scfg, $volname) = @_;
6122
d81f0f09 6123 if ($scfg->{path} && $volname =~ m/\.(raw|cow|qcow|qcow2|qed|vmdk|cloop)$/) {
5133de42 6124 return $1;
be190583 6125 } else {
5133de42 6126 return "raw";
5133de42
AD
6127 }
6128}
6129
cfad42af 6130sub qemu_drive_mirror {
ab6ecffe 6131 my ($vmid, $drive, $dst_volid, $vmiddst) = @_;
cfad42af 6132
cfad42af 6133 my $storecfg = PVE::Storage::config();
08ac653f 6134 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid);
152fe752 6135
08ac653f 6136 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
cfad42af 6137
d81f0f09 6138 my $format = qemu_img_format($dst_scfg, $dst_volname);
21ccdb50 6139
08ac653f 6140 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
21ccdb50 6141
22967505 6142 my $opts = { timeout => 10, device => "drive-$drive", mode => "existing", sync => "full", target => $dst_path };
88383920
DM
6143 $opts->{format} = $format if $format;
6144
22967505 6145 print "drive mirror is starting (scanning bitmap) : this step can take some minutes/hours, depend of disk size and storage speed\n";
21ccdb50 6146
08ac653f 6147 eval {
22967505 6148 vm_mon_cmd($vmid, "drive-mirror", %$opts);
08ac653f
DM
6149 while (1) {
6150 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
6151 my $stat = @$stats[0];
6152 die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
6153 die "error job is not mirroring" if $stat->{type} ne "mirror";
6154
08ac653f 6155 my $busy = $stat->{busy};
ad123d97 6156 my $ready = $stat->{ready};
08ac653f 6157
6f708643
DM
6158 if (my $total = $stat->{len}) {
6159 my $transferred = $stat->{offset} || 0;
6160 my $remaining = $total - $transferred;
6161 my $percent = sprintf "%.2f", ($transferred * 100 / $total);
67fb9de6 6162
ad123d97 6163 print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent % busy: $busy ready: $ready \n";
6f708643 6164 }
f34ebd52 6165
08ac653f 6166
ad123d97 6167 if ($stat->{ready} eq 'true') {
f34ebd52 6168
ad123d97 6169 last if $vmiddst != $vmid;
b467f79a 6170
ad123d97
AD
6171 # try to switch the disk if source and destination are on the same guest
6172 eval { vm_mon_cmd($vmid, "block-job-complete", device => "drive-$drive") };
6173 last if !$@;
6174 die $@ if $@ !~ m/cannot be completed/;
08ac653f 6175 }
08ac653f 6176 sleep 1;
cfad42af
AD
6177 }
6178
08ac653f
DM
6179
6180 };
88383920 6181 my $err = $@;
08ac653f 6182
88383920 6183 my $cancel_job = sub {
08ac653f
DM
6184 vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive");
6185 while (1) {
6186 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
6187 my $stat = @$stats[0];
6188 last if !$stat;
6189 sleep 1;
cfad42af 6190 }
88383920
DM
6191 };
6192
6193 if ($err) {
f34ebd52 6194 eval { &$cancel_job(); };
88383920
DM
6195 die "mirroring error: $err";
6196 }
6197
6198 if ($vmiddst != $vmid) {
6199 # if we clone a disk for a new target vm, we don't switch the disk
6200 &$cancel_job(); # so we call block-job-cancel
cfad42af
AD
6201 }
6202}
6203
152fe752 6204sub clone_disk {
be190583 6205 my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
152fe752
DM
6206 $newvmid, $storage, $format, $full, $newvollist) = @_;
6207
6208 my $newvolid;
6209
6210 if (!$full) {
6211 print "create linked clone of drive $drivename ($drive->{file})\n";
258e646c 6212 $newvolid = PVE::Storage::vdisk_clone($storecfg, $drive->{file}, $newvmid, $snapname);
152fe752
DM
6213 push @$newvollist, $newvolid;
6214 } else {
6215 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file});
6216 $storeid = $storage if $storage;
6217
1377d7b0
DM
6218 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($storecfg, $storeid);
6219 if (!$format) {
d81f0f09
DM
6220 my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
6221 $format = qemu_img_format($scfg, $volname);
152fe752
DM
6222 }
6223
1377d7b0
DM
6224 # test if requested format is supported - else use default
6225 my $supported = grep { $_ eq $format } @$validFormats;
6226 $format = $defFormat if !$supported;
6227
152fe752
DM
6228 my ($size) = PVE::Storage::volume_size_info($storecfg, $drive->{file}, 3);
6229
6230 print "create full clone of drive $drivename ($drive->{file})\n";
6231 $newvolid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $newvmid, $format, undef, ($size/1024));
6232 push @$newvollist, $newvolid;
6233
6234 if (!$running || $snapname) {
6235 qemu_img_convert($drive->{file}, $newvolid, $size, $snapname);
6236 } else {
6237 qemu_drive_mirror($vmid, $drivename, $newvolid, $newvmid);
be190583 6238 }
152fe752
DM
6239 }
6240
6241 my ($size) = PVE::Storage::volume_size_info($storecfg, $newvolid, 3);
6242
6243 my $disk = $drive;
6244 $disk->{format} = undef;
6245 $disk->{file} = $newvolid;
6246 $disk->{size} = $size;
6247
6248 return $disk;
6249}
6250
ff556cf2
DM
6251# this only works if VM is running
6252sub get_current_qemu_machine {
6253 my ($vmid) = @_;
6254
6255 my $cmd = { execute => 'query-machines', arguments => {} };
8e90138a 6256 my $res = vm_qmp_command($vmid, $cmd);
ff556cf2
DM
6257
6258 my ($current, $default);
6259 foreach my $e (@$res) {
6260 $default = $e->{name} if $e->{'is-default'};
6261 $current = $e->{name} if $e->{'is-current'};
6262 }
6263
6264 # fallback to the default machine if current is not supported by qemu
6265 return $current || $default || 'pc';
6266}
6267
23f73120
AD
6268sub qemu_machine_feature_enabled {
6269 my ($machine, $kvmver, $version_major, $version_minor) = @_;
6270
6271 my $current_major;
6272 my $current_minor;
6273
6274 if ($machine && $machine =~ m/^(pc(-i440fx|-q35)?-(\d+)\.(\d+))/) {
6275
6276 $current_major = $3;
6277 $current_minor = $4;
6278
6279 } elsif ($kvmver =~ m/^(\d+)\.(\d+)/) {
6280
6281 $current_major = $1;
6282 $current_minor = $2;
6283 }
6284
6285 return 1 if $current_major >= $version_major && $current_minor >= $version_minor;
6286
6287
6288}
6289
4543ecf0
AD
6290sub lspci {
6291
6292 my $devices = {};
6293
6294 dir_glob_foreach("$pcisysfs/devices", '[a-f0-9]{4}:([a-f0-9]{2}:[a-f0-9]{2})\.([0-9])', sub {
6295 my (undef, $id, $function) = @_;
6296 my $res = { id => $id, function => $function};
6297 push @{$devices->{$id}}, $res;
6298 });
6299
6300 return $devices;
6301}
6302
22de899a
AD
6303sub vm_iothreads_list {
6304 my ($vmid) = @_;
6305
6306 my $res = vm_mon_cmd($vmid, 'query-iothreads');
6307
6308 my $iothreads = {};
6309 foreach my $iothread (@$res) {
6310 $iothreads->{ $iothread->{id} } = $iothread->{"thread-id"};
6311 }
6312
6313 return $iothreads;
6314}
6315
ee034f5c
AD
6316sub scsihw_infos {
6317 my ($conf, $drive) = @_;
6318
6319 my $maxdev = 0;
6320
6321 if ($conf->{scsihw} && ($conf->{scsihw} =~ m/^lsi/)) {
6322 $maxdev = 7;
a1511b3c 6323 } elsif ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
ee034f5c
AD
6324 $maxdev = 1;
6325 } else {
6326 $maxdev = 256;
6327 }
6328
6329 my $controller = int($drive->{index} / $maxdev);
a1511b3c 6330 my $controller_prefix = ($conf->{scsihw} && $conf->{scsihw} eq 'virtio-scsi-single') ? "virtioscsi" : "scsihw";
ee034f5c
AD
6331
6332 return ($maxdev, $controller, $controller_prefix);
6333}
a1511b3c 6334
1e3baf05 63351;