]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer.pm
cpuflags : remove enforce for cpumodel=host
[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};
604ea644
AD
2350
2351 if ($full) {
2352 $d->{nics}->{$dev}->{netout} = $netdev->{$dev}->{receive};
2353 $d->{nics}->{$dev}->{netin} = $netdev->{$dev}->{transmit};
2354 }
2355
1e3baf05
DM
2356 }
2357
1e3baf05
DM
2358 my $ctime = gettimeofday;
2359
2360 foreach my $vmid (keys %$list) {
2361
2362 my $d = $res->{$vmid};
2363 my $pid = $d->{pid};
2364 next if !$pid;
2365
694fcad4
DM
2366 my $pstat = PVE::ProcFSTools::read_proc_pid_stat($pid);
2367 next if !$pstat; # not running
19672434 2368
694fcad4 2369 my $used = $pstat->{utime} + $pstat->{stime};
1e3baf05 2370
694fcad4 2371 $d->{uptime} = int(($uptime - $pstat->{starttime})/$cpuinfo->{user_hz});
1e3baf05 2372
694fcad4 2373 if ($pstat->{vsize}) {
6b64503e 2374 $d->{mem} = int(($pstat->{rss}/$pstat->{vsize})*$d->{maxmem});
1e3baf05
DM
2375 }
2376
2377 my $old = $last_proc_pid_stat->{$pid};
2378 if (!$old) {
19672434
DM
2379 $last_proc_pid_stat->{$pid} = {
2380 time => $ctime,
1e3baf05
DM
2381 used => $used,
2382 cpu => 0,
1e3baf05
DM
2383 };
2384 next;
2385 }
2386
7f0b5beb 2387 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz};
1e3baf05
DM
2388
2389 if ($dtime > 1000) {
2390 my $dutime = $used - $old->{used};
2391
ae4915a2 2392 $d->{cpu} = (($dutime/$dtime)* $cpucount) / $d->{cpus};
1e3baf05 2393 $last_proc_pid_stat->{$pid} = {
19672434 2394 time => $ctime,
1e3baf05
DM
2395 used => $used,
2396 cpu => $d->{cpu},
1e3baf05
DM
2397 };
2398 } else {
2399 $d->{cpu} = $old->{cpu};
1e3baf05
DM
2400 }
2401 }
2402
f5eb281a 2403 return $res if !$full;
03a33f30
DM
2404
2405 my $qmpclient = PVE::QMPClient->new();
2406
64e7fcf2
DM
2407 my $ballooncb = sub {
2408 my ($vmid, $resp) = @_;
2409
2410 my $info = $resp->{'return'};
38babf81
DM
2411 return if !$info->{max_mem};
2412
64e7fcf2
DM
2413 my $d = $res->{$vmid};
2414
38babf81
DM
2415 # use memory assigned to VM
2416 $d->{maxmem} = $info->{max_mem};
2417 $d->{balloon} = $info->{actual};
2418
2419 if (defined($info->{total_mem}) && defined($info->{free_mem})) {
2420 $d->{mem} = $info->{total_mem} - $info->{free_mem};
2421 $d->{freemem} = $info->{free_mem};
64e7fcf2
DM
2422 }
2423
604ea644 2424 $d->{ballooninfo} = $info;
64e7fcf2
DM
2425 };
2426
03a33f30
DM
2427 my $blockstatscb = sub {
2428 my ($vmid, $resp) = @_;
2429 my $data = $resp->{'return'} || [];
2430 my $totalrdbytes = 0;
2431 my $totalwrbytes = 0;
604ea644 2432
03a33f30
DM
2433 for my $blockstat (@$data) {
2434 $totalrdbytes = $totalrdbytes + $blockstat->{stats}->{rd_bytes};
2435 $totalwrbytes = $totalwrbytes + $blockstat->{stats}->{wr_bytes};
604ea644
AD
2436
2437 $blockstat->{device} =~ s/drive-//;
2438 $res->{$vmid}->{blockstat}->{$blockstat->{device}} = $blockstat->{stats};
03a33f30
DM
2439 }
2440 $res->{$vmid}->{diskread} = $totalrdbytes;
2441 $res->{$vmid}->{diskwrite} = $totalwrbytes;
2442 };
2443
2444 my $statuscb = sub {
2445 my ($vmid, $resp) = @_;
64e7fcf2 2446
03a33f30 2447 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
64e7fcf2
DM
2448 # this fails if ballon driver is not loaded, so this must be
2449 # the last commnand (following command are aborted if this fails).
38babf81 2450 $qmpclient->queue_cmd($vmid, $ballooncb, 'query-balloon');
03a33f30
DM
2451
2452 my $status = 'unknown';
2453 if (!defined($status = $resp->{'return'}->{status})) {
2454 warn "unable to get VM status\n";
2455 return;
2456 }
2457
2458 $res->{$vmid}->{qmpstatus} = $resp->{'return'}->{status};
2459 };
2460
2461 foreach my $vmid (keys %$list) {
2462 next if $opt_vmid && ($vmid ne $opt_vmid);
2463 next if !$res->{$vmid}->{pid}; # not running
2464 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2465 }
2466
c8125172 2467 $qmpclient->queue_execute(undef, 1);
03a33f30
DM
2468
2469 foreach my $vmid (keys %$list) {
2470 next if $opt_vmid && ($vmid ne $opt_vmid);
2471 $res->{$vmid}->{qmpstatus} = $res->{$vmid}->{status} if !$res->{$vmid}->{qmpstatus};
2472 }
2473
1e3baf05
DM
2474 return $res;
2475}
2476
e059fb4d
AD
2477sub foreach_dimm {
2478 my ($conf, $vmid, $memory, $sockets, $func) = @_;
2479
2480 my $dimm_id = 0;
2481 my $current_size = 1024;
2482 my $dimm_size = 512;
2483 return if $current_size == $memory;
2484
2485 for (my $j = 0; $j < 8; $j++) {
2486 for (my $i = 0; $i < 32; $i++) {
2487 my $name = "dimm${dimm_id}";
2488 $dimm_id++;
2489 my $numanode = $i % $sockets;
2490 $current_size += $dimm_size;
2491 &$func($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory);
2492 return $current_size if $current_size >= $memory;
2493 }
2494 $dimm_size *= 2;
2495 }
2496}
2497
1e3baf05
DM
2498sub foreach_drive {
2499 my ($conf, $func) = @_;
2500
2501 foreach my $ds (keys %$conf) {
2502 next if !valid_drivename($ds);
2503
6b64503e 2504 my $drive = parse_drive($ds, $conf->{$ds});
1e3baf05
DM
2505 next if !$drive;
2506
2507 &$func($ds, $drive);
2508 }
2509}
2510
d5769dc2
DM
2511sub foreach_volid {
2512 my ($conf, $func) = @_;
be190583 2513
d5769dc2
DM
2514 my $volhash = {};
2515
2516 my $test_volid = sub {
2517 my ($volid, $is_cdrom) = @_;
2518
2519 return if !$volid;
be190583 2520
d5769dc2
DM
2521 $volhash->{$volid} = $is_cdrom || 0;
2522 };
2523
ed221350 2524 foreach_drive($conf, sub {
d5769dc2
DM
2525 my ($ds, $drive) = @_;
2526 &$test_volid($drive->{file}, drive_is_cdrom($drive));
2527 });
2528
2529 foreach my $snapname (keys %{$conf->{snapshots}}) {
2530 my $snap = $conf->{snapshots}->{$snapname};
2531 &$test_volid($snap->{vmstate}, 0);
ed221350 2532 foreach_drive($snap, sub {
d5769dc2
DM
2533 my ($ds, $drive) = @_;
2534 &$test_volid($drive->{file}, drive_is_cdrom($drive));
2535 });
2536 }
2537
2538 foreach my $volid (keys %$volhash) {
be190583 2539 &$func($volid, $volhash->{$volid});
d5769dc2
DM
2540 }
2541}
2542
86b8228b
DM
2543sub vga_conf_has_spice {
2544 my ($vga) = @_;
2545
590e698c
DM
2546 return 0 if !$vga || $vga !~ m/^qxl([234])?$/;
2547
2548 return $1 || 1;
86b8228b
DM
2549}
2550
1e3baf05 2551sub config_to_command {
952958bc 2552 my ($storecfg, $vmid, $conf, $defaults, $forcemachine) = @_;
1e3baf05
DM
2553
2554 my $cmd = [];
8c559505
DM
2555 my $globalFlags = [];
2556 my $machineFlags = [];
2557 my $rtcFlags = [];
519ed28c 2558 my $cpuFlags = [];
5bdcf937 2559 my $devices = [];
b78ebef7 2560 my $pciaddr = '';
5bdcf937 2561 my $bridges = {};
1e3baf05
DM
2562 my $kvmver = kvm_user_version();
2563 my $vernum = 0; # unknown
a3c52213
DM
2564 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2565 $vernum = $1*1000000+$2*1000;
2566 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
1e3baf05
DM
2567 $vernum = $1*1000000+$2*1000+$3;
2568 }
2569
a3c52213 2570 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
1e3baf05
DM
2571
2572 my $have_ovz = -f '/proc/vz/vestat';
2573
db656e5f 2574 my $q35 = machine_type_is_q35($conf);
4d3f29ed 2575 my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
23f73120 2576 my $machine_type = $forcemachine || $conf->{machine};
db656e5f 2577
f08e17c7
AD
2578 my $cpuunits = defined($conf->{cpuunits}) ?
2579 $conf->{cpuunits} : $defaults->{cpuunits};
2580
2581 push @$cmd, '/usr/bin/systemd-run';
2582 push @$cmd, '--scope';
2583 push @$cmd, '--slice', "qemu";
2584 push @$cmd, '--unit', $vmid;
2585 push @$cmd, '-p', "CPUShares=$cpuunits";
58be00f1 2586 if ($conf->{cpulimit}) {
c6f773b8
DM
2587 my $cpulimit = int($conf->{cpulimit} * 100);
2588 push @$cmd, '-p', "CPUQuota=$cpulimit\%";
58be00f1 2589 }
f08e17c7 2590
1e3baf05
DM
2591 push @$cmd, '/usr/bin/kvm';
2592
2593 push @$cmd, '-id', $vmid;
2594
2595 my $use_virtio = 0;
2596
c971c4f2
AD
2597 my $qmpsocket = qmp_socket($vmid);
2598 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2599 push @$cmd, '-mon', "chardev=qmp,mode=control";
2600
7b7c6d1b 2601 my $socket = vnc_socket($vmid);
1e3baf05
DM
2602 push @$cmd, '-vnc', "unix:$socket,x509,password";
2603
6b64503e 2604 push @$cmd, '-pidfile' , pidfile_name($vmid);
19672434 2605
1e3baf05
DM
2606 push @$cmd, '-daemonize';
2607
2796e7d5
DM
2608 if ($conf->{smbios1}) {
2609 push @$cmd, '-smbios', "type=1,$conf->{smbios1}";
2610 }
2611
db656e5f 2612 if ($q35) {
b467f79a 2613 # the q35 chipset support native usb2, so we enable usb controller
db656e5f 2614 # by default for this machine type
f8e83f05 2615 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-q35.cfg';
db656e5f 2616 } else {
f8e83f05
AD
2617 $pciaddr = print_pci_addr("piix3", $bridges);
2618 push @$devices, '-device', "piix3-usb-uhci,id=uhci$pciaddr.0x2";
24f0d39a 2619
f8e83f05 2620 my $use_usb2 = 0;
db656e5f
DM
2621 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2622 next if !$conf->{"usb$i"};
2623 $use_usb2 = 1;
2624 }
2625 # include usb device config
2626 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
fcc573ab 2627 }
19672434 2628
5acbfe9e 2629 my $vga = $conf->{vga};
2fa3151e 2630
590e698c
DM
2631 my $qxlnum = vga_conf_has_spice($vga);
2632 $vga = 'qxl' if $qxlnum;
2fa3151e 2633
5acbfe9e 2634 if (!$vga) {
264e519f
DM
2635 if ($conf->{ostype} && ($conf->{ostype} eq 'win8' ||
2636 $conf->{ostype} eq 'win7' ||
5acbfe9e
DM
2637 $conf->{ostype} eq 'w2k8')) {
2638 $vga = 'std';
2639 } else {
2640 $vga = 'cirrus';
2641 }
2642 }
2643
1e3baf05 2644 # enable absolute mouse coordinates (needed by vnc)
5acbfe9e
DM
2645 my $tablet;
2646 if (defined($conf->{tablet})) {
2647 $tablet = $conf->{tablet};
2648 } else {
2649 $tablet = $defaults->{tablet};
590e698c 2650 $tablet = 0 if $qxlnum; # disable for spice because it is not needed
ef5e2be2 2651 $tablet = 0 if $vga =~ m/^serial\d+$/; # disable if we use serial terminal (no vga card)
5acbfe9e
DM
2652 }
2653
db656e5f 2654 push @$devices, '-device', print_tabletdevice_full($conf) if $tablet;
b467f79a 2655
1e3baf05 2656 # host pci devices
040b06b7 2657 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2e3b7e2a
AD
2658 my $d = parse_hostpci($conf->{"hostpci$i"});
2659 next if !$d;
2660
2661 my $pcie = $d->{pcie};
2662 if($pcie){
2663 die "q35 machine model is not enabled" if !$q35;
2664 $pciaddr = print_pcie_addr("hostpci$i");
2665 }else{
2666 $pciaddr = print_pci_addr("hostpci$i", $bridges);
2667 }
2668
2669 my $rombar = $d->{rombar} && $d->{rombar} eq 'off' ? ",rombar=0" : "";
2670 my $driver = $d->{driver} && $d->{driver} eq 'vfio' ? "vfio-pci" : "pci-assign";
2671 my $xvga = $d->{'x-vga'} && $d->{'x-vga'} eq 'on' ? ",x-vga=on" : "";
137483c0
AD
2672 if ($xvga && $xvga ne '') {
2673 push @$cpuFlags, 'kvm=off';
2674 $vga = 'none';
2675 }
2e3b7e2a 2676 $driver = "vfio-pci" if $xvga ne '';
4543ecf0
AD
2677 my $pcidevices = $d->{pciid};
2678 my $multifunction = 1 if @$pcidevices > 1;
2e3b7e2a 2679
4543ecf0
AD
2680 my $j=0;
2681 foreach my $pcidevice (@$pcidevices) {
2e3b7e2a 2682
4543ecf0
AD
2683 my $id = "hostpci$i";
2684 $id .= ".$j" if $multifunction;
2685 my $addr = $pciaddr;
2686 $addr .= ".$j" if $multifunction;
2687 my $devicestr = "$driver,host=$pcidevice->{id}.$pcidevice->{function},id=$id$addr";
2688
2689 if($j == 0){
2690 $devicestr .= "$rombar$xvga";
2691 $devicestr .= ",multifunction=on" if $multifunction;
2692 }
2693
2694 push @$devices, '-device', $devicestr;
2695 $j++;
2696 }
1e3baf05
DM
2697 }
2698
2699 # usb devices
2700 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2701 my $d = parse_usb_device($conf->{"usb$i"});
2702 next if !$d;
2703 if ($d->{vendorid} && $d->{productid}) {
5bdcf937 2704 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
1e3baf05 2705 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
5bdcf937 2706 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
80401dd8
DM
2707 } elsif ($d->{spice}) {
2708 # usb redir support for spice
2709 push @$devices, '-chardev', "spicevmc,id=usbredirchardev$i,name=usbredir";
2710 push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=ehci.0";
1e3baf05
DM
2711 }
2712 }
2713
1e3baf05 2714 # serial devices
bae179aa 2715 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
34978be3 2716 if (my $path = $conf->{"serial$i"}) {
9f9d2fb2
DM
2717 if ($path eq 'socket') {
2718 my $socket = "/var/run/qemu-server/${vmid}.serial$i";
2719 push @$devices, '-chardev', "socket,id=serial$i,path=$socket,server,nowait";
2720 push @$devices, '-device', "isa-serial,chardev=serial$i";
2721 } else {
2722 die "no such serial device\n" if ! -c $path;
2723 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2724 push @$devices, '-device', "isa-serial,chardev=serial$i";
2725 }
34978be3 2726 }
1e3baf05
DM
2727 }
2728
2729 # parallel devices
1989a89c 2730 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
34978be3 2731 if (my $path = $conf->{"parallel$i"}) {
19672434 2732 die "no such parallel device\n" if ! -c $path;
32e69805 2733 my $devtype = $path =~ m!^/dev/usb/lp! ? 'tty' : 'parport';
4c5dbaf6 2734 push @$devices, '-chardev', "$devtype,id=parallel$i,path=$path";
5bdcf937 2735 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
34978be3 2736 }
1e3baf05
DM
2737 }
2738
2739 my $vmname = $conf->{name} || "vm$vmid";
2740
2741 push @$cmd, '-name', $vmname;
19672434 2742
1e3baf05
DM
2743 my $sockets = 1;
2744 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2745 $sockets = $conf->{sockets} if $conf->{sockets};
2746
2747 my $cores = $conf->{cores} || 1;
3bd18e48 2748
de9d1e55 2749 my $maxcpus = $sockets * $cores;
76267728 2750
de9d1e55 2751 my $vcpus = $conf->{vcpus} ? $conf->{vcpus} : $maxcpus;
76267728 2752
de9d1e55
AD
2753 my $allowed_vcpus = $cpuinfo->{cpus};
2754
2755 die "MAX $maxcpus vcpus allowed per VM on this node\n"
2756 if ($allowed_vcpus < $maxcpus);
2757
2758 push @$cmd, '-smp', "$vcpus,sockets=$sockets,cores=$cores,maxcpus=$maxcpus";
1e3baf05 2759
1e3baf05
DM
2760 push @$cmd, '-nodefaults';
2761
32baffb4 2762 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
3b408e82 2763
0888fdce
DM
2764 my $bootindex_hash = {};
2765 my $i = 1;
2766 foreach my $o (split(//, $bootorder)) {
2767 $bootindex_hash->{$o} = $i*100;
2768 $i++;
afdb31d5 2769 }
3b408e82 2770
cf71f776 2771 push @$cmd, '-boot', "menu=on,strict=on,reboot-timeout=1000";
1e3baf05 2772
6b64503e 2773 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
1e3baf05 2774
6b64503e 2775 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
1e3baf05 2776
ef5e2be2 2777 push @$cmd, '-vga', $vga if $vga && $vga !~ m/^serial\d+$/; # for kvm 77 and later
1e3baf05
DM
2778
2779 # time drift fix
6b64503e 2780 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
1e3baf05 2781
6b64503e 2782 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
8c559505 2783 my $useLocaltime = $conf->{localtime};
1e3baf05
DM
2784
2785 if (my $ost = $conf->{ostype}) {
6b9d84cf 2786 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26, solaris
1e3baf05
DM
2787
2788 if ($ost =~ m/^w/) { # windows
8c559505 2789 $useLocaltime = 1 if !defined($conf->{localtime});
1e3baf05 2790
8c559505 2791 # use time drift fix when acpi is enabled
6b64503e 2792 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
8c559505 2793 $tdf = 1 if !defined($conf->{tdf});
1e3baf05
DM
2794 }
2795 }
2796
be190583 2797 if ($ost eq 'win7' || $ost eq 'win8' || $ost eq 'w2k8' ||
a70ebde3 2798 $ost eq 'wvista') {
8c559505 2799 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
b7e0c8bf 2800 push @$cmd, '-no-hpet';
8f3f959d
AD
2801 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
2802 push @$cpuFlags , 'hv_spinlocks=0x1fff' if !$nokvm;
8a054ffd 2803 push @$cpuFlags , 'hv_vapic' if !$nokvm;
cfac0be4 2804 push @$cpuFlags , 'hv_time' if !$nokvm;
8a054ffd 2805
a1b7d579 2806 } else {
8f3f959d
AD
2807 push @$cpuFlags , 'hv_spinlocks=0xffff' if !$nokvm;
2808 }
462e8d19
AD
2809 }
2810
2811 if ($ost eq 'win7' || $ost eq 'win8') {
2812 push @$cpuFlags , 'hv_relaxed' if !$nokvm;
b7e0c8bf 2813 }
1e3baf05
DM
2814 }
2815
8c559505
DM
2816 push @$rtcFlags, 'driftfix=slew' if $tdf;
2817
7f0b5beb 2818 if ($nokvm) {
8c559505 2819 push @$machineFlags, 'accel=tcg';
7f0b5beb
DM
2820 } else {
2821 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2822 }
1e3baf05 2823
952958bc
DM
2824 if ($machine_type) {
2825 push @$machineFlags, "type=${machine_type}";
3bafc510
DM
2826 }
2827
8c559505
DM
2828 if ($conf->{startdate}) {
2829 push @$rtcFlags, "base=$conf->{startdate}";
2830 } elsif ($useLocaltime) {
2831 push @$rtcFlags, 'base=localtime';
2832 }
1e3baf05 2833
519ed28c
AD
2834 my $cpu = $nokvm ? "qemu64" : "kvm64";
2835 $cpu = $conf->{cpu} if $conf->{cpu};
2836
4dc339e7
AD
2837 push @$cpuFlags , '+lahf_lm' if $cpu eq 'kvm64';
2838
6b9d84cf
AD
2839 push @$cpuFlags , '+x2apic' if !$nokvm && $conf->{ostype} ne 'solaris';
2840
2841 push @$cpuFlags , '-x2apic' if $conf->{ostype} eq 'solaris';
519ed28c 2842
2e1a5389
AD
2843 push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32';
2844
0dc48c3d
AD
2845 push @$cpuFlags, '-rdtscp' if $cpu =~ m/^Opteron/;
2846
117a0414
AD
2847 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
2848
2849 push @$cpuFlags , '+kvm_pv_unhalt' if !$nokvm;
0da5a08c 2850 push @$cpuFlags , '+kvm_pv_eoi' if !$nokvm;
117a0414
AD
2851 }
2852
dac7c619
AD
2853 push @$cpuFlags, 'enforce' if $cpu ne 'host';
2854
be190583 2855 $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags);
519ed28c 2856
dac7c619 2857 push @$cmd, '-cpu', $cpu;
519ed28c 2858
4d3f29ed
AD
2859 my $memory = $conf->{memory} || $defaults->{memory};
2860 my $static_memory = 0;
2861 my $dimm_memory = 0;
2862
2863 if ($hotplug_features->{memory}) {
996635e5
DM
2864 die "Numa need to be enabled for memory hotplug\n" if !$conf->{numa};
2865 die "Total memory is bigger than ${MAX_MEM}MB\n" if $memory > $MAX_MEM;
4d3f29ed 2866 $static_memory = $STATICMEM;
996635e5 2867 die "minimum memory must be ${static_memory}MB\n" if($memory < $static_memory);
4d3f29ed 2868 $dimm_memory = $memory - $static_memory;
996635e5 2869 push @$cmd, '-m', "size=${static_memory},slots=255,maxmem=${MAX_MEM}M";
4d3f29ed
AD
2870
2871 } else {
2872
2873 $static_memory = $memory;
2874 push @$cmd, '-m', $static_memory;
2875 }
8a010eae 2876
67fb9de6 2877 if ($conf->{numa}) {
8a010eae 2878
2ed5d572
AD
2879 my $numa_totalmemory = undef;
2880 for (my $i = 0; $i < $MAX_NUMA; $i++) {
2881 next if !$conf->{"numa$i"};
2882 my $numa = parse_numa($conf->{"numa$i"});
2883 next if !$numa;
67fb9de6
DM
2884 # memory
2885 die "missing numa node$i memory value\n" if !$numa->{memory};
2ed5d572
AD
2886 my $numa_memory = $numa->{memory};
2887 $numa_totalmemory += $numa_memory;
996635e5 2888 my $numa_object = "memory-backend-ram,id=ram-node$i,size=${numa_memory}M";
2ed5d572 2889
67fb9de6 2890 # cpus
2ed5d572 2891 my $cpus_start = $numa->{cpus}->{start};
67fb9de6 2892 die "missing numa node$i cpus\n" if !defined($cpus_start);
2ed5d572
AD
2893 my $cpus_end = $numa->{cpus}->{end} if defined($numa->{cpus}->{end});
2894 my $cpus = $cpus_start;
2895 if (defined($cpus_end)) {
2896 $cpus .= "-$cpus_end";
67fb9de6 2897 die "numa node$i : cpu range $cpus is incorrect\n" if $cpus_end <= $cpus_start;
2ed5d572 2898 }
8a010eae 2899
67fb9de6 2900 # hostnodes
2ed5d572
AD
2901 my $hostnodes_start = $numa->{hostnodes}->{start};
2902 if (defined($hostnodes_start)) {
2903 my $hostnodes_end = $numa->{hostnodes}->{end} if defined($numa->{hostnodes}->{end});
2904 my $hostnodes = $hostnodes_start;
2905 if (defined($hostnodes_end)) {
2906 $hostnodes .= "-$hostnodes_end";
67fb9de6 2907 die "host node $hostnodes range is incorrect\n" if $hostnodes_end <= $hostnodes_start;
2ed5d572 2908 }
8a010eae 2909
2ed5d572
AD
2910 my $hostnodes_end_range = defined($hostnodes_end) ? $hostnodes_end : $hostnodes_start;
2911 for (my $i = $hostnodes_start; $i <= $hostnodes_end_range; $i++ ) {
67fb9de6 2912 die "host numa node$i don't exist\n" if ! -d "/sys/devices/system/node/node$i/";
2ed5d572 2913 }
8a010eae 2914
67fb9de6 2915 # policy
2ed5d572 2916 my $policy = $numa->{policy};
67fb9de6
DM
2917 die "you need to define a policy for hostnode $hostnodes\n" if !$policy;
2918 $numa_object .= ",host-nodes=$hostnodes,policy=$policy";
2ed5d572
AD
2919 }
2920
2921 push @$cmd, '-object', $numa_object;
8a010eae
AD
2922 push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
2923 }
67fb9de6 2924
4d3f29ed
AD
2925 die "total memory for NUMA nodes must be equal to vm static memory\n"
2926 if $numa_totalmemory && $numa_totalmemory != $static_memory;
2ed5d572
AD
2927
2928 #if no custom tology, we split memory and cores across numa nodes
2929 if(!$numa_totalmemory) {
2930
4d3f29ed 2931 my $numa_memory = ($static_memory / $sockets) . "M";
2ed5d572
AD
2932
2933 for (my $i = 0; $i < $sockets; $i++) {
2934
2935 my $cpustart = ($cores * $i);
2936 my $cpuend = ($cpustart + $cores - 1) if $cores && $cores > 1;
2937 my $cpus = $cpustart;
2938 $cpus .= "-$cpuend" if $cpuend;
2939
2940 push @$cmd, '-object', "memory-backend-ram,size=$numa_memory,id=ram-node$i";
2941 push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
2942 }
2943 }
8a010eae
AD
2944 }
2945
4d3f29ed 2946 if ($hotplug_features->{memory}) {
e059fb4d
AD
2947 foreach_dimm($conf, $vmid, $memory, $sockets, sub {
2948 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
996635e5 2949 push @$cmd, "-object" , "memory-backend-ram,id=mem-$name,size=${dimm_size}M";
e059fb4d
AD
2950 push @$cmd, "-device", "pc-dimm,id=$name,memdev=mem-$name,node=$numanode";
2951
2952 #if dimm_memory is not aligned to dimm map
2953 if($current_size > $memory) {
2954 $conf->{memory} = $current_size;
2955 update_config_nolock($vmid, $conf, 1);
2956 }
2957 });
4d3f29ed
AD
2958 }
2959
1e3baf05
DM
2960 push @$cmd, '-S' if $conf->{freeze};
2961
2962 # set keyboard layout
2963 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2964 push @$cmd, '-k', $kb if $kb;
2965
2966 # enable sound
2967 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2968 #push @$cmd, '-soundhw', 'es1370';
2969 #push @$cmd, '-soundhw', $soundhw if $soundhw;
ab6a046f 2970
bc84dcca 2971 if($conf->{agent}) {
7a6c2150 2972 my $qgasocket = qmp_socket($vmid, 1);
ab6a046f
AD
2973 my $pciaddr = print_pci_addr("qga0", $bridges);
2974 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2975 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2976 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2977 }
2978
1d794448 2979 my $spice_port;
2fa3151e 2980
590e698c
DM
2981 if ($qxlnum) {
2982 if ($qxlnum > 1) {
2983 if ($conf->{ostype} && $conf->{ostype} =~ m/^w/){
2984 for(my $i = 1; $i < $qxlnum; $i++){
2985 my $pciaddr = print_pci_addr("vga$i", $bridges);
2986 push @$cmd, '-device', "qxl,id=vga$i,ram_size=67108864,vram_size=33554432$pciaddr";
2987 }
2988 } else {
2989 # assume other OS works like Linux
2990 push @$cmd, '-global', 'qxl-vga.ram_size=134217728';
2991 push @$cmd, '-global', 'qxl-vga.vram_size=67108864';
2fa3151e
AD
2992 }
2993 }
2994
1011b570 2995 my $pciaddr = print_pci_addr("spice", $bridges);
95a4b4a9 2996
af0eba7e
WB
2997 my $nodename = PVE::INotify::nodename();
2998 my $pfamily = PVE::Tools::get_host_address_family($nodename);
2999 $spice_port = PVE::Tools::next_spice_port($pfamily);
943340a6 3000
fd1f36ac 3001 push @$devices, '-spice', "tls-port=${spice_port},addr=localhost,tls-ciphers=DES-CBC3-SHA,seamless-migration=on";
1011b570 3002
d2da6d9b
AD
3003 push @$devices, '-device', "virtio-serial,id=spice$pciaddr";
3004 push @$devices, '-chardev', "spicevmc,id=vdagent,name=vdagent";
3005 push @$devices, '-device', "virtserialport,chardev=vdagent,name=com.redhat.spice.0";
1011b570
DM
3006 }
3007
8d9ae0d2
DM
3008 # enable balloon by default, unless explicitly disabled
3009 if (!defined($conf->{balloon}) || $conf->{balloon}) {
3010 $pciaddr = print_pci_addr("balloon0", $bridges);
3011 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr";
3012 }
1e3baf05 3013
0ea9541d
DM
3014 if ($conf->{watchdog}) {
3015 my $wdopts = parse_watchdog($conf->{watchdog});
5bdcf937 3016 $pciaddr = print_pci_addr("watchdog", $bridges);
0a40e8ea 3017 my $watchdog = $wdopts->{model} || 'i6300esb';
5bdcf937
AD
3018 push @$devices, '-device', "$watchdog$pciaddr";
3019 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
0ea9541d
DM
3020 }
3021
1e3baf05 3022 my $vollist = [];
941e0c42 3023 my $scsicontroller = {};
26ee04b6 3024 my $ahcicontroller = {};
cdd20088 3025 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
1e3baf05 3026
5881b913
DM
3027 # Add iscsi initiator name if available
3028 if (my $initiator = get_initiator_name()) {
3029 push @$devices, '-iscsi', "initiator-name=$initiator";
3030 }
3031
1e3baf05
DM
3032 foreach_drive($conf, sub {
3033 my ($ds, $drive) = @_;
3034
ff1a2432 3035 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
1e3baf05 3036 push @$vollist, $drive->{file};
ff1a2432 3037 }
afdb31d5 3038
1e3baf05 3039 $use_virtio = 1 if $ds =~ m/^virtio/;
3b408e82
DM
3040
3041 if (drive_is_cdrom ($drive)) {
3042 if ($bootindex_hash->{d}) {
3043 $drive->{bootindex} = $bootindex_hash->{d};
3044 $bootindex_hash->{d} += 1;
3045 }
3046 } else {
3047 if ($bootindex_hash->{c}) {
3048 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
3049 $bootindex_hash->{c} += 1;
3050 }
3051 }
3052
51f492cd
AD
3053 if($drive->{interface} eq 'virtio'){
3054 push @$cmd, '-object', "iothread,id=iothread-$ds" if $drive->{iothread};
3055 }
3056
941e0c42 3057 if ($drive->{interface} eq 'scsi') {
cdd20088 3058
ee034f5c 3059 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $drive);
6731a4cf 3060
6731a4cf 3061 $pciaddr = print_pci_addr("$controller_prefix$controller", $bridges);
a1b7d579 3062 my $scsihw_type = $scsihw =~ m/^virtio-scsi-single/ ? "virtio-scsi-pci" : $scsihw;
fc8b40fd
AD
3063
3064 my $iothread = '';
3065 if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{iothread}){
3066 $iothread .= ",iothread=iothread-$controller_prefix$controller";
3067 push @$cmd, '-object', "iothread,id=iothread-$controller_prefix$controller";
3068 }
3069
6e11f143
AD
3070 my $queues = '';
3071 if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{queues}){
3072 $queues = ",num_queues=$drive->{queues}";
3073 }
3074
3075 push @$devices, '-device', "$scsihw_type,id=$controller_prefix$controller$pciaddr$iothread$queues" if !$scsicontroller->{$controller};
cdd20088 3076 $scsicontroller->{$controller}=1;
941e0c42 3077 }
3b408e82 3078
26ee04b6
DA
3079 if ($drive->{interface} eq 'sata') {
3080 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
5bdcf937
AD
3081 $pciaddr = print_pci_addr("ahci$controller", $bridges);
3082 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
26ee04b6
DA
3083 $ahcicontroller->{$controller}=1;
3084 }
46f58b5f 3085
15b21acc
MR
3086 my $drive_cmd = print_drive_full($storecfg, $vmid, $drive);
3087 push @$devices, '-drive',$drive_cmd;
46f58b5f 3088 push @$devices, '-device', print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
1e3baf05
DM
3089 });
3090
cc4d6182 3091 for (my $i = 0; $i < $MAX_NETS; $i++) {
5f0c4c32 3092 next if !$conf->{"net$i"};
cc4d6182
DA
3093 my $d = parse_net($conf->{"net$i"});
3094 next if !$d;
1e3baf05 3095
cc4d6182 3096 $use_virtio = 1 if $d->{model} eq 'virtio';
1e3baf05 3097
cc4d6182
DA
3098 if ($bootindex_hash->{n}) {
3099 $d->{bootindex} = $bootindex_hash->{n};
3100 $bootindex_hash->{n} += 1;
3101 }
1e3baf05 3102
cc4d6182 3103 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
5bdcf937
AD
3104 push @$devices, '-netdev', $netdevfull;
3105
3106 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i",$bridges);
3107 push @$devices, '-device', $netdevicefull;
3108 }
1e3baf05 3109
db656e5f
DM
3110 if (!$q35) {
3111 # add pci bridges
fc79e813
AD
3112 if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) {
3113 $bridges->{1} = 1;
3114 $bridges->{2} = 1;
3115 }
3116
6731a4cf
AD
3117 $bridges->{3} = 1 if $scsihw =~ m/^virtio-scsi-single/;
3118
f8e83f05
AD
3119 while (my ($k, $v) = each %$bridges) {
3120 $pciaddr = print_pci_addr("pci.$k");
3121 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
3122 }
19672434
DM
3123 }
3124
1e3baf05
DM
3125 # add custom args
3126 if ($conf->{args}) {
3ada46c9 3127 my $aa = PVE::Tools::split_args($conf->{args});
1e3baf05
DM
3128 push @$cmd, @$aa;
3129 }
3130
5bdcf937 3131 push @$cmd, @$devices;
be190583 3132 push @$cmd, '-rtc', join(',', @$rtcFlags)
8c559505 3133 if scalar(@$rtcFlags);
be190583 3134 push @$cmd, '-machine', join(',', @$machineFlags)
8c559505
DM
3135 if scalar(@$machineFlags);
3136 push @$cmd, '-global', join(',', @$globalFlags)
3137 if scalar(@$globalFlags);
3138
1d794448 3139 return wantarray ? ($cmd, $vollist, $spice_port) : $cmd;
1e3baf05 3140}
19672434 3141
1e3baf05
DM
3142sub vnc_socket {
3143 my ($vmid) = @_;
3144 return "${var_run_tmpdir}/$vmid.vnc";
3145}
3146
943340a6 3147sub spice_port {
1011b570 3148 my ($vmid) = @_;
943340a6 3149
1d794448 3150 my $res = vm_mon_cmd($vmid, 'query-spice');
943340a6
DM
3151
3152 return $res->{'tls-port'} || $res->{'port'} || die "no spice port\n";
1011b570
DM
3153}
3154
c971c4f2 3155sub qmp_socket {
693d12a2
AD
3156 my ($vmid, $qga) = @_;
3157 my $sockettype = $qga ? 'qga' : 'qmp';
3158 return "${var_run_tmpdir}/$vmid.$sockettype";
c971c4f2
AD
3159}
3160
1e3baf05
DM
3161sub pidfile_name {
3162 my ($vmid) = @_;
3163 return "${var_run_tmpdir}/$vmid.pid";
3164}
3165
86fdcfb2
DA
3166sub vm_devices_list {
3167 my ($vmid) = @_;
3168
ceea9078 3169 my $res = vm_mon_cmd($vmid, 'query-pci');
ceea9078
DM
3170 my $devices = {};
3171 foreach my $pcibus (@$res) {
3172 foreach my $device (@{$pcibus->{devices}}) {
6e62a21f 3173 next if !$device->{'qdev_id'};
200644a7 3174 if ($device->{'pci_bridge'}) {
200644a7
AD
3175 $devices->{$device->{'qdev_id'}} = 1;
3176 foreach my $bridge_device (@{$device->{'pci_bridge'}->{devices}}) {
3177 next if !$bridge_device->{'qdev_id'};
3178 $devices->{$bridge_device->{'qdev_id'}} = 1;
3179 $devices->{$device->{'qdev_id'}}++;
3180 }
3181 } else {
200644a7
AD
3182 $devices->{$device->{'qdev_id'}} = 1;
3183 }
f78cc802
AD
3184 }
3185 }
3186
3187 my $resblock = vm_mon_cmd($vmid, 'query-block');
3188 foreach my $block (@$resblock) {
3189 if($block->{device} =~ m/^drive-(\S+)/){
3190 $devices->{$1} = 1;
1dc4f496
DM
3191 }
3192 }
86fdcfb2 3193
3d7389fe
DM
3194 my $resmice = vm_mon_cmd($vmid, 'query-mice');
3195 foreach my $mice (@$resmice) {
3196 if ($mice->{name} eq 'QEMU HID Tablet') {
3197 $devices->{tablet} = 1;
3198 last;
3199 }
3200 }
3201
1dc4f496 3202 return $devices;
86fdcfb2
DA
3203}
3204
ec21aa11 3205sub vm_deviceplug {
f19d1c47 3206 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
ae57f6b3 3207
db656e5f
DM
3208 my $q35 = machine_type_is_q35($conf);
3209
95d6343b
DA
3210 my $devices_list = vm_devices_list($vmid);
3211 return 1 if defined($devices_list->{$deviceid});
3212
fee46675
DM
3213 qemu_add_pci_bridge($storecfg, $conf, $vmid, $deviceid); # add PCI bridge if we need it for the device
3214
3d7389fe 3215 if ($deviceid eq 'tablet') {
fee46675 3216
3d7389fe 3217 qemu_deviceadd($vmid, print_tabletdevice_full($conf));
3d7389fe 3218
fee46675 3219 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
40f28a9f 3220
22de899a
AD
3221 qemu_iothread_add($vmid, $deviceid, $device);
3222
fee46675 3223 qemu_driveadd($storecfg, $vmid, $device);
cdd20088 3224 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
fee46675 3225
5e5dcb73 3226 qemu_deviceadd($vmid, $devicefull);
fee46675
DM
3227 eval { qemu_deviceaddverify($vmid, $deviceid); };
3228 if (my $err = $@) {
63c2da2f
DM
3229 eval { qemu_drivedel($vmid, $deviceid); };
3230 warn $@ if $@;
fee46675 3231 die $err;
5e5dcb73 3232 }
cfc817c7 3233
2733141c 3234 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
fee46675 3235
fc8b40fd 3236
cdd20088 3237 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
cfc817c7 3238 my $pciaddr = print_pci_addr($deviceid);
a1b7d579 3239 my $scsihw_type = $scsihw eq 'virtio-scsi-single' ? "virtio-scsi-pci" : $scsihw;
2733141c
AD
3240
3241 my $devicefull = "$scsihw_type,id=$deviceid$pciaddr";
fee46675 3242
fc8b40fd
AD
3243 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{iothread}) {
3244 qemu_iothread_add($vmid, $deviceid, $device);
3245 $devicefull .= ",iothread=iothread-$deviceid";
3246 }
3247
6e11f143
AD
3248 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{queues}) {
3249 $devicefull .= ",num_queues=$device->{queues}";
3250 }
3251
cfc817c7 3252 qemu_deviceadd($vmid, $devicefull);
fee46675 3253 qemu_deviceaddverify($vmid, $deviceid);
cfc817c7 3254
fee46675
DM
3255 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
3256
3257 qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
3258 qemu_driveadd($storecfg, $vmid, $device);
a1b7d579 3259
fee46675
DM
3260 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
3261 eval { qemu_deviceadd($vmid, $devicefull); };
3262 if (my $err = $@) {
63c2da2f
DM
3263 eval { qemu_drivedel($vmid, $deviceid); };
3264 warn $@ if $@;
fee46675 3265 die $err;
a4f091a0 3266 }
a4f091a0 3267
fee46675
DM
3268 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
3269
2630d2a9
DA
3270 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
3271 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
3272 qemu_deviceadd($vmid, $netdevicefull);
fee46675
DM
3273 eval { qemu_deviceaddverify($vmid, $deviceid); };
3274 if (my $err = $@) {
3275 eval { qemu_netdevdel($vmid, $deviceid); };
3276 warn $@ if $@;
3277 die $err;
2630d2a9 3278 }
2630d2a9 3279
fee46675 3280 } elsif (!$q35 && $deviceid =~ m/^(pci\.)(\d+)$/) {
b467f79a 3281
40f28a9f
AD
3282 my $bridgeid = $2;
3283 my $pciaddr = print_pci_addr($deviceid);
3284 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
a1b7d579 3285
40f28a9f 3286 qemu_deviceadd($vmid, $devicefull);
fee46675
DM
3287 qemu_deviceaddverify($vmid, $deviceid);
3288
3289 } else {
a1b7d579 3290 die "can't hotplug device '$deviceid'\n";
40f28a9f
AD
3291 }
3292
5e5dcb73 3293 return 1;
a4dea331
DA
3294}
3295
3eec5767 3296# fixme: this should raise exceptions on error!
ec21aa11 3297sub vm_deviceunplug {
f19d1c47 3298 my ($vmid, $conf, $deviceid) = @_;
873c2d69 3299
95d6343b
DA
3300 my $devices_list = vm_devices_list($vmid);
3301 return 1 if !defined($devices_list->{$deviceid});
3302
63c2da2f
DM
3303 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
3304
3d7389fe 3305 if ($deviceid eq 'tablet') {
63c2da2f 3306
3d7389fe 3307 qemu_devicedel($vmid, $deviceid);
3d7389fe 3308
63c2da2f 3309 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
f19d1c47 3310
5e5dcb73 3311 qemu_devicedel($vmid, $deviceid);
63c2da2f
DM
3312 qemu_devicedelverify($vmid, $deviceid);
3313 qemu_drivedel($vmid, $deviceid);
22de899a
AD
3314 qemu_iothread_del($conf, $vmid, $deviceid);
3315
2733141c 3316 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
a1b7d579 3317
63c2da2f 3318 qemu_devicedel($vmid, $deviceid);
8ce30dde 3319 qemu_devicedelverify($vmid, $deviceid);
fc8b40fd 3320 qemu_iothread_del($conf, $vmid, $deviceid);
a1b7d579 3321
63c2da2f 3322 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
cfc817c7 3323
8bcf3068
AD
3324 #qemu 2.3 segfault on drive_del with virtioscsi + iothread
3325 my $device = parse_drive($deviceid, $conf->{$deviceid});
3326 die "virtioscsi with iothread is not hot-unplugglable currently" if $device->{iothread};
3327
63c2da2f
DM
3328 qemu_devicedel($vmid, $deviceid);
3329 qemu_drivedel($vmid, $deviceid);
a1b7d579 3330 qemu_deletescsihw($conf, $vmid, $deviceid);
8ce30dde 3331
63c2da2f 3332 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
a4f091a0 3333
2630d2a9 3334 qemu_devicedel($vmid, $deviceid);
63c2da2f
DM
3335 qemu_devicedelverify($vmid, $deviceid);
3336 qemu_netdevdel($vmid, $deviceid);
3337
3338 } else {
3339 die "can't unplug device '$deviceid'\n";
2630d2a9
DA
3340 }
3341
5e5dcb73
DA
3342 return 1;
3343}
3344
3345sub qemu_deviceadd {
3346 my ($vmid, $devicefull) = @_;
873c2d69 3347
d695b5b7
AD
3348 $devicefull = "driver=".$devicefull;
3349 my %options = split(/[=,]/, $devicefull);
f19d1c47 3350
d695b5b7 3351 vm_mon_cmd($vmid, "device_add" , %options);
5e5dcb73 3352}
afdb31d5 3353
5e5dcb73 3354sub qemu_devicedel {
fee46675 3355 my ($vmid, $deviceid) = @_;
63c2da2f 3356
5a77d8c1 3357 my $ret = vm_mon_cmd($vmid, "device_del", id => $deviceid);
5e5dcb73
DA
3358}
3359
22de899a
AD
3360sub qemu_iothread_add {
3361 my($vmid, $deviceid, $device) = @_;
3362
3363 if ($device->{iothread}) {
3364 my $iothreads = vm_iothreads_list($vmid);
3365 qemu_objectadd($vmid, "iothread-$deviceid", "iothread") if !$iothreads->{"iothread-$deviceid"};
3366 }
3367}
3368
3369sub qemu_iothread_del {
3370 my($conf, $vmid, $deviceid) = @_;
3371
3372 my $device = parse_drive($deviceid, $conf->{$deviceid});
3373 if ($device->{iothread}) {
3374 my $iothreads = vm_iothreads_list($vmid);
3375 qemu_objectdel($vmid, "iothread-$deviceid") if $iothreads->{"iothread-$deviceid"};
3376 }
3377}
3378
4d3f29ed
AD
3379sub qemu_objectadd {
3380 my($vmid, $objectid, $qomtype) = @_;
3381
3382 vm_mon_cmd($vmid, "object-add", id => $objectid, "qom-type" => $qomtype);
3383
3384 return 1;
3385}
3386
3387sub qemu_objectdel {
3388 my($vmid, $objectid) = @_;
3389
3390 vm_mon_cmd($vmid, "object-del", id => $objectid);
3391
3392 return 1;
3393}
3394
5e5dcb73 3395sub qemu_driveadd {
fee46675 3396 my ($storecfg, $vmid, $device) = @_;
5e5dcb73
DA
3397
3398 my $drive = print_drive_full($storecfg, $vmid, $device);
7a69fc3c 3399 $drive =~ s/\\/\\\\/g;
8ead5ec7 3400 my $ret = vm_human_monitor_command($vmid, "drive_add auto \"$drive\"");
fee46675 3401
5e5dcb73 3402 # If the command succeeds qemu prints: "OK"
fee46675
DM
3403 return 1 if $ret =~ m/OK/s;
3404
3405 die "adding drive failed: $ret\n";
5e5dcb73 3406}
afdb31d5 3407
5e5dcb73
DA
3408sub qemu_drivedel {
3409 my($vmid, $deviceid) = @_;
873c2d69 3410
7b7c6d1b 3411 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
5e5dcb73 3412 $ret =~ s/^\s+//;
a1b7d579 3413
63c2da2f 3414 return 1 if $ret eq "";
a1b7d579 3415
63c2da2f 3416 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
a1b7d579
DM
3417 return 1 if $ret =~ m/Device \'.*?\' not found/s;
3418
63c2da2f 3419 die "deleting drive $deviceid failed : $ret\n";
5e5dcb73 3420}
f19d1c47 3421
5e5dcb73 3422sub qemu_deviceaddverify {
fee46675 3423 my ($vmid, $deviceid) = @_;
873c2d69 3424
5e5dcb73
DA
3425 for (my $i = 0; $i <= 5; $i++) {
3426 my $devices_list = vm_devices_list($vmid);
3427 return 1 if defined($devices_list->{$deviceid});
3428 sleep 1;
afdb31d5 3429 }
fee46675
DM
3430
3431 die "error on hotplug device '$deviceid'\n";
5e5dcb73 3432}
afdb31d5 3433
5e5dcb73
DA
3434
3435sub qemu_devicedelverify {
63c2da2f
DM
3436 my ($vmid, $deviceid) = @_;
3437
a1b7d579 3438 # need to verify that the device is correctly removed as device_del
63c2da2f 3439 # is async and empty return is not reliable
5e5dcb73 3440
5e5dcb73
DA
3441 for (my $i = 0; $i <= 5; $i++) {
3442 my $devices_list = vm_devices_list($vmid);
3443 return 1 if !defined($devices_list->{$deviceid});
3444 sleep 1;
afdb31d5 3445 }
63c2da2f
DM
3446
3447 die "error on hot-unplugging device '$deviceid'\n";
873c2d69
DA
3448}
3449
cdd20088 3450sub qemu_findorcreatescsihw {
cfc817c7
DA
3451 my ($storecfg, $conf, $vmid, $device) = @_;
3452
ee034f5c 3453 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
2733141c
AD
3454
3455 my $scsihwid="$controller_prefix$controller";
cfc817c7
DA
3456 my $devices_list = vm_devices_list($vmid);
3457
cdd20088 3458 if(!defined($devices_list->{$scsihwid})) {
fc8b40fd 3459 vm_deviceplug($storecfg, $conf, $vmid, $scsihwid, $device);
cfc817c7 3460 }
fee46675 3461
cfc817c7
DA
3462 return 1;
3463}
3464
8ce30dde
AD
3465sub qemu_deletescsihw {
3466 my ($conf, $vmid, $opt) = @_;
3467
3468 my $device = parse_drive($opt, $conf->{$opt});
3469
a1511b3c 3470 if ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
2733141c
AD
3471 vm_deviceunplug($vmid, $conf, "virtioscsi$device->{index}");
3472 return 1;
3473 }
3474
ee034f5c 3475 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
8ce30dde
AD
3476
3477 my $devices_list = vm_devices_list($vmid);
3478 foreach my $opt (keys %{$devices_list}) {
3479 if (PVE::QemuServer::valid_drivename($opt)) {
3480 my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
3481 if($drive->{interface} eq 'scsi' && $drive->{index} < (($maxdev-1)*($controller+1))) {
3482 return 1;
3483 }
3484 }
3485 }
3486
3487 my $scsihwid="scsihw$controller";
3488
3489 vm_deviceunplug($vmid, $conf, $scsihwid);
3490
3491 return 1;
3492}
3493
281fedb3 3494sub qemu_add_pci_bridge {
40f28a9f
AD
3495 my ($storecfg, $conf, $vmid, $device) = @_;
3496
3497 my $bridges = {};
281fedb3
DM
3498
3499 my $bridgeid;
3500
40f28a9f
AD
3501 print_pci_addr($device, $bridges);
3502
3503 while (my ($k, $v) = each %$bridges) {
3504 $bridgeid = $k;
3505 }
fee46675 3506 return 1 if !defined($bridgeid) || $bridgeid < 1;
281fedb3 3507
40f28a9f
AD
3508 my $bridge = "pci.$bridgeid";
3509 my $devices_list = vm_devices_list($vmid);
3510
281fedb3 3511 if (!defined($devices_list->{$bridge})) {
fee46675 3512 vm_deviceplug($storecfg, $conf, $vmid, $bridge);
40f28a9f 3513 }
281fedb3 3514
40f28a9f
AD
3515 return 1;
3516}
3517
25088687
DM
3518sub qemu_set_link_status {
3519 my ($vmid, $device, $up) = @_;
3520
a1b7d579 3521 vm_mon_cmd($vmid, "set_link", name => $device,
25088687
DM
3522 up => $up ? JSON::true : JSON::false);
3523}
3524
2630d2a9
DA
3525sub qemu_netdevadd {
3526 my ($vmid, $conf, $device, $deviceid) = @_;
3527
3528 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
73aa03b8 3529 my %options = split(/[=,]/, $netdev);
2630d2a9 3530
73aa03b8
AD
3531 vm_mon_cmd($vmid, "netdev_add", %options);
3532 return 1;
2630d2a9
DA
3533}
3534
3535sub qemu_netdevdel {
3536 my ($vmid, $deviceid) = @_;
3537
89c1e0f4 3538 vm_mon_cmd($vmid, "netdev_del", id => $deviceid);
2630d2a9
DA
3539}
3540
838776ab 3541sub qemu_cpu_hotplug {
8edc9c08 3542 my ($vmid, $conf, $vcpus) = @_;
838776ab 3543
8edc9c08
AD
3544 my $sockets = 1;
3545 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
3546 $sockets = $conf->{sockets} if $conf->{sockets};
3547 my $cores = $conf->{cores} || 1;
3548 my $maxcpus = $sockets * $cores;
838776ab 3549
8edc9c08 3550 $vcpus = $maxcpus if !$vcpus;
3a11fadb 3551
8edc9c08
AD
3552 die "you can't add more vcpus than maxcpus\n"
3553 if $vcpus > $maxcpus;
3a11fadb 3554
8edc9c08 3555 my $currentvcpus = $conf->{vcpus} || $maxcpus;
3a11fadb 3556 die "online cpu unplug is not yet possible\n"
8edc9c08 3557 if $vcpus < $currentvcpus;
838776ab 3558
8edc9c08
AD
3559 my $currentrunningvcpus = vm_mon_cmd($vmid, "query-cpus");
3560 die "vcpus in running vm is different than configuration\n"
3561 if scalar(@{$currentrunningvcpus}) != $currentvcpus;
838776ab 3562
8edc9c08 3563 for (my $i = $currentvcpus; $i < $vcpus; $i++) {
838776ab
AD
3564 vm_mon_cmd($vmid, "cpu-add", id => int($i));
3565 }
3566}
3567
4d3f29ed
AD
3568sub qemu_memory_hotplug {
3569 my ($vmid, $conf, $defaults, $opt, $value) = @_;
3570
3571 return $value if !check_running($vmid);
a1b7d579 3572
4d3f29ed 3573 my $memory = $conf->{memory} || $defaults->{memory};
a1b7d579 3574 $value = $defaults->{memory} if !$value;
4d3f29ed
AD
3575 return $value if $value == $memory;
3576
3577 my $static_memory = $STATICMEM;
3578 my $dimm_memory = $memory - $static_memory;
3579
3580 die "memory can't be lower than $static_memory MB" if $value < $static_memory;
3581 die "memory unplug is not yet available" if $value < $memory;
4d3f29ed
AD
3582 die "you cannot add more memory than $MAX_MEM MB!\n" if $memory > $MAX_MEM;
3583
3584
3585 my $sockets = 1;
3586 $sockets = $conf->{sockets} if $conf->{sockets};
3587
e059fb4d
AD
3588 foreach_dimm($conf, $vmid, $value, $sockets, sub {
3589 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
3590
3591 return if $current_size <= $conf->{memory};
4d3f29ed
AD
3592
3593 eval { vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-ram", id => "mem-$name", props => { size => int($dimm_size*1024*1024) } ) };
3594 if (my $err = $@) {
3595 eval { qemu_objectdel($vmid, "mem-$name"); };
3596 die $err;
3597 }
3598
3599 eval { vm_mon_cmd($vmid, "device_add", driver => "pc-dimm", id => "$name", memdev => "mem-$name", node => $numanode) };
3600 if (my $err = $@) {
3601 eval { qemu_objectdel($vmid, "mem-$name"); };
3602 die $err;
3603 }
3604 #update conf after each succesful module hotplug
e059fb4d 3605 $conf->{memory} = $current_size;
4d3f29ed 3606 update_config_nolock($vmid, $conf, 1);
e059fb4d 3607 });
4d3f29ed
AD
3608}
3609
affd2f88
AD
3610sub qemu_block_set_io_throttle {
3611 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
3612
f3f323a3
AD
3613 return if !check_running($vmid) ;
3614
f3f323a3
AD
3615 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));
3616
affd2f88
AD
3617}
3618
f5eb281a 3619# old code, only used to shutdown old VM after update
dab36e1e
DM
3620sub __read_avail {
3621 my ($fh, $timeout) = @_;
3622
3623 my $sel = new IO::Select;
3624 $sel->add($fh);
3625
3626 my $res = '';
3627 my $buf;
3628
3629 my @ready;
3630 while (scalar (@ready = $sel->can_read($timeout))) {
3631 my $count;
3632 if ($count = $fh->sysread($buf, 8192)) {
3633 if ($buf =~ /^(.*)\(qemu\) $/s) {
3634 $res .= $1;
3635 last;
3636 } else {
3637 $res .= $buf;
3638 }
3639 } else {
3640 if (!defined($count)) {
3641 die "$!\n";
3642 }
3643 last;
3644 }
3645 }
3646
3647 die "monitor read timeout\n" if !scalar(@ready);
f5eb281a 3648
dab36e1e
DM
3649 return $res;
3650}
3651
f5eb281a 3652# old code, only used to shutdown old VM after update
dab36e1e
DM
3653sub vm_monitor_command {
3654 my ($vmid, $cmdstr, $nocheck) = @_;
f5eb281a 3655
dab36e1e
DM
3656 my $res;
3657
3658 eval {
3659 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
3660
3661 my $sname = "${var_run_tmpdir}/$vmid.mon";
3662
3663 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
3664 die "unable to connect to VM $vmid socket - $!\n";
3665
3666 my $timeout = 3;
3667
3668 # hack: migrate sometime blocks the monitor (when migrate_downtime
3669 # is set)
3670 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3671 $timeout = 60*60; # 1 hour
3672 }
3673
3674 # read banner;
3675 my $data = __read_avail($sock, $timeout);
3676
3677 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
3678 die "got unexpected qemu monitor banner\n";
3679 }
3680
3681 my $sel = new IO::Select;
3682 $sel->add($sock);
3683
3684 if (!scalar(my @ready = $sel->can_write($timeout))) {
3685 die "monitor write error - timeout";
3686 }
3687
3688 my $fullcmd = "$cmdstr\r";
3689
3690 # syslog('info', "VM $vmid monitor command: $cmdstr");
3691
3692 my $b;
3693 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
3694 die "monitor write error - $!";
3695 }
3696
3697 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
3698
3699 $timeout = 20;
3700
3701 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3702 $timeout = 60*60; # 1 hour
3703 } elsif ($cmdstr =~ m/^(eject|change)/) {
3704 $timeout = 60; # note: cdrom mount command is slow
3705 }
3706 if ($res = __read_avail($sock, $timeout)) {
3707
3708 my @lines = split("\r?\n", $res);
f5eb281a 3709
dab36e1e 3710 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
f5eb281a 3711
dab36e1e
DM
3712 $res = join("\n", @lines);
3713 $res .= "\n";
3714 }
3715 };
3716
3717 my $err = $@;
3718
3719 if ($err) {
3720 syslog("err", "VM $vmid monitor command failed - $err");
3721 die $err;
3722 }
f5eb281a 3723
dab36e1e
DM
3724 return $res;
3725}
3726
c1175c92
AD
3727sub qemu_block_resize {
3728 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
3729
ed221350 3730 my $running = check_running($vmid);
c1175c92
AD
3731
3732 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
3733
3734 return if !$running;
3735
3736 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
3737
3738}
3739
1ab0057c
AD
3740sub qemu_volume_snapshot {
3741 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3742
ed221350 3743 my $running = check_running($vmid);
1ab0057c 3744
e5eaa028
WL
3745 if ($running && do_snapshots_with_qemu($storecfg, $volid)){
3746 vm_mon_cmd($vmid, "snapshot-drive", device => $deviceid, name => $snap);
3747 } else {
3748 PVE::Storage::volume_snapshot($storecfg, $volid, $snap);
3749 }
1ab0057c
AD
3750}
3751
fc46aff9
AD
3752sub qemu_volume_snapshot_delete {
3753 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3754
ed221350 3755 my $running = check_running($vmid);
fc46aff9
AD
3756
3757 return if !PVE::Storage::volume_snapshot_delete($storecfg, $volid, $snap, $running);
3758
3759 return if !$running;
3760
18bfb361 3761 vm_mon_cmd($vmid, "delete-drive-snapshot", device => $deviceid, name => $snap);
fc46aff9
AD
3762}
3763
264e519f
DM
3764sub set_migration_caps {
3765 my ($vmid) = @_;
a89fded1 3766
8b8345f3 3767 my $cap_ref = [];
a89fded1
AD
3768
3769 my $enabled_cap = {
8b8345f3
DM
3770 "auto-converge" => 1,
3771 "xbzrle" => 0,
3772 "x-rdma-pin-all" => 0,
3773 "zero-blocks" => 0,
a89fded1
AD
3774 };
3775
8b8345f3 3776 my $supported_capabilities = vm_mon_cmd_nocheck($vmid, "query-migrate-capabilities");
a89fded1 3777
8b8345f3 3778 for my $supported_capability (@$supported_capabilities) {
b463a3ce
SP
3779 push @$cap_ref, {
3780 capability => $supported_capability->{capability},
22430fa2
DM
3781 state => $enabled_cap->{$supported_capability->{capability}} ? JSON::true : JSON::false,
3782 };
a89fded1
AD
3783 }
3784
8b8345f3
DM
3785 vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => $cap_ref);
3786}
a89fded1 3787
81d95ae1 3788my $fast_plug_option = {
7498eb64 3789 'lock' => 1,
81d95ae1 3790 'name' => 1,
a1b7d579 3791 'onboot' => 1,
81d95ae1
DM
3792 'shares' => 1,
3793 'startup' => 1,
3794};
3795
3a11fadb
DM
3796# hotplug changes in [PENDING]
3797# $selection hash can be used to only apply specified options, for
3798# example: { cores => 1 } (only apply changed 'cores')
3799# $errors ref is used to return error messages
c427973b 3800sub vmconfig_hotplug_pending {
3a11fadb 3801 my ($vmid, $conf, $storecfg, $selection, $errors) = @_;
c427973b 3802
8e90138a 3803 my $defaults = load_defaults();
c427973b
DM
3804
3805 # commit values which do not have any impact on running VM first
3a11fadb
DM
3806 # Note: those option cannot raise errors, we we do not care about
3807 # $selection and always apply them.
3808
3809 my $add_error = sub {
3810 my ($opt, $msg) = @_;
3811 $errors->{$opt} = "hotplug problem - $msg";
3812 };
c427973b
DM
3813
3814 my $changes = 0;
3815 foreach my $opt (keys %{$conf->{pending}}) { # add/change
81d95ae1 3816 if ($fast_plug_option->{$opt}) {
c427973b
DM
3817 $conf->{$opt} = $conf->{pending}->{$opt};
3818 delete $conf->{pending}->{$opt};
3819 $changes = 1;
3820 }
3821 }
3822
3823 if ($changes) {
3824 update_config_nolock($vmid, $conf, 1);
3825 $conf = load_config($vmid); # update/reload
3826 }
3827
b3c2bdd1 3828 my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
c427973b 3829
3d7389fe
DM
3830 my @delete = PVE::Tools::split_list($conf->{pending}->{delete});
3831 foreach my $opt (@delete) {
3a11fadb 3832 next if $selection && !$selection->{$opt};
3a11fadb 3833 eval {
51a6f637
AD
3834 if ($opt eq 'hotplug') {
3835 die "skip\n" if ($conf->{hotplug} =~ /memory/);
3836 } elsif ($opt eq 'tablet') {
b3c2bdd1 3837 die "skip\n" if !$hotplug_features->{usb};
3a11fadb
DM
3838 if ($defaults->{tablet}) {
3839 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3840 } else {
3841 vm_deviceunplug($vmid, $conf, $opt);
3842 }
8edc9c08 3843 } elsif ($opt eq 'vcpus') {
b3c2bdd1 3844 die "skip\n" if !$hotplug_features->{cpu};
8edc9c08 3845 qemu_cpu_hotplug($vmid, $conf, undef);
9c2f7069 3846 } elsif ($opt eq 'balloon') {
81d95ae1
DM
3847 # enable balloon device is not hotpluggable
3848 die "skip\n" if !defined($conf->{balloon}) || $conf->{balloon};
3849 } elsif ($fast_plug_option->{$opt}) {
3850 # do nothing
3eec5767 3851 } elsif ($opt =~ m/^net(\d+)$/) {
b3c2bdd1 3852 die "skip\n" if !$hotplug_features->{network};
3eec5767 3853 vm_deviceunplug($vmid, $conf, $opt);
a05cff86 3854 } elsif (valid_drivename($opt)) {
b3c2bdd1 3855 die "skip\n" if !$hotplug_features->{disk} || $opt =~ m/(ide|sata)(\d+)/;
19120f99
AD
3856 vm_deviceunplug($vmid, $conf, $opt);
3857 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}));
4d3f29ed
AD
3858 } elsif ($opt =~ m/^memory$/) {
3859 die "skip\n" if !$hotplug_features->{memory};
3860 qemu_memory_hotplug($vmid, $conf, $defaults, $opt);
c8effec3
AD
3861 } elsif ($opt eq 'cpuunits') {
3862 cgroups_write("cpu", $vmid, "cpu.shares", $defaults->{cpuunits});
58be00f1
AD
3863 } elsif ($opt eq 'cpulimit') {
3864 cgroups_write("cpu", $vmid, "cpu.cfs_quota_us", -1);
3d7389fe 3865 } else {
e56beeda 3866 die "skip\n";
3d7389fe 3867 }
3a11fadb
DM
3868 };
3869 if (my $err = $@) {
e56beeda
DM
3870 &$add_error($opt, $err) if $err ne "skip\n";
3871 } else {
3a11fadb
DM
3872 # save new config if hotplug was successful
3873 delete $conf->{$opt};
3874 vmconfig_undelete_pending_option($conf, $opt);
3875 update_config_nolock($vmid, $conf, 1);
3876 $conf = load_config($vmid); # update/reload
3d7389fe 3877 }
3d7389fe
DM
3878 }
3879
3880 foreach my $opt (keys %{$conf->{pending}}) {
3a11fadb 3881 next if $selection && !$selection->{$opt};
3d7389fe 3882 my $value = $conf->{pending}->{$opt};
3a11fadb 3883 eval {
51a6f637
AD
3884 if ($opt eq 'hotplug') {
3885 die "skip\n" if ($value =~ /memory/) || ($value !~ /memory/ && $conf->{hotplug} =~ /memory/);
3886 } elsif ($opt eq 'tablet') {
b3c2bdd1 3887 die "skip\n" if !$hotplug_features->{usb};
3a11fadb
DM
3888 if ($value == 1) {
3889 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3890 } elsif ($value == 0) {
3891 vm_deviceunplug($vmid, $conf, $opt);
3892 }
8edc9c08 3893 } elsif ($opt eq 'vcpus') {
b3c2bdd1 3894 die "skip\n" if !$hotplug_features->{cpu};
3a11fadb
DM
3895 qemu_cpu_hotplug($vmid, $conf, $value);
3896 } elsif ($opt eq 'balloon') {
81d95ae1 3897 # enable/disable balloning device is not hotpluggable
8fe689e7 3898 my $old_balloon_enabled = !!(!defined($conf->{balloon}) || $conf->{balloon});
a1b7d579 3899 my $new_balloon_enabled = !!(!defined($conf->{pending}->{balloon}) || $conf->{pending}->{balloon});
81d95ae1
DM
3900 die "skip\n" if $old_balloon_enabled != $new_balloon_enabled;
3901
3a11fadb 3902 # allow manual ballooning if shares is set to zero
4cc1efa6 3903 if ((defined($conf->{shares}) && ($conf->{shares} == 0))) {
9c2f7069
AD
3904 my $balloon = $conf->{pending}->{balloon} || $conf->{memory} || $defaults->{memory};
3905 vm_mon_cmd($vmid, "balloon", value => $balloon*1024*1024);
3906 }
a1b7d579 3907 } elsif ($opt =~ m/^net(\d+)$/) {
3eec5767 3908 # some changes can be done without hotplug
a1b7d579 3909 vmconfig_update_net($storecfg, $conf, $hotplug_features->{network},
b3c2bdd1 3910 $vmid, $opt, $value);
a05cff86
DM
3911 } elsif (valid_drivename($opt)) {
3912 # some changes can be done without hotplug
b3c2bdd1
DM
3913 vmconfig_update_disk($storecfg, $conf, $hotplug_features->{disk},
3914 $vmid, $opt, $value, 1);
4d3f29ed
AD
3915 } elsif ($opt =~ m/^memory$/) { #dimms
3916 die "skip\n" if !$hotplug_features->{memory};
3917 $value = qemu_memory_hotplug($vmid, $conf, $defaults, $opt, $value);
c8effec3
AD
3918 } elsif ($opt eq 'cpuunits') {
3919 cgroups_write("cpu", $vmid, "cpu.shares", $conf->{pending}->{$opt});
58be00f1 3920 } elsif ($opt eq 'cpulimit') {
c6f773b8 3921 my $cpulimit = $conf->{pending}->{$opt} == 0 ? -1 : int($conf->{pending}->{$opt} * 100000);
58be00f1 3922 cgroups_write("cpu", $vmid, "cpu.cfs_quota_us", $cpulimit);
3a11fadb 3923 } else {
e56beeda 3924 die "skip\n"; # skip non-hot-pluggable options
3d7389fe 3925 }
3a11fadb
DM
3926 };
3927 if (my $err = $@) {
e56beeda
DM
3928 &$add_error($opt, $err) if $err ne "skip\n";
3929 } else {
3a11fadb
DM
3930 # save new config if hotplug was successful
3931 $conf->{$opt} = $value;
3932 delete $conf->{pending}->{$opt};
3933 update_config_nolock($vmid, $conf, 1);
3934 $conf = load_config($vmid); # update/reload
3d7389fe 3935 }
3d7389fe 3936 }
c427973b 3937}
055d554d
DM
3938
3939sub vmconfig_apply_pending {
3a11fadb 3940 my ($vmid, $conf, $storecfg) = @_;
c427973b
DM
3941
3942 # cold plug
055d554d
DM
3943
3944 my @delete = PVE::Tools::split_list($conf->{pending}->{delete});
3945 foreach my $opt (@delete) { # delete
3946 die "internal error" if $opt =~ m/^unused/;
3947 $conf = load_config($vmid); # update/reload
3948 if (!defined($conf->{$opt})) {
3949 vmconfig_undelete_pending_option($conf, $opt);
3950 update_config_nolock($vmid, $conf, 1);
3951 } elsif (valid_drivename($opt)) {
3952 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}));
3953 vmconfig_undelete_pending_option($conf, $opt);
3954 delete $conf->{$opt};
3955 update_config_nolock($vmid, $conf, 1);
3956 } else {
3957 vmconfig_undelete_pending_option($conf, $opt);
3958 delete $conf->{$opt};
3959 update_config_nolock($vmid, $conf, 1);
3960 }
3961 }
3962
3963 $conf = load_config($vmid); # update/reload
3964
3965 foreach my $opt (keys %{$conf->{pending}}) { # add/change
3966 $conf = load_config($vmid); # update/reload
3967
3968 if (defined($conf->{$opt}) && ($conf->{$opt} eq $conf->{pending}->{$opt})) {
3969 # skip if nothing changed
3970 } elsif (valid_drivename($opt)) {
3971 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}))
3972 if defined($conf->{$opt});
3973 $conf->{$opt} = $conf->{pending}->{$opt};
3974 } else {
3975 $conf->{$opt} = $conf->{pending}->{$opt};
3976 }
3977
3978 delete $conf->{pending}->{$opt};
3979 update_config_nolock($vmid, $conf, 1);
3980 }
3981}
3982
3eec5767
DM
3983my $safe_num_ne = sub {
3984 my ($a, $b) = @_;
3985
3986 return 0 if !defined($a) && !defined($b);
3987 return 1 if !defined($a);
3988 return 1 if !defined($b);
3989
3990 return $a != $b;
3991};
3992
3993my $safe_string_ne = sub {
3994 my ($a, $b) = @_;
3995
3996 return 0 if !defined($a) && !defined($b);
3997 return 1 if !defined($a);
3998 return 1 if !defined($b);
3999
4000 return $a ne $b;
4001};
4002
4003sub vmconfig_update_net {
b3c2bdd1 4004 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value) = @_;
3eec5767
DM
4005
4006 my $newnet = parse_net($value);
4007
4008 if ($conf->{$opt}) {
4009 my $oldnet = parse_net($conf->{$opt});
4010
4011 if (&$safe_string_ne($oldnet->{model}, $newnet->{model}) ||
4012 &$safe_string_ne($oldnet->{macaddr}, $newnet->{macaddr}) ||
4013 &$safe_num_ne($oldnet->{queues}, $newnet->{queues}) ||
4014 !($newnet->{bridge} && $oldnet->{bridge})) { # bridge/nat mode change
4015
4016 # for non online change, we try to hot-unplug
7196b757 4017 die "skip\n" if !$hotplug;
3eec5767
DM
4018 vm_deviceunplug($vmid, $conf, $opt);
4019 } else {
4020
4021 die "internal error" if $opt !~ m/net(\d+)/;
4022 my $iface = "tap${vmid}i$1";
a1b7d579 4023
3eec5767
DM
4024 if (&$safe_num_ne($oldnet->{rate}, $newnet->{rate})) {
4025 PVE::Network::tap_rate_limit($iface, $newnet->{rate});
4026 }
4027
25088687
DM
4028 if (&$safe_string_ne($oldnet->{bridge}, $newnet->{bridge}) ||
4029 &$safe_num_ne($oldnet->{tag}, $newnet->{tag}) ||
4030 &$safe_num_ne($oldnet->{firewall}, $newnet->{firewall})) {
3eec5767
DM
4031 PVE::Network::tap_unplug($iface);
4032 PVE::Network::tap_plug($iface, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall});
4033 }
38c590d9 4034
25088687
DM
4035 if (&$safe_string_ne($oldnet->{link_down}, $newnet->{link_down})) {
4036 qemu_set_link_status($vmid, $opt, !$newnet->{link_down});
4037 }
4038
38c590d9 4039 return 1;
3eec5767
DM
4040 }
4041 }
a1b7d579 4042
7196b757 4043 if ($hotplug) {
38c590d9
DM
4044 vm_deviceplug($storecfg, $conf, $vmid, $opt, $newnet);
4045 } else {
4046 die "skip\n";
4047 }
3eec5767
DM
4048}
4049
a05cff86 4050sub vmconfig_update_disk {
b3c2bdd1 4051 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value, $force) = @_;
a05cff86
DM
4052
4053 # fixme: do we need force?
4054
4055 my $drive = parse_drive($opt, $value);
4056
4057 if ($conf->{$opt}) {
4058
4059 if (my $old_drive = parse_drive($opt, $conf->{$opt})) {
4060
4061 my $media = $drive->{media} || 'disk';
4062 my $oldmedia = $old_drive->{media} || 'disk';
4063 die "unable to change media type\n" if $media ne $oldmedia;
4064
4065 if (!drive_is_cdrom($old_drive)) {
4066
a1b7d579 4067 if ($drive->{file} ne $old_drive->{file}) {
a05cff86 4068
7196b757 4069 die "skip\n" if !$hotplug;
a05cff86
DM
4070
4071 # unplug and register as unused
4072 vm_deviceunplug($vmid, $conf, $opt);
4073 vmconfig_register_unused_drive($storecfg, $vmid, $conf, $old_drive)
a1b7d579 4074
a05cff86
DM
4075 } else {
4076 # update existing disk
4077
4078 # skip non hotpluggable value
a1b7d579 4079 if (&$safe_num_ne($drive->{discard}, $old_drive->{discard}) ||
22de899a 4080 &$safe_string_ne($drive->{iothread}, $old_drive->{iothread}) ||
6e11f143 4081 &$safe_string_ne($drive->{queues}, $old_drive->{queues}) ||
a05cff86
DM
4082 &$safe_string_ne($drive->{cache}, $old_drive->{cache})) {
4083 die "skip\n";
4084 }
4085
4086 # apply throttle
4087 if (&$safe_num_ne($drive->{mbps}, $old_drive->{mbps}) ||
4088 &$safe_num_ne($drive->{mbps_rd}, $old_drive->{mbps_rd}) ||
4089 &$safe_num_ne($drive->{mbps_wr}, $old_drive->{mbps_wr}) ||
4090 &$safe_num_ne($drive->{iops}, $old_drive->{iops}) ||
4091 &$safe_num_ne($drive->{iops_rd}, $old_drive->{iops_rd}) ||
4092 &$safe_num_ne($drive->{iops_wr}, $old_drive->{iops_wr}) ||
4093 &$safe_num_ne($drive->{mbps_max}, $old_drive->{mbps_max}) ||
4094 &$safe_num_ne($drive->{mbps_rd_max}, $old_drive->{mbps_rd_max}) ||
4095 &$safe_num_ne($drive->{mbps_wr_max}, $old_drive->{mbps_wr_max}) ||
4096 &$safe_num_ne($drive->{iops_max}, $old_drive->{iops_max}) ||
4097 &$safe_num_ne($drive->{iops_rd_max}, $old_drive->{iops_rd_max}) ||
4098 &$safe_num_ne($drive->{iops_wr_max}, $old_drive->{iops_wr_max})) {
a1b7d579 4099
a05cff86
DM
4100 qemu_block_set_io_throttle($vmid,"drive-$opt",
4101 ($drive->{mbps} || 0)*1024*1024,
4102 ($drive->{mbps_rd} || 0)*1024*1024,
4103 ($drive->{mbps_wr} || 0)*1024*1024,
4104 $drive->{iops} || 0,
4105 $drive->{iops_rd} || 0,
4106 $drive->{iops_wr} || 0,
4107 ($drive->{mbps_max} || 0)*1024*1024,
4108 ($drive->{mbps_rd_max} || 0)*1024*1024,
4109 ($drive->{mbps_wr_max} || 0)*1024*1024,
4110 $drive->{iops_max} || 0,
4111 $drive->{iops_rd_max} || 0,
4112 $drive->{iops_wr_max} || 0);
4113
4114 }
a1b7d579 4115
a05cff86
DM
4116 return 1;
4117 }
4de1bb25
DM
4118
4119 } else { # cdrom
a1b7d579 4120
4de1bb25
DM
4121 if ($drive->{file} eq 'none') {
4122 vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt");
4123 } else {
4124 my $path = get_iso_path($storecfg, $vmid, $drive->{file});
4125 vm_mon_cmd($vmid, "eject", force => JSON::true,device => "drive-$opt"); # force eject if locked
4126 vm_mon_cmd($vmid, "change", device => "drive-$opt",target => "$path") if $path;
4127 }
a1b7d579 4128
34758d66 4129 return 1;
a05cff86
DM
4130 }
4131 }
4132 }
4133
a1b7d579 4134 die "skip\n" if !$hotplug || $opt =~ m/(ide|sata)(\d+)/;
4de1bb25
DM
4135 # hotplug new disks
4136 vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
a05cff86
DM
4137}
4138
1e3baf05 4139sub vm_start {
1d794448 4140 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
1e3baf05 4141
6b64503e 4142 lock_config($vmid, sub {
7e8dcf2c 4143 my $conf = load_config($vmid, $migratedfrom);
1e3baf05 4144
8b43bc11 4145 die "you can't start a vm if it's a template\n" if is_template($conf);
3dcb98d5 4146
6b64503e 4147 check_lock($conf) if !$skiplock;
1e3baf05 4148
7e8dcf2c 4149 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
1e3baf05 4150
055d554d 4151 if (!$statefile && scalar(keys %{$conf->{pending}})) {
3a11fadb 4152 vmconfig_apply_pending($vmid, $conf, $storecfg);
055d554d
DM
4153 $conf = load_config($vmid); # update/reload
4154 }
4155
6c47d546
DM
4156 my $defaults = load_defaults();
4157
4158 # set environment variable useful inside network script
4159 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
4160
1d794448 4161 my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
6c47d546 4162
1e3baf05 4163 my $migrate_port = 0;
5bc1e039 4164 my $migrate_uri;
1e3baf05
DM
4165 if ($statefile) {
4166 if ($statefile eq 'tcp') {
5bc1e039
SP
4167 my $localip = "localhost";
4168 my $datacenterconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
af0eba7e 4169 my $nodename = PVE::INotify::nodename();
5bc1e039 4170 if ($datacenterconf->{migration_unsecure}) {
5bc1e039
SP
4171 $localip = PVE::Cluster::remote_node_ip($nodename, 1);
4172 }
af0eba7e
WB
4173 my $pfamily = PVE::Tools::get_host_address_family($nodename);
4174 $migrate_port = PVE::Tools::next_migrate_port($pfamily);
2fbd27ea 4175 $migrate_uri = "tcp:[${localip}]:${migrate_port}";
6c47d546
DM
4176 push @$cmd, '-incoming', $migrate_uri;
4177 push @$cmd, '-S';
1e3baf05 4178 } else {
6c47d546 4179 push @$cmd, '-loadstate', $statefile;
1e3baf05 4180 }
91bd6c90
DM
4181 } elsif ($paused) {
4182 push @$cmd, '-S';
1e3baf05
DM
4183 }
4184
1e3baf05 4185 # host pci devices
040b06b7
DA
4186 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
4187 my $d = parse_hostpci($conf->{"hostpci$i"});
4188 next if !$d;
b1f72af6
AD
4189 my $pcidevices = $d->{pciid};
4190 foreach my $pcidevice (@$pcidevices) {
4191 my $pciid = $pcidevice->{id}.".".$pcidevice->{function};
000fc0a2 4192
b1f72af6
AD
4193 my $info = pci_device_info("0000:$pciid");
4194 die "IOMMU not present\n" if !check_iommu_support();
4195 die "no pci device info for device '$pciid'\n" if !$info;
000fc0a2 4196
b1f72af6
AD
4197 if ($d->{driver} && $d->{driver} eq "vfio") {
4198 die "can't unbind/bind pci group to vfio '$pciid'\n" if !pci_dev_group_bind_to_vfio($pciid);
4199 } else {
4200 die "can't unbind/bind to stub pci device '$pciid'\n" if !pci_dev_bind_to_stub($info);
4201 }
4202
8f3e88af 4203 die "can't reset pci device '$pciid'\n" if $info->{has_fl_reset} and !pci_dev_reset($info);
b1f72af6 4204 }
040b06b7 4205 }
1e3baf05
DM
4206
4207 PVE::Storage::activate_volumes($storecfg, $vollist);
4208
585b6e28
DM
4209 eval { run_command($cmd, timeout => $statefile ? undef : 30,
4210 umask => 0077); };
1e3baf05 4211 my $err = $@;
ff1a2432 4212 die "start failed: $err" if $err;
1e3baf05 4213
5bc1e039 4214 print "migration listens on $migrate_uri\n" if $migrate_uri;
afdb31d5 4215
8c609afd 4216 if ($statefile && $statefile ne 'tcp') {
95381ce0 4217 eval { vm_mon_cmd_nocheck($vmid, "cont"); };
8c609afd 4218 warn $@ if $@;
62de2cbd
DM
4219 }
4220
1d794448 4221 if ($migratedfrom) {
a89fded1
AD
4222
4223 eval {
8e90138a 4224 set_migration_caps($vmid);
a89fded1 4225 };
1d794448 4226 warn $@ if $@;
a89fded1 4227
1d794448
DM
4228 if ($spice_port) {
4229 print "spice listens on port $spice_port\n";
4230 if ($spice_ticket) {
8e90138a
DM
4231 vm_mon_cmd_nocheck($vmid, "set_password", protocol => 'spice', password => $spice_ticket);
4232 vm_mon_cmd_nocheck($vmid, "expire_password", protocol => 'spice', time => "+30");
95a4b4a9
AD
4233 }
4234 }
4235
1d794448 4236 } else {
4ec05c4c 4237
15b1fc93 4238 if (!$statefile && (!defined($conf->{balloon}) || $conf->{balloon})) {
be190583 4239 vm_mon_cmd_nocheck($vmid, "balloon", value => $conf->{balloon}*1024*1024)
4ec05c4c 4240 if $conf->{balloon};
4ec05c4c 4241 }
25088687
DM
4242
4243 foreach my $opt (keys %$conf) {
4244 next if $opt !~ m/^net\d+$/;
4245 my $nicconf = parse_net($conf->{$opt});
4246 qemu_set_link_status($vmid, $opt, 0) if $nicconf->{link_down};
4247 }
e18b0b99 4248 }
a1b7d579 4249
eb065317
AD
4250 vm_mon_cmd_nocheck($vmid, 'qom-set',
4251 path => "machine/peripheral/balloon0",
4252 property => "guest-stats-polling-interval",
4253 value => 2) if (!defined($conf->{balloon}) || $conf->{balloon});
4254
1e3baf05
DM
4255 });
4256}
4257
0eedc444
AD
4258sub vm_mon_cmd {
4259 my ($vmid, $execute, %params) = @_;
4260
26f11676
DM
4261 my $cmd = { execute => $execute, arguments => \%params };
4262 vm_qmp_command($vmid, $cmd);
0eedc444
AD
4263}
4264
4265sub vm_mon_cmd_nocheck {
4266 my ($vmid, $execute, %params) = @_;
4267
26f11676
DM
4268 my $cmd = { execute => $execute, arguments => \%params };
4269 vm_qmp_command($vmid, $cmd, 1);
0eedc444
AD
4270}
4271
c971c4f2 4272sub vm_qmp_command {
c5a07de5 4273 my ($vmid, $cmd, $nocheck) = @_;
97d62eb7 4274
c971c4f2 4275 my $res;
26f11676 4276
14db5366
DM
4277 my $timeout;
4278 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
4279 $timeout = $cmd->{arguments}->{timeout};
4280 delete $cmd->{arguments}->{timeout};
4281 }
be190583 4282
c971c4f2
AD
4283 eval {
4284 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
7a6c2150
DM
4285 my $sname = qmp_socket($vmid);
4286 if (-e $sname) { # test if VM is reasonambe new and supports qmp/qga
c5a07de5 4287 my $qmpclient = PVE::QMPClient->new();
dab36e1e 4288
14db5366 4289 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
c5a07de5 4290 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
dab36e1e
DM
4291 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
4292 if scalar(%{$cmd->{arguments}});
4293 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
4294 } else {
4295 die "unable to open monitor socket\n";
4296 }
c971c4f2 4297 };
26f11676 4298 if (my $err = $@) {
c971c4f2
AD
4299 syslog("err", "VM $vmid qmp command failed - $err");
4300 die $err;
4301 }
4302
4303 return $res;
4304}
4305
9df5cbcc
DM
4306sub vm_human_monitor_command {
4307 my ($vmid, $cmdline) = @_;
4308
4309 my $res;
4310
f5eb281a 4311 my $cmd = {
9df5cbcc
DM
4312 execute => 'human-monitor-command',
4313 arguments => { 'command-line' => $cmdline},
4314 };
4315
4316 return vm_qmp_command($vmid, $cmd);
4317}
4318
1e3baf05
DM
4319sub vm_commandline {
4320 my ($storecfg, $vmid) = @_;
4321
6b64503e 4322 my $conf = load_config($vmid);
1e3baf05
DM
4323
4324 my $defaults = load_defaults();
4325
6b64503e 4326 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
1e3baf05 4327
6b64503e 4328 return join(' ', @$cmd);
1e3baf05
DM
4329}
4330
4331sub vm_reset {
4332 my ($vmid, $skiplock) = @_;
4333
6b64503e 4334 lock_config($vmid, sub {
1e3baf05 4335
6b64503e 4336 my $conf = load_config($vmid);
1e3baf05 4337
6b64503e 4338 check_lock($conf) if !$skiplock;
1e3baf05 4339
816e2c4a 4340 vm_mon_cmd($vmid, "system_reset");
ff1a2432
DM
4341 });
4342}
4343
4344sub get_vm_volumes {
4345 my ($conf) = @_;
1e3baf05 4346
ff1a2432 4347 my $vollist = [];
d5769dc2
DM
4348 foreach_volid($conf, sub {
4349 my ($volid, $is_cdrom) = @_;
ff1a2432 4350
d5769dc2 4351 return if $volid =~ m|^/|;
ff1a2432 4352
d5769dc2
DM
4353 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
4354 return if !$sid;
ff1a2432
DM
4355
4356 push @$vollist, $volid;
1e3baf05 4357 });
ff1a2432
DM
4358
4359 return $vollist;
4360}
4361
4362sub vm_stop_cleanup {
70b04821 4363 my ($storecfg, $vmid, $conf, $keepActive, $apply_pending_changes) = @_;
ff1a2432 4364
745fed70 4365 eval {
ff1a2432 4366
254575e9
DM
4367 if (!$keepActive) {
4368 my $vollist = get_vm_volumes($conf);
4369 PVE::Storage::deactivate_volumes($storecfg, $vollist);
4370 }
a1b7d579 4371
ab6a046f 4372 foreach my $ext (qw(mon qmp pid vnc qga)) {
961bfcb2
DM
4373 unlink "/var/run/qemu-server/${vmid}.$ext";
4374 }
a1b7d579 4375
70b04821 4376 vmconfig_apply_pending($vmid, $conf, $storecfg) if $apply_pending_changes;
745fed70
DM
4377 };
4378 warn $@ if $@; # avoid errors - just warn
1e3baf05
DM
4379}
4380
e6c3b671 4381# Note: use $nockeck to skip tests if VM configuration file exists.
254575e9
DM
4382# We need that when migration VMs to other nodes (files already moved)
4383# Note: we set $keepActive in vzdump stop mode - volumes need to stay active
1e3baf05 4384sub vm_stop {
af30308f 4385 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
9269013a 4386
9269013a 4387 $force = 1 if !defined($force) && !$shutdown;
1e3baf05 4388
af30308f
DM
4389 if ($migratedfrom){
4390 my $pid = check_running($vmid, $nocheck, $migratedfrom);
4391 kill 15, $pid if $pid;
4392 my $conf = load_config($vmid, $migratedfrom);
70b04821 4393 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 0);
af30308f
DM
4394 return;
4395 }
4396
e6c3b671 4397 lock_config($vmid, sub {
1e3baf05 4398
e6c3b671 4399 my $pid = check_running($vmid, $nocheck);
ff1a2432 4400 return if !$pid;
1e3baf05 4401
ff1a2432 4402 my $conf;
e6c3b671 4403 if (!$nocheck) {
ff1a2432 4404 $conf = load_config($vmid);
e6c3b671 4405 check_lock($conf) if !$skiplock;
7f4a5b5a
DM
4406 if (!defined($timeout) && $shutdown && $conf->{startup}) {
4407 my $opts = parse_startup($conf->{startup});
4408 $timeout = $opts->{down} if $opts->{down};
4409 }
e6c3b671 4410 }
19672434 4411
7f4a5b5a 4412 $timeout = 60 if !defined($timeout);
67fb9de6 4413
9269013a
DM
4414 eval {
4415 if ($shutdown) {
fbda7965 4416 if (defined($conf) && $conf->{agent}) {
2ea54503 4417 vm_qmp_command($vmid, { execute => "guest-shutdown" }, $nocheck);
1c0c1c17 4418 } else {
2ea54503 4419 vm_qmp_command($vmid, { execute => "system_powerdown" }, $nocheck);
1c0c1c17 4420 }
9269013a 4421 } else {
2ea54503 4422 vm_qmp_command($vmid, { execute => "quit" }, $nocheck);
afdb31d5 4423 }
9269013a 4424 };
1e3baf05
DM
4425 my $err = $@;
4426
4427 if (!$err) {
1e3baf05 4428 my $count = 0;
e6c3b671 4429 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
4430 $count++;
4431 sleep 1;
4432 }
4433
4434 if ($count >= $timeout) {
9269013a
DM
4435 if ($force) {
4436 warn "VM still running - terminating now with SIGTERM\n";
4437 kill 15, $pid;
4438 } else {
4439 die "VM quit/powerdown failed - got timeout\n";
4440 }
4441 } else {
70b04821 4442 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
9269013a 4443 return;
1e3baf05
DM
4444 }
4445 } else {
9269013a
DM
4446 if ($force) {
4447 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
4448 kill 15, $pid;
4449 } else {
afdb31d5 4450 die "VM quit/powerdown failed\n";
9269013a 4451 }
1e3baf05
DM
4452 }
4453
4454 # wait again
ff1a2432 4455 $timeout = 10;
1e3baf05
DM
4456
4457 my $count = 0;
e6c3b671 4458 while (($count < $timeout) && check_running($vmid, $nocheck)) {
1e3baf05
DM
4459 $count++;
4460 sleep 1;
4461 }
4462
4463 if ($count >= $timeout) {
ff1a2432 4464 warn "VM still running - terminating now with SIGKILL\n";
1e3baf05 4465 kill 9, $pid;
ff1a2432 4466 sleep 1;
1e3baf05
DM
4467 }
4468
70b04821 4469 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
ff1a2432 4470 });
1e3baf05
DM
4471}
4472
4473sub vm_suspend {
4474 my ($vmid, $skiplock) = @_;
4475
6b64503e 4476 lock_config($vmid, sub {
1e3baf05 4477
6b64503e 4478 my $conf = load_config($vmid);
1e3baf05 4479
051347aa 4480 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
bcb7c9cf 4481
f77f91f3 4482 vm_mon_cmd($vmid, "stop");
1e3baf05
DM
4483 });
4484}
4485
4486sub vm_resume {
4487 my ($vmid, $skiplock) = @_;
4488
6b64503e 4489 lock_config($vmid, sub {
1e3baf05 4490
6b64503e 4491 my $conf = load_config($vmid);
1e3baf05 4492
051347aa 4493 check_lock($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
1e3baf05 4494
12060fe8 4495 vm_mon_cmd($vmid, "cont");
1e3baf05
DM
4496 });
4497}
4498
5fdbe4f0
DM
4499sub vm_sendkey {
4500 my ($vmid, $skiplock, $key) = @_;
1e3baf05 4501
6b64503e 4502 lock_config($vmid, sub {
1e3baf05 4503
6b64503e 4504 my $conf = load_config($vmid);
f5eb281a 4505
7b7c6d1b
DM
4506 # there is no qmp command, so we use the human monitor command
4507 vm_human_monitor_command($vmid, "sendkey $key");
1e3baf05
DM
4508 });
4509}
4510
4511sub vm_destroy {
4512 my ($storecfg, $vmid, $skiplock) = @_;
4513
6b64503e 4514 lock_config($vmid, sub {
1e3baf05 4515
6b64503e 4516 my $conf = load_config($vmid);
1e3baf05 4517
6b64503e 4518 check_lock($conf) if !$skiplock;
1e3baf05 4519
ff1a2432 4520 if (!check_running($vmid)) {
ff1a2432
DM
4521 destroy_vm($storecfg, $vmid);
4522 } else {
4523 die "VM $vmid is running - destroy failed\n";
1e3baf05
DM
4524 }
4525 });
4526}
4527
1e3baf05
DM
4528# pci helpers
4529
4530sub file_write {
4531 my ($filename, $buf) = @_;
4532
6b64503e 4533 my $fh = IO::File->new($filename, "w");
1e3baf05
DM
4534 return undef if !$fh;
4535
4536 my $res = print $fh $buf;
4537
4538 $fh->close();
4539
4540 return $res;
4541}
4542
4543sub pci_device_info {
4544 my ($name) = @_;
4545
4546 my $res;
4547
4548 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
4549 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
4550
4551 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
4552 return undef if !defined($irq) || $irq !~ m/^\d+$/;
4553
4554 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
4555 return undef if !defined($vendor) || $vendor !~ s/^0x//;
4556
4557 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
4558 return undef if !defined($product) || $product !~ s/^0x//;
4559
4560 $res = {
4561 name => $name,
4562 vendor => $vendor,
4563 product => $product,
4564 domain => $domain,
4565 bus => $bus,
4566 slot => $slot,
4567 func => $func,
4568 irq => $irq,
4569 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
4570 };
4571
4572 return $res;
4573}
4574
4575sub pci_dev_reset {
4576 my ($dev) = @_;
4577
4578 my $name = $dev->{name};
4579
4580 my $fn = "$pcisysfs/devices/$name/reset";
4581
6b64503e 4582 return file_write($fn, "1");
1e3baf05
DM
4583}
4584
4585sub pci_dev_bind_to_stub {
4586 my ($dev) = @_;
4587
4588 my $name = $dev->{name};
4589
4590 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
4591 return 1 if -d $testdir;
4592
4593 my $data = "$dev->{vendor} $dev->{product}";
6b64503e 4594 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
1e3baf05
DM
4595
4596 my $fn = "$pcisysfs/devices/$name/driver/unbind";
6b64503e 4597 if (!file_write($fn, $name)) {
1e3baf05
DM
4598 return undef if -f $fn;
4599 }
4600
4601 $fn = "$pcisysfs/drivers/pci-stub/bind";
4602 if (! -d $testdir) {
6b64503e 4603 return undef if !file_write($fn, $name);
1e3baf05
DM
4604 }
4605
4606 return -d $testdir;
4607}
4608
000fc0a2
SP
4609sub pci_dev_bind_to_vfio {
4610 my ($dev) = @_;
4611
4612 my $name = $dev->{name};
4613
4614 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4615
4616 if (!-d $vfio_basedir) {
4617 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4618 }
4619 die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir;
4620
4621 my $testdir = "$vfio_basedir/$name";
4622 return 1 if -d $testdir;
4623
4624 my $data = "$dev->{vendor} $dev->{product}";
4625 return undef if !file_write("$vfio_basedir/new_id", $data);
4626
4627 my $fn = "$pcisysfs/devices/$name/driver/unbind";
4628 if (!file_write($fn, $name)) {
4629 return undef if -f $fn;
4630 }
4631
4632 $fn = "$vfio_basedir/bind";
4633 if (! -d $testdir) {
4634 return undef if !file_write($fn, $name);
4635 }
4636
4637 return -d $testdir;
4638}
4639
4640sub pci_dev_group_bind_to_vfio {
4641 my ($pciid) = @_;
4642
4643 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4644
4645 if (!-d $vfio_basedir) {
4646 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4647 }
4648 die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir;
4649
4650 # get IOMMU group devices
4651 opendir(my $D, "$pcisysfs/devices/0000:$pciid/iommu_group/devices/") || die "Cannot open iommu_group: $!\n";
4652 my @devs = grep /^0000:/, readdir($D);
4653 closedir($D);
4654
4655 foreach my $pciid (@devs) {
4656 $pciid =~ m/^([:\.\da-f]+)$/ or die "PCI ID $pciid not valid!\n";
f8fa2ed7
SP
4657
4658 # pci bridges, switches or root ports are not supported
4659 # they have a pci_bus subdirectory so skip them
4660 next if (-e "$pcisysfs/devices/$pciid/pci_bus");
4661
000fc0a2
SP
4662 my $info = pci_device_info($1);
4663 pci_dev_bind_to_vfio($info) || die "Cannot bind $pciid to vfio\n";
4664 }
4665
4666 return 1;
4667}
4668
afdb31d5 4669sub print_pci_addr {
5bdcf937 4670 my ($id, $bridges) = @_;
6b64503e 4671
72a063e4 4672 my $res = '';
6b64503e 4673 my $devices = {
24f0d39a 4674 piix3 => { bus => 0, addr => 1 },
e5f7f8ed 4675 #addr2 : first videocard
13b5a753 4676 balloon0 => { bus => 0, addr => 3 },
0a40e8ea 4677 watchdog => { bus => 0, addr => 4 },
a1b7d579 4678 scsihw0 => { bus => 0, addr => 5 },
6731a4cf 4679 'pci.3' => { bus => 0, addr => 5 }, #can also be used for virtio-scsi-single bridge
cdd20088 4680 scsihw1 => { bus => 0, addr => 6 },
26ee04b6 4681 ahci0 => { bus => 0, addr => 7 },
ab6a046f 4682 qga0 => { bus => 0, addr => 8 },
1011b570 4683 spice => { bus => 0, addr => 9 },
6b64503e
DM
4684 virtio0 => { bus => 0, addr => 10 },
4685 virtio1 => { bus => 0, addr => 11 },
4686 virtio2 => { bus => 0, addr => 12 },
4687 virtio3 => { bus => 0, addr => 13 },
4688 virtio4 => { bus => 0, addr => 14 },
4689 virtio5 => { bus => 0, addr => 15 },
b78ebef7
DA
4690 hostpci0 => { bus => 0, addr => 16 },
4691 hostpci1 => { bus => 0, addr => 17 },
f290f8d9
DA
4692 net0 => { bus => 0, addr => 18 },
4693 net1 => { bus => 0, addr => 19 },
4694 net2 => { bus => 0, addr => 20 },
4695 net3 => { bus => 0, addr => 21 },
4696 net4 => { bus => 0, addr => 22 },
4697 net5 => { bus => 0, addr => 23 },
2fa3151e
AD
4698 vga1 => { bus => 0, addr => 24 },
4699 vga2 => { bus => 0, addr => 25 },
4700 vga3 => { bus => 0, addr => 26 },
5cffb2d2
AD
4701 hostpci2 => { bus => 0, addr => 27 },
4702 hostpci3 => { bus => 0, addr => 28 },
e5f7f8ed 4703 #addr29 : usb-host (pve-usb.cfg)
5bdcf937
AD
4704 'pci.1' => { bus => 0, addr => 30 },
4705 'pci.2' => { bus => 0, addr => 31 },
4706 'net6' => { bus => 1, addr => 1 },
4707 'net7' => { bus => 1, addr => 2 },
4708 'net8' => { bus => 1, addr => 3 },
4709 'net9' => { bus => 1, addr => 4 },
4710 'net10' => { bus => 1, addr => 5 },
4711 'net11' => { bus => 1, addr => 6 },
4712 'net12' => { bus => 1, addr => 7 },
4713 'net13' => { bus => 1, addr => 8 },
4714 'net14' => { bus => 1, addr => 9 },
4715 'net15' => { bus => 1, addr => 10 },
4716 'net16' => { bus => 1, addr => 11 },
4717 'net17' => { bus => 1, addr => 12 },
4718 'net18' => { bus => 1, addr => 13 },
4719 'net19' => { bus => 1, addr => 14 },
4720 'net20' => { bus => 1, addr => 15 },
4721 'net21' => { bus => 1, addr => 16 },
4722 'net22' => { bus => 1, addr => 17 },
4723 'net23' => { bus => 1, addr => 18 },
4724 'net24' => { bus => 1, addr => 19 },
4725 'net25' => { bus => 1, addr => 20 },
4726 'net26' => { bus => 1, addr => 21 },
4727 'net27' => { bus => 1, addr => 22 },
4728 'net28' => { bus => 1, addr => 23 },
4729 'net29' => { bus => 1, addr => 24 },
4730 'net30' => { bus => 1, addr => 25 },
4731 'net31' => { bus => 1, addr => 26 },
4732 'virtio6' => { bus => 2, addr => 1 },
4733 'virtio7' => { bus => 2, addr => 2 },
4734 'virtio8' => { bus => 2, addr => 3 },
4735 'virtio9' => { bus => 2, addr => 4 },
4736 'virtio10' => { bus => 2, addr => 5 },
4737 'virtio11' => { bus => 2, addr => 6 },
4738 'virtio12' => { bus => 2, addr => 7 },
4739 'virtio13' => { bus => 2, addr => 8 },
4740 'virtio14' => { bus => 2, addr => 9 },
4741 'virtio15' => { bus => 2, addr => 10 },
6731a4cf
AD
4742 'virtioscsi0' => { bus => 3, addr => 1 },
4743 'virtioscsi1' => { bus => 3, addr => 2 },
4744 'virtioscsi2' => { bus => 3, addr => 3 },
4745 'virtioscsi3' => { bus => 3, addr => 4 },
4746 'virtioscsi4' => { bus => 3, addr => 5 },
4747 'virtioscsi5' => { bus => 3, addr => 6 },
4748 'virtioscsi6' => { bus => 3, addr => 7 },
4749 'virtioscsi7' => { bus => 3, addr => 8 },
4750 'virtioscsi8' => { bus => 3, addr => 9 },
4751 'virtioscsi9' => { bus => 3, addr => 10 },
4752 'virtioscsi10' => { bus => 3, addr => 11 },
4753 'virtioscsi11' => { bus => 3, addr => 12 },
4754 'virtioscsi12' => { bus => 3, addr => 13 },
4755 'virtioscsi13' => { bus => 3, addr => 14 },
4756 'virtioscsi14' => { bus => 3, addr => 15 },
4757 'virtioscsi15' => { bus => 3, addr => 16 },
4758 'virtioscsi16' => { bus => 3, addr => 17 },
4759 'virtioscsi17' => { bus => 3, addr => 18 },
4760 'virtioscsi18' => { bus => 3, addr => 19 },
4761 'virtioscsi19' => { bus => 3, addr => 20 },
4762 'virtioscsi20' => { bus => 3, addr => 21 },
4763 'virtioscsi21' => { bus => 3, addr => 22 },
4764 'virtioscsi22' => { bus => 3, addr => 23 },
4765 'virtioscsi23' => { bus => 3, addr => 24 },
4766 'virtioscsi24' => { bus => 3, addr => 25 },
4767 'virtioscsi25' => { bus => 3, addr => 26 },
4768 'virtioscsi26' => { bus => 3, addr => 27 },
4769 'virtioscsi27' => { bus => 3, addr => 28 },
4770 'virtioscsi28' => { bus => 3, addr => 29 },
4771 'virtioscsi29' => { bus => 3, addr => 30 },
4772 'virtioscsi30' => { bus => 3, addr => 31 },
4773
6b64503e
DM
4774 };
4775
4776 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
72a063e4 4777 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
5bdcf937
AD
4778 my $bus = $devices->{$id}->{bus};
4779 $res = ",bus=pci.$bus,addr=$addr";
98627641 4780 $bridges->{$bus} = 1 if $bridges;
72a063e4
DA
4781 }
4782 return $res;
4783
4784}
4785
2e3b7e2a
AD
4786sub print_pcie_addr {
4787 my ($id) = @_;
4788
4789 my $res = '';
4790 my $devices = {
4791 hostpci0 => { bus => "ich9-pcie-port-1", addr => 0 },
4792 hostpci1 => { bus => "ich9-pcie-port-2", addr => 0 },
4793 hostpci2 => { bus => "ich9-pcie-port-3", addr => 0 },
4794 hostpci3 => { bus => "ich9-pcie-port-4", addr => 0 },
4795 };
4796
4797 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
4798 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
4799 my $bus = $devices->{$id}->{bus};
4800 $res = ",bus=$bus,addr=$addr";
4801 }
4802 return $res;
4803
4804}
4805
3e16d5fc
DM
4806# vzdump restore implementaion
4807
ed221350 4808sub tar_archive_read_firstfile {
3e16d5fc 4809 my $archive = shift;
afdb31d5 4810
3e16d5fc
DM
4811 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
4812
4813 # try to detect archive type first
4814 my $pid = open (TMP, "tar tf '$archive'|") ||
4815 die "unable to open file '$archive'\n";
4816 my $firstfile = <TMP>;
4817 kill 15, $pid;
4818 close TMP;
4819
4820 die "ERROR: archive contaions no data\n" if !$firstfile;
4821 chomp $firstfile;
4822
4823 return $firstfile;
4824}
4825
ed221350
DM
4826sub tar_restore_cleanup {
4827 my ($storecfg, $statfile) = @_;
3e16d5fc
DM
4828
4829 print STDERR "starting cleanup\n";
4830
4831 if (my $fd = IO::File->new($statfile, "r")) {
4832 while (defined(my $line = <$fd>)) {
4833 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
4834 my $volid = $2;
4835 eval {
4836 if ($volid =~ m|^/|) {
4837 unlink $volid || die 'unlink failed\n';
4838 } else {
ed221350 4839 PVE::Storage::vdisk_free($storecfg, $volid);
3e16d5fc 4840 }
afdb31d5 4841 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3e16d5fc
DM
4842 };
4843 print STDERR "unable to cleanup '$volid' - $@" if $@;
4844 } else {
4845 print STDERR "unable to parse line in statfile - $line";
afdb31d5 4846 }
3e16d5fc
DM
4847 }
4848 $fd->close();
4849 }
4850}
4851
4852sub restore_archive {
a0d1b1a2 4853 my ($archive, $vmid, $user, $opts) = @_;
3e16d5fc 4854
91bd6c90
DM
4855 my $format = $opts->{format};
4856 my $comp;
4857
4858 if ($archive =~ m/\.tgz$/ || $archive =~ m/\.tar\.gz$/) {
4859 $format = 'tar' if !$format;
4860 $comp = 'gzip';
4861 } elsif ($archive =~ m/\.tar$/) {
4862 $format = 'tar' if !$format;
4863 } elsif ($archive =~ m/.tar.lzo$/) {
4864 $format = 'tar' if !$format;
4865 $comp = 'lzop';
4866 } elsif ($archive =~ m/\.vma$/) {
4867 $format = 'vma' if !$format;
4868 } elsif ($archive =~ m/\.vma\.gz$/) {
4869 $format = 'vma' if !$format;
4870 $comp = 'gzip';
4871 } elsif ($archive =~ m/\.vma\.lzo$/) {
4872 $format = 'vma' if !$format;
4873 $comp = 'lzop';
4874 } else {
4875 $format = 'vma' if !$format; # default
4876 }
4877
4878 # try to detect archive format
4879 if ($format eq 'tar') {
4880 return restore_tar_archive($archive, $vmid, $user, $opts);
4881 } else {
4882 return restore_vma_archive($archive, $vmid, $user, $opts, $comp);
4883 }
4884}
4885
4886sub restore_update_config_line {
4887 my ($outfd, $cookie, $vmid, $map, $line, $unique) = @_;
4888
4889 return if $line =~ m/^\#qmdump\#/;
4890 return if $line =~ m/^\#vzdump\#/;
4891 return if $line =~ m/^lock:/;
4892 return if $line =~ m/^unused\d+:/;
4893 return if $line =~ m/^parent:/;
ca3e4fa4 4894 return if $line =~ m/^template:/; # restored VM is never a template
91bd6c90
DM
4895
4896 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
4897 # try to convert old 1.X settings
4898 my ($id, $ind, $ethcfg) = ($1, $2, $3);
4899 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
4900 my ($model, $macaddr) = split(/\=/, $devconfig);
4901 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $unique;
4902 my $net = {
4903 model => $model,
4904 bridge => "vmbr$ind",
4905 macaddr => $macaddr,
4906 };
4907 my $netstr = print_net($net);
4908
4909 print $outfd "net$cookie->{netcount}: $netstr\n";
4910 $cookie->{netcount}++;
4911 }
4912 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && $unique) {
4913 my ($id, $netstr) = ($1, $2);
4914 my $net = parse_net($netstr);
4915 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
4916 $netstr = print_net($net);
4917 print $outfd "$id: $netstr\n";
4918 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
4919 my $virtdev = $1;
907ea891 4920 my $value = $3;
91bd6c90
DM
4921 if ($line =~ m/backup=no/) {
4922 print $outfd "#$line";
4923 } elsif ($virtdev && $map->{$virtdev}) {
ed221350 4924 my $di = parse_drive($virtdev, $value);
8fd57431 4925 delete $di->{format}; # format can change on restore
91bd6c90 4926 $di->{file} = $map->{$virtdev};
ed221350 4927 $value = print_drive($vmid, $di);
91bd6c90
DM
4928 print $outfd "$virtdev: $value\n";
4929 } else {
4930 print $outfd $line;
4931 }
4932 } else {
4933 print $outfd $line;
4934 }
4935}
4936
4937sub scan_volids {
4938 my ($cfg, $vmid) = @_;
4939
4940 my $info = PVE::Storage::vdisk_list($cfg, undef, $vmid);
4941
4942 my $volid_hash = {};
4943 foreach my $storeid (keys %$info) {
4944 foreach my $item (@{$info->{$storeid}}) {
4945 next if !($item->{volid} && $item->{size});
5996a936 4946 $item->{path} = PVE::Storage::path($cfg, $item->{volid});
91bd6c90
DM
4947 $volid_hash->{$item->{volid}} = $item;
4948 }
4949 }
4950
4951 return $volid_hash;
4952}
4953
a8e2f942
DM
4954sub get_used_paths {
4955 my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
4956
4957 my $used_path = {};
4958
4959 my $scan_config = sub {
4960 my ($cref, $snapname) = @_;
4961
4962 foreach my $key (keys %$cref) {
4963 my $value = $cref->{$key};
4964 if (valid_drivename($key)) {
4965 next if $skip_drive && $key eq $skip_drive;
4966 my $drive = parse_drive($key, $value);
4967 next if !$drive || !$drive->{file} || drive_is_cdrom($drive);
4968 if ($drive->{file} =~ m!^/!) {
4969 $used_path->{$drive->{file}}++; # = 1;
4970 } else {
4971 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
4972 next if !$storeid;
4973 my $scfg = PVE::Storage::storage_config($storecfg, $storeid, 1);
4974 next if !$scfg;
4975 my $path = PVE::Storage::path($storecfg, $drive->{file}, $snapname);
4976 $used_path->{$path}++; # = 1;
4977 }
4978 }
4979 }
4980 };
4981
4982 &$scan_config($conf);
4983
4984 undef $skip_drive;
4985
4986 if ($scan_snapshots) {
4987 foreach my $snapname (keys %{$conf->{snapshots}}) {
4988 &$scan_config($conf->{snapshots}->{$snapname}, $snapname);
4989 }
4990 }
4991
4992 return $used_path;
4993}
4994
91bd6c90
DM
4995sub update_disksize {
4996 my ($vmid, $conf, $volid_hash) = @_;
be190583 4997
91bd6c90
DM
4998 my $changes;
4999
5000 my $used = {};
5001
5996a936
DM
5002 # Note: it is allowed to define multiple storages with same path (alias), so
5003 # we need to check both 'volid' and real 'path' (two different volid can point
5004 # to the same path).
5005
5006 my $usedpath = {};
be190583 5007
91bd6c90
DM
5008 # update size info
5009 foreach my $opt (keys %$conf) {
ed221350
DM
5010 if (valid_drivename($opt)) {
5011 my $drive = parse_drive($opt, $conf->{$opt});
91bd6c90
DM
5012 my $volid = $drive->{file};
5013 next if !$volid;
5014
5015 $used->{$volid} = 1;
be190583 5016 if ($volid_hash->{$volid} &&
5996a936
DM
5017 (my $path = $volid_hash->{$volid}->{path})) {
5018 $usedpath->{$path} = 1;
5019 }
91bd6c90 5020
ed221350 5021 next if drive_is_cdrom($drive);
91bd6c90
DM
5022 next if !$volid_hash->{$volid};
5023
5024 $drive->{size} = $volid_hash->{$volid}->{size};
7a907ce6
DM
5025 my $new = print_drive($vmid, $drive);
5026 if ($new ne $conf->{$opt}) {
5027 $changes = 1;
5028 $conf->{$opt} = $new;
5029 }
91bd6c90
DM
5030 }
5031 }
5032
5996a936
DM
5033 # remove 'unusedX' entry if volume is used
5034 foreach my $opt (keys %$conf) {
5035 next if $opt !~ m/^unused\d+$/;
5036 my $volid = $conf->{$opt};
5037 my $path = $volid_hash->{$volid}->{path} if $volid_hash->{$volid};
be190583 5038 if ($used->{$volid} || ($path && $usedpath->{$path})) {
5996a936
DM
5039 $changes = 1;
5040 delete $conf->{$opt};
5041 }
5042 }
5043
91bd6c90
DM
5044 foreach my $volid (sort keys %$volid_hash) {
5045 next if $volid =~ m/vm-$vmid-state-/;
5046 next if $used->{$volid};
5996a936
DM
5047 my $path = $volid_hash->{$volid}->{path};
5048 next if !$path; # just to be sure
5049 next if $usedpath->{$path};
91bd6c90 5050 $changes = 1;
ed221350 5051 add_unused_volume($conf, $volid);
05937a14 5052 $usedpath->{$path} = 1; # avoid to add more than once (aliases)
91bd6c90
DM
5053 }
5054
5055 return $changes;
5056}
5057
5058sub rescan {
5059 my ($vmid, $nolock) = @_;
5060
5061 my $cfg = PVE::Cluster::cfs_read_file("storage.cfg");
5062
5063 my $volid_hash = scan_volids($cfg, $vmid);
5064
5065 my $updatefn = sub {
5066 my ($vmid) = @_;
5067
ed221350 5068 my $conf = load_config($vmid);
be190583 5069
ed221350 5070 check_lock($conf);
91bd6c90 5071
03da3f0d
DM
5072 my $vm_volids = {};
5073 foreach my $volid (keys %$volid_hash) {
5074 my $info = $volid_hash->{$volid};
5075 $vm_volids->{$volid} = $info if $info->{vmid} && $info->{vmid} == $vmid;
5076 }
5077
5078 my $changes = update_disksize($vmid, $conf, $vm_volids);
91bd6c90 5079
ed221350 5080 update_config_nolock($vmid, $conf, 1) if $changes;
91bd6c90
DM
5081 };
5082
5083 if (defined($vmid)) {
5084 if ($nolock) {
5085 &$updatefn($vmid);
5086 } else {
ed221350 5087 lock_config($vmid, $updatefn, $vmid);
91bd6c90
DM
5088 }
5089 } else {
5090 my $vmlist = config_list();
5091 foreach my $vmid (keys %$vmlist) {
5092 if ($nolock) {
5093 &$updatefn($vmid);
5094 } else {
ed221350 5095 lock_config($vmid, $updatefn, $vmid);
be190583 5096 }
91bd6c90
DM
5097 }
5098 }
5099}
5100
5101sub restore_vma_archive {
5102 my ($archive, $vmid, $user, $opts, $comp) = @_;
5103
5104 my $input = $archive eq '-' ? "<&STDIN" : undef;
5105 my $readfrom = $archive;
5106
5107 my $uncomp = '';
5108 if ($comp) {
5109 $readfrom = '-';
5110 my $qarchive = PVE::Tools::shellquote($archive);
5111 if ($comp eq 'gzip') {
5112 $uncomp = "zcat $qarchive|";
5113 } elsif ($comp eq 'lzop') {
5114 $uncomp = "lzop -d -c $qarchive|";
5115 } else {
5116 die "unknown compression method '$comp'\n";
5117 }
be190583 5118
91bd6c90
DM
5119 }
5120
5121 my $tmpdir = "/var/tmp/vzdumptmp$$";
5122 rmtree $tmpdir;
5123
5124 # disable interrupts (always do cleanups)
5125 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
5126 warn "got interrupt - ignored\n";
5127 };
5128
5129 my $mapfifo = "/var/tmp/vzdumptmp$$.fifo";
5130 POSIX::mkfifo($mapfifo, 0600);
5131 my $fifofh;
5132
5133 my $openfifo = sub {
5134 open($fifofh, '>', $mapfifo) || die $!;
5135 };
5136
5137 my $cmd = "${uncomp}vma extract -v -r $mapfifo $readfrom $tmpdir";
5138
5139 my $oldtimeout;
5140 my $timeout = 5;
5141
5142 my $devinfo = {};
5143
5144 my $rpcenv = PVE::RPCEnvironment::get();
5145
ed221350 5146 my $conffile = config_file($vmid);
91bd6c90
DM
5147 my $tmpfn = "$conffile.$$.tmp";
5148
ed221350
DM
5149 # Note: $oldconf is undef if VM does not exists
5150 my $oldconf = PVE::Cluster::cfs_read_file(cfs_config_path($vmid));
5151
91bd6c90
DM
5152 my $print_devmap = sub {
5153 my $virtdev_hash = {};
5154
5155 my $cfgfn = "$tmpdir/qemu-server.conf";
5156
5157 # we can read the config - that is already extracted
5158 my $fh = IO::File->new($cfgfn, "r") ||
5159 "unable to read qemu-server.conf - $!\n";
5160
5161 while (defined(my $line = <$fh>)) {
5162 if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
5163 my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
5164 die "archive does not contain data for drive '$virtdev'\n"
5165 if !$devinfo->{$devname};
5166 if (defined($opts->{storage})) {
5167 $storeid = $opts->{storage} || 'local';
5168 } elsif (!$storeid) {
5169 $storeid = 'local';
5170 }
5171 $format = 'raw' if !$format;
5172 $devinfo->{$devname}->{devname} = $devname;
5173 $devinfo->{$devname}->{virtdev} = $virtdev;
5174 $devinfo->{$devname}->{format} = $format;
5175 $devinfo->{$devname}->{storeid} = $storeid;
5176
be190583 5177 # check permission on storage
91bd6c90
DM
5178 my $pool = $opts->{pool}; # todo: do we need that?
5179 if ($user ne 'root@pam') {
5180 $rpcenv->check($user, "/storage/$storeid", ['Datastore.AllocateSpace']);
5181 }
5182
5183 $virtdev_hash->{$virtdev} = $devinfo->{$devname};
5184 }
5185 }
5186
5187 foreach my $devname (keys %$devinfo) {
be190583
DM
5188 die "found no device mapping information for device '$devname'\n"
5189 if !$devinfo->{$devname}->{virtdev};
91bd6c90
DM
5190 }
5191
91bd6c90 5192 my $cfg = cfs_read_file('storage.cfg');
ed221350
DM
5193
5194 # create empty/temp config
be190583 5195 if ($oldconf) {
ed221350
DM
5196 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
5197 foreach_drive($oldconf, sub {
5198 my ($ds, $drive) = @_;
5199
5200 return if drive_is_cdrom($drive);
5201
5202 my $volid = $drive->{file};
5203
5204 return if !$volid || $volid =~ m|^/|;
5205
5206 my ($path, $owner) = PVE::Storage::path($cfg, $volid);
5207 return if !$path || !$owner || ($owner != $vmid);
5208
5209 # Note: only delete disk we want to restore
5210 # other volumes will become unused
5211 if ($virtdev_hash->{$ds}) {
5212 PVE::Storage::vdisk_free($cfg, $volid);
5213 }
5214 });
5215 }
5216
5217 my $map = {};
91bd6c90
DM
5218 foreach my $virtdev (sort keys %$virtdev_hash) {
5219 my $d = $virtdev_hash->{$virtdev};
5220 my $alloc_size = int(($d->{size} + 1024 - 1)/1024);
5221 my $scfg = PVE::Storage::storage_config($cfg, $d->{storeid});
8fd57431
DM
5222
5223 # test if requested format is supported
5224 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($cfg, $d->{storeid});
5225 my $supported = grep { $_ eq $d->{format} } @$validFormats;
5226 $d->{format} = $defFormat if !$supported;
5227
91bd6c90
DM
5228 my $volid = PVE::Storage::vdisk_alloc($cfg, $d->{storeid}, $vmid,
5229 $d->{format}, undef, $alloc_size);
5230 print STDERR "new volume ID is '$volid'\n";
5231 $d->{volid} = $volid;
5232 my $path = PVE::Storage::path($cfg, $volid);
5233
5234 my $write_zeros = 1;
5235 # fixme: what other storages types initialize volumes with zero?
244f2577 5236 if ($scfg->{type} eq 'dir' || $scfg->{type} eq 'nfs' || $scfg->{type} eq 'glusterfs' ||
013d5275 5237 $scfg->{type} eq 'sheepdog' || $scfg->{type} eq 'rbd') {
91bd6c90
DM
5238 $write_zeros = 0;
5239 }
5240
5241 print $fifofh "${write_zeros}:$d->{devname}=$path\n";
5242
5243 print "map '$d->{devname}' to '$path' (write zeros = ${write_zeros})\n";
5244 $map->{$virtdev} = $volid;
5245 }
5246
5247 $fh->seek(0, 0) || die "seek failed - $!\n";
5248
5249 my $outfd = new IO::File ($tmpfn, "w") ||
5250 die "unable to write config for VM $vmid\n";
5251
5252 my $cookie = { netcount => 0 };
5253 while (defined(my $line = <$fh>)) {
be190583 5254 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
91bd6c90
DM
5255 }
5256
5257 $fh->close();
5258 $outfd->close();
5259 };
5260
5261 eval {
5262 # enable interrupts
5263 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
5264 die "interrupted by signal\n";
5265 };
5266 local $SIG{ALRM} = sub { die "got timeout\n"; };
5267
5268 $oldtimeout = alarm($timeout);
5269
5270 my $parser = sub {
5271 my $line = shift;
5272
5273 print "$line\n";
5274
5275 if ($line =~ m/^DEV:\sdev_id=(\d+)\ssize:\s(\d+)\sdevname:\s(\S+)$/) {
5276 my ($dev_id, $size, $devname) = ($1, $2, $3);
5277 $devinfo->{$devname} = { size => $size, dev_id => $dev_id };
5278 } elsif ($line =~ m/^CTIME: /) {
46f58b5f 5279 # we correctly received the vma config, so we can disable
3cf90d7a
DM
5280 # the timeout now for disk allocation (set to 10 minutes, so
5281 # that we always timeout if something goes wrong)
5282 alarm(600);
91bd6c90
DM
5283 &$print_devmap();
5284 print $fifofh "done\n";
5285 my $tmp = $oldtimeout || 0;
5286 $oldtimeout = undef;
5287 alarm($tmp);
5288 close($fifofh);
5289 }
5290 };
be190583 5291
91bd6c90
DM
5292 print "restore vma archive: $cmd\n";
5293 run_command($cmd, input => $input, outfunc => $parser, afterfork => $openfifo);
5294 };
5295 my $err = $@;
5296
5297 alarm($oldtimeout) if $oldtimeout;
5298
5299 unlink $mapfifo;
5300
5301 if ($err) {
5302 rmtree $tmpdir;
5303 unlink $tmpfn;
5304
5305 my $cfg = cfs_read_file('storage.cfg');
5306 foreach my $devname (keys %$devinfo) {
5307 my $volid = $devinfo->{$devname}->{volid};
5308 next if !$volid;
5309 eval {
5310 if ($volid =~ m|^/|) {
5311 unlink $volid || die 'unlink failed\n';
5312 } else {
5313 PVE::Storage::vdisk_free($cfg, $volid);
5314 }
5315 print STDERR "temporary volume '$volid' sucessfuly removed\n";
5316 };
5317 print STDERR "unable to cleanup '$volid' - $@" if $@;
5318 }
5319 die $err;
5320 }
5321
5322 rmtree $tmpdir;
ed221350
DM
5323
5324 rename($tmpfn, $conffile) ||
91bd6c90
DM
5325 die "unable to commit configuration file '$conffile'\n";
5326
ed221350
DM
5327 PVE::Cluster::cfs_update(); # make sure we read new file
5328
91bd6c90
DM
5329 eval { rescan($vmid, 1); };
5330 warn $@ if $@;
5331}
5332
5333sub restore_tar_archive {
5334 my ($archive, $vmid, $user, $opts) = @_;
5335
9c502e26 5336 if ($archive ne '-') {
ed221350 5337 my $firstfile = tar_archive_read_firstfile($archive);
9c502e26
DM
5338 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
5339 if $firstfile ne 'qemu-server.conf';
5340 }
3e16d5fc 5341
ed221350 5342 my $storecfg = cfs_read_file('storage.cfg');
ebb55558 5343
ed221350 5344 # destroy existing data - keep empty config
8e90138a 5345 my $vmcfgfn = config_file($vmid);
ebb55558 5346 destroy_vm($storecfg, $vmid, 1) if -f $vmcfgfn;
ed221350 5347
3e16d5fc
DM
5348 my $tocmd = "/usr/lib/qemu-server/qmextract";
5349
2415a446 5350 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
a0d1b1a2 5351 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3e16d5fc
DM
5352 $tocmd .= ' --prealloc' if $opts->{prealloc};
5353 $tocmd .= ' --info' if $opts->{info};
5354
a0d1b1a2 5355 # tar option "xf" does not autodetect compression when read from STDIN,
9c502e26 5356 # so we pipe to zcat
2415a446
DM
5357 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
5358 PVE::Tools::shellquote("--to-command=$tocmd");
3e16d5fc
DM
5359
5360 my $tmpdir = "/var/tmp/vzdumptmp$$";
5361 mkpath $tmpdir;
5362
5363 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
5364 local $ENV{VZDUMP_VMID} = $vmid;
a0d1b1a2 5365 local $ENV{VZDUMP_USER} = $user;
3e16d5fc 5366
ed221350 5367 my $conffile = config_file($vmid);
3e16d5fc
DM
5368 my $tmpfn = "$conffile.$$.tmp";
5369
5370 # disable interrupts (always do cleanups)
5371 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
5372 print STDERR "got interrupt - ignored\n";
5373 };
5374
afdb31d5 5375 eval {
3e16d5fc
DM
5376 # enable interrupts
5377 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
5378 die "interrupted by signal\n";
5379 };
5380
9c502e26
DM
5381 if ($archive eq '-') {
5382 print "extracting archive from STDIN\n";
5383 run_command($cmd, input => "<&STDIN");
5384 } else {
5385 print "extracting archive '$archive'\n";
5386 run_command($cmd);
5387 }
3e16d5fc
DM
5388
5389 return if $opts->{info};
5390
5391 # read new mapping
5392 my $map = {};
5393 my $statfile = "$tmpdir/qmrestore.stat";
5394 if (my $fd = IO::File->new($statfile, "r")) {
5395 while (defined (my $line = <$fd>)) {
5396 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
5397 $map->{$1} = $2 if $1;
5398 } else {
5399 print STDERR "unable to parse line in statfile - $line\n";
5400 }
5401 }
5402 $fd->close();
5403 }
5404
5405 my $confsrc = "$tmpdir/qemu-server.conf";
5406
5407 my $srcfd = new IO::File($confsrc, "r") ||
5408 die "unable to open file '$confsrc'\n";
5409
5410 my $outfd = new IO::File ($tmpfn, "w") ||
5411 die "unable to write config for VM $vmid\n";
5412
91bd6c90 5413 my $cookie = { netcount => 0 };
3e16d5fc 5414 while (defined (my $line = <$srcfd>)) {
be190583 5415 restore_update_config_line($outfd, $cookie, $vmid, $map, $line, $opts->{unique});
3e16d5fc
DM
5416 }
5417
5418 $srcfd->close();
5419 $outfd->close();
5420 };
5421 my $err = $@;
5422
afdb31d5 5423 if ($err) {
3e16d5fc
DM
5424
5425 unlink $tmpfn;
5426
ed221350 5427 tar_restore_cleanup($storecfg, "$tmpdir/qmrestore.stat") if !$opts->{info};
afdb31d5 5428
3e16d5fc 5429 die $err;
afdb31d5 5430 }
3e16d5fc
DM
5431
5432 rmtree $tmpdir;
5433
5434 rename $tmpfn, $conffile ||
5435 die "unable to commit configuration file '$conffile'\n";
91bd6c90 5436
ed221350
DM
5437 PVE::Cluster::cfs_update(); # make sure we read new file
5438
91bd6c90
DM
5439 eval { rescan($vmid, 1); };
5440 warn $@ if $@;
3e16d5fc
DM
5441};
5442
0d18dcfc
DM
5443
5444# Internal snapshots
5445
5446# NOTE: Snapshot create/delete involves several non-atomic
5447# action, and can take a long time.
5448# So we try to avoid locking the file and use 'lock' variable
5449# inside the config file instead.
5450
ef59d1ca
DM
5451my $snapshot_copy_config = sub {
5452 my ($source, $dest) = @_;
5453
5454 foreach my $k (keys %$source) {
5455 next if $k eq 'snapshots';
982c7f12
DM
5456 next if $k eq 'snapstate';
5457 next if $k eq 'snaptime';
18bfb361 5458 next if $k eq 'vmstate';
ef59d1ca
DM
5459 next if $k eq 'lock';
5460 next if $k eq 'digest';
db7c26e5 5461 next if $k eq 'description';
ef59d1ca 5462 next if $k =~ m/^unused\d+$/;
be190583 5463
ef59d1ca
DM
5464 $dest->{$k} = $source->{$k};
5465 }
5466};
5467
5468my $snapshot_apply_config = sub {
5469 my ($conf, $snap) = @_;
5470
5471 # copy snapshot list
5472 my $newconf = {
5473 snapshots => $conf->{snapshots},
5474 };
5475
db7c26e5 5476 # keep description and list of unused disks
ef59d1ca 5477 foreach my $k (keys %$conf) {
db7c26e5 5478 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
ef59d1ca
DM
5479 $newconf->{$k} = $conf->{$k};
5480 }
5481
5482 &$snapshot_copy_config($snap, $newconf);
5483
5484 return $newconf;
5485};
5486
18bfb361
DM
5487sub foreach_writable_storage {
5488 my ($conf, $func) = @_;
5489
5490 my $sidhash = {};
5491
5492 foreach my $ds (keys %$conf) {
5493 next if !valid_drivename($ds);
5494
5495 my $drive = parse_drive($ds, $conf->{$ds});
5496 next if !$drive;
5497 next if drive_is_cdrom($drive);
5498
5499 my $volid = $drive->{file};
5500
5501 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
be190583 5502 $sidhash->{$sid} = $sid if $sid;
18bfb361
DM
5503 }
5504
5505 foreach my $sid (sort keys %$sidhash) {
5506 &$func($sid);
5507 }
5508}
5509
5510my $alloc_vmstate_volid = sub {
5511 my ($storecfg, $vmid, $conf, $snapname) = @_;
be190583 5512
18bfb361
DM
5513 # Note: we try to be smart when selecting a $target storage
5514
5515 my $target;
5516
5517 # search shared storage first
5518 foreach_writable_storage($conf, sub {
5519 my ($sid) = @_;
5520 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
5521 return if !$scfg->{shared};
5522
5523 $target = $sid if !$target || $scfg->{path}; # prefer file based storage
5524 });
5525
5526 if (!$target) {
5527 # now search local storage
5528 foreach_writable_storage($conf, sub {
5529 my ($sid) = @_;
5530 my $scfg = PVE::Storage::storage_config($storecfg, $sid);
5531 return if $scfg->{shared};
5532
5533 $target = $sid if !$target || $scfg->{path}; # prefer file based storage;
5534 });
5535 }
5536
5537 $target = 'local' if !$target;
5538
fe6249f4
DM
5539 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
5540 # we abort live save after $conf->{memory}, so we need at max twice that space
5541 my $size = $conf->{memory}*2 + $driver_state_size;
18bfb361
DM
5542
5543 my $name = "vm-$vmid-state-$snapname";
5544 my $scfg = PVE::Storage::storage_config($storecfg, $target);
5545 $name .= ".raw" if $scfg->{path}; # add filename extension for file base storage
5546 my $volid = PVE::Storage::vdisk_alloc($storecfg, $target, $vmid, 'raw', $name, $size*1024);
5547
5548 return $volid;
5549};
5550
0d18dcfc 5551my $snapshot_prepare = sub {
18bfb361 5552 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
22c377f0
DM
5553
5554 my $snap;
0d18dcfc
DM
5555
5556 my $updatefn = sub {
5557
5558 my $conf = load_config($vmid);
5559
be190583 5560 die "you can't take a snapshot if it's a template\n"
5295b23d
DM
5561 if is_template($conf);
5562
0d18dcfc
DM
5563 check_lock($conf);
5564
22c377f0
DM
5565 $conf->{lock} = 'snapshot';
5566
be190583
DM
5567 die "snapshot name '$snapname' already used\n"
5568 if defined($conf->{snapshots}->{$snapname});
0d18dcfc 5569
ee2f90b1 5570 my $storecfg = PVE::Storage::config();
7ea975ef 5571 die "snapshot feature is not available" if !has_feature('snapshot', $conf, $storecfg);
18bfb361 5572
782f4f75 5573 $snap = $conf->{snapshots}->{$snapname} = {};
0d18dcfc 5574
18bfb361
DM
5575 if ($save_vmstate && check_running($vmid)) {
5576 $snap->{vmstate} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
5577 }
5578
ef59d1ca 5579 &$snapshot_copy_config($conf, $snap);
0d18dcfc 5580
782f4f75
DM
5581 $snap->{snapstate} = "prepare";
5582 $snap->{snaptime} = time();
5583 $snap->{description} = $comment if $comment;
5584
4b15803d
DM
5585 # always overwrite machine if we save vmstate. This makes sure we
5586 # can restore it later using correct machine type
5587 $snap->{machine} = get_current_qemu_machine($vmid) if $snap->{vmstate};
5588
0d18dcfc
DM
5589 update_config_nolock($vmid, $conf, 1);
5590 };
5591
5592 lock_config($vmid, $updatefn);
22c377f0
DM
5593
5594 return $snap;
0d18dcfc
DM
5595};
5596
5597my $snapshot_commit = sub {
5598 my ($vmid, $snapname) = @_;
5599
5600 my $updatefn = sub {
5601
5602 my $conf = load_config($vmid);
5603
be190583
DM
5604 die "missing snapshot lock\n"
5605 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
0d18dcfc 5606
7946e0fa
DM
5607 my $has_machine_config = defined($conf->{machine});
5608
0d18dcfc
DM
5609 my $snap = $conf->{snapshots}->{$snapname};
5610
be190583
DM
5611 die "snapshot '$snapname' does not exist\n" if !defined($snap);
5612
5613 die "wrong snapshot state\n"
5614 if !($snap->{snapstate} && $snap->{snapstate} eq "prepare");
0d18dcfc 5615
0d18dcfc 5616 delete $snap->{snapstate};
ee2f90b1 5617 delete $conf->{lock};
0d18dcfc 5618
ef59d1ca 5619 my $newconf = &$snapshot_apply_config($conf, $snap);
0d18dcfc 5620
7946e0fa
DM
5621 delete $newconf->{machine} if !$has_machine_config;
5622
05e5ad3f
DM
5623 $newconf->{parent} = $snapname;
5624
0d18dcfc
DM
5625 update_config_nolock($vmid, $newconf, 1);
5626 };
5627
5628 lock_config($vmid, $updatefn);
5629};
5630
22c377f0
DM
5631sub snapshot_rollback {
5632 my ($vmid, $snapname) = @_;
5633
22c377f0
DM
5634 my $prepare = 1;
5635
a3222b91 5636 my $storecfg = PVE::Storage::config();
be190583 5637
ba4eea15 5638 my $conf = load_config($vmid);
22c377f0 5639
ba4eea15 5640 my $get_snapshot_config = sub {
22c377f0 5641
8b43bc11 5642 die "you can't rollback if vm is a template\n" if is_template($conf);
90b0c6b3 5643
ba4eea15 5644 my $res = $conf->{snapshots}->{$snapname};
ab33a7c2 5645
ba4eea15
WL
5646 die "snapshot '$snapname' does not exist\n" if !defined($res);
5647
5648 return $res;
5649 };
5650
5651 my $snap = &$get_snapshot_config();
5652
5653 foreach_drive($snap, sub {
5654 my ($ds, $drive) = @_;
5655
5656 return if drive_is_cdrom($drive);
5657
5658 my $volid = $drive->{file};
5659
5660 PVE::Storage::volume_rollback_is_possible($storecfg, $volid, $snapname);
5661 });
5662
5663 my $updatefn = sub {
5664
5665 $conf = load_config($vmid);
5666
5667 $snap = &$get_snapshot_config();
ab33a7c2 5668
be190583 5669 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
ab33a7c2
DM
5670 if $snap->{snapstate};
5671
a3222b91
DM
5672 if ($prepare) {
5673 check_lock($conf);
5674 vm_stop($storecfg, $vmid, undef, undef, 5, undef, undef);
5675 }
22c377f0
DM
5676
5677 die "unable to rollback vm $vmid: vm is running\n"
5678 if check_running($vmid);
5679
5680 if ($prepare) {
5681 $conf->{lock} = 'rollback';
5682 } else {
5683 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
5684 delete $conf->{lock};
5685 }
5686
4b15803d
DM
5687 my $forcemachine;
5688
22c377f0 5689 if (!$prepare) {
4b15803d
DM
5690 my $has_machine_config = defined($conf->{machine});
5691
22c377f0 5692 # copy snapshot config to current config
ef59d1ca
DM
5693 $conf = &$snapshot_apply_config($conf, $snap);
5694 $conf->{parent} = $snapname;
4b15803d 5695
d8b916fd
DM
5696 # Note: old code did not store 'machine', so we try to be smart
5697 # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
5698 $forcemachine = $conf->{machine} || 'pc-i440fx-1.4';
be190583 5699 # we remove the 'machine' configuration if not explicitly specified
4b15803d
DM
5700 # in the original config.
5701 delete $conf->{machine} if $snap->{vmstate} && !$has_machine_config;
22c377f0
DM
5702 }
5703
5704 update_config_nolock($vmid, $conf, 1);
a3222b91
DM
5705
5706 if (!$prepare && $snap->{vmstate}) {
5707 my $statefile = PVE::Storage::path($storecfg, $snap->{vmstate});
4b15803d 5708 vm_start($storecfg, $vmid, $statefile, undef, undef, undef, $forcemachine);
a3222b91 5709 }
22c377f0
DM
5710 };
5711
5712 lock_config($vmid, $updatefn);
be190583 5713
22c377f0
DM
5714 foreach_drive($snap, sub {
5715 my ($ds, $drive) = @_;
5716
5717 return if drive_is_cdrom($drive);
5718
5719 my $volid = $drive->{file};
5720 my $device = "drive-$ds";
5721
79e57b29 5722 PVE::Storage::volume_snapshot_rollback($storecfg, $volid, $snapname);
22c377f0
DM
5723 });
5724
5725 $prepare = 0;
5726 lock_config($vmid, $updatefn);
5727}
5728
9dcf4909
DM
5729my $savevm_wait = sub {
5730 my ($vmid) = @_;
5731
5732 for(;;) {
ed221350 5733 my $stat = vm_mon_cmd_nocheck($vmid, "query-savevm");
9dcf4909
DM
5734 if (!$stat->{status}) {
5735 die "savevm not active\n";
5736 } elsif ($stat->{status} eq 'active') {
5737 sleep(1);
5738 next;
5739 } elsif ($stat->{status} eq 'completed') {
5740 last;
5741 } else {
5742 die "query-savevm returned status '$stat->{status}'\n";
5743 }
5744 }
5745};
5746
e5eaa028
WL
5747sub do_snapshots_with_qemu {
5748 my ($storecfg, $volid) = @_;
5749
5750 my $storage_name = PVE::Storage::parse_volume_id($volid);
5751
5752 if ($qemu_snap_storage->{$storecfg->{ids}->{$storage_name}->{type}} ){
5753 return 1;
5754 }
5755
5756 if ($volid =~ m/\.(qcow2|qed)$/){
5757 return 1;
5758 }
5759
5760 return undef;
5761}
5762
0d18dcfc 5763sub snapshot_create {
af9110dd 5764 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
0d18dcfc 5765
18bfb361 5766 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
0d18dcfc 5767
af9110dd 5768 $save_vmstate = 0 if !$snap->{vmstate}; # vm is not running
18bfb361 5769
67fb9de6
DM
5770 my $config = load_config($vmid);
5771
af9110dd
WL
5772 my $running = check_running($vmid);
5773
67fb9de6 5774 my $freezefs = $running && $config->{agent};
af9110dd
WL
5775 $freezefs = 0 if $snap->{vmstate}; # not needed if we save RAM
5776
5777 my $drivehash = {};
5778
5779 if ($freezefs) {
65994ad7
WL
5780 eval { vm_mon_cmd($vmid, "guest-fsfreeze-freeze"); };
5781 warn "guest-fsfreeze-freeze problems - $@" if $@;
5782 }
67fb9de6 5783
0d18dcfc
DM
5784 eval {
5785 # create internal snapshots of all drives
22c377f0
DM
5786
5787 my $storecfg = PVE::Storage::config();
a3222b91
DM
5788
5789 if ($running) {
5790 if ($snap->{vmstate}) {
be190583 5791 my $path = PVE::Storage::path($storecfg, $snap->{vmstate});
9dcf4909
DM
5792 vm_mon_cmd($vmid, "savevm-start", statefile => $path);
5793 &$savevm_wait($vmid);
a3222b91 5794 } else {
9dcf4909 5795 vm_mon_cmd($vmid, "savevm-start");
a3222b91
DM
5796 }
5797 };
5798
22c377f0
DM
5799 foreach_drive($snap, sub {
5800 my ($ds, $drive) = @_;
5801
5802 return if drive_is_cdrom($drive);
0d18dcfc 5803
22c377f0
DM
5804 my $volid = $drive->{file};
5805 my $device = "drive-$ds";
5806
5807 qemu_volume_snapshot($vmid, $device, $storecfg, $volid, $snapname);
3ee28e38 5808 $drivehash->{$ds} = 1;
22c377f0 5809 });
0d18dcfc 5810 };
22c377f0
DM
5811 my $err = $@;
5812
65994ad7
WL
5813 if ($running) {
5814 eval { vm_mon_cmd($vmid, "savevm-end") };
5815 warn $@ if $@;
22c377f0 5816
af9110dd 5817 if ($freezefs) {
67fb9de6 5818 eval { vm_mon_cmd($vmid, "guest-fsfreeze-thaw"); };
65994ad7
WL
5819 warn "guest-fsfreeze-thaw problems - $@" if $@;
5820 }
22c377f0 5821
65994ad7 5822 # savevm-end is async, we need to wait
f34ebd52 5823 for (;;) {
2c9e8036
AD
5824 my $stat = vm_mon_cmd_nocheck($vmid, "query-savevm");
5825 if (!$stat->{bytes}) {
5826 last;
5827 } else {
5828 print "savevm not yet finished\n";
5829 sleep(1);
5830 next;
5831 }
5832 }
5833 }
5834
22c377f0 5835 if ($err) {
0d18dcfc 5836 warn "snapshot create failed: starting cleanup\n";
3ee28e38 5837 eval { snapshot_delete($vmid, $snapname, 0, $drivehash); };
0d18dcfc
DM
5838 warn $@ if $@;
5839 die $err;
5840 }
5841
5842 &$snapshot_commit($vmid, $snapname);
5843}
5844
3ee28e38 5845# Note: $drivehash is only set when called from snapshot_create.
0d18dcfc 5846sub snapshot_delete {
3ee28e38 5847 my ($vmid, $snapname, $force, $drivehash) = @_;
0d18dcfc
DM
5848
5849 my $prepare = 1;
5850
22c377f0 5851 my $snap;
ee2f90b1 5852 my $unused = [];
0d18dcfc 5853
6cb1a8cf
DM
5854 my $unlink_parent = sub {
5855 my ($confref, $new_parent) = @_;
5856
5857 if ($confref->{parent} && $confref->{parent} eq $snapname) {
5858 if ($new_parent) {
5859 $confref->{parent} = $new_parent;
5860 } else {
5861 delete $confref->{parent};
5862 }
5863 }
5864 };
be190583 5865
0d18dcfc 5866 my $updatefn = sub {
2009f324 5867 my ($remove_drive) = @_;
0d18dcfc 5868
22c377f0 5869 my $conf = load_config($vmid);
0d18dcfc 5870
5295b23d
DM
5871 if (!$drivehash) {
5872 check_lock($conf);
be190583 5873 die "you can't delete a snapshot if vm is a template\n"
5295b23d
DM
5874 if is_template($conf);
5875 }
0d18dcfc 5876
22c377f0 5877 $snap = $conf->{snapshots}->{$snapname};
0d18dcfc 5878
be190583 5879 die "snapshot '$snapname' does not exist\n" if !defined($snap);
0d18dcfc
DM
5880
5881 # remove parent refs
8fd882a4
SP
5882 if (!$prepare) {
5883 &$unlink_parent($conf, $snap->{parent});
5884 foreach my $sn (keys %{$conf->{snapshots}}) {
5885 next if $sn eq $snapname;
5886 &$unlink_parent($conf->{snapshots}->{$sn}, $snap->{parent});
5887 }
0d18dcfc
DM
5888 }
5889
2009f324 5890 if ($remove_drive) {
18bfb361
DM
5891 if ($remove_drive eq 'vmstate') {
5892 delete $snap->{$remove_drive};
5893 } else {
5894 my $drive = parse_drive($remove_drive, $snap->{$remove_drive});
5895 my $volid = $drive->{file};
5896 delete $snap->{$remove_drive};
5897 add_unused_volume($conf, $volid);
5898 }
2009f324
DM
5899 }
5900
0d18dcfc
DM
5901 if ($prepare) {
5902 $snap->{snapstate} = 'delete';
5903 } else {
5904 delete $conf->{snapshots}->{$snapname};
3ee28e38 5905 delete $conf->{lock} if $drivehash;
ee2f90b1
DM
5906 foreach my $volid (@$unused) {
5907 add_unused_volume($conf, $volid);
5908 }
0d18dcfc
DM
5909 }
5910
5911 update_config_nolock($vmid, $conf, 1);
5912 };
5913
5914 lock_config($vmid, $updatefn);
5915
18bfb361 5916 # now remove vmstate file
0d18dcfc 5917
22c377f0
DM
5918 my $storecfg = PVE::Storage::config();
5919
18bfb361
DM
5920 if ($snap->{vmstate}) {
5921 eval { PVE::Storage::vdisk_free($storecfg, $snap->{vmstate}); };
5922 if (my $err = $@) {
5923 die $err if !$force;
5924 warn $err;
5925 }
5926 # save changes (remove vmstate from snapshot)
5927 lock_config($vmid, $updatefn, 'vmstate') if !$force;
5928 };
5929
5930 # now remove all internal snapshots
5931 foreach_drive($snap, sub {
22c377f0
DM
5932 my ($ds, $drive) = @_;
5933
5934 return if drive_is_cdrom($drive);
3ee28e38 5935
22c377f0
DM
5936 my $volid = $drive->{file};
5937 my $device = "drive-$ds";
5938
2009f324
DM
5939 if (!$drivehash || $drivehash->{$ds}) {
5940 eval { qemu_volume_snapshot_delete($vmid, $device, $storecfg, $volid, $snapname); };
5941 if (my $err = $@) {
5942 die $err if !$force;
5943 warn $err;
5944 }
3ee28e38 5945 }
2009f324
DM
5946
5947 # save changes (remove drive fron snapshot)
5948 lock_config($vmid, $updatefn, $ds) if !$force;
ee2f90b1 5949 push @$unused, $volid;
22c377f0 5950 });
0d18dcfc
DM
5951
5952 # now cleanup config
5953 $prepare = 0;
5954 lock_config($vmid, $updatefn);
5955}
5956
9cd07842 5957sub has_feature {
7ea975ef
AD
5958 my ($feature, $conf, $storecfg, $snapname, $running) = @_;
5959
719893a9 5960 my $err;
7ea975ef
AD
5961 foreach_drive($conf, sub {
5962 my ($ds, $drive) = @_;
5963
5964 return if drive_is_cdrom($drive);
5965 my $volid = $drive->{file};
5966 $err = 1 if !PVE::Storage::volume_has_feature($storecfg, $feature, $volid, $snapname, $running);
5967 });
5968
719893a9 5969 return $err ? 0 : 1;
7ea975ef 5970}
04a69bb4
AD
5971
5972sub template_create {
5973 my ($vmid, $conf, $disk) = @_;
5974
04a69bb4 5975 my $storecfg = PVE::Storage::config();
04a69bb4 5976
9cd07842
DM
5977 foreach_drive($conf, sub {
5978 my ($ds, $drive) = @_;
5979
5980 return if drive_is_cdrom($drive);
5981 return if $disk && $ds ne $disk;
5982
5983 my $volid = $drive->{file};
bbd56097 5984 return if !PVE::Storage::volume_has_feature($storecfg, 'template', $volid);
9cd07842 5985
04a69bb4
AD
5986 my $voliddst = PVE::Storage::vdisk_create_base($storecfg, $volid);
5987 $drive->{file} = $voliddst;
152fe752
DM
5988 $conf->{$ds} = print_drive($vmid, $drive);
5989 update_config_nolock($vmid, $conf, 1);
04a69bb4 5990 });
04a69bb4
AD
5991}
5992
624361b3
AD
5993sub is_template {
5994 my ($conf) = @_;
5995
96d695c0 5996 return 1 if defined $conf->{template} && $conf->{template} == 1;
624361b3
AD
5997}
5998
5133de42
AD
5999sub qemu_img_convert {
6000 my ($src_volid, $dst_volid, $size, $snapname) = @_;
6001
6002 my $storecfg = PVE::Storage::config();
6003 my ($src_storeid, $src_volname) = PVE::Storage::parse_volume_id($src_volid, 1);
6004 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid, 1);
6005
6006 if ($src_storeid && $dst_storeid) {
6007 my $src_scfg = PVE::Storage::storage_config($storecfg, $src_storeid);
6008 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
6009
6010 my $src_format = qemu_img_format($src_scfg, $src_volname);
6011 my $dst_format = qemu_img_format($dst_scfg, $dst_volname);
6012
6013 my $src_path = PVE::Storage::path($storecfg, $src_volid, $snapname);
6014 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
6015
6016 my $cmd = [];
71ddbff9 6017 push @$cmd, '/usr/bin/qemu-img', 'convert', '-t', 'writeback', '-p', '-n';
5133de42
AD
6018 push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
6019 push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path, $dst_path;
6020
6021 my $parser = sub {
6022 my $line = shift;
6023 if($line =~ m/\((\S+)\/100\%\)/){
6024 my $percent = $1;
6025 my $transferred = int($size * $percent / 100);
6026 my $remaining = $size - $transferred;
6027
6028 print "transferred: $transferred bytes remaining: $remaining bytes total: $size bytes progression: $percent %\n";
6029 }
6030
6031 };
6032
6033 eval { run_command($cmd, timeout => undef, outfunc => $parser); };
6034 my $err = $@;
6035 die "copy failed: $err" if $err;
6036 }
6037}
6038
6039sub qemu_img_format {
6040 my ($scfg, $volname) = @_;
6041
d81f0f09 6042 if ($scfg->{path} && $volname =~ m/\.(raw|cow|qcow|qcow2|qed|vmdk|cloop)$/) {
5133de42 6043 return $1;
be190583 6044 } else {
5133de42 6045 return "raw";
5133de42
AD
6046 }
6047}
6048
cfad42af 6049sub qemu_drive_mirror {
ab6ecffe 6050 my ($vmid, $drive, $dst_volid, $vmiddst) = @_;
cfad42af 6051
cfad42af 6052 my $storecfg = PVE::Storage::config();
08ac653f 6053 my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid);
152fe752 6054
08ac653f 6055 my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
cfad42af 6056
d81f0f09 6057 my $format = qemu_img_format($dst_scfg, $dst_volname);
21ccdb50 6058
08ac653f 6059 my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
21ccdb50 6060
22967505 6061 my $opts = { timeout => 10, device => "drive-$drive", mode => "existing", sync => "full", target => $dst_path };
88383920
DM
6062 $opts->{format} = $format if $format;
6063
22967505 6064 print "drive mirror is starting (scanning bitmap) : this step can take some minutes/hours, depend of disk size and storage speed\n";
21ccdb50 6065
08ac653f 6066 eval {
22967505 6067 vm_mon_cmd($vmid, "drive-mirror", %$opts);
08ac653f
DM
6068 while (1) {
6069 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
6070 my $stat = @$stats[0];
6071 die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
6072 die "error job is not mirroring" if $stat->{type} ne "mirror";
6073
08ac653f 6074 my $busy = $stat->{busy};
ad123d97 6075 my $ready = $stat->{ready};
08ac653f 6076
6f708643
DM
6077 if (my $total = $stat->{len}) {
6078 my $transferred = $stat->{offset} || 0;
6079 my $remaining = $total - $transferred;
6080 my $percent = sprintf "%.2f", ($transferred * 100 / $total);
67fb9de6 6081
ad123d97 6082 print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent % busy: $busy ready: $ready \n";
6f708643 6083 }
f34ebd52 6084
08ac653f 6085
ad123d97 6086 if ($stat->{ready} eq 'true') {
f34ebd52 6087
ad123d97 6088 last if $vmiddst != $vmid;
b467f79a 6089
ad123d97
AD
6090 # try to switch the disk if source and destination are on the same guest
6091 eval { vm_mon_cmd($vmid, "block-job-complete", device => "drive-$drive") };
6092 last if !$@;
6093 die $@ if $@ !~ m/cannot be completed/;
08ac653f 6094 }
08ac653f 6095 sleep 1;
cfad42af
AD
6096 }
6097
08ac653f
DM
6098
6099 };
88383920 6100 my $err = $@;
08ac653f 6101
88383920 6102 my $cancel_job = sub {
08ac653f
DM
6103 vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive");
6104 while (1) {
6105 my $stats = vm_mon_cmd($vmid, "query-block-jobs");
6106 my $stat = @$stats[0];
6107 last if !$stat;
6108 sleep 1;
cfad42af 6109 }
88383920
DM
6110 };
6111
6112 if ($err) {
f34ebd52 6113 eval { &$cancel_job(); };
88383920
DM
6114 die "mirroring error: $err";
6115 }
6116
6117 if ($vmiddst != $vmid) {
6118 # if we clone a disk for a new target vm, we don't switch the disk
6119 &$cancel_job(); # so we call block-job-cancel
cfad42af
AD
6120 }
6121}
6122
152fe752 6123sub clone_disk {
be190583 6124 my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
152fe752
DM
6125 $newvmid, $storage, $format, $full, $newvollist) = @_;
6126
6127 my $newvolid;
6128
6129 if (!$full) {
6130 print "create linked clone of drive $drivename ($drive->{file})\n";
258e646c 6131 $newvolid = PVE::Storage::vdisk_clone($storecfg, $drive->{file}, $newvmid, $snapname);
152fe752
DM
6132 push @$newvollist, $newvolid;
6133 } else {
6134 my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file});
6135 $storeid = $storage if $storage;
6136
1377d7b0
DM
6137 my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($storecfg, $storeid);
6138 if (!$format) {
d81f0f09
DM
6139 my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
6140 $format = qemu_img_format($scfg, $volname);
152fe752
DM
6141 }
6142
1377d7b0
DM
6143 # test if requested format is supported - else use default
6144 my $supported = grep { $_ eq $format } @$validFormats;
6145 $format = $defFormat if !$supported;
6146
152fe752
DM
6147 my ($size) = PVE::Storage::volume_size_info($storecfg, $drive->{file}, 3);
6148
6149 print "create full clone of drive $drivename ($drive->{file})\n";
6150 $newvolid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $newvmid, $format, undef, ($size/1024));
6151 push @$newvollist, $newvolid;
6152
6153 if (!$running || $snapname) {
6154 qemu_img_convert($drive->{file}, $newvolid, $size, $snapname);
6155 } else {
6156 qemu_drive_mirror($vmid, $drivename, $newvolid, $newvmid);
be190583 6157 }
152fe752
DM
6158 }
6159
6160 my ($size) = PVE::Storage::volume_size_info($storecfg, $newvolid, 3);
6161
6162 my $disk = $drive;
6163 $disk->{format} = undef;
6164 $disk->{file} = $newvolid;
6165 $disk->{size} = $size;
6166
6167 return $disk;
6168}
6169
ff556cf2
DM
6170# this only works if VM is running
6171sub get_current_qemu_machine {
6172 my ($vmid) = @_;
6173
6174 my $cmd = { execute => 'query-machines', arguments => {} };
8e90138a 6175 my $res = vm_qmp_command($vmid, $cmd);
ff556cf2
DM
6176
6177 my ($current, $default);
6178 foreach my $e (@$res) {
6179 $default = $e->{name} if $e->{'is-default'};
6180 $current = $e->{name} if $e->{'is-current'};
6181 }
6182
6183 # fallback to the default machine if current is not supported by qemu
6184 return $current || $default || 'pc';
6185}
6186
23f73120
AD
6187sub qemu_machine_feature_enabled {
6188 my ($machine, $kvmver, $version_major, $version_minor) = @_;
6189
6190 my $current_major;
6191 my $current_minor;
6192
6193 if ($machine && $machine =~ m/^(pc(-i440fx|-q35)?-(\d+)\.(\d+))/) {
6194
6195 $current_major = $3;
6196 $current_minor = $4;
6197
6198 } elsif ($kvmver =~ m/^(\d+)\.(\d+)/) {
6199
6200 $current_major = $1;
6201 $current_minor = $2;
6202 }
6203
6204 return 1 if $current_major >= $version_major && $current_minor >= $version_minor;
6205
6206
6207}
6208
4543ecf0
AD
6209sub lspci {
6210
6211 my $devices = {};
6212
6213 dir_glob_foreach("$pcisysfs/devices", '[a-f0-9]{4}:([a-f0-9]{2}:[a-f0-9]{2})\.([0-9])', sub {
6214 my (undef, $id, $function) = @_;
6215 my $res = { id => $id, function => $function};
6216 push @{$devices->{$id}}, $res;
6217 });
6218
6219 return $devices;
6220}
6221
22de899a
AD
6222sub vm_iothreads_list {
6223 my ($vmid) = @_;
6224
6225 my $res = vm_mon_cmd($vmid, 'query-iothreads');
6226
6227 my $iothreads = {};
6228 foreach my $iothread (@$res) {
6229 $iothreads->{ $iothread->{id} } = $iothread->{"thread-id"};
6230 }
6231
6232 return $iothreads;
6233}
6234
ee034f5c
AD
6235sub scsihw_infos {
6236 my ($conf, $drive) = @_;
6237
6238 my $maxdev = 0;
6239
6240 if ($conf->{scsihw} && ($conf->{scsihw} =~ m/^lsi/)) {
6241 $maxdev = 7;
a1511b3c 6242 } elsif ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
ee034f5c
AD
6243 $maxdev = 1;
6244 } else {
6245 $maxdev = 256;
6246 }
6247
6248 my $controller = int($drive->{index} / $maxdev);
a1511b3c 6249 my $controller_prefix = ($conf->{scsihw} && $conf->{scsihw} eq 'virtio-scsi-single') ? "virtioscsi" : "scsihw";
ee034f5c
AD
6250
6251 return ($maxdev, $controller, $controller_prefix);
6252}
a1511b3c 6253
1e3baf05 62541;