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