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