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