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