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