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