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