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