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