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