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