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