]> git.proxmox.com Git - qemu-server.git/blob - PVE/QemuServer.pm
rename option 'qga' to 'agent'
[qemu-server.git] / PVE / QemuServer.pm
1 package PVE::QemuServer;
2
3 use strict;
4 use POSIX;
5 use IO::Handle;
6 use IO::Select;
7 use IO::File;
8 use IO::Dir;
9 use IO::Socket::UNIX;
10 use File::Basename;
11 use File::Path;
12 use File::stat;
13 use Getopt::Long;
14 use Digest::SHA;
15 use Fcntl ':flock';
16 use Cwd 'abs_path';
17 use IPC::Open3;
18 use JSON;
19 use Fcntl;
20 use PVE::SafeSyslog;
21 use Storable qw(dclone);
22 use PVE::Exception qw(raise raise_param_exc);
23 use PVE::Storage;
24 use PVE::Tools qw(run_command lock_file file_read_firstline);
25 use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
26 use PVE::INotify;
27 use PVE::ProcFSTools;
28 use PVE::QMPClient;
29 use Time::HiRes qw(gettimeofday);
30
31 my $cpuinfo = PVE::ProcFSTools::read_cpuinfo();
32
33 # Note about locking: we use flock on the config file protect
34 # against concurent actions.
35 # Aditionaly, we have a 'lock' setting in the config file. This
36 # can be set to 'migrate' or 'backup'. Most actions are not
37 # allowed when such lock is set. But you can ignore this kind of
38 # lock with the --skiplock flag.
39
40 cfs_register_file('/qemu-server/',
41 \&parse_vm_config,
42 \&write_vm_config);
43
44 PVE::JSONSchema::register_standard_option('skiplock', {
45 description => "Ignore locks - only root is allowed to use this option.",
46 type => 'boolean',
47 optional => 1,
48 });
49
50 PVE::JSONSchema::register_standard_option('pve-qm-stateuri', {
51 description => "Some command save/restore state from this location.",
52 type => 'string',
53 maxLength => 128,
54 optional => 1,
55 });
56
57 #no warnings 'redefine';
58
59 unless(defined(&_VZSYSCALLS_H_)) {
60 eval 'sub _VZSYSCALLS_H_ () {1;}' unless defined(&_VZSYSCALLS_H_);
61 require 'sys/syscall.ph';
62 if(defined(&__x86_64__)) {
63 eval 'sub __NR_fairsched_vcpus () {499;}' unless defined(&__NR_fairsched_vcpus);
64 eval 'sub __NR_fairsched_mknod () {504;}' unless defined(&__NR_fairsched_mknod);
65 eval 'sub __NR_fairsched_rmnod () {505;}' unless defined(&__NR_fairsched_rmnod);
66 eval 'sub __NR_fairsched_chwt () {506;}' unless defined(&__NR_fairsched_chwt);
67 eval 'sub __NR_fairsched_mvpr () {507;}' unless defined(&__NR_fairsched_mvpr);
68 eval 'sub __NR_fairsched_rate () {508;}' unless defined(&__NR_fairsched_rate);
69 eval 'sub __NR_setluid () {501;}' unless defined(&__NR_setluid);
70 eval 'sub __NR_setublimit () {502;}' unless defined(&__NR_setublimit);
71 }
72 elsif(defined( &__i386__) ) {
73 eval 'sub __NR_fairsched_mknod () {500;}' unless defined(&__NR_fairsched_mknod);
74 eval 'sub __NR_fairsched_rmnod () {501;}' unless defined(&__NR_fairsched_rmnod);
75 eval 'sub __NR_fairsched_chwt () {502;}' unless defined(&__NR_fairsched_chwt);
76 eval 'sub __NR_fairsched_mvpr () {503;}' unless defined(&__NR_fairsched_mvpr);
77 eval 'sub __NR_fairsched_rate () {504;}' unless defined(&__NR_fairsched_rate);
78 eval 'sub __NR_fairsched_vcpus () {505;}' unless defined(&__NR_fairsched_vcpus);
79 eval 'sub __NR_setluid () {511;}' unless defined(&__NR_setluid);
80 eval 'sub __NR_setublimit () {512;}' unless defined(&__NR_setublimit);
81 } else {
82 die("no fairsched syscall for this arch");
83 }
84 require 'asm/ioctl.ph';
85 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined(&KVM_GET_API_VERSION);
86 }
87
88 sub fairsched_mknod {
89 my ($parent, $weight, $desired) = @_;
90
91 return syscall(&__NR_fairsched_mknod, int($parent), int($weight), int($desired));
92 }
93
94 sub fairsched_rmnod {
95 my ($id) = @_;
96
97 return syscall(&__NR_fairsched_rmnod, int($id));
98 }
99
100 sub fairsched_mvpr {
101 my ($pid, $newid) = @_;
102
103 return syscall(&__NR_fairsched_mvpr, int($pid), int($newid));
104 }
105
106 sub fairsched_vcpus {
107 my ($id, $vcpus) = @_;
108
109 return syscall(&__NR_fairsched_vcpus, int($id), int($vcpus));
110 }
111
112 sub fairsched_rate {
113 my ($id, $op, $rate) = @_;
114
115 return syscall(&__NR_fairsched_rate, int($id), int($op), int($rate));
116 }
117
118 use constant FAIRSCHED_SET_RATE => 0;
119 use constant FAIRSCHED_DROP_RATE => 1;
120 use constant FAIRSCHED_GET_RATE => 2;
121
122 sub fairsched_cpulimit {
123 my ($id, $limit) = @_;
124
125 my $cpulim1024 = int($limit * 1024 / 100);
126 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE : FAIRSCHED_DROP_RATE;
127
128 return fairsched_rate($id, $op, $cpulim1024);
129 }
130
131 my $nodename = PVE::INotify::nodename();
132
133 mkdir "/etc/pve/nodes/$nodename";
134 my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
135 mkdir $confdir;
136
137 my $var_run_tmpdir = "/var/run/qemu-server";
138 mkdir $var_run_tmpdir;
139
140 my $lock_dir = "/var/lock/qemu-server";
141 mkdir $lock_dir;
142
143 my $pcisysfs = "/sys/bus/pci";
144
145 my $confdesc = {
146 onboot => {
147 optional => 1,
148 type => 'boolean',
149 description => "Specifies whether a VM will be started during system bootup.",
150 default => 0,
151 },
152 autostart => {
153 optional => 1,
154 type => 'boolean',
155 description => "Automatic restart after crash (currently ignored).",
156 default => 0,
157 },
158 hotplug => {
159 optional => 1,
160 type => 'boolean',
161 description => "Activate hotplug for disk and network device",
162 default => 0,
163 },
164 reboot => {
165 optional => 1,
166 type => 'boolean',
167 description => "Allow reboot. If set to '0' the VM exit on reboot.",
168 default => 1,
169 },
170 lock => {
171 optional => 1,
172 type => 'string',
173 description => "Lock/unlock the VM.",
174 enum => [qw(migrate backup)],
175 },
176 cpulimit => {
177 optional => 1,
178 type => 'integer',
179 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.",
180 minimum => 0,
181 default => 0,
182 },
183 cpuunits => {
184 optional => 1,
185 type => 'integer',
186 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.",
187 minimum => 0,
188 maximum => 500000,
189 default => 1000,
190 },
191 memory => {
192 optional => 1,
193 type => 'integer',
194 description => "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
195 minimum => 16,
196 default => 512,
197 },
198 balloon => {
199 optional => 1,
200 type => 'integer',
201 description => "Amount of target RAM for the VM in MB.",
202 minimum => 16,
203 },
204 keyboard => {
205 optional => 1,
206 type => 'string',
207 description => "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
208 enum => PVE::Tools::kvmkeymaplist(),
209 default => 'en-us',
210 },
211 name => {
212 optional => 1,
213 type => 'string', format => 'dns-name',
214 description => "Set a name for the VM. Only used on the configuration web interface.",
215 },
216 scsihw => {
217 optional => 1,
218 type => 'string',
219 description => "scsi controller model",
220 enum => [qw(lsi virtio-scsi-pci megasas)],
221 default => 'lsi',
222 },
223 description => {
224 optional => 1,
225 type => 'string',
226 description => "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
227 },
228 ostype => {
229 optional => 1,
230 type => 'string',
231 enum => [qw(other wxp w2k w2k3 w2k8 wvista win7 l24 l26)],
232 description => <<EODESC,
233 Used to enable special optimization/features for specific
234 operating systems:
235
236 other => unspecified OS
237 wxp => Microsoft Windows XP
238 w2k => Microsoft Windows 2000
239 w2k3 => Microsoft Windows 2003
240 w2k8 => Microsoft Windows 2008
241 wvista => Microsoft Windows Vista
242 win7 => Microsoft Windows 7
243 l24 => Linux 2.4 Kernel
244 l26 => Linux 2.6/3.X Kernel
245
246 other|l24|l26 ... no special behaviour
247 wxp|w2k|w2k3|w2k8|wvista|win7 ... use --localtime switch
248 EODESC
249 },
250 boot => {
251 optional => 1,
252 type => 'string',
253 description => "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
254 pattern => '[acdn]{1,4}',
255 default => 'cdn',
256 },
257 bootdisk => {
258 optional => 1,
259 type => 'string', format => 'pve-qm-bootdisk',
260 description => "Enable booting from specified disk.",
261 pattern => '(ide|sata|scsi|virtio)\d+',
262 },
263 smp => {
264 optional => 1,
265 type => 'integer',
266 description => "The number of CPUs. Please use option -sockets instead.",
267 minimum => 1,
268 default => 1,
269 },
270 sockets => {
271 optional => 1,
272 type => 'integer',
273 description => "The number of CPU sockets.",
274 minimum => 1,
275 default => 1,
276 },
277 cores => {
278 optional => 1,
279 type => 'integer',
280 description => "The number of cores per socket.",
281 minimum => 1,
282 default => 1,
283 },
284 acpi => {
285 optional => 1,
286 type => 'boolean',
287 description => "Enable/disable ACPI.",
288 default => 1,
289 },
290 agent => {
291 optional => 1,
292 type => 'boolean',
293 description => "Enable/disable Qemu GuestAgent.",
294 default => 1,
295 },
296 kvm => {
297 optional => 1,
298 type => 'boolean',
299 description => "Enable/disable KVM hardware virtualization.",
300 default => 1,
301 },
302 tdf => {
303 optional => 1,
304 type => 'boolean',
305 description => "Enable/disable time drift fix. This is ignored for kvm versions newer that 1.0 (not needed anymore).",
306 default => 1,
307 },
308 localtime => {
309 optional => 1,
310 type => 'boolean',
311 description => "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
312 },
313 freeze => {
314 optional => 1,
315 type => 'boolean',
316 description => "Freeze CPU at startup (use 'c' monitor command to start execution).",
317 },
318 vga => {
319 optional => 1,
320 type => 'string',
321 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 win7/w2k8, and 'cirrur' for other OS types",
322 enum => [qw(std cirrus vmware)],
323 },
324 watchdog => {
325 optional => 1,
326 type => 'string', format => 'pve-qm-watchdog',
327 typetext => '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
328 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)",
329 },
330 startdate => {
331 optional => 1,
332 type => 'string',
333 typetext => "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
334 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'.",
335 pattern => '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
336 default => 'now',
337 },
338 startup => {
339 optional => 1,
340 type => 'string', format => 'pve-qm-startup',
341 typetext => '[[order=]\d+] [,up=\d+] [,down=\d+] ',
342 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.",
343 },
344 args => {
345 optional => 1,
346 type => 'string',
347 description => <<EODESCR,
348 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
349
350 args: -no-reboot -no-hpet
351 EODESCR
352 },
353 tablet => {
354 optional => 1,
355 type => 'boolean',
356 default => 1,
357 description => "Enable/disable the usb tablet device. This device is usually needed to allow absolute mouse positioning. 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.",
358 },
359 migrate_speed => {
360 optional => 1,
361 type => 'integer',
362 description => "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
363 minimum => 0,
364 default => 0,
365 },
366 migrate_downtime => {
367 optional => 1,
368 type => 'integer',
369 description => "Set maximum tolerated downtime (in seconds) for migrations.",
370 minimum => 0,
371 default => 1,
372 },
373 cdrom => {
374 optional => 1,
375 type => 'string', format => 'pve-qm-drive',
376 typetext => 'volume',
377 description => "This is an alias for option -ide2",
378 },
379 cpu => {
380 optional => 1,
381 description => "Emulated CPU type.",
382 type => 'string',
383 enum => [ qw(486 athlon pentium pentium2 pentium3 coreduo core2duo kvm32 kvm64 qemu32 qemu64 phenom cpu64-rhel6 cpu64-rhel5 Conroe Penryn Nehalem Westmere Opteron_G1 Opteron_G2 Opteron_G3 host) ],
384 default => 'qemu64',
385 },
386 };
387
388 # what about other qemu settings ?
389 #cpu => 'string',
390 #machine => 'string',
391 #fda => 'file',
392 #fdb => 'file',
393 #mtdblock => 'file',
394 #sd => 'file',
395 #pflash => 'file',
396 #snapshot => 'bool',
397 #bootp => 'file',
398 ##tftp => 'dir',
399 ##smb => 'dir',
400 #kernel => 'file',
401 #append => 'string',
402 #initrd => 'file',
403 ##soundhw => 'string',
404
405 while (my ($k, $v) = each %$confdesc) {
406 PVE::JSONSchema::register_standard_option("pve-qm-$k", $v);
407 }
408
409 my $MAX_IDE_DISKS = 4;
410 my $MAX_SCSI_DISKS = 14;
411 my $MAX_VIRTIO_DISKS = 16;
412 my $MAX_SATA_DISKS = 6;
413 my $MAX_USB_DEVICES = 5;
414 my $MAX_NETS = 32;
415 my $MAX_UNUSED_DISKS = 8;
416 my $MAX_HOSTPCI_DEVICES = 2;
417 my $MAX_SERIAL_PORTS = 4;
418 my $MAX_PARALLEL_PORTS = 3;
419
420 my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
421 'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
422 my $nic_model_list_txt = join(' ', sort @$nic_model_list);
423
424 # fixme:
425 my $netdesc = {
426 optional => 1,
427 type => 'string', format => 'pve-qm-net',
428 typetext => "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>][,tag=<vlanid>]",
429 description => <<EODESCR,
430 Specify network devices.
431
432 MODEL is one of: $nic_model_list_txt
433
434 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
435 automatically generated if not specified.
436
437 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
438
439 Option 'rate' is used to limit traffic bandwidth from and to this interface. It is specified as floating point number, unit is 'Megabytes per second'.
440
441 If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
442
443 10.0.2.2 Gateway
444 10.0.2.3 DNS Server
445 10.0.2.4 SMB Server
446
447 The DHCP server assign addresses to the guest starting from 10.0.2.15.
448
449 EODESCR
450 };
451 PVE::JSONSchema::register_standard_option("pve-qm-net", $netdesc);
452
453 for (my $i = 0; $i < $MAX_NETS; $i++) {
454 $confdesc->{"net$i"} = $netdesc;
455 }
456
457 my $drivename_hash;
458
459 my $idedesc = {
460 optional => 1,
461 type => 'string', format => 'pve-qm-drive',
462 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]',
463 description => "Use volume as IDE hard disk or CD-ROM (n is 0 to " .($MAX_IDE_DISKS -1) . ").",
464 };
465 PVE::JSONSchema::register_standard_option("pve-qm-ide", $idedesc);
466
467 my $scsidesc = {
468 optional => 1,
469 type => 'string', format => 'pve-qm-drive',
470 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]',
471 description => "Use volume as SCSI hard disk or CD-ROM (n is 0 to " . ($MAX_SCSI_DISKS - 1) . ").",
472 };
473 PVE::JSONSchema::register_standard_option("pve-qm-scsi", $scsidesc);
474
475 my $satadesc = {
476 optional => 1,
477 type => 'string', format => 'pve-qm-drive',
478 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]',
479 description => "Use volume as SATA hard disk or CD-ROM (n is 0 to " . ($MAX_SATA_DISKS - 1). ").",
480 };
481 PVE::JSONSchema::register_standard_option("pve-qm-sata", $satadesc);
482
483 my $virtiodesc = {
484 optional => 1,
485 type => 'string', format => 'pve-qm-drive',
486 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]',
487 description => "Use volume as VIRTIO hard disk (n is 0 to " . ($MAX_VIRTIO_DISKS - 1) . ").",
488 };
489 PVE::JSONSchema::register_standard_option("pve-qm-virtio", $virtiodesc);
490
491 my $usbdesc = {
492 optional => 1,
493 type => 'string', format => 'pve-qm-usb-device',
494 typetext => 'host=HOSTUSBDEVICE',
495 description => <<EODESCR,
496 Configure an USB device (n is 0 to 4). This can be used to
497 pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
498
499 'bus-port(.port)*' (decimal numbers) or
500 'vendor_id:product_id' (hexadeciaml numbers)
501
502 You can use the 'lsusb -t' command to list existing usb devices.
503
504 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
505
506 EODESCR
507 };
508 PVE::JSONSchema::register_standard_option("pve-qm-usb", $usbdesc);
509
510 my $hostpcidesc = {
511 optional => 1,
512 type => 'string', format => 'pve-qm-hostpci',
513 typetext => "HOSTPCIDEVICE",
514 description => <<EODESCR,
515 Map host pci devices. HOSTPCIDEVICE syntax is:
516
517 'bus:dev.func' (hexadecimal numbers)
518
519 You can us the 'lspci' command to list existing pci devices.
520
521 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
522
523 Experimental: user reported problems with this option.
524 EODESCR
525 };
526 PVE::JSONSchema::register_standard_option("pve-qm-hostpci", $hostpcidesc);
527
528 my $serialdesc = {
529 optional => 1,
530 type => 'string',
531 pattern => '/dev/ttyS\d+',
532 description => <<EODESCR,
533 Map host serial devices (n is 0 to 3).
534
535 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
536
537 Experimental: user reported problems with this option.
538 EODESCR
539 };
540
541 my $paralleldesc= {
542 optional => 1,
543 type => 'string',
544 pattern => '/dev/parport\d+',
545 description => <<EODESCR,
546 Map host parallel devices (n is 0 to 2).
547
548 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
549
550 Experimental: user reported problems with this option.
551 EODESCR
552 };
553
554 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
555 $confdesc->{"parallel$i"} = $paralleldesc;
556 }
557
558 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
559 $confdesc->{"serial$i"} = $serialdesc;
560 }
561
562 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
563 $confdesc->{"hostpci$i"} = $hostpcidesc;
564 }
565
566 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
567 $drivename_hash->{"ide$i"} = 1;
568 $confdesc->{"ide$i"} = $idedesc;
569 }
570
571 for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
572 $drivename_hash->{"sata$i"} = 1;
573 $confdesc->{"sata$i"} = $satadesc;
574 }
575
576 for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
577 $drivename_hash->{"scsi$i"} = 1;
578 $confdesc->{"scsi$i"} = $scsidesc ;
579 }
580
581 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
582 $drivename_hash->{"virtio$i"} = 1;
583 $confdesc->{"virtio$i"} = $virtiodesc;
584 }
585
586 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
587 $confdesc->{"usb$i"} = $usbdesc;
588 }
589
590 my $unuseddesc = {
591 optional => 1,
592 type => 'string', format => 'pve-volume-id',
593 description => "Reference to unused volumes.",
594 };
595
596 for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
597 $confdesc->{"unused$i"} = $unuseddesc;
598 }
599
600 my $kvm_api_version = 0;
601
602 sub kvm_version {
603
604 return $kvm_api_version if $kvm_api_version;
605
606 my $fh = IO::File->new("</dev/kvm") ||
607 return 0;
608
609 if (my $v = $fh->ioctl(KVM_GET_API_VERSION(), 0)) {
610 $kvm_api_version = $v;
611 }
612
613 $fh->close();
614
615 return $kvm_api_version;
616 }
617
618 my $kvm_user_version;
619
620 sub kvm_user_version {
621
622 return $kvm_user_version if $kvm_user_version;
623
624 $kvm_user_version = 'unknown';
625
626 my $tmp = `kvm -help 2>/dev/null`;
627
628 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?) /) {
629 $kvm_user_version = $2;
630 }
631
632 return $kvm_user_version;
633
634 }
635
636 my $kernel_has_vhost_net = -c '/dev/vhost-net';
637
638 sub disknames {
639 # order is important - used to autoselect boot disk
640 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
641 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
642 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
643 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
644 }
645
646 sub valid_drivename {
647 my $dev = shift;
648
649 return defined($drivename_hash->{$dev});
650 }
651
652 sub option_exists {
653 my $key = shift;
654 return defined($confdesc->{$key});
655 }
656
657 sub nic_models {
658 return $nic_model_list;
659 }
660
661 sub os_list_description {
662
663 return {
664 other => 'Other',
665 wxp => 'Windows XP',
666 w2k => 'Windows 2000',
667 w2k3 =>, 'Windows 2003',
668 w2k8 => 'Windows 2008',
669 wvista => 'Windows Vista',
670 win7 => 'Windows 7',
671 l24 => 'Linux 2.4',
672 l26 => 'Linux 2.6',
673 };
674 }
675
676 my $cdrom_path;
677
678 sub get_cdrom_path {
679
680 return $cdrom_path if $cdrom_path;
681
682 return $cdrom_path = "/dev/cdrom" if -l "/dev/cdrom";
683 return $cdrom_path = "/dev/cdrom1" if -l "/dev/cdrom1";
684 return $cdrom_path = "/dev/cdrom2" if -l "/dev/cdrom2";
685 }
686
687 sub get_iso_path {
688 my ($storecfg, $vmid, $cdrom) = @_;
689
690 if ($cdrom eq 'cdrom') {
691 return get_cdrom_path();
692 } elsif ($cdrom eq 'none') {
693 return '';
694 } elsif ($cdrom =~ m|^/|) {
695 return $cdrom;
696 } else {
697 return PVE::Storage::path($storecfg, $cdrom);
698 }
699 }
700
701 # try to convert old style file names to volume IDs
702 sub filename_to_volume_id {
703 my ($vmid, $file, $media) = @_;
704
705 if (!($file eq 'none' || $file eq 'cdrom' ||
706 $file =~ m|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
707
708 return undef if $file =~ m|/|;
709
710 if ($media && $media eq 'cdrom') {
711 $file = "local:iso/$file";
712 } else {
713 $file = "local:$vmid/$file";
714 }
715 }
716
717 return $file;
718 }
719
720 sub verify_media_type {
721 my ($opt, $vtype, $media) = @_;
722
723 return if !$media;
724
725 my $etype;
726 if ($media eq 'disk') {
727 $etype = 'images';
728 } elsif ($media eq 'cdrom') {
729 $etype = 'iso';
730 } else {
731 die "internal error";
732 }
733
734 return if ($vtype eq $etype);
735
736 raise_param_exc({ $opt => "unexpected media type ($vtype != $etype)" });
737 }
738
739 sub cleanup_drive_path {
740 my ($opt, $storecfg, $drive) = @_;
741
742 # try to convert filesystem paths to volume IDs
743
744 if (($drive->{file} !~ m/^(cdrom|none)$/) &&
745 ($drive->{file} !~ m|^/dev/.+|) &&
746 ($drive->{file} !~ m/^([^:]+):(.+)$/) &&
747 ($drive->{file} !~ m/^\d+$/)) {
748 my ($vtype, $volid) = PVE::Storage::path_to_volume_id($storecfg, $drive->{file});
749 raise_param_exc({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
750 $drive->{media} = 'cdrom' if !$drive->{media} && $vtype eq 'iso';
751 verify_media_type($opt, $vtype, $drive->{media});
752 $drive->{file} = $volid;
753 }
754
755 $drive->{media} = 'cdrom' if !$drive->{media} && $drive->{file} =~ m/^(cdrom|none)$/;
756 }
757
758 sub create_conf_nolock {
759 my ($vmid, $settings) = @_;
760
761 my $filename = config_file($vmid);
762
763 die "configuration file '$filename' already exists\n" if -f $filename;
764
765 my $defaults = load_defaults();
766
767 $settings->{name} = "vm$vmid" if !$settings->{name};
768 $settings->{memory} = $defaults->{memory} if !$settings->{memory};
769
770 my $data = '';
771 foreach my $opt (keys %$settings) {
772 next if !$confdesc->{$opt};
773
774 my $value = $settings->{$opt};
775 next if !$value;
776
777 $data .= "$opt: $value\n";
778 }
779
780 PVE::Tools::file_set_contents($filename, $data);
781 }
782
783 my $parse_size = sub {
784 my ($value) = @_;
785
786 return undef if $value !~ m/^(\d+(\.\d+)?)([KMG])?$/;
787 my ($size, $unit) = ($1, $3);
788 if ($unit) {
789 if ($unit eq 'K') {
790 $size = $size * 1024;
791 } elsif ($unit eq 'M') {
792 $size = $size * 1024 * 1024;
793 } elsif ($unit eq 'G') {
794 $size = $size * 1024 * 1024 * 1024;
795 }
796 }
797 return int($size);
798 };
799
800 my $format_size = sub {
801 my ($size) = @_;
802
803 $size = int($size);
804
805 my $kb = int($size/1024);
806 return $size if $kb*1024 != $size;
807
808 my $mb = int($kb/1024);
809 return "${kb}K" if $mb*1024 != $kb;
810
811 my $gb = int($mb/1024);
812 return "${mb}M" if $gb*1024 != $mb;
813
814 return "${gb}G";
815 };
816
817 # ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
818 # [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
819 # [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
820 # [,aio=native|threads]
821
822 sub parse_drive {
823 my ($key, $data) = @_;
824
825 my $res = {};
826
827 # $key may be undefined - used to verify JSON parameters
828 if (!defined($key)) {
829 $res->{interface} = 'unknown'; # should not harm when used to verify parameters
830 $res->{index} = 0;
831 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
832 $res->{interface} = $1;
833 $res->{index} = $2;
834 } else {
835 return undef;
836 }
837
838 foreach my $p (split (/,/, $data)) {
839 next if $p =~ m/^\s*$/;
840
841 if ($p =~ m/^(file|volume|cyls|heads|secs|trans|media|snapshot|cache|format|rerror|werror|backup|aio|bps|mbps|bps_rd|mbps_rd|bps_wr|mbps_wr|iops|iops_rd|iops_wr|size)=(.+)$/) {
842 my ($k, $v) = ($1, $2);
843
844 $k = 'file' if $k eq 'volume';
845
846 return undef if defined $res->{$k};
847
848 if ($k eq 'bps' || $k eq 'bps_rd' || $k eq 'bps_wr') {
849 return undef if !$v || $v !~ m/^\d+/;
850 $k = "m$k";
851 $v = sprintf("%.3f", $v / (1024*1024));
852 }
853 $res->{$k} = $v;
854 } else {
855 if (!$res->{file} && $p !~ m/=/) {
856 $res->{file} = $p;
857 } else {
858 return undef;
859 }
860 }
861 }
862
863 return undef if !$res->{file};
864
865 return undef if $res->{cache} &&
866 $res->{cache} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
867 return undef if $res->{snapshot} && $res->{snapshot} !~ m/^(on|off)$/;
868 return undef if $res->{cyls} && $res->{cyls} !~ m/^\d+$/;
869 return undef if $res->{heads} && $res->{heads} !~ m/^\d+$/;
870 return undef if $res->{secs} && $res->{secs} !~ m/^\d+$/;
871 return undef if $res->{media} && $res->{media} !~ m/^(disk|cdrom)$/;
872 return undef if $res->{trans} && $res->{trans} !~ m/^(none|lba|auto)$/;
873 return undef if $res->{format} && $res->{format} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
874 return undef if $res->{rerror} && $res->{rerror} !~ m/^(ignore|report|stop)$/;
875 return undef if $res->{werror} && $res->{werror} !~ m/^(enospc|ignore|report|stop)$/;
876 return undef if $res->{backup} && $res->{backup} !~ m/^(yes|no)$/;
877 return undef if $res->{aio} && $res->{aio} !~ m/^(native|threads)$/;
878
879
880 return undef if $res->{mbps_rd} && $res->{mbps};
881 return undef if $res->{mbps_wr} && $res->{mbps};
882
883 return undef if $res->{mbps} && $res->{mbps} !~ m/^\d+(\.\d+)?$/;
884 return undef if $res->{mbps_rd} && $res->{mbps_rd} !~ m/^\d+(\.\d+)?$/;
885 return undef if $res->{mbps_wr} && $res->{mbps_wr} !~ m/^\d+(\.\d+)?$/;
886
887 return undef if $res->{iops_rd} && $res->{iops};
888 return undef if $res->{iops_wr} && $res->{iops};
889 return undef if $res->{iops} && $res->{iops} !~ m/^\d+$/;
890 return undef if $res->{iops_rd} && $res->{iops_rd} !~ m/^\d+$/;
891 return undef if $res->{iops_wr} && $res->{iops_wr} !~ m/^\d+$/;
892
893
894 if ($res->{size}) {
895 return undef if !defined($res->{size} = &$parse_size($res->{size}));
896 }
897
898 if ($res->{media} && ($res->{media} eq 'cdrom')) {
899 return undef if $res->{snapshot} || $res->{trans} || $res->{format};
900 return undef if $res->{heads} || $res->{secs} || $res->{cyls};
901 return undef if $res->{interface} eq 'virtio';
902 }
903
904 # rerror does not work with scsi drives
905 if ($res->{rerror}) {
906 return undef if $res->{interface} eq 'scsi';
907 }
908
909 return $res;
910 }
911
912 my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio iops iops_rd iops_wr);
913
914 sub print_drive {
915 my ($vmid, $drive) = @_;
916
917 my $opts = '';
918 foreach my $o (@qemu_drive_options, 'mbps', 'mbps_rd', 'mbps_wr', 'backup') {
919 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
920 }
921
922 if ($drive->{size}) {
923 $opts .= ",size=" . &$format_size($drive->{size});
924 }
925
926 return "$drive->{file}$opts";
927 }
928
929 sub scsi_inquiry {
930 my($fh, $noerr) = @_;
931
932 my $SG_IO = 0x2285;
933 my $SG_GET_VERSION_NUM = 0x2282;
934
935 my $versionbuf = "\x00" x 8;
936 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
937 if (!$ret) {
938 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
939 return undef;
940 }
941 my $version = unpack("I", $versionbuf);
942 if ($version < 30000) {
943 die "scsi generic interface too old\n" if !$noerr;
944 return undef;
945 }
946
947 my $buf = "\x00" x 36;
948 my $sensebuf = "\x00" x 8;
949 my $cmd = pack("C x3 C x11", 0x12, 36);
950
951 # see /usr/include/scsi/sg.h
952 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";
953
954 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
955 length($sensebuf), 0, length($buf), $buf,
956 $cmd, $sensebuf, 6000);
957
958 $ret = ioctl($fh, $SG_IO, $packet);
959 if (!$ret) {
960 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
961 return undef;
962 }
963
964 my @res = unpack($sg_io_hdr_t, $packet);
965 if ($res[17] || $res[18]) {
966 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
967 return undef;
968 }
969
970 my $res = {};
971 ($res->{device}, $res->{removable}, $res->{venodor},
972 $res->{product}, $res->{revision}) = unpack("C C x6 A8 A16 A4", $buf);
973
974 return $res;
975 }
976
977 sub path_is_scsi {
978 my ($path) = @_;
979
980 my $fh = IO::File->new("+<$path") || return undef;
981 my $res = scsi_inquiry($fh, 1);
982 close($fh);
983
984 return $res;
985 }
986
987 sub print_drivedevice_full {
988 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
989
990 my $device = '';
991 my $maxdev = 0;
992
993 if ($drive->{interface} eq 'virtio') {
994 my $pciaddr = print_pci_addr("$drive->{interface}$drive->{index}", $bridges);
995 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
996 } elsif ($drive->{interface} eq 'scsi') {
997 $maxdev = ($conf->{scsihw} && $conf->{scsihw} ne 'lsi') ? 256 : 7;
998 my $controller = int($drive->{index} / $maxdev);
999 my $unit = $drive->{index} % $maxdev;
1000 my $devicetype = 'hd';
1001 my $path = '';
1002 if (drive_is_cdrom($drive)) {
1003 $devicetype = 'cd';
1004 } else {
1005 if ($drive->{file} =~ m|^/|) {
1006 $path = $drive->{file};
1007 } else {
1008 $path = PVE::Storage::path($storecfg, $drive->{file});
1009 }
1010
1011 if($path =~ m/^iscsi\:\/\//){
1012 $devicetype = 'generic';
1013 }
1014 else {
1015 $devicetype = 'block' if path_is_scsi($path);
1016 }
1017 }
1018
1019 if (!$conf->{scsihw} || $conf->{scsihw} eq 'lsi'){
1020 $device = "scsi-$devicetype,bus=scsihw$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}" if !$conf->{scsihw} || $conf->{scsihw} eq 'lsi';
1021 } else {
1022 $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}";
1023 }
1024
1025 } elsif ($drive->{interface} eq 'ide'){
1026 $maxdev = 2;
1027 my $controller = int($drive->{index} / $maxdev);
1028 my $unit = $drive->{index} % $maxdev;
1029 my $devicetype = ($drive->{media} && $drive->{media} eq 'cdrom') ? "cd" : "hd";
1030
1031 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1032 } elsif ($drive->{interface} eq 'sata'){
1033 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1034 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1035 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1036 } elsif ($drive->{interface} eq 'usb') {
1037 die "implement me";
1038 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1039 } else {
1040 die "unsupported interface type";
1041 }
1042
1043 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex};
1044
1045 return $device;
1046 }
1047
1048 sub print_drive_full {
1049 my ($storecfg, $vmid, $drive) = @_;
1050
1051 my $opts = '';
1052 foreach my $o (@qemu_drive_options) {
1053 next if $o eq 'bootindex';
1054 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1055 }
1056
1057 foreach my $o (qw(bps bps_rd bps_wr)) {
1058 my $v = $drive->{"m$o"};
1059 $opts .= ",$o=" . int($v*1024*1024) if $v;
1060 }
1061
1062 # use linux-aio by default (qemu default is threads)
1063 $opts .= ",aio=native" if !$drive->{aio};
1064
1065 my $path;
1066 my $volid = $drive->{file};
1067 if (drive_is_cdrom($drive)) {
1068 $path = get_iso_path($storecfg, $vmid, $volid);
1069 } else {
1070 if ($volid =~ m|^/|) {
1071 $path = $volid;
1072 } else {
1073 $path = PVE::Storage::path($storecfg, $volid);
1074 }
1075 if (!$drive->{cache} && ($path =~ m|^/dev/| || $path =~ m|\.raw$|)) {
1076 $opts .= ",cache=none";
1077 }
1078 }
1079
1080 my $pathinfo = $path ? "file=$path," : '';
1081
1082 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1083 }
1084
1085 sub print_netdevice_full {
1086 my ($vmid, $conf, $net, $netid, $bridges) = @_;
1087
1088 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
1089
1090 my $device = $net->{model};
1091 if ($net->{model} eq 'virtio') {
1092 $device = 'virtio-net-pci';
1093 };
1094
1095 # qemu > 0.15 always try to boot from network - we disable that by
1096 # not loading the pxe rom file
1097 my $extra = ($bootorder !~ m/n/) ? "romfile=," : '';
1098 my $pciaddr = print_pci_addr("$netid", $bridges);
1099 my $tmpstr = "$device,${extra}mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1100 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex} ;
1101 return $tmpstr;
1102 }
1103
1104 sub print_netdev_full {
1105 my ($vmid, $conf, $net, $netid) = @_;
1106
1107 my $i = '';
1108 if ($netid =~ m/^net(\d+)$/) {
1109 $i = int($1);
1110 }
1111
1112 die "got strange net id '$i'\n" if $i >= ${MAX_NETS};
1113
1114 my $ifname = "tap${vmid}i$i";
1115
1116 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1117 die "interface name '$ifname' is too long (max 15 character)\n"
1118 if length($ifname) >= 16;
1119
1120 my $vhostparam = '';
1121 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model} eq 'virtio';
1122
1123 my $vmname = $conf->{name} || "vm$vmid";
1124
1125 if ($net->{bridge}) {
1126 return "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
1127 } else {
1128 return "type=user,id=$netid,hostname=$vmname";
1129 }
1130 }
1131
1132 sub drive_is_cdrom {
1133 my ($drive) = @_;
1134
1135 return $drive && $drive->{media} && ($drive->{media} eq 'cdrom');
1136
1137 }
1138
1139 sub parse_hostpci {
1140 my ($value) = @_;
1141
1142 return undef if !$value;
1143
1144 my $res = {};
1145
1146 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
1147 $res->{pciid} = $value;
1148 } else {
1149 return undef;
1150 }
1151
1152 return $res;
1153 }
1154
1155 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1156 sub parse_net {
1157 my ($data) = @_;
1158
1159 my $res = {};
1160
1161 foreach my $kvp (split(/,/, $data)) {
1162
1163 if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
1164 my $model = lc($1);
1165 my $mac = uc($3) || PVE::Tools::random_ether_addr();
1166 $res->{model} = $model;
1167 $res->{macaddr} = $mac;
1168 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1169 $res->{bridge} = $1;
1170 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1171 $res->{rate} = $1;
1172 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1173 $res->{tag} = $1;
1174 } else {
1175 return undef;
1176 }
1177
1178 }
1179
1180 return undef if !$res->{model};
1181
1182 return $res;
1183 }
1184
1185 sub print_net {
1186 my $net = shift;
1187
1188 my $res = "$net->{model}";
1189 $res .= "=$net->{macaddr}" if $net->{macaddr};
1190 $res .= ",bridge=$net->{bridge}" if $net->{bridge};
1191 $res .= ",rate=$net->{rate}" if $net->{rate};
1192 $res .= ",tag=$net->{tag}" if $net->{tag};
1193
1194 return $res;
1195 }
1196
1197 sub add_random_macs {
1198 my ($settings) = @_;
1199
1200 foreach my $opt (keys %$settings) {
1201 next if $opt !~ m/^net(\d+)$/;
1202 my $net = parse_net($settings->{$opt});
1203 next if !$net;
1204 $settings->{$opt} = print_net($net);
1205 }
1206 }
1207
1208 sub add_unused_volume {
1209 my ($config, $volid) = @_;
1210
1211 my $key;
1212 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1213 my $test = "unused$ind";
1214 if (my $vid = $config->{$test}) {
1215 return if $vid eq $volid; # do not add duplicates
1216 } else {
1217 $key = $test;
1218 }
1219 }
1220
1221 die "To many unused volume - please delete them first.\n" if !$key;
1222
1223 $config->{$key} = $volid;
1224
1225 return $key;
1226 }
1227
1228 # fixme: remove all thos $noerr parameters?
1229
1230 PVE::JSONSchema::register_format('pve-qm-bootdisk', \&verify_bootdisk);
1231 sub verify_bootdisk {
1232 my ($value, $noerr) = @_;
1233
1234 return $value if valid_drivename($value);
1235
1236 return undef if $noerr;
1237
1238 die "invalid boot disk '$value'\n";
1239 }
1240
1241 PVE::JSONSchema::register_format('pve-qm-net', \&verify_net);
1242 sub verify_net {
1243 my ($value, $noerr) = @_;
1244
1245 return $value if parse_net($value);
1246
1247 return undef if $noerr;
1248
1249 die "unable to parse network options\n";
1250 }
1251
1252 PVE::JSONSchema::register_format('pve-qm-drive', \&verify_drive);
1253 sub verify_drive {
1254 my ($value, $noerr) = @_;
1255
1256 return $value if parse_drive(undef, $value);
1257
1258 return undef if $noerr;
1259
1260 die "unable to parse drive options\n";
1261 }
1262
1263 PVE::JSONSchema::register_format('pve-qm-hostpci', \&verify_hostpci);
1264 sub verify_hostpci {
1265 my ($value, $noerr) = @_;
1266
1267 return $value if parse_hostpci($value);
1268
1269 return undef if $noerr;
1270
1271 die "unable to parse pci id\n";
1272 }
1273
1274 PVE::JSONSchema::register_format('pve-qm-watchdog', \&verify_watchdog);
1275 sub verify_watchdog {
1276 my ($value, $noerr) = @_;
1277
1278 return $value if parse_watchdog($value);
1279
1280 return undef if $noerr;
1281
1282 die "unable to parse watchdog options\n";
1283 }
1284
1285 sub parse_watchdog {
1286 my ($value) = @_;
1287
1288 return undef if !$value;
1289
1290 my $res = {};
1291
1292 foreach my $p (split(/,/, $value)) {
1293 next if $p =~ m/^\s*$/;
1294
1295 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1296 $res->{model} = $2;
1297 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1298 $res->{action} = $2;
1299 } else {
1300 return undef;
1301 }
1302 }
1303
1304 return $res;
1305 }
1306
1307 PVE::JSONSchema::register_format('pve-qm-startup', \&verify_startup);
1308 sub verify_startup {
1309 my ($value, $noerr) = @_;
1310
1311 return $value if parse_startup($value);
1312
1313 return undef if $noerr;
1314
1315 die "unable to parse startup options\n";
1316 }
1317
1318 sub parse_startup {
1319 my ($value) = @_;
1320
1321 return undef if !$value;
1322
1323 my $res = {};
1324
1325 foreach my $p (split(/,/, $value)) {
1326 next if $p =~ m/^\s*$/;
1327
1328 if ($p =~ m/^(order=)?(\d+)$/) {
1329 $res->{order} = $2;
1330 } elsif ($p =~ m/^up=(\d+)$/) {
1331 $res->{up} = $1;
1332 } elsif ($p =~ m/^down=(\d+)$/) {
1333 $res->{down} = $1;
1334 } else {
1335 return undef;
1336 }
1337 }
1338
1339 return $res;
1340 }
1341
1342 sub parse_usb_device {
1343 my ($value) = @_;
1344
1345 return undef if !$value;
1346
1347 my @dl = split(/,/, $value);
1348 my $found;
1349
1350 my $res = {};
1351 foreach my $v (@dl) {
1352 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1353 $found = 1;
1354 $res->{vendorid} = $2;
1355 $res->{productid} = $4;
1356 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1357 $found = 1;
1358 $res->{hostbus} = $1;
1359 $res->{hostport} = $2;
1360 } else {
1361 return undef;
1362 }
1363 }
1364 return undef if !$found;
1365
1366 return $res;
1367 }
1368
1369 PVE::JSONSchema::register_format('pve-qm-usb-device', \&verify_usb_device);
1370 sub verify_usb_device {
1371 my ($value, $noerr) = @_;
1372
1373 return $value if parse_usb_device($value);
1374
1375 return undef if $noerr;
1376
1377 die "unable to parse usb device\n";
1378 }
1379
1380 # add JSON properties for create and set function
1381 sub json_config_properties {
1382 my $prop = shift;
1383
1384 foreach my $opt (keys %$confdesc) {
1385 $prop->{$opt} = $confdesc->{$opt};
1386 }
1387
1388 return $prop;
1389 }
1390
1391 sub check_type {
1392 my ($key, $value) = @_;
1393
1394 die "unknown setting '$key'\n" if !$confdesc->{$key};
1395
1396 my $type = $confdesc->{$key}->{type};
1397
1398 if (!defined($value)) {
1399 die "got undefined value\n";
1400 }
1401
1402 if ($value =~ m/[\n\r]/) {
1403 die "property contains a line feed\n";
1404 }
1405
1406 if ($type eq 'boolean') {
1407 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1408 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1409 die "type check ('boolean') failed - got '$value'\n";
1410 } elsif ($type eq 'integer') {
1411 return int($1) if $value =~ m/^(\d+)$/;
1412 die "type check ('integer') failed - got '$value'\n";
1413 } elsif ($type eq 'string') {
1414 if (my $fmt = $confdesc->{$key}->{format}) {
1415 if ($fmt eq 'pve-qm-drive') {
1416 # special case - we need to pass $key to parse_drive()
1417 my $drive = parse_drive($key, $value);
1418 return $value if $drive;
1419 die "unable to parse drive options\n";
1420 }
1421 PVE::JSONSchema::check_format($fmt, $value);
1422 return $value;
1423 }
1424 $value =~ s/^\"(.*)\"$/$1/;
1425 return $value;
1426 } else {
1427 die "internal error"
1428 }
1429 }
1430
1431 sub lock_config_full {
1432 my ($vmid, $timeout, $code, @param) = @_;
1433
1434 my $filename = config_file_lock($vmid);
1435
1436 my $res = lock_file($filename, $timeout, $code, @param);
1437
1438 die $@ if $@;
1439
1440 return $res;
1441 }
1442
1443 sub lock_config {
1444 my ($vmid, $code, @param) = @_;
1445
1446 return lock_config_full($vmid, 10, $code, @param);
1447 }
1448
1449 sub cfs_config_path {
1450 my ($vmid, $node) = @_;
1451
1452 $node = $nodename if !$node;
1453 return "nodes/$node/qemu-server/$vmid.conf";
1454 }
1455
1456 sub check_iommu_support{
1457 #fixme : need to check IOMMU support
1458 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1459
1460 my $iommu=1;
1461 return $iommu;
1462
1463 }
1464
1465 sub config_file {
1466 my ($vmid, $node) = @_;
1467
1468 my $cfspath = cfs_config_path($vmid, $node);
1469 return "/etc/pve/$cfspath";
1470 }
1471
1472 sub config_file_lock {
1473 my ($vmid) = @_;
1474
1475 return "$lock_dir/lock-$vmid.conf";
1476 }
1477
1478 sub touch_config {
1479 my ($vmid) = @_;
1480
1481 my $conf = config_file($vmid);
1482 utime undef, undef, $conf;
1483 }
1484
1485 sub destroy_vm {
1486 my ($storecfg, $vmid, $keep_empty_config) = @_;
1487
1488 my $conffile = config_file($vmid);
1489
1490 my $conf = load_config($vmid);
1491
1492 check_lock($conf);
1493
1494 # only remove disks owned by this VM
1495 foreach_drive($conf, sub {
1496 my ($ds, $drive) = @_;
1497
1498 return if drive_is_cdrom($drive);
1499
1500 my $volid = $drive->{file};
1501 return if !$volid || $volid =~ m|^/|;
1502
1503 my ($path, $owner) = PVE::Storage::path($storecfg, $volid);
1504 return if !$path || !$owner || ($owner != $vmid);
1505
1506 PVE::Storage::vdisk_free($storecfg, $volid);
1507 });
1508
1509 if ($keep_empty_config) {
1510 PVE::Tools::file_set_contents($conffile, "memory: 128\n");
1511 } else {
1512 unlink $conffile;
1513 }
1514
1515 # also remove unused disk
1516 eval {
1517 my $dl = PVE::Storage::vdisk_list($storecfg, undef, $vmid);
1518
1519 eval {
1520 PVE::Storage::foreach_volid($dl, sub {
1521 my ($volid, $sid, $volname, $d) = @_;
1522 PVE::Storage::vdisk_free($storecfg, $volid);
1523 });
1524 };
1525 warn $@ if $@;
1526
1527 };
1528 warn $@ if $@;
1529 }
1530
1531 sub load_config {
1532 my ($vmid, $node) = @_;
1533
1534 my $cfspath = cfs_config_path($vmid, $node);
1535
1536 my $conf = PVE::Cluster::cfs_read_file($cfspath);
1537
1538 die "no such VM ('$vmid')\n" if !defined($conf);
1539
1540 return $conf;
1541 }
1542
1543 sub parse_vm_config {
1544 my ($filename, $raw) = @_;
1545
1546 return undef if !defined($raw);
1547
1548 my $res = {
1549 digest => Digest::SHA::sha1_hex($raw),
1550 };
1551
1552 $filename =~ m|/qemu-server/(\d+)\.conf$|
1553 || die "got strange filename '$filename'";
1554
1555 my $vmid = $1;
1556
1557 my $descr = '';
1558
1559 while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
1560 my $line = $1;
1561
1562 next if $line =~ m/^\s*$/;
1563
1564 if ($line =~ m/^\#(.*)\s*$/) {
1565 $descr .= PVE::Tools::decode_text($1) . "\n";
1566 next;
1567 }
1568
1569 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1570 $descr .= PVE::Tools::decode_text($2);
1571 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1572 my $key = $1;
1573 my $value = $2;
1574 $res->{$key} = $value;
1575 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1576 my $key = $1;
1577 my $value = $2;
1578 eval { $value = check_type($key, $value); };
1579 if ($@) {
1580 warn "vm $vmid - unable to parse value of '$key' - $@";
1581 } else {
1582 my $fmt = $confdesc->{$key}->{format};
1583 if ($fmt && $fmt eq 'pve-qm-drive') {
1584 my $v = parse_drive($key, $value);
1585 if (my $volid = filename_to_volume_id($vmid, $v->{file}, $v->{media})) {
1586 $v->{file} = $volid;
1587 $value = print_drive($vmid, $v);
1588 } else {
1589 warn "vm $vmid - unable to parse value of '$key'\n";
1590 next;
1591 }
1592 }
1593
1594 if ($key eq 'cdrom') {
1595 $res->{ide2} = $value;
1596 } else {
1597 $res->{$key} = $value;
1598 }
1599 }
1600 }
1601 }
1602
1603 $res->{description} = $descr if $descr;
1604
1605 # convert old smp to sockets
1606 if ($res->{smp} && !$res->{sockets}) {
1607 $res->{sockets} = $res->{smp};
1608 }
1609 delete $res->{smp};
1610
1611 return $res;
1612 }
1613
1614 sub write_vm_config {
1615 my ($filename, $conf) = @_;
1616
1617 if ($conf->{cdrom}) {
1618 die "option ide2 conflicts with cdrom\n" if $conf->{ide2};
1619 $conf->{ide2} = $conf->{cdrom};
1620 delete $conf->{cdrom};
1621 }
1622
1623 # we do not use 'smp' any longer
1624 if ($conf->{sockets}) {
1625 delete $conf->{smp};
1626 } elsif ($conf->{smp}) {
1627 $conf->{sockets} = $conf->{smp};
1628 delete $conf->{cores};
1629 delete $conf->{smp};
1630 }
1631
1632 my $new_volids = {};
1633 foreach my $key (keys %$conf) {
1634 next if $key eq 'digest' || $key eq 'description';
1635 my $value = $conf->{$key};
1636 eval { $value = check_type($key, $value); };
1637 die "unable to parse value of '$key' - $@" if $@;
1638
1639 $conf->{$key} = $value;
1640
1641 if (valid_drivename($key)) {
1642 my $drive = PVE::QemuServer::parse_drive($key, $value);
1643 $new_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
1644 }
1645 }
1646
1647 # remove 'unusedX' settings if we re-add a volume
1648 foreach my $key (keys %$conf) {
1649 my $value = $conf->{$key};
1650 if ($key =~ m/^unused/ && $new_volids->{$value}) {
1651 delete $conf->{$key};
1652 }
1653 }
1654
1655 # gererate RAW data
1656 my $raw = '';
1657
1658 # add description as comment to top of file
1659 my $descr = $conf->{description} || '';
1660 foreach my $cl (split(/\n/, $descr)) {
1661 $raw .= '#' . PVE::Tools::encode_text($cl) . "\n";
1662 }
1663
1664 foreach my $key (sort keys %$conf) {
1665 next if $key eq 'digest' || $key eq 'description';
1666 $raw .= "$key: $conf->{$key}\n";
1667 }
1668
1669 return $raw;
1670 }
1671
1672 sub update_config_nolock {
1673 my ($vmid, $conf, $skiplock) = @_;
1674
1675 check_lock($conf) if !$skiplock;
1676
1677 my $cfspath = cfs_config_path($vmid);
1678
1679 PVE::Cluster::cfs_write_file($cfspath, $conf);
1680 }
1681
1682 sub update_config {
1683 my ($vmid, $conf, $skiplock) = @_;
1684
1685 lock_config($vmid, &update_config_nolock, $conf, $skiplock);
1686 }
1687
1688 sub load_defaults {
1689
1690 my $res = {};
1691
1692 # we use static defaults from our JSON schema configuration
1693 foreach my $key (keys %$confdesc) {
1694 if (defined(my $default = $confdesc->{$key}->{default})) {
1695 $res->{$key} = $default;
1696 }
1697 }
1698
1699 my $conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
1700 $res->{keyboard} = $conf->{keyboard} if $conf->{keyboard};
1701
1702 return $res;
1703 }
1704
1705 sub config_list {
1706 my $vmlist = PVE::Cluster::get_vmlist();
1707 my $res = {};
1708 return $res if !$vmlist || !$vmlist->{ids};
1709 my $ids = $vmlist->{ids};
1710
1711 foreach my $vmid (keys %$ids) {
1712 my $d = $ids->{$vmid};
1713 next if !$d->{node} || $d->{node} ne $nodename;
1714 next if !$d->{type} || $d->{type} ne 'qemu';
1715 $res->{$vmid}->{exists} = 1;
1716 }
1717 return $res;
1718 }
1719
1720 # test if VM uses local resources (to prevent migration)
1721 sub check_local_resources {
1722 my ($conf, $noerr) = @_;
1723
1724 my $loc_res = 0;
1725
1726 $loc_res = 1 if $conf->{hostusb}; # old syntax
1727 $loc_res = 1 if $conf->{hostpci}; # old syntax
1728
1729 foreach my $k (keys %$conf) {
1730 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
1731 }
1732
1733 die "VM uses local resources\n" if $loc_res && !$noerr;
1734
1735 return $loc_res;
1736 }
1737
1738 # check is used storages are available on all nodes (use by migrate)
1739 sub check_storage_availability {
1740 my ($storecfg, $conf, $node) = @_;
1741
1742 foreach_drive($conf, sub {
1743 my ($ds, $drive) = @_;
1744
1745 my $volid = $drive->{file};
1746 return if !$volid;
1747
1748 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
1749 return if !$sid;
1750
1751 # check if storage is available on both nodes
1752 my $scfg = PVE::Storage::storage_check_node($storecfg, $sid);
1753 PVE::Storage::storage_check_node($storecfg, $sid, $node);
1754 });
1755 }
1756
1757 sub check_lock {
1758 my ($conf) = @_;
1759
1760 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1761 }
1762
1763 sub check_cmdline {
1764 my ($pidfile, $pid) = @_;
1765
1766 my $fh = IO::File->new("/proc/$pid/cmdline", "r");
1767 if (defined($fh)) {
1768 my $line = <$fh>;
1769 $fh->close;
1770 return undef if !$line;
1771 my @param = split(/\0/, $line);
1772
1773 my $cmd = $param[0];
1774 return if !$cmd || ($cmd !~ m|kvm$|);
1775
1776 for (my $i = 0; $i < scalar (@param); $i++) {
1777 my $p = $param[$i];
1778 next if !$p;
1779 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1780 my $p = $param[$i+1];
1781 return 1 if $p && ($p eq $pidfile);
1782 return undef;
1783 }
1784 }
1785 }
1786 return undef;
1787 }
1788
1789 sub check_running {
1790 my ($vmid, $nocheck, $node) = @_;
1791
1792 my $filename = config_file($vmid, $node);
1793
1794 die "unable to find configuration file for VM $vmid - no such machine\n"
1795 if !$nocheck && ! -f $filename;
1796
1797 my $pidfile = pidfile_name($vmid);
1798
1799 if (my $fd = IO::File->new("<$pidfile")) {
1800 my $st = stat($fd);
1801 my $line = <$fd>;
1802 close($fd);
1803
1804 my $mtime = $st->mtime;
1805 if ($mtime > time()) {
1806 warn "file '$filename' modified in future\n";
1807 }
1808
1809 if ($line =~ m/^(\d+)$/) {
1810 my $pid = $1;
1811 if (check_cmdline($pidfile, $pid)) {
1812 if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
1813 return $pid;
1814 }
1815 }
1816 }
1817 }
1818
1819 return undef;
1820 }
1821
1822 sub vzlist {
1823
1824 my $vzlist = config_list();
1825
1826 my $fd = IO::Dir->new($var_run_tmpdir) || return $vzlist;
1827
1828 while (defined(my $de = $fd->read)) {
1829 next if $de !~ m/^(\d+)\.pid$/;
1830 my $vmid = $1;
1831 next if !defined($vzlist->{$vmid});
1832 if (my $pid = check_running($vmid)) {
1833 $vzlist->{$vmid}->{pid} = $pid;
1834 }
1835 }
1836
1837 return $vzlist;
1838 }
1839
1840 sub disksize {
1841 my ($storecfg, $conf) = @_;
1842
1843 my $bootdisk = $conf->{bootdisk};
1844 return undef if !$bootdisk;
1845 return undef if !valid_drivename($bootdisk);
1846
1847 return undef if !$conf->{$bootdisk};
1848
1849 my $drive = parse_drive($bootdisk, $conf->{$bootdisk});
1850 return undef if !defined($drive);
1851
1852 return undef if drive_is_cdrom($drive);
1853
1854 my $volid = $drive->{file};
1855 return undef if !$volid;
1856
1857 return $drive->{size};
1858 }
1859
1860 my $last_proc_pid_stat;
1861
1862 # get VM status information
1863 # This must be fast and should not block ($full == false)
1864 # We only query KVM using QMP if $full == true (this can be slow)
1865 sub vmstatus {
1866 my ($opt_vmid, $full) = @_;
1867
1868 my $res = {};
1869
1870 my $storecfg = PVE::Storage::config();
1871
1872 my $list = vzlist();
1873 my ($uptime) = PVE::ProcFSTools::read_proc_uptime(1);
1874
1875 my $cpucount = $cpuinfo->{cpus} || 1;
1876
1877 foreach my $vmid (keys %$list) {
1878 next if $opt_vmid && ($vmid ne $opt_vmid);
1879
1880 my $cfspath = cfs_config_path($vmid);
1881 my $conf = PVE::Cluster::cfs_read_file($cfspath) || {};
1882
1883 my $d = {};
1884 $d->{pid} = $list->{$vmid}->{pid};
1885
1886 # fixme: better status?
1887 $d->{status} = $list->{$vmid}->{pid} ? 'running' : 'stopped';
1888
1889 my $size = disksize($storecfg, $conf);
1890 if (defined($size)) {
1891 $d->{disk} = 0; # no info available
1892 $d->{maxdisk} = $size;
1893 } else {
1894 $d->{disk} = 0;
1895 $d->{maxdisk} = 0;
1896 }
1897
1898 $d->{cpus} = ($conf->{sockets} || 1) * ($conf->{cores} || 1);
1899 $d->{cpus} = $cpucount if $d->{cpus} > $cpucount;
1900
1901 $d->{name} = $conf->{name} || "VM $vmid";
1902 $d->{maxmem} = $conf->{memory} ? $conf->{memory}*(1024*1024) : 0;
1903
1904 $d->{uptime} = 0;
1905 $d->{cpu} = 0;
1906 $d->{mem} = 0;
1907
1908 $d->{netout} = 0;
1909 $d->{netin} = 0;
1910
1911 $d->{diskread} = 0;
1912 $d->{diskwrite} = 0;
1913
1914 $res->{$vmid} = $d;
1915 }
1916
1917 my $netdev = PVE::ProcFSTools::read_proc_net_dev();
1918 foreach my $dev (keys %$netdev) {
1919 next if $dev !~ m/^tap([1-9]\d*)i/;
1920 my $vmid = $1;
1921 my $d = $res->{$vmid};
1922 next if !$d;
1923
1924 $d->{netout} += $netdev->{$dev}->{receive};
1925 $d->{netin} += $netdev->{$dev}->{transmit};
1926 }
1927
1928 my $ctime = gettimeofday;
1929
1930 foreach my $vmid (keys %$list) {
1931
1932 my $d = $res->{$vmid};
1933 my $pid = $d->{pid};
1934 next if !$pid;
1935
1936 my $pstat = PVE::ProcFSTools::read_proc_pid_stat($pid);
1937 next if !$pstat; # not running
1938
1939 my $used = $pstat->{utime} + $pstat->{stime};
1940
1941 $d->{uptime} = int(($uptime - $pstat->{starttime})/$cpuinfo->{user_hz});
1942
1943 if ($pstat->{vsize}) {
1944 $d->{mem} = int(($pstat->{rss}/$pstat->{vsize})*$d->{maxmem});
1945 }
1946
1947 my $old = $last_proc_pid_stat->{$pid};
1948 if (!$old) {
1949 $last_proc_pid_stat->{$pid} = {
1950 time => $ctime,
1951 used => $used,
1952 cpu => 0,
1953 };
1954 next;
1955 }
1956
1957 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz};
1958
1959 if ($dtime > 1000) {
1960 my $dutime = $used - $old->{used};
1961
1962 $d->{cpu} = (($dutime/$dtime)* $cpucount) / $d->{cpus};
1963 $last_proc_pid_stat->{$pid} = {
1964 time => $ctime,
1965 used => $used,
1966 cpu => $d->{cpu},
1967 };
1968 } else {
1969 $d->{cpu} = $old->{cpu};
1970 }
1971 }
1972
1973 return $res if !$full;
1974
1975 my $qmpclient = PVE::QMPClient->new();
1976
1977 my $blockstatscb = sub {
1978 my ($vmid, $resp) = @_;
1979 my $data = $resp->{'return'} || [];
1980 my $totalrdbytes = 0;
1981 my $totalwrbytes = 0;
1982 for my $blockstat (@$data) {
1983 $totalrdbytes = $totalrdbytes + $blockstat->{stats}->{rd_bytes};
1984 $totalwrbytes = $totalwrbytes + $blockstat->{stats}->{wr_bytes};
1985 }
1986 $res->{$vmid}->{diskread} = $totalrdbytes;
1987 $res->{$vmid}->{diskwrite} = $totalwrbytes;
1988 };
1989
1990 my $statuscb = sub {
1991 my ($vmid, $resp) = @_;
1992 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
1993
1994 my $status = 'unknown';
1995 if (!defined($status = $resp->{'return'}->{status})) {
1996 warn "unable to get VM status\n";
1997 return;
1998 }
1999
2000 $res->{$vmid}->{qmpstatus} = $resp->{'return'}->{status};
2001 };
2002
2003 foreach my $vmid (keys %$list) {
2004 next if $opt_vmid && ($vmid ne $opt_vmid);
2005 next if !$res->{$vmid}->{pid}; # not running
2006 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2007 }
2008
2009 $qmpclient->queue_execute();
2010
2011 foreach my $vmid (keys %$list) {
2012 next if $opt_vmid && ($vmid ne $opt_vmid);
2013 $res->{$vmid}->{qmpstatus} = $res->{$vmid}->{status} if !$res->{$vmid}->{qmpstatus};
2014 }
2015
2016 return $res;
2017 }
2018
2019 sub foreach_drive {
2020 my ($conf, $func) = @_;
2021
2022 foreach my $ds (keys %$conf) {
2023 next if !valid_drivename($ds);
2024
2025 my $drive = parse_drive($ds, $conf->{$ds});
2026 next if !$drive;
2027
2028 &$func($ds, $drive);
2029 }
2030 }
2031
2032 sub config_to_command {
2033 my ($storecfg, $vmid, $conf, $defaults, $migrate_uri) = @_;
2034
2035 my $cmd = [];
2036 my $devices = [];
2037 my $pciaddr = '';
2038 my $bridges = {};
2039 my $kvmver = kvm_user_version();
2040 my $vernum = 0; # unknown
2041 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2042 $vernum = $1*1000000+$2*1000;
2043 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
2044 $vernum = $1*1000000+$2*1000+$3;
2045 }
2046
2047 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
2048
2049 my $have_ovz = -f '/proc/vz/vestat';
2050
2051 push @$cmd, '/usr/bin/kvm';
2052
2053 push @$cmd, '-id', $vmid;
2054
2055 my $use_virtio = 0;
2056
2057 my $qmpsocket = qmp_socket($vmid);
2058 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2059 push @$cmd, '-mon', "chardev=qmp,mode=control";
2060
2061 my $socket = vnc_socket($vmid);
2062 push @$cmd, '-vnc', "unix:$socket,x509,password";
2063
2064 push @$cmd, '-pidfile' , pidfile_name($vmid);
2065
2066 push @$cmd, '-daemonize';
2067
2068 push @$cmd, '-incoming', $migrate_uri if $migrate_uri;
2069
2070 push @$cmd, '-S' if $migrate_uri;
2071
2072 my $use_usb2 = 0;
2073 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2074 next if !$conf->{"usb$i"};
2075 $use_usb2 = 1;
2076 }
2077 # include usb device config
2078 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
2079
2080 # enable absolute mouse coordinates (needed by vnc)
2081 my $tablet = defined($conf->{tablet}) ? $conf->{tablet} : $defaults->{tablet};
2082 if ($tablet) {
2083 if ($use_usb2) {
2084 push @$devices, '-device', 'usb-tablet,bus=ehci.0,port=6';
2085 } else {
2086 push @$devices, '-usbdevice', 'tablet';
2087 }
2088 }
2089
2090 # host pci devices
2091 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2092 my $d = parse_hostpci($conf->{"hostpci$i"});
2093 next if !$d;
2094 $pciaddr = print_pci_addr("hostpci$i", $bridges);
2095 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
2096 }
2097
2098 # usb devices
2099 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2100 my $d = parse_usb_device($conf->{"usb$i"});
2101 next if !$d;
2102 if ($d->{vendorid} && $d->{productid}) {
2103 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
2104 } elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
2105 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2106 }
2107 }
2108
2109 # serial devices
2110 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
2111 if (my $path = $conf->{"serial$i"}) {
2112 die "no such serial device\n" if ! -c $path;
2113 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2114 push @$devices, '-device', "isa-serial,chardev=serial$i";
2115 }
2116 }
2117
2118 # parallel devices
2119 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
2120 if (my $path = $conf->{"parallel$i"}) {
2121 die "no such parallel device\n" if ! -c $path;
2122 push @$devices, '-chardev', "parport,id=parallel$i,path=$path";
2123 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
2124 }
2125 }
2126
2127 my $vmname = $conf->{name} || "vm$vmid";
2128
2129 push @$cmd, '-name', $vmname;
2130
2131 my $sockets = 1;
2132 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
2133 $sockets = $conf->{sockets} if $conf->{sockets};
2134
2135 my $cores = $conf->{cores} || 1;
2136
2137 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2138
2139 push @$cmd, '-cpu', $conf->{cpu} if $conf->{cpu};
2140
2141 push @$cmd, '-nodefaults';
2142
2143 my $bootorder = $conf->{boot} || $confdesc->{boot}->{default};
2144
2145 my $bootindex_hash = {};
2146 my $i = 1;
2147 foreach my $o (split(//, $bootorder)) {
2148 $bootindex_hash->{$o} = $i*100;
2149 $i++;
2150 }
2151
2152 push @$cmd, '-boot', "menu=on";
2153
2154 push @$cmd, '-no-acpi' if defined($conf->{acpi}) && $conf->{acpi} == 0;
2155
2156 push @$cmd, '-no-reboot' if defined($conf->{reboot}) && $conf->{reboot} == 0;
2157
2158 my $vga = $conf->{vga};
2159 if (!$vga) {
2160 if ($conf->{ostype} && ($conf->{ostype} eq 'win7' || $conf->{ostype} eq 'w2k8')) {
2161 $vga = 'std';
2162 } else {
2163 $vga = 'cirrus';
2164 }
2165 }
2166
2167 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2168
2169 # time drift fix
2170 my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf};
2171 # ignore - no longer supported by newer kvm
2172 # push @$cmd, '-tdf' if $tdf;
2173
2174 my $nokvm = defined($conf->{kvm}) && $conf->{kvm} == 0 ? 1 : 0;
2175
2176 if (my $ost = $conf->{ostype}) {
2177 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2178
2179 if ($ost =~ m/^w/) { # windows
2180 push @$cmd, '-localtime' if !defined($conf->{localtime});
2181
2182 # use rtc-td-hack when acpi is enabled
2183 if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) {
2184 push @$cmd, '-rtc-td-hack';
2185 }
2186 }
2187
2188 if ($ost eq 'win7' || $ost eq 'w2k8' || $ost eq 'wvista') {
2189 push @$cmd, '-no-kvm-pit-reinjection';
2190 push @$cmd, '-no-hpet';
2191 }
2192
2193 # -tdf ?
2194 # -no-acpi
2195 # -no-kvm
2196 # -win2k-hack ?
2197 }
2198
2199 if ($nokvm) {
2200 push @$cmd, '-no-kvm';
2201 } else {
2202 die "No accelerator found!\n" if !$cpuinfo->{hvm};
2203 }
2204
2205 push @$cmd, '-localtime' if $conf->{localtime};
2206
2207 push @$cmd, '-startdate', $conf->{startdate} if $conf->{startdate};
2208
2209 push @$cmd, '-S' if $conf->{freeze};
2210
2211 # set keyboard layout
2212 my $kb = $conf->{keyboard} || $defaults->{keyboard};
2213 push @$cmd, '-k', $kb if $kb;
2214
2215 # enable sound
2216 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2217 #push @$cmd, '-soundhw', 'es1370';
2218 #push @$cmd, '-soundhw', $soundhw if $soundhw;
2219
2220 if($conf->{agent}) {
2221 my $qgasocket = qga_socket($vmid);
2222 my $pciaddr = print_pci_addr("qga0", $bridges);
2223 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2224 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2225 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2226 }
2227
2228 $pciaddr = print_pci_addr("balloon0", $bridges);
2229 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon};
2230
2231 if ($conf->{watchdog}) {
2232 my $wdopts = parse_watchdog($conf->{watchdog});
2233 $pciaddr = print_pci_addr("watchdog", $bridges);
2234 my $watchdog = $wdopts->{model} || 'i6300esb';
2235 push @$devices, '-device', "$watchdog$pciaddr";
2236 push @$devices, '-watchdog-action', $wdopts->{action} if $wdopts->{action};
2237 }
2238
2239 my $vollist = [];
2240 my $scsicontroller = {};
2241 my $ahcicontroller = {};
2242 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : $defaults->{scsihw};
2243
2244 foreach_drive($conf, sub {
2245 my ($ds, $drive) = @_;
2246
2247 if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
2248 push @$vollist, $drive->{file};
2249 }
2250
2251 $use_virtio = 1 if $ds =~ m/^virtio/;
2252
2253 if (drive_is_cdrom ($drive)) {
2254 if ($bootindex_hash->{d}) {
2255 $drive->{bootindex} = $bootindex_hash->{d};
2256 $bootindex_hash->{d} += 1;
2257 }
2258 } else {
2259 if ($bootindex_hash->{c}) {
2260 $drive->{bootindex} = $bootindex_hash->{c} if $conf->{bootdisk} && ($conf->{bootdisk} eq $ds);
2261 $bootindex_hash->{c} += 1;
2262 }
2263 }
2264
2265 if ($drive->{interface} eq 'scsi') {
2266
2267 my $maxdev = ($scsihw ne 'lsi') ? 256 : 7;
2268 my $controller = int($drive->{index} / $maxdev);
2269 $pciaddr = print_pci_addr("scsihw$controller", $bridges);
2270 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
2271 $scsicontroller->{$controller}=1;
2272 }
2273
2274 if ($drive->{interface} eq 'sata') {
2275 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
2276 $pciaddr = print_pci_addr("ahci$controller", $bridges);
2277 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
2278 $ahcicontroller->{$controller}=1;
2279 }
2280
2281 push @$devices, '-drive',print_drive_full($storecfg, $vmid, $drive);
2282 push @$devices, '-device',print_drivedevice_full($storecfg, $conf, $vmid, $drive, $bridges);
2283 });
2284
2285 push @$cmd, '-m', $conf->{memory} || $defaults->{memory};
2286
2287 for (my $i = 0; $i < $MAX_NETS; $i++) {
2288 next if !$conf->{"net$i"};
2289 my $d = parse_net($conf->{"net$i"});
2290 next if !$d;
2291
2292 $use_virtio = 1 if $d->{model} eq 'virtio';
2293
2294 if ($bootindex_hash->{n}) {
2295 $d->{bootindex} = $bootindex_hash->{n};
2296 $bootindex_hash->{n} += 1;
2297 }
2298
2299 my $netdevfull = print_netdev_full($vmid,$conf,$d,"net$i");
2300 push @$devices, '-netdev', $netdevfull;
2301
2302 my $netdevicefull = print_netdevice_full($vmid,$conf,$d,"net$i",$bridges);
2303 push @$devices, '-device', $netdevicefull;
2304 }
2305
2306 #bridges
2307 while (my ($k, $v) = each %$bridges) {
2308 $pciaddr = print_pci_addr("pci.$k");
2309 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
2310 }
2311
2312
2313 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2314 # when the VM uses virtio devices.
2315 if (!$use_virtio && $have_ovz) {
2316
2317 my $cpuunits = defined($conf->{cpuunits}) ?
2318 $conf->{cpuunits} : $defaults->{cpuunits};
2319
2320 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2321
2322 # fixme: cpulimit is currently ignored
2323 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2324 }
2325
2326 # add custom args
2327 if ($conf->{args}) {
2328 my $aa = PVE::Tools::split_args($conf->{args});
2329 push @$cmd, @$aa;
2330 }
2331
2332 push @$cmd, @$devices;
2333 return wantarray ? ($cmd, $vollist) : $cmd;
2334 }
2335
2336 sub vnc_socket {
2337 my ($vmid) = @_;
2338 return "${var_run_tmpdir}/$vmid.vnc";
2339 }
2340
2341 sub qmp_socket {
2342 my ($vmid) = @_;
2343 return "${var_run_tmpdir}/$vmid.qmp";
2344 }
2345
2346 sub qga_socket {
2347 my ($vmid) = @_;
2348 return "${var_run_tmpdir}/$vmid.qga";
2349 }
2350
2351 sub pidfile_name {
2352 my ($vmid) = @_;
2353 return "${var_run_tmpdir}/$vmid.pid";
2354 }
2355
2356 sub next_migrate_port {
2357
2358 for (my $p = 60000; $p < 60010; $p++) {
2359
2360 my $sock = IO::Socket::INET->new(Listen => 5,
2361 LocalAddr => 'localhost',
2362 LocalPort => $p,
2363 ReuseAddr => 1,
2364 Proto => 0);
2365
2366 if ($sock) {
2367 close($sock);
2368 return $p;
2369 }
2370 }
2371
2372 die "unable to find free migration port";
2373 }
2374
2375 sub vm_devices_list {
2376 my ($vmid) = @_;
2377
2378 my $res = vm_mon_cmd($vmid, 'query-pci');
2379
2380 my $devices = {};
2381 foreach my $pcibus (@$res) {
2382 foreach my $device (@{$pcibus->{devices}}) {
2383 next if !$device->{'qdev_id'};
2384 $devices->{$device->{'qdev_id'}} = $device;
2385 }
2386 }
2387
2388 return $devices;
2389 }
2390
2391 sub vm_deviceplug {
2392 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
2393
2394 return 1 if !check_running($vmid) || !$conf->{hotplug};
2395
2396 my $devices_list = vm_devices_list($vmid);
2397 return 1 if defined($devices_list->{$deviceid});
2398
2399 qemu_bridgeadd($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2400
2401 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2402 return undef if !qemu_driveadd($storecfg, $vmid, $device);
2403 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
2404 qemu_deviceadd($vmid, $devicefull);
2405 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2406 qemu_drivedel($vmid, $deviceid);
2407 return undef;
2408 }
2409 }
2410
2411 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2412 my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
2413 my $pciaddr = print_pci_addr($deviceid);
2414 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
2415 qemu_deviceadd($vmid, $devicefull);
2416 return undef if(!qemu_deviceaddverify($vmid, $deviceid));
2417 }
2418
2419 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2420 return 1 if ($conf->{scsihw} && $conf->{scsihw} ne 'lsi'); #virtio-scsi not yet support hotplug
2421 return undef if !qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
2422 return undef if !qemu_driveadd($storecfg, $vmid, $device);
2423 my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
2424 if(!qemu_deviceadd($vmid, $devicefull)) {
2425 qemu_drivedel($vmid, $deviceid);
2426 return undef;
2427 }
2428 }
2429
2430 if ($deviceid =~ m/^(net)(\d+)$/) {
2431 return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
2432 my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
2433 qemu_deviceadd($vmid, $netdevicefull);
2434 if(!qemu_deviceaddverify($vmid, $deviceid)) {
2435 qemu_netdevdel($vmid, $deviceid);
2436 return undef;
2437 }
2438 }
2439
2440 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2441 my $bridgeid = $2;
2442 my $pciaddr = print_pci_addr($deviceid);
2443 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2444 qemu_deviceadd($vmid, $devicefull);
2445 return undef if !qemu_deviceaddverify($vmid, $deviceid);
2446 }
2447
2448 return 1;
2449 }
2450
2451 sub vm_deviceunplug {
2452 my ($vmid, $conf, $deviceid) = @_;
2453
2454 return 1 if !check_running ($vmid) || !$conf->{hotplug};
2455
2456 my $devices_list = vm_devices_list($vmid);
2457 return 1 if !defined($devices_list->{$deviceid});
2458
2459 die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
2460
2461 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2462 return undef if !qemu_drivedel($vmid, $deviceid);
2463 qemu_devicedel($vmid, $deviceid);
2464 return undef if !qemu_devicedelverify($vmid, $deviceid);
2465 }
2466
2467 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2468 return undef if !qemu_devicedel($vmid, $deviceid);
2469 }
2470
2471 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2472 return undef if !qemu_devicedel($vmid, $deviceid);
2473 return undef if !qemu_drivedel($vmid, $deviceid);
2474 }
2475
2476 if ($deviceid =~ m/^(net)(\d+)$/) {
2477 return undef if !qemu_netdevdel($vmid, $deviceid);
2478 qemu_devicedel($vmid, $deviceid);
2479 return undef if !qemu_devicedelverify($vmid, $deviceid);
2480 }
2481
2482 return 1;
2483 }
2484
2485 sub qemu_deviceadd {
2486 my ($vmid, $devicefull) = @_;
2487
2488 my $ret = vm_human_monitor_command($vmid, "device_add $devicefull");
2489 $ret =~ s/^\s+//;
2490 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
2491 return 1 if $ret eq "";
2492 syslog("err", "error on hotplug device : $ret");
2493 return undef;
2494
2495 }
2496
2497 sub qemu_devicedel {
2498 my($vmid, $deviceid) = @_;
2499
2500 my $ret = vm_human_monitor_command($vmid, "device_del $deviceid");
2501 $ret =~ s/^\s+//;
2502 return 1 if $ret eq "";
2503 syslog("err", "detaching device $deviceid failed : $ret");
2504 return undef;
2505 }
2506
2507 sub qemu_driveadd {
2508 my($storecfg, $vmid, $device) = @_;
2509
2510 my $drive = print_drive_full($storecfg, $vmid, $device);
2511 my $ret = vm_human_monitor_command($vmid, "drive_add auto $drive");
2512 # If the command succeeds qemu prints: "OK"
2513 if ($ret !~ m/OK/s) {
2514 syslog("err", "adding drive failed: $ret");
2515 return undef;
2516 }
2517 return 1;
2518 }
2519
2520 sub qemu_drivedel {
2521 my($vmid, $deviceid) = @_;
2522
2523 my $ret = vm_human_monitor_command($vmid, "drive_del drive-$deviceid");
2524 $ret =~ s/^\s+//;
2525 if ($ret =~ m/Device \'.*?\' not found/s) {
2526 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
2527 }
2528 elsif ($ret ne "") {
2529 syslog("err", "deleting drive $deviceid failed : $ret");
2530 return undef;
2531 }
2532 return 1;
2533 }
2534
2535 sub qemu_deviceaddverify {
2536 my ($vmid,$deviceid) = @_;
2537
2538 for (my $i = 0; $i <= 5; $i++) {
2539 my $devices_list = vm_devices_list($vmid);
2540 return 1 if defined($devices_list->{$deviceid});
2541 sleep 1;
2542 }
2543 syslog("err", "error on hotplug device $deviceid");
2544 return undef;
2545 }
2546
2547
2548 sub qemu_devicedelverify {
2549 my ($vmid,$deviceid) = @_;
2550
2551 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2552 for (my $i = 0; $i <= 5; $i++) {
2553 my $devices_list = vm_devices_list($vmid);
2554 return 1 if !defined($devices_list->{$deviceid});
2555 sleep 1;
2556 }
2557 syslog("err", "error on hot-unplugging device $deviceid");
2558 return undef;
2559 }
2560
2561 sub qemu_findorcreatescsihw {
2562 my ($storecfg, $conf, $vmid, $device) = @_;
2563
2564 my $maxdev = ($conf->{scsihw} && $conf->{scsihw} ne 'lsi') ? 256 : 7;
2565 my $controller = int($device->{index} / $maxdev);
2566 my $scsihwid="scsihw$controller";
2567 my $devices_list = vm_devices_list($vmid);
2568
2569 if(!defined($devices_list->{$scsihwid})) {
2570 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $scsihwid);
2571 }
2572 return 1;
2573 }
2574
2575 sub qemu_bridgeadd {
2576 my ($storecfg, $conf, $vmid, $device) = @_;
2577
2578 my $bridges = {};
2579 my $bridgeid = undef;
2580 print_pci_addr($device, $bridges);
2581
2582 while (my ($k, $v) = each %$bridges) {
2583 $bridgeid = $k;
2584 }
2585 return if $bridgeid < 1;
2586 my $bridge = "pci.$bridgeid";
2587 my $devices_list = vm_devices_list($vmid);
2588
2589 if(!defined($devices_list->{$bridge})) {
2590 return undef if !vm_deviceplug($storecfg, $conf, $vmid, $bridge);
2591 }
2592 return 1;
2593 }
2594
2595 sub qemu_netdevadd {
2596 my ($vmid, $conf, $device, $deviceid) = @_;
2597
2598 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
2599 my $ret = vm_human_monitor_command($vmid, "netdev_add $netdev");
2600 $ret =~ s/^\s+//;
2601
2602 #if the command succeeds, no output is sent. So any non-empty string shows an error
2603 return 1 if $ret eq "";
2604 syslog("err", "adding netdev failed: $ret");
2605 return undef;
2606 }
2607
2608 sub qemu_netdevdel {
2609 my ($vmid, $deviceid) = @_;
2610
2611 my $ret = vm_human_monitor_command($vmid, "netdev_del $deviceid");
2612 $ret =~ s/^\s+//;
2613 #if the command succeeds, no output is sent. So any non-empty string shows an error
2614 return 1 if $ret eq "";
2615 syslog("err", "deleting netdev failed: $ret");
2616 return undef;
2617 }
2618
2619 sub qemu_block_set_io_throttle {
2620 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2621
2622 return if !check_running($vmid) ;
2623
2624 $bps = 0 if !$bps;
2625 $bps_rd = 0 if !$bps_rd;
2626 $bps_wr = 0 if !$bps_wr;
2627 $iops = 0 if !$iops;
2628 $iops_rd = 0 if !$iops_rd;
2629 $iops_wr = 0 if !$iops_wr;
2630
2631 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));
2632
2633 }
2634
2635 # old code, only used to shutdown old VM after update
2636 sub __read_avail {
2637 my ($fh, $timeout) = @_;
2638
2639 my $sel = new IO::Select;
2640 $sel->add($fh);
2641
2642 my $res = '';
2643 my $buf;
2644
2645 my @ready;
2646 while (scalar (@ready = $sel->can_read($timeout))) {
2647 my $count;
2648 if ($count = $fh->sysread($buf, 8192)) {
2649 if ($buf =~ /^(.*)\(qemu\) $/s) {
2650 $res .= $1;
2651 last;
2652 } else {
2653 $res .= $buf;
2654 }
2655 } else {
2656 if (!defined($count)) {
2657 die "$!\n";
2658 }
2659 last;
2660 }
2661 }
2662
2663 die "monitor read timeout\n" if !scalar(@ready);
2664
2665 return $res;
2666 }
2667
2668 # old code, only used to shutdown old VM after update
2669 sub vm_monitor_command {
2670 my ($vmid, $cmdstr, $nocheck) = @_;
2671
2672 my $res;
2673
2674 eval {
2675 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
2676
2677 my $sname = "${var_run_tmpdir}/$vmid.mon";
2678
2679 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
2680 die "unable to connect to VM $vmid socket - $!\n";
2681
2682 my $timeout = 3;
2683
2684 # hack: migrate sometime blocks the monitor (when migrate_downtime
2685 # is set)
2686 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2687 $timeout = 60*60; # 1 hour
2688 }
2689
2690 # read banner;
2691 my $data = __read_avail($sock, $timeout);
2692
2693 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2694 die "got unexpected qemu monitor banner\n";
2695 }
2696
2697 my $sel = new IO::Select;
2698 $sel->add($sock);
2699
2700 if (!scalar(my @ready = $sel->can_write($timeout))) {
2701 die "monitor write error - timeout";
2702 }
2703
2704 my $fullcmd = "$cmdstr\r";
2705
2706 # syslog('info', "VM $vmid monitor command: $cmdstr");
2707
2708 my $b;
2709 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2710 die "monitor write error - $!";
2711 }
2712
2713 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2714
2715 $timeout = 20;
2716
2717 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2718 $timeout = 60*60; # 1 hour
2719 } elsif ($cmdstr =~ m/^(eject|change)/) {
2720 $timeout = 60; # note: cdrom mount command is slow
2721 }
2722 if ($res = __read_avail($sock, $timeout)) {
2723
2724 my @lines = split("\r?\n", $res);
2725
2726 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
2727
2728 $res = join("\n", @lines);
2729 $res .= "\n";
2730 }
2731 };
2732
2733 my $err = $@;
2734
2735 if ($err) {
2736 syslog("err", "VM $vmid monitor command failed - $err");
2737 die $err;
2738 }
2739
2740 return $res;
2741 }
2742
2743 sub qemu_block_resize {
2744 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2745
2746 my $running = PVE::QemuServer::check_running($vmid);
2747
2748 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
2749
2750 return if !$running;
2751
2752 vm_mon_cmd($vmid, "block_resize", device => $deviceid, size => int($size));
2753
2754 }
2755
2756 sub vm_start {
2757 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom) = @_;
2758
2759 lock_config($vmid, sub {
2760 my $conf = load_config($vmid, $migratedfrom);
2761
2762 check_lock($conf) if !$skiplock;
2763
2764 die "VM $vmid already running\n" if check_running($vmid, undef, $migratedfrom);
2765
2766 my $migrate_uri;
2767 my $migrate_port = 0;
2768
2769 if ($statefile) {
2770 if ($statefile eq 'tcp') {
2771 $migrate_port = next_migrate_port();
2772 $migrate_uri = "tcp:localhost:${migrate_port}";
2773 } else {
2774 if (-f $statefile) {
2775 $migrate_uri = "exec:cat $statefile";
2776 } else {
2777 warn "state file '$statefile' does not exist - doing normal startup\n";
2778 }
2779 }
2780 }
2781
2782 my $defaults = load_defaults();
2783
2784 # set environment variable useful inside network script
2785 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
2786
2787 my ($cmd, $vollist) = config_to_command($storecfg, $vmid, $conf, $defaults, $migrate_uri);
2788 # host pci devices
2789 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2790 my $d = parse_hostpci($conf->{"hostpci$i"});
2791 next if !$d;
2792 my $info = pci_device_info("0000:$d->{pciid}");
2793 die "IOMMU not present\n" if !check_iommu_support();
2794 die "no pci device info for device '$d->{pciid}'\n" if !$info;
2795 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub($info);
2796 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset($info);
2797 }
2798
2799 PVE::Storage::activate_volumes($storecfg, $vollist);
2800
2801 eval { run_command($cmd, timeout => $migrate_uri ? undef : 30); };
2802 my $err = $@;
2803 die "start failed: $err" if $err;
2804
2805 if ($statefile) {
2806
2807 if ($statefile eq 'tcp') {
2808 print "migration listens on port $migrate_port\n";
2809 } else {
2810 unlink $statefile;
2811 # fixme: send resume - is that necessary ?
2812 eval { vm_mon_cmd($vmid, "cont"); };
2813 }
2814 }
2815
2816 # always set migrate speed (overwrite kvm default of 32m)
2817 # we set a very hight default of 8192m which is basically unlimited
2818 my $migrate_speed = $defaults->{migrate_speed} || 8192;
2819 $migrate_speed = $conf->{migrate_speed} || $migrate_speed;
2820 $migrate_speed = $migrate_speed * 1048576;
2821 eval {
2822 vm_mon_cmd($vmid, "migrate_set_speed", value => $migrate_speed);
2823 };
2824
2825 my $migrate_downtime = $defaults->{migrate_downtime};
2826 $migrate_downtime = $conf->{migrate_downtime} if defined($conf->{migrate_downtime});
2827 if (defined($migrate_downtime)) {
2828 eval { vm_mon_cmd($vmid, "migrate_set_downtime", value => $migrate_downtime); };
2829 }
2830
2831 if($migratedfrom) {
2832 my $capabilities = {};
2833 $capabilities->{capability} = "xbzrle";
2834 $capabilities->{state} = JSON::true;
2835 eval { PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => [$capabilities]); };
2836 }
2837
2838 vm_balloonset($vmid, $conf->{balloon}) if $conf->{balloon};
2839
2840 });
2841 }
2842
2843 sub vm_mon_cmd {
2844 my ($vmid, $execute, %params) = @_;
2845
2846 my $cmd = { execute => $execute, arguments => \%params };
2847 vm_qmp_command($vmid, $cmd);
2848 }
2849
2850 sub vm_mon_cmd_nocheck {
2851 my ($vmid, $execute, %params) = @_;
2852
2853 my $cmd = { execute => $execute, arguments => \%params };
2854 vm_qmp_command($vmid, $cmd, 1);
2855 }
2856
2857 sub vm_qmp_command {
2858 my ($vmid, $cmd, $nocheck) = @_;
2859
2860 my $res;
2861
2862 my $timeout;
2863 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
2864 $timeout = $cmd->{arguments}->{timeout};
2865 delete $cmd->{arguments}->{timeout};
2866 }
2867
2868 eval {
2869 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
2870 my $sname = PVE::QemuServer::qmp_socket($vmid);
2871 if (-e $sname) {
2872 my $qmpclient = PVE::QMPClient->new();
2873
2874 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
2875 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
2876 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
2877 if scalar(%{$cmd->{arguments}});
2878 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
2879 } else {
2880 die "unable to open monitor socket\n";
2881 }
2882 };
2883 if (my $err = $@) {
2884 syslog("err", "VM $vmid qmp command failed - $err");
2885 die $err;
2886 }
2887
2888 return $res;
2889 }
2890
2891 sub vm_human_monitor_command {
2892 my ($vmid, $cmdline) = @_;
2893
2894 my $res;
2895
2896 my $cmd = {
2897 execute => 'human-monitor-command',
2898 arguments => { 'command-line' => $cmdline},
2899 };
2900
2901 return vm_qmp_command($vmid, $cmd);
2902 }
2903
2904 sub vm_commandline {
2905 my ($storecfg, $vmid) = @_;
2906
2907 my $conf = load_config($vmid);
2908
2909 my $defaults = load_defaults();
2910
2911 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
2912
2913 return join(' ', @$cmd);
2914 }
2915
2916 sub vm_reset {
2917 my ($vmid, $skiplock) = @_;
2918
2919 lock_config($vmid, sub {
2920
2921 my $conf = load_config($vmid);
2922
2923 check_lock($conf) if !$skiplock;
2924
2925 vm_mon_cmd($vmid, "system_reset");
2926 });
2927 }
2928
2929 sub get_vm_volumes {
2930 my ($conf) = @_;
2931
2932 my $vollist = [];
2933 foreach_drive($conf, sub {
2934 my ($ds, $drive) = @_;
2935
2936 my ($sid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
2937 return if !$sid;
2938
2939 my $volid = $drive->{file};
2940 return if !$volid || $volid =~ m|^/|;
2941
2942 push @$vollist, $volid;
2943 });
2944
2945 return $vollist;
2946 }
2947
2948 sub vm_stop_cleanup {
2949 my ($storecfg, $vmid, $conf, $keepActive) = @_;
2950
2951 eval {
2952 fairsched_rmnod($vmid); # try to destroy group
2953
2954 if (!$keepActive) {
2955 my $vollist = get_vm_volumes($conf);
2956 PVE::Storage::deactivate_volumes($storecfg, $vollist);
2957 }
2958
2959 foreach my $ext (qw(mon qmp pid vnc qga)) {
2960 unlink "/var/run/qemu-server/${vmid}.$ext";
2961 }
2962 };
2963 warn $@ if $@; # avoid errors - just warn
2964 }
2965
2966 # Note: use $nockeck to skip tests if VM configuration file exists.
2967 # We need that when migration VMs to other nodes (files already moved)
2968 # Note: we set $keepActive in vzdump stop mode - volumes need to stay active
2969 sub vm_stop {
2970 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
2971
2972 $force = 1 if !defined($force) && !$shutdown;
2973
2974 if ($migratedfrom){
2975 my $pid = check_running($vmid, $nocheck, $migratedfrom);
2976 kill 15, $pid if $pid;
2977 my $conf = load_config($vmid, $migratedfrom);
2978 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive);
2979 return;
2980 }
2981
2982 lock_config($vmid, sub {
2983
2984 my $pid = check_running($vmid, $nocheck);
2985 return if !$pid;
2986
2987 my $conf;
2988 if (!$nocheck) {
2989 $conf = load_config($vmid);
2990 check_lock($conf) if !$skiplock;
2991 if (!defined($timeout) && $shutdown && $conf->{startup}) {
2992 my $opts = parse_startup($conf->{startup});
2993 $timeout = $opts->{down} if $opts->{down};
2994 }
2995 }
2996
2997 $timeout = 60 if !defined($timeout);
2998
2999 eval {
3000 if ($shutdown) {
3001 $nocheck ? vm_mon_cmd_nocheck($vmid, "system_powerdown") : vm_mon_cmd($vmid, "system_powerdown");
3002
3003 } else {
3004 $nocheck ? vm_mon_cmd_nocheck($vmid, "quit") : vm_mon_cmd($vmid, "quit");
3005 }
3006 };
3007 my $err = $@;
3008
3009 if (!$err) {
3010 my $count = 0;
3011 while (($count < $timeout) && check_running($vmid, $nocheck)) {
3012 $count++;
3013 sleep 1;
3014 }
3015
3016 if ($count >= $timeout) {
3017 if ($force) {
3018 warn "VM still running - terminating now with SIGTERM\n";
3019 kill 15, $pid;
3020 } else {
3021 die "VM quit/powerdown failed - got timeout\n";
3022 }
3023 } else {
3024 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
3025 return;
3026 }
3027 } else {
3028 if ($force) {
3029 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3030 kill 15, $pid;
3031 } else {
3032 die "VM quit/powerdown failed\n";
3033 }
3034 }
3035
3036 # wait again
3037 $timeout = 10;
3038
3039 my $count = 0;
3040 while (($count < $timeout) && check_running($vmid, $nocheck)) {
3041 $count++;
3042 sleep 1;
3043 }
3044
3045 if ($count >= $timeout) {
3046 warn "VM still running - terminating now with SIGKILL\n";
3047 kill 9, $pid;
3048 sleep 1;
3049 }
3050
3051 vm_stop_cleanup($storecfg, $vmid, $conf, $keepActive) if $conf;
3052 });
3053 }
3054
3055 sub vm_suspend {
3056 my ($vmid, $skiplock) = @_;
3057
3058 lock_config($vmid, sub {
3059
3060 my $conf = load_config($vmid);
3061
3062 check_lock($conf) if !$skiplock;
3063
3064 vm_mon_cmd($vmid, "stop");
3065 });
3066 }
3067
3068 sub vm_resume {
3069 my ($vmid, $skiplock) = @_;
3070
3071 lock_config($vmid, sub {
3072
3073 my $conf = load_config($vmid);
3074
3075 check_lock($conf) if !$skiplock;
3076
3077 vm_mon_cmd($vmid, "cont");
3078 });
3079 }
3080
3081 sub vm_sendkey {
3082 my ($vmid, $skiplock, $key) = @_;
3083
3084 lock_config($vmid, sub {
3085
3086 my $conf = load_config($vmid);
3087
3088 # there is no qmp command, so we use the human monitor command
3089 vm_human_monitor_command($vmid, "sendkey $key");
3090 });
3091 }
3092
3093 sub vm_destroy {
3094 my ($storecfg, $vmid, $skiplock) = @_;
3095
3096 lock_config($vmid, sub {
3097
3098 my $conf = load_config($vmid);
3099
3100 check_lock($conf) if !$skiplock;
3101
3102 if (!check_running($vmid)) {
3103 fairsched_rmnod($vmid); # try to destroy group
3104 destroy_vm($storecfg, $vmid);
3105 } else {
3106 die "VM $vmid is running - destroy failed\n";
3107 }
3108 });
3109 }
3110
3111 # pci helpers
3112
3113 sub file_write {
3114 my ($filename, $buf) = @_;
3115
3116 my $fh = IO::File->new($filename, "w");
3117 return undef if !$fh;
3118
3119 my $res = print $fh $buf;
3120
3121 $fh->close();
3122
3123 return $res;
3124 }
3125
3126 sub pci_device_info {
3127 my ($name) = @_;
3128
3129 my $res;
3130
3131 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3132 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3133
3134 my $irq = file_read_firstline("$pcisysfs/devices/$name/irq");
3135 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3136
3137 my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor");
3138 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3139
3140 my $product = file_read_firstline("$pcisysfs/devices/$name/device");
3141 return undef if !defined($product) || $product !~ s/^0x//;
3142
3143 $res = {
3144 name => $name,
3145 vendor => $vendor,
3146 product => $product,
3147 domain => $domain,
3148 bus => $bus,
3149 slot => $slot,
3150 func => $func,
3151 irq => $irq,
3152 has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0,
3153 };
3154
3155 return $res;
3156 }
3157
3158 sub pci_dev_reset {
3159 my ($dev) = @_;
3160
3161 my $name = $dev->{name};
3162
3163 my $fn = "$pcisysfs/devices/$name/reset";
3164
3165 return file_write($fn, "1");
3166 }
3167
3168 sub pci_dev_bind_to_stub {
3169 my ($dev) = @_;
3170
3171 my $name = $dev->{name};
3172
3173 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3174 return 1 if -d $testdir;
3175
3176 my $data = "$dev->{vendor} $dev->{product}";
3177 return undef if !file_write("$pcisysfs/drivers/pci-stub/new_id", $data);
3178
3179 my $fn = "$pcisysfs/devices/$name/driver/unbind";
3180 if (!file_write($fn, $name)) {
3181 return undef if -f $fn;
3182 }
3183
3184 $fn = "$pcisysfs/drivers/pci-stub/bind";
3185 if (! -d $testdir) {
3186 return undef if !file_write($fn, $name);
3187 }
3188
3189 return -d $testdir;
3190 }
3191
3192 sub print_pci_addr {
3193 my ($id, $bridges) = @_;
3194
3195 my $res = '';
3196 my $devices = {
3197 #addr1 : ide,parallel,serial (motherboard)
3198 #addr2 : first videocard
3199 balloon0 => { bus => 0, addr => 3 },
3200 watchdog => { bus => 0, addr => 4 },
3201 scsihw0 => { bus => 0, addr => 5 },
3202 scsihw1 => { bus => 0, addr => 6 },
3203 ahci0 => { bus => 0, addr => 7 },
3204 qga0 => { bus => 0, addr => 8 },
3205 virtio0 => { bus => 0, addr => 10 },
3206 virtio1 => { bus => 0, addr => 11 },
3207 virtio2 => { bus => 0, addr => 12 },
3208 virtio3 => { bus => 0, addr => 13 },
3209 virtio4 => { bus => 0, addr => 14 },
3210 virtio5 => { bus => 0, addr => 15 },
3211 hostpci0 => { bus => 0, addr => 16 },
3212 hostpci1 => { bus => 0, addr => 17 },
3213 net0 => { bus => 0, addr => 18 },
3214 net1 => { bus => 0, addr => 19 },
3215 net2 => { bus => 0, addr => 20 },
3216 net3 => { bus => 0, addr => 21 },
3217 net4 => { bus => 0, addr => 22 },
3218 net5 => { bus => 0, addr => 23 },
3219 #addr29 : usb-host (pve-usb.cfg)
3220 'pci.1' => { bus => 0, addr => 30 },
3221 'pci.2' => { bus => 0, addr => 31 },
3222 'net6' => { bus => 1, addr => 1 },
3223 'net7' => { bus => 1, addr => 2 },
3224 'net8' => { bus => 1, addr => 3 },
3225 'net9' => { bus => 1, addr => 4 },
3226 'net10' => { bus => 1, addr => 5 },
3227 'net11' => { bus => 1, addr => 6 },
3228 'net12' => { bus => 1, addr => 7 },
3229 'net13' => { bus => 1, addr => 8 },
3230 'net14' => { bus => 1, addr => 9 },
3231 'net15' => { bus => 1, addr => 10 },
3232 'net16' => { bus => 1, addr => 11 },
3233 'net17' => { bus => 1, addr => 12 },
3234 'net18' => { bus => 1, addr => 13 },
3235 'net19' => { bus => 1, addr => 14 },
3236 'net20' => { bus => 1, addr => 15 },
3237 'net21' => { bus => 1, addr => 16 },
3238 'net22' => { bus => 1, addr => 17 },
3239 'net23' => { bus => 1, addr => 18 },
3240 'net24' => { bus => 1, addr => 19 },
3241 'net25' => { bus => 1, addr => 20 },
3242 'net26' => { bus => 1, addr => 21 },
3243 'net27' => { bus => 1, addr => 22 },
3244 'net28' => { bus => 1, addr => 23 },
3245 'net29' => { bus => 1, addr => 24 },
3246 'net30' => { bus => 1, addr => 25 },
3247 'net31' => { bus => 1, addr => 26 },
3248 'virtio6' => { bus => 2, addr => 1 },
3249 'virtio7' => { bus => 2, addr => 2 },
3250 'virtio8' => { bus => 2, addr => 3 },
3251 'virtio9' => { bus => 2, addr => 4 },
3252 'virtio10' => { bus => 2, addr => 5 },
3253 'virtio11' => { bus => 2, addr => 6 },
3254 'virtio12' => { bus => 2, addr => 7 },
3255 'virtio13' => { bus => 2, addr => 8 },
3256 'virtio14' => { bus => 2, addr => 9 },
3257 'virtio15' => { bus => 2, addr => 10 },
3258 };
3259
3260 if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
3261 my $addr = sprintf("0x%x", $devices->{$id}->{addr});
3262 my $bus = $devices->{$id}->{bus};
3263 $res = ",bus=pci.$bus,addr=$addr";
3264 $bridges->{$bus} = 1 if $bridges;
3265 }
3266 return $res;
3267
3268 }
3269
3270 sub vm_balloonset {
3271 my ($vmid, $value) = @_;
3272
3273 vm_mon_cmd($vmid, "balloon", value => $value);
3274 }
3275
3276 # vzdump restore implementaion
3277
3278 sub archive_read_firstfile {
3279 my $archive = shift;
3280
3281 die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
3282
3283 # try to detect archive type first
3284 my $pid = open (TMP, "tar tf '$archive'|") ||
3285 die "unable to open file '$archive'\n";
3286 my $firstfile = <TMP>;
3287 kill 15, $pid;
3288 close TMP;
3289
3290 die "ERROR: archive contaions no data\n" if !$firstfile;
3291 chomp $firstfile;
3292
3293 return $firstfile;
3294 }
3295
3296 sub restore_cleanup {
3297 my $statfile = shift;
3298
3299 print STDERR "starting cleanup\n";
3300
3301 if (my $fd = IO::File->new($statfile, "r")) {
3302 while (defined(my $line = <$fd>)) {
3303 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3304 my $volid = $2;
3305 eval {
3306 if ($volid =~ m|^/|) {
3307 unlink $volid || die 'unlink failed\n';
3308 } else {
3309 my $cfg = cfs_read_file('storage.cfg');
3310 PVE::Storage::vdisk_free($cfg, $volid);
3311 }
3312 print STDERR "temporary volume '$volid' sucessfuly removed\n";
3313 };
3314 print STDERR "unable to cleanup '$volid' - $@" if $@;
3315 } else {
3316 print STDERR "unable to parse line in statfile - $line";
3317 }
3318 }
3319 $fd->close();
3320 }
3321 }
3322
3323 sub restore_archive {
3324 my ($archive, $vmid, $user, $opts) = @_;
3325
3326 if ($archive ne '-') {
3327 my $firstfile = archive_read_firstfile($archive);
3328 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
3329 if $firstfile ne 'qemu-server.conf';
3330 }
3331
3332 my $tocmd = "/usr/lib/qemu-server/qmextract";
3333
3334 $tocmd .= " --storage " . PVE::Tools::shellquote($opts->{storage}) if $opts->{storage};
3335 $tocmd .= " --pool " . PVE::Tools::shellquote($opts->{pool}) if $opts->{pool};
3336 $tocmd .= ' --prealloc' if $opts->{prealloc};
3337 $tocmd .= ' --info' if $opts->{info};
3338
3339 # tar option "xf" does not autodetect compression when read from STDIN,
3340 # so we pipe to zcat
3341 my $cmd = "zcat -f|tar xf " . PVE::Tools::shellquote($archive) . " " .
3342 PVE::Tools::shellquote("--to-command=$tocmd");
3343
3344 my $tmpdir = "/var/tmp/vzdumptmp$$";
3345 mkpath $tmpdir;
3346
3347 local $ENV{VZDUMP_TMPDIR} = $tmpdir;
3348 local $ENV{VZDUMP_VMID} = $vmid;
3349 local $ENV{VZDUMP_USER} = $user;
3350
3351 my $conffile = PVE::QemuServer::config_file($vmid);
3352 my $tmpfn = "$conffile.$$.tmp";
3353
3354 # disable interrupts (always do cleanups)
3355 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
3356 print STDERR "got interrupt - ignored\n";
3357 };
3358
3359 eval {
3360 # enable interrupts
3361 local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
3362 die "interrupted by signal\n";
3363 };
3364
3365 if ($archive eq '-') {
3366 print "extracting archive from STDIN\n";
3367 run_command($cmd, input => "<&STDIN");
3368 } else {
3369 print "extracting archive '$archive'\n";
3370 run_command($cmd);
3371 }
3372
3373 return if $opts->{info};
3374
3375 # read new mapping
3376 my $map = {};
3377 my $statfile = "$tmpdir/qmrestore.stat";
3378 if (my $fd = IO::File->new($statfile, "r")) {
3379 while (defined (my $line = <$fd>)) {
3380 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3381 $map->{$1} = $2 if $1;
3382 } else {
3383 print STDERR "unable to parse line in statfile - $line\n";
3384 }
3385 }
3386 $fd->close();
3387 }
3388
3389 my $confsrc = "$tmpdir/qemu-server.conf";
3390
3391 my $srcfd = new IO::File($confsrc, "r") ||
3392 die "unable to open file '$confsrc'\n";
3393
3394 my $outfd = new IO::File ($tmpfn, "w") ||
3395 die "unable to write config for VM $vmid\n";
3396
3397 my $netcount = 0;
3398
3399 while (defined (my $line = <$srcfd>)) {
3400 next if $line =~ m/^\#vzdump\#/;
3401 next if $line =~ m/^lock:/;
3402 next if $line =~ m/^unused\d+:/;
3403
3404 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3405 # try to convert old 1.X settings
3406 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3407 foreach my $devconfig (PVE::Tools::split_list($ethcfg)) {
3408 my ($model, $macaddr) = split(/\=/, $devconfig);
3409 $macaddr = PVE::Tools::random_ether_addr() if !$macaddr || $opts->{unique};
3410 my $net = {
3411 model => $model,
3412 bridge => "vmbr$ind",
3413 macaddr => $macaddr,
3414 };
3415 my $netstr = print_net($net);
3416 print $outfd "net${netcount}: $netstr\n";
3417 $netcount++;
3418 }
3419 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && ($opts->{unique})) {
3420 my ($id, $netstr) = ($1, $2);
3421 my $net = parse_net($netstr);
3422 $net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
3423 $netstr = print_net($net);
3424 print $outfd "$id: $netstr\n";
3425 } elsif ($line =~ m/^((ide|scsi|virtio)\d+):\s*(\S+)\s*$/) {
3426 my $virtdev = $1;
3427 my $value = $2;
3428 if ($line =~ m/backup=no/) {
3429 print $outfd "#$line";
3430 } elsif ($virtdev && $map->{$virtdev}) {
3431 my $di = PVE::QemuServer::parse_drive($virtdev, $value);
3432 $di->{file} = $map->{$virtdev};
3433 $value = PVE::QemuServer::print_drive($vmid, $di);
3434 print $outfd "$virtdev: $value\n";
3435 } else {
3436 print $outfd $line;
3437 }
3438 } else {
3439 print $outfd $line;
3440 }
3441 }
3442
3443 $srcfd->close();
3444 $outfd->close();
3445 };
3446 my $err = $@;
3447
3448 if ($err) {
3449
3450 unlink $tmpfn;
3451
3452 restore_cleanup("$tmpdir/qmrestore.stat") if !$opts->{info};
3453
3454 die $err;
3455 }
3456
3457 rmtree $tmpdir;
3458
3459 rename $tmpfn, $conffile ||
3460 die "unable to commit configuration file '$conffile'\n";
3461 };
3462
3463 1;