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