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