1 package PVE
::QemuServer
;
21 use Storable
qw(dclone);
22 use PVE
::Exception
qw(raise raise_param_exc);
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);
29 use Time
::HiRes
qw(gettimeofday);
31 my $cpuinfo = PVE
::ProcFSTools
::read_cpuinfo
();
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.
40 cfs_register_file
('/qemu-server/',
44 PVE
::JSONSchema
::register_standard_option
('skiplock', {
45 description
=> "Ignore locks - only root is allowed to use this option.",
50 PVE
::JSONSchema
::register_standard_option
('pve-qm-stateuri', {
51 description
=> "Some command save/restore state from this location.",
57 #no warnings 'redefine';
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
);
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
);
82 die("no fairsched syscall for this arch");
84 require 'asm/ioctl.ph';
85 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined(&KVM_GET_API_VERSION
);
89 my ($parent, $weight, $desired) = @_;
91 return syscall(&__NR_fairsched_mknod
, int($parent), int($weight), int($desired));
97 return syscall(&__NR_fairsched_rmnod
, int($id));
101 my ($pid, $newid) = @_;
103 return syscall(&__NR_fairsched_mvpr
, int($pid), int($newid));
106 sub fairsched_vcpus
{
107 my ($id, $vcpus) = @_;
109 return syscall(&__NR_fairsched_vcpus
, int($id), int($vcpus));
113 my ($id, $op, $rate) = @_;
115 return syscall(&__NR_fairsched_rate
, int($id), int($op), int($rate));
118 use constant FAIRSCHED_SET_RATE
=> 0;
119 use constant FAIRSCHED_DROP_RATE
=> 1;
120 use constant FAIRSCHED_GET_RATE
=> 2;
122 sub fairsched_cpulimit
{
123 my ($id, $limit) = @_;
125 my $cpulim1024 = int($limit * 1024 / 100);
126 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE
: FAIRSCHED_DROP_RATE
;
128 return fairsched_rate
($id, $op, $cpulim1024);
131 my $nodename = PVE
::INotify
::nodename
();
133 mkdir "/etc/pve/nodes/$nodename";
134 my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
137 my $var_run_tmpdir = "/var/run/qemu-server";
138 mkdir $var_run_tmpdir;
140 my $lock_dir = "/var/lock/qemu-server";
143 my $pcisysfs = "/sys/bus/pci";
149 description
=> "Specifies whether a VM will be started during system bootup.",
155 description
=> "Automatic restart after crash (currently ignored).",
161 description
=> "Activate hotplug for disk and network device",
167 description
=> "Allow reboot. If set to '0' the VM exit on reboot.",
173 description
=> "Lock/unlock the VM.",
174 enum
=> [qw(migrate backup)],
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.",
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.",
194 description
=> "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
201 description
=> "Amount of target RAM for the VM in MB.",
207 description
=> "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
208 enum
=> PVE
::Tools
::kvmkeymaplist
(),
213 type
=> 'string', format
=> 'dns-name',
214 description
=> "Set a name for the VM. Only used on the configuration web interface.",
219 description
=> "scsi controller model",
220 enum
=> [qw(lsi virtio-scsi-pci megasas)],
226 description
=> "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
231 enum
=> [qw(other wxp w2k w2k3 w2k8 wvista win7 l24 l26)],
232 description
=> <<EODESC,
233 Used to enable special optimization/features for specific
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
246 other|l24|l26 ... no special behaviour
247 wxp|w2k|w2k3|w2k8|wvista|win7 ... use --localtime switch
253 description
=> "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
254 pattern
=> '[acdn]{1,4}',
259 type
=> 'string', format
=> 'pve-qm-bootdisk',
260 description
=> "Enable booting from specified disk.",
261 pattern
=> '(ide|sata|scsi|virtio)\d+',
266 description
=> "The number of CPUs. Please use option -sockets instead.",
273 description
=> "The number of CPU sockets.",
280 description
=> "The number of cores per socket.",
287 description
=> "Enable/disable ACPI.",
293 description
=> "Enable/disable KVM hardware virtualization.",
299 description
=> "Enable/disable time drift fix. This is ignored for kvm versions newer that 1.0 (not needed anymore).",
305 description
=> "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
310 description
=> "Freeze CPU at startup (use 'c' monitor command to start execution).",
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)],
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)",
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})?)',
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.",
341 description
=> <<EODESCR,
342 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
344 args: -no-reboot -no-hpet
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.",
356 description
=> "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
360 migrate_downtime
=> {
363 description
=> "Set maximum tolerated downtime (in seconds) for migrations.",
369 type
=> 'string', format
=> 'pve-qm-drive',
370 typetext
=> 'volume',
371 description
=> "This is an alias for option -ide2",
375 description
=> "Emulated CPU type.",
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) ],
382 # what about other qemu settings ?
384 #machine => 'string',
397 ##soundhw => 'string',
399 while (my ($k, $v) = each %$confdesc) {
400 PVE
::JSONSchema
::register_standard_option
("pve-qm-$k", $v);
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;
409 my $MAX_UNUSED_DISKS = 8;
410 my $MAX_HOSTPCI_DEVICES = 2;
411 my $MAX_SERIAL_PORTS = 4;
412 my $MAX_PARALLEL_PORTS = 3;
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);
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.
426 MODEL is one of: $nic_model_list_txt
428 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
429 automatically generated if not specified.
431 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
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'.
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:
441 The DHCP server assign addresses to the guest starting from 10.0.2.15.
445 PVE
::JSONSchema
::register_standard_option
("pve-qm-net", $netdesc);
447 for (my $i = 0; $i < $MAX_NETS; $i++) {
448 $confdesc->{"net$i"} = $netdesc;
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) . ").",
459 PVE
::JSONSchema
::register_standard_option
("pve-qm-ide", $idedesc);
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) . ").",
467 PVE
::JSONSchema
::register_standard_option
("pve-qm-scsi", $scsidesc);
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). ").",
475 PVE
::JSONSchema
::register_standard_option
("pve-qm-sata", $satadesc);
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) . ").",
483 PVE
::JSONSchema
::register_standard_option
("pve-qm-virtio", $virtiodesc);
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:
493 'bus-port(.port)*' (decimal numbers) or
494 'vendor_id:product_id' (hexadeciaml numbers)
496 You can use the 'lsusb -t' command to list existing usb devices.
498 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
502 PVE
::JSONSchema
::register_standard_option
("pve-qm-usb", $usbdesc);
506 type
=> 'string', format
=> 'pve-qm-hostpci',
507 typetext
=> "HOSTPCIDEVICE",
508 description
=> <<EODESCR,
509 Map host pci devices. HOSTPCIDEVICE syntax is:
511 'bus:dev.func' (hexadecimal numbers)
513 You can us the 'lspci' command to list existing pci devices.
515 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
517 Experimental: user reported problems with this option.
520 PVE
::JSONSchema
::register_standard_option
("pve-qm-hostpci", $hostpcidesc);
525 pattern
=> '/dev/ttyS\d+',
526 description
=> <<EODESCR,
527 Map host serial devices (n is 0 to 3).
529 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
531 Experimental: user reported problems with this option.
538 pattern
=> '/dev/parport\d+',
539 description
=> <<EODESCR,
540 Map host parallel devices (n is 0 to 2).
542 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
544 Experimental: user reported problems with this option.
548 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
549 $confdesc->{"parallel$i"} = $paralleldesc;
552 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
553 $confdesc->{"serial$i"} = $serialdesc;
556 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
557 $confdesc->{"hostpci$i"} = $hostpcidesc;
560 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
561 $drivename_hash->{"ide$i"} = 1;
562 $confdesc->{"ide$i"} = $idedesc;
565 for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
566 $drivename_hash->{"sata$i"} = 1;
567 $confdesc->{"sata$i"} = $satadesc;
570 for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
571 $drivename_hash->{"scsi$i"} = 1;
572 $confdesc->{"scsi$i"} = $scsidesc ;
575 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
576 $drivename_hash->{"virtio$i"} = 1;
577 $confdesc->{"virtio$i"} = $virtiodesc;
580 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
581 $confdesc->{"usb$i"} = $usbdesc;
586 type
=> 'string', format
=> 'pve-volume-id',
587 description
=> "Reference to unused volumes.",
590 for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
591 $confdesc->{"unused$i"} = $unuseddesc;
594 my $kvm_api_version = 0;
598 return $kvm_api_version if $kvm_api_version;
600 my $fh = IO
::File-
>new("</dev/kvm") ||
603 if (my $v = $fh->ioctl(KVM_GET_API_VERSION
(), 0)) {
604 $kvm_api_version = $v;
609 return $kvm_api_version;
612 my $kvm_user_version;
614 sub kvm_user_version
{
616 return $kvm_user_version if $kvm_user_version;
618 $kvm_user_version = 'unknown';
620 my $tmp = `kvm -help 2>/dev/null`;
622 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?) /) {
623 $kvm_user_version = $2;
626 return $kvm_user_version;
630 my $kernel_has_vhost_net = -c
'/dev/vhost-net';
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))));
640 sub valid_drivename
{
643 return defined($drivename_hash->{$dev});
648 return defined($confdesc->{$key});
652 return $nic_model_list;
655 sub os_list_description
{
660 w2k
=> 'Windows 2000',
661 w2k3
=>, 'Windows 2003',
662 w2k8
=> 'Windows 2008',
663 wvista
=> 'Windows Vista',
674 return $cdrom_path if $cdrom_path;
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";
682 my ($storecfg, $vmid, $cdrom) = @_;
684 if ($cdrom eq 'cdrom') {
685 return get_cdrom_path
();
686 } elsif ($cdrom eq 'none') {
688 } elsif ($cdrom =~ m
|^/|) {
691 return PVE
::Storage
::path
($storecfg, $cdrom);
695 # try to convert old style file names to volume IDs
696 sub filename_to_volume_id
{
697 my ($vmid, $file, $media) = @_;
699 if (!($file eq 'none' || $file eq 'cdrom' ||
700 $file =~ m
|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
702 return undef if $file =~ m
|/|;
704 if ($media && $media eq 'cdrom') {
705 $file = "local:iso/$file";
707 $file = "local:$vmid/$file";
714 sub verify_media_type
{
715 my ($opt, $vtype, $media) = @_;
720 if ($media eq 'disk') {
722 } elsif ($media eq 'cdrom') {
725 die "internal error";
728 return if ($vtype eq $etype);
730 raise_param_exc
({ $opt => "unexpected media type ($vtype != $etype)" });
733 sub cleanup_drive_path
{
734 my ($opt, $storecfg, $drive) = @_;
736 # try to convert filesystem paths to volume IDs
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;
749 $drive->{media
} = 'cdrom' if !$drive->{media
} && $drive->{file
} =~ m/^(cdrom|none)$/;
752 sub create_conf_nolock
{
753 my ($vmid, $settings) = @_;
755 my $filename = config_file
($vmid);
757 die "configuration file '$filename' already exists\n" if -f
$filename;
759 my $defaults = load_defaults
();
761 $settings->{name
} = "vm$vmid" if !$settings->{name
};
762 $settings->{memory
} = $defaults->{memory
} if !$settings->{memory
};
765 foreach my $opt (keys %$settings) {
766 next if !$confdesc->{$opt};
768 my $value = $settings->{$opt};
771 $data .= "$opt: $value\n";
774 PVE
::Tools
::file_set_contents
($filename, $data);
777 my $parse_size = sub {
780 return undef if $value !~ m/^([1-9]\d*(\.\d+)?)([KMG])?$/;
781 my ($size, $unit) = ($1, $3);
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;
794 my $format_size = sub {
799 my $kb = int($size/1024);
800 return $size if $kb*1024 != $size;
802 my $mb = int($kb/1024);
803 return "${kb}K" if $mb*1024 != $kb;
805 my $gb = int($mb/1024);
806 return "${mb}M" if $gb*1024 != $mb;
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]
817 my ($key, $data) = @_;
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
825 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
826 $res->{interface
} = $1;
832 foreach my $p (split (/,/, $data)) {
833 next if $p =~ m/^\s*$/;
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);
838 $k = 'file' if $k eq 'volume';
840 return undef if defined $res->{$k};
844 if (!$res->{file
} && $p !~ m/=/) {
852 return undef if !$res->{file
};
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)$/;
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
};
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+$/;
882 return undef if !defined($res->{size
} = &$parse_size($res->{size
}));
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';
891 # rerror does not work with scsi drives
892 if ($res->{rerror
}) {
893 return undef if $res->{interface
} eq 'scsi';
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);
902 my ($vmid, $drive) = @_;
905 foreach my $o (@qemu_drive_options, 'backup') {
906 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
909 if ($drive->{size
}) {
910 $opts .= ",size=" . &$format_size($drive->{size
});
913 return "$drive->{file}$opts";
917 my($fh, $noerr) = @_;
920 my $SG_GET_VERSION_NUM = 0x2282;
922 my $versionbuf = "\x00" x
8;
923 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
925 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
928 my $version = unpack("I", $versionbuf);
929 if ($version < 30000) {
930 die "scsi generic interface too old\n" if !$noerr;
934 my $buf = "\x00" x
36;
935 my $sensebuf = "\x00" x
8;
936 my $cmd = pack("C x3 C x11", 0x12, 36);
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";
941 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
942 length($sensebuf), 0, length($buf), $buf,
943 $cmd, $sensebuf, 6000);
945 $ret = ioctl($fh, $SG_IO, $packet);
947 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
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;
958 ($res->{device
}, $res->{removable
}, $res->{venodor
},
959 $res->{product
}, $res->{revision
}) = unpack("C C x6 A8 A16 A4", $buf);
967 my $fh = IO
::File-
>new("+<$path") || return undef;
968 my $res = scsi_inquiry
($fh, 1);
974 sub print_drivedevice_full
{
975 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
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';
989 if (drive_is_cdrom
($drive)) {
992 if ($drive->{file
} =~ m
|^/|) {
993 $path = $drive->{file
};
995 $path = PVE
::Storage
::path
($storecfg, $drive->{file
});
998 if($path =~ m/^iscsi\:\/\
//){
999 $devicetype = 'generic';
1002 $devicetype = 'block' if path_is_scsi
($path);
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';
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}";
1012 } elsif ($drive->{interface
} eq 'ide'){
1014 my $controller = int($drive->{index} / $maxdev);
1015 my $unit = $drive->{index} % $maxdev;
1016 my $devicetype = ($drive->{media
} && $drive->{media
} eq 'cdrom') ?
"cd" : "hd";
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') {
1025 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1027 die "unsupported interface type";
1030 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex
};
1035 sub print_drive_full
{
1036 my ($storecfg, $vmid, $drive) = @_;
1039 foreach my $o (@qemu_drive_options) {
1040 next if $o eq 'bootindex';
1041 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1044 # use linux-aio by default (qemu default is threads)
1045 $opts .= ",aio=native" if !$drive->{aio
};
1048 my $volid = $drive->{file
};
1049 if (drive_is_cdrom
($drive)) {
1050 $path = get_iso_path
($storecfg, $vmid, $volid);
1052 if ($volid =~ m
|^/|) {
1055 $path = PVE
::Storage
::path
($storecfg, $volid);
1057 if (!$drive->{cache
} && ($path =~ m
|^/dev/| || $path =~ m
|\
.raw
$|)) {
1058 $opts .= ",cache=none";
1062 my $pathinfo = $path ?
"file=$path," : '';
1064 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1067 sub print_netdevice_full
{
1068 my ($vmid, $conf, $net, $netid, $bridges) = @_;
1070 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
1072 my $device = $net->{model
};
1073 if ($net->{model
} eq 'virtio') {
1074 $device = 'virtio-net-pci';
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
} ;
1086 sub print_netdev_full
{
1087 my ($vmid, $conf, $net, $netid) = @_;
1090 if ($netid =~ m/^net(\d+)$/) {
1094 die "got strange net id '$i'\n" if $i >= ${MAX_NETS
};
1096 my $ifname = "tap${vmid}i$i";
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;
1102 my $vhostparam = '';
1103 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model
} eq 'virtio';
1105 my $vmname = $conf->{name
} || "vm$vmid";
1107 if ($net->{bridge
}) {
1108 return "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
1110 return "type=user,id=$netid,hostname=$vmname";
1114 sub drive_is_cdrom
{
1117 return $drive && $drive->{media
} && ($drive->{media
} eq 'cdrom');
1124 return undef if !$value;
1128 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
1129 $res->{pciid
} = $value;
1137 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1143 foreach my $kvp (split(/,/, $data)) {
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) {
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+)?)$/) {
1154 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1162 return undef if !$res->{model
};
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
};
1179 sub add_random_macs
{
1180 my ($settings) = @_;
1182 foreach my $opt (keys %$settings) {
1183 next if $opt !~ m/^net(\d+)$/;
1184 my $net = parse_net
($settings->{$opt});
1186 $settings->{$opt} = print_net
($net);
1190 sub add_unused_volume
{
1191 my ($config, $volid) = @_;
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
1203 die "To many unused volume - please delete them first.\n" if !$key;
1205 $config->{$key} = $volid;
1210 # fixme: remove all thos $noerr parameters?
1212 PVE
::JSONSchema
::register_format
('pve-qm-bootdisk', \
&verify_bootdisk
);
1213 sub verify_bootdisk
{
1214 my ($value, $noerr) = @_;
1216 return $value if valid_drivename
($value);
1218 return undef if $noerr;
1220 die "invalid boot disk '$value'\n";
1223 PVE
::JSONSchema
::register_format
('pve-qm-net', \
&verify_net
);
1225 my ($value, $noerr) = @_;
1227 return $value if parse_net
($value);
1229 return undef if $noerr;
1231 die "unable to parse network options\n";
1234 PVE
::JSONSchema
::register_format
('pve-qm-drive', \
&verify_drive
);
1236 my ($value, $noerr) = @_;
1238 return $value if parse_drive
(undef, $value);
1240 return undef if $noerr;
1242 die "unable to parse drive options\n";
1245 PVE
::JSONSchema
::register_format
('pve-qm-hostpci', \
&verify_hostpci
);
1246 sub verify_hostpci
{
1247 my ($value, $noerr) = @_;
1249 return $value if parse_hostpci
($value);
1251 return undef if $noerr;
1253 die "unable to parse pci id\n";
1256 PVE
::JSONSchema
::register_format
('pve-qm-watchdog', \
&verify_watchdog
);
1257 sub verify_watchdog
{
1258 my ($value, $noerr) = @_;
1260 return $value if parse_watchdog
($value);
1262 return undef if $noerr;
1264 die "unable to parse watchdog options\n";
1267 sub parse_watchdog
{
1270 return undef if !$value;
1274 foreach my $p (split(/,/, $value)) {
1275 next if $p =~ m/^\s*$/;
1277 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1279 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1280 $res->{action
} = $2;
1289 PVE
::JSONSchema
::register_format
('pve-qm-startup', \
&verify_startup
);
1290 sub verify_startup
{
1291 my ($value, $noerr) = @_;
1293 return $value if parse_startup
($value);
1295 return undef if $noerr;
1297 die "unable to parse startup options\n";
1303 return undef if !$value;
1307 foreach my $p (split(/,/, $value)) {
1308 next if $p =~ m/^\s*$/;
1310 if ($p =~ m/^(order=)?(\d+)$/) {
1312 } elsif ($p =~ m/^up=(\d+)$/) {
1314 } elsif ($p =~ m/^down=(\d+)$/) {
1324 sub parse_usb_device
{
1327 return undef if !$value;
1329 my @dl = split(/,/, $value);
1333 foreach my $v (@dl) {
1334 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1336 $res->{vendorid
} = $2;
1337 $res->{productid
} = $4;
1338 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1340 $res->{hostbus
} = $1;
1341 $res->{hostport
} = $2;
1346 return undef if !$found;
1351 PVE
::JSONSchema
::register_format
('pve-qm-usb-device', \
&verify_usb_device
);
1352 sub verify_usb_device
{
1353 my ($value, $noerr) = @_;
1355 return $value if parse_usb_device
($value);
1357 return undef if $noerr;
1359 die "unable to parse usb device\n";
1362 # add JSON properties for create and set function
1363 sub json_config_properties
{
1366 foreach my $opt (keys %$confdesc) {
1367 $prop->{$opt} = $confdesc->{$opt};
1374 my ($key, $value) = @_;
1376 die "unknown setting '$key'\n" if !$confdesc->{$key};
1378 my $type = $confdesc->{$key}->{type
};
1380 if (!defined($value)) {
1381 die "got undefined value\n";
1384 if ($value =~ m/[\n\r]/) {
1385 die "property contains a line feed\n";
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";
1403 PVE
::JSONSchema
::check_format
($fmt, $value);
1406 $value =~ s/^\"(.*)\"$/$1/;
1409 die "internal error"
1413 sub lock_config_full
{
1414 my ($vmid, $timeout, $code, @param) = @_;
1416 my $filename = config_file_lock
($vmid);
1418 my $res = lock_file
($filename, $timeout, $code, @param);
1426 my ($vmid, $code, @param) = @_;
1428 return lock_config_full
($vmid, 10, $code, @param);
1431 sub cfs_config_path
{
1432 my ($vmid, $node) = @_;
1434 $node = $nodename if !$node;
1435 return "nodes/$node/qemu-server/$vmid.conf";
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
1448 my ($vmid, $node) = @_;
1450 my $cfspath = cfs_config_path
($vmid, $node);
1451 return "/etc/pve/$cfspath";
1454 sub config_file_lock
{
1457 return "$lock_dir/lock-$vmid.conf";
1463 my $conf = config_file
($vmid);
1464 utime undef, undef, $conf;
1468 my ($storecfg, $vmid, $keep_empty_config) = @_;
1470 my $conffile = config_file
($vmid);
1472 my $conf = load_config
($vmid);
1476 # only remove disks owned by this VM
1477 foreach_drive
($conf, sub {
1478 my ($ds, $drive) = @_;
1480 return if drive_is_cdrom
($drive);
1482 my $volid = $drive->{file
};
1483 return if !$volid || $volid =~ m
|^/|;
1485 my ($path, $owner) = PVE
::Storage
::path
($storecfg, $volid);
1486 return if !$path || !$owner || ($owner != $vmid);
1488 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1491 if ($keep_empty_config) {
1492 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
1497 # also remove unused disk
1499 my $dl = PVE
::Storage
::vdisk_list
($storecfg, undef, $vmid);
1502 PVE
::Storage
::foreach_volid
($dl, sub {
1503 my ($volid, $sid, $volname, $d) = @_;
1504 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1514 my ($vmid, $node) = @_;
1516 my $cfspath = cfs_config_path
($vmid, $node);
1518 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath);
1520 die "no such VM ('$vmid')\n" if !defined($conf);
1525 sub parse_vm_config
{
1526 my ($filename, $raw) = @_;
1528 return undef if !defined($raw);
1531 digest
=> Digest
::SHA
::sha1_hex
($raw),
1534 $filename =~ m
|/qemu-server/(\d
+)\
.conf
$|
1535 || die "got strange filename '$filename'";
1541 while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
1544 next if $line =~ m/^\s*$/;
1546 if ($line =~ m/^\#(.*)\s*$/) {
1547 $descr .= PVE
::Tools
::decode_text
($1) . "\n";
1551 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1552 $descr .= PVE
::Tools
::decode_text
($2);
1553 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1556 $res->{$key} = $value;
1557 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1560 eval { $value = check_type
($key, $value); };
1562 warn "vm $vmid - unable to parse value of '$key' - $@";
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);
1571 warn "vm $vmid - unable to parse value of '$key'\n";
1576 if ($key eq 'cdrom') {
1577 $res->{ide2
} = $value;
1579 $res->{$key} = $value;
1585 $res->{description
} = $descr if $descr;
1587 # convert old smp to sockets
1588 if ($res->{smp
} && !$res->{sockets
}) {
1589 $res->{sockets
} = $res->{smp
};
1596 sub write_vm_config
{
1597 my ($filename, $conf) = @_;
1599 if ($conf->{cdrom
}) {
1600 die "option ide2 conflicts with cdrom\n" if $conf->{ide2
};
1601 $conf->{ide2
} = $conf->{cdrom
};
1602 delete $conf->{cdrom
};
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
};
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 $@;
1621 $conf->{$key} = $value;
1623 if (valid_drivename
($key)) {
1624 my $drive = PVE
::QemuServer
::parse_drive
($key, $value);
1625 $new_volids->{$drive->{file
}} = 1 if $drive && $drive->{file
};
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};
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";
1646 foreach my $key (sort keys %$conf) {
1647 next if $key eq 'digest' || $key eq 'description';
1648 $raw .= "$key: $conf->{$key}\n";
1654 sub update_config_nolock
{
1655 my ($vmid, $conf, $skiplock) = @_;
1657 check_lock
($conf) if !$skiplock;
1659 my $cfspath = cfs_config_path
($vmid);
1661 PVE
::Cluster
::cfs_write_file
($cfspath, $conf);
1665 my ($vmid, $conf, $skiplock) = @_;
1667 lock_config
($vmid, &update_config_nolock
, $conf, $skiplock);
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;
1681 my $conf = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
1682 $res->{keyboard
} = $conf->{keyboard
} if $conf->{keyboard
};
1688 my $vmlist = PVE
::Cluster
::get_vmlist
();
1690 return $res if !$vmlist || !$vmlist->{ids
};
1691 my $ids = $vmlist->{ids
};
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;
1702 # test if VM uses local resources (to prevent migration)
1703 sub check_local_resources
{
1704 my ($conf, $noerr) = @_;
1708 $loc_res = 1 if $conf->{hostusb
}; # old syntax
1709 $loc_res = 1 if $conf->{hostpci
}; # old syntax
1711 foreach my $k (keys %$conf) {
1712 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
1715 die "VM uses local resources\n" if $loc_res && !$noerr;
1720 # check is used storages are available on all nodes (use by migrate)
1721 sub check_storage_availability
{
1722 my ($storecfg, $conf, $node) = @_;
1724 foreach_drive
($conf, sub {
1725 my ($ds, $drive) = @_;
1727 my $volid = $drive->{file
};
1730 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
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);
1742 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1746 my ($pidfile, $pid) = @_;
1748 my $fh = IO
::File-
>new("/proc/$pid/cmdline", "r");
1752 return undef if !$line;
1753 my @param = split(/\0/, $line);
1755 my $cmd = $param[0];
1756 return if !$cmd || ($cmd !~ m
|kvm
$|);
1758 for (my $i = 0; $i < scalar (@param); $i++) {
1761 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1762 my $p = $param[$i+1];
1763 return 1 if $p && ($p eq $pidfile);
1772 my ($vmid, $nocheck, $node) = @_;
1774 my $filename = config_file
($vmid, $node);
1776 die "unable to find configuration file for VM $vmid - no such machine\n"
1777 if !$nocheck && ! -f
$filename;
1779 my $pidfile = pidfile_name
($vmid);
1781 if (my $fd = IO
::File-
>new("<$pidfile")) {
1786 my $mtime = $st->mtime;
1787 if ($mtime > time()) {
1788 warn "file '$filename' modified in future\n";
1791 if ($line =~ m/^(\d+)$/) {
1793 if (check_cmdline
($pidfile, $pid)) {
1794 if (my $pinfo = PVE
::ProcFSTools
::check_process_running
($pid)) {
1806 my $vzlist = config_list
();
1808 my $fd = IO
::Dir-
>new($var_run_tmpdir) || return $vzlist;
1810 while (defined(my $de = $fd->read)) {
1811 next if $de !~ m/^(\d+)\.pid$/;
1813 next if !defined($vzlist->{$vmid});
1814 if (my $pid = check_running
($vmid)) {
1815 $vzlist->{$vmid}->{pid
} = $pid;
1823 my ($storecfg, $conf) = @_;
1825 my $bootdisk = $conf->{bootdisk
};
1826 return undef if !$bootdisk;
1827 return undef if !valid_drivename
($bootdisk);
1829 return undef if !$conf->{$bootdisk};
1831 my $drive = parse_drive
($bootdisk, $conf->{$bootdisk});
1832 return undef if !defined($drive);
1834 return undef if drive_is_cdrom
($drive);
1836 my $volid = $drive->{file
};
1837 return undef if !$volid;
1839 return $drive->{size
};
1842 my $last_proc_pid_stat;
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)
1848 my ($opt_vmid, $full) = @_;
1852 my $storecfg = PVE
::Storage
::config
();
1854 my $list = vzlist
();
1855 my ($uptime) = PVE
::ProcFSTools
::read_proc_uptime
(1);
1857 my $cpucount = $cpuinfo->{cpus
} || 1;
1859 foreach my $vmid (keys %$list) {
1860 next if $opt_vmid && ($vmid ne $opt_vmid);
1862 my $cfspath = cfs_config_path
($vmid);
1863 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath) || {};
1866 $d->{pid
} = $list->{$vmid}->{pid
};
1868 # fixme: better status?
1869 $d->{status
} = $list->{$vmid}->{pid
} ?
'running' : 'stopped';
1871 my $size = disksize
($storecfg, $conf);
1872 if (defined($size)) {
1873 $d->{disk
} = 0; # no info available
1874 $d->{maxdisk
} = $size;
1880 $d->{cpus
} = ($conf->{sockets
} || 1) * ($conf->{cores
} || 1);
1881 $d->{cpus
} = $cpucount if $d->{cpus
} > $cpucount;
1883 $d->{name
} = $conf->{name
} || "VM $vmid";
1884 $d->{maxmem
} = $conf->{memory
} ?
$conf->{memory
}*(1024*1024) : 0;
1894 $d->{diskwrite
} = 0;
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/;
1903 my $d = $res->{$vmid};
1906 $d->{netout
} += $netdev->{$dev}->{receive
};
1907 $d->{netin
} += $netdev->{$dev}->{transmit
};
1910 my $ctime = gettimeofday
;
1912 foreach my $vmid (keys %$list) {
1914 my $d = $res->{$vmid};
1915 my $pid = $d->{pid
};
1918 my $pstat = PVE
::ProcFSTools
::read_proc_pid_stat
($pid);
1919 next if !$pstat; # not running
1921 my $used = $pstat->{utime} + $pstat->{stime
};
1923 $d->{uptime
} = int(($uptime - $pstat->{starttime
})/$cpuinfo->{user_hz
});
1925 if ($pstat->{vsize
}) {
1926 $d->{mem
} = int(($pstat->{rss
}/$pstat->{vsize
})*$d->{maxmem
});
1929 my $old = $last_proc_pid_stat->{$pid};
1931 $last_proc_pid_stat->{$pid} = {
1939 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz
};
1941 if ($dtime > 1000) {
1942 my $dutime = $used - $old->{used
};
1944 $d->{cpu
} = (($dutime/$dtime)* $cpucount) / $d->{cpus
};
1945 $last_proc_pid_stat->{$pid} = {
1951 $d->{cpu
} = $old->{cpu
};
1955 return $res if !$full;
1957 my $qmpclient = PVE
::QMPClient-
>new();
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
};
1968 $res->{$vmid}->{diskread
} = $totalrdbytes;
1969 $res->{$vmid}->{diskwrite
} = $totalwrbytes;
1972 my $statuscb = sub {
1973 my ($vmid, $resp) = @_;
1974 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
1976 my $status = 'unknown';
1977 if (!defined($status = $resp->{'return'}->{status
})) {
1978 warn "unable to get VM status\n";
1982 $res->{$vmid}->{qmpstatus
} = $resp->{'return'}->{status
};
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');
1991 $qmpclient->queue_execute();
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
};
2002 my ($conf, $func) = @_;
2004 foreach my $ds (keys %$conf) {
2005 next if !valid_drivename
($ds);
2007 my $drive = parse_drive
($ds, $conf->{$ds});
2010 &$func($ds, $drive);
2014 sub config_to_command
{
2015 my ($storecfg, $vmid, $conf, $defaults, $migrate_uri) = @_;
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;
2029 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
2031 my $have_ovz = -f
'/proc/vz/vestat';
2033 push @$cmd, '/usr/bin/kvm';
2035 push @$cmd, '-id', $vmid;
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";
2043 my $socket = vnc_socket
($vmid);
2044 push @$cmd, '-vnc', "unix:$socket,x509,password";
2046 push @$cmd, '-pidfile' , pidfile_name
($vmid);
2048 push @$cmd, '-daemonize';
2050 push @$cmd, '-incoming', $migrate_uri if $migrate_uri;
2052 push @$cmd, '-S' if $migrate_uri;
2055 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2056 next if !$conf->{"usb$i"};
2059 # include usb device config
2060 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
2062 # enable absolute mouse coordinates (needed by vnc)
2063 my $tablet = defined($conf->{tablet
}) ?
$conf->{tablet
} : $defaults->{tablet
};
2066 push @$devices, '-device', 'usb-tablet,bus=ehci.0,port=6';
2068 push @$devices, '-usbdevice', 'tablet';
2073 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2074 my $d = parse_hostpci
($conf->{"hostpci$i"});
2076 $pciaddr = print_pci_addr
("hostpci$i", $bridges);
2077 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
2081 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2082 my $d = parse_usb_device
($conf->{"usb$i"});
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}";
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";
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";
2109 my $vmname = $conf->{name
} || "vm$vmid";
2111 push @$cmd, '-name', $vmname;
2114 $sockets = $conf->{smp
} if $conf->{smp
}; # old style - no longer iused
2115 $sockets = $conf->{sockets
} if $conf->{sockets
};
2117 my $cores = $conf->{cores
} || 1;
2119 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2121 push @$cmd, '-cpu', $conf->{cpu
} if $conf->{cpu
};
2123 push @$cmd, '-nodefaults';
2125 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
2127 my $bootindex_hash = {};
2129 foreach my $o (split(//, $bootorder)) {
2130 $bootindex_hash->{$o} = $i*100;
2134 push @$cmd, '-boot', "menu=on";
2136 push @$cmd, '-no-acpi' if defined($conf->{acpi
}) && $conf->{acpi
} == 0;
2138 push @$cmd, '-no-reboot' if defined($conf->{reboot
}) && $conf->{reboot
} == 0;
2140 my $vga = $conf->{vga
};
2142 if ($conf->{ostype
} && ($conf->{ostype
} eq 'win7' || $conf->{ostype
} eq 'w2k8')) {
2149 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2152 my $tdf = defined($conf->{tdf
}) ?
$conf->{tdf
} : $defaults->{tdf
};
2153 # ignore - no longer supported by newer kvm
2154 # push @$cmd, '-tdf' if $tdf;
2156 my $nokvm = defined($conf->{kvm
}) && $conf->{kvm
} == 0 ?
1 : 0;
2158 if (my $ost = $conf->{ostype
}) {
2159 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2161 if ($ost =~ m/^w/) { # windows
2162 push @$cmd, '-localtime' if !defined($conf->{localtime});
2164 # use rtc-td-hack when acpi is enabled
2165 if (!(defined($conf->{acpi
}) && $conf->{acpi
} == 0)) {
2166 push @$cmd, '-rtc-td-hack';
2170 if ($ost eq 'win7' || $ost eq 'w2k8' || $ost eq 'wvista') {
2171 push @$cmd, '-no-kvm-pit-reinjection';
2172 push @$cmd, '-no-hpet';
2182 push @$cmd, '-no-kvm';
2184 die "No accelerator found!\n" if !$cpuinfo->{hvm
};
2187 push @$cmd, '-localtime' if $conf->{localtime};
2189 push @$cmd, '-startdate', $conf->{startdate
} if $conf->{startdate
};
2191 push @$cmd, '-S' if $conf->{freeze
};
2193 # set keyboard layout
2194 my $kb = $conf->{keyboard
} || $defaults->{keyboard
};
2195 push @$cmd, '-k', $kb if $kb;
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
};
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
};
2213 my $scsicontroller = {};
2214 my $ahcicontroller = {};
2215 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : $defaults->{scsihw
};
2217 foreach_drive
($conf, sub {
2218 my ($ds, $drive) = @_;
2220 if (PVE
::Storage
::parse_volume_id
($drive->{file
}, 1)) {
2221 push @$vollist, $drive->{file
};
2224 $use_virtio = 1 if $ds =~ m/^virtio/;
2226 if (drive_is_cdrom
($drive)) {
2227 if ($bootindex_hash->{d
}) {
2228 $drive->{bootindex
} = $bootindex_hash->{d
};
2229 $bootindex_hash->{d
} += 1;
2232 if ($bootindex_hash->{c
}) {
2233 $drive->{bootindex
} = $bootindex_hash->{c
} if $conf->{bootdisk
} && ($conf->{bootdisk
} eq $ds);
2234 $bootindex_hash->{c
} += 1;
2238 if ($drive->{interface
} eq 'scsi') {
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;
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;
2254 push @$devices, '-drive',print_drive_full
($storecfg, $vmid, $drive);
2255 push @$devices, '-device',print_drivedevice_full
($storecfg, $conf, $vmid, $drive, $bridges);
2258 push @$cmd, '-m', $conf->{memory
} || $defaults->{memory
};
2260 for (my $i = 0; $i < $MAX_NETS; $i++) {
2261 next if !$conf->{"net$i"};
2262 my $d = parse_net
($conf->{"net$i"});
2265 $use_virtio = 1 if $d->{model
} eq 'virtio';
2267 if ($bootindex_hash->{n
}) {
2268 $d->{bootindex
} = $bootindex_hash->{n
};
2269 $bootindex_hash->{n
} += 1;
2272 my $netdevfull = print_netdev_full
($vmid,$conf,$d,"net$i");
2273 push @$devices, '-netdev', $netdevfull;
2275 my $netdevicefull = print_netdevice_full
($vmid,$conf,$d,"net$i",$bridges);
2276 push @$devices, '-device', $netdevicefull;
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;
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) {
2290 my $cpuunits = defined($conf->{cpuunits
}) ?
2291 $conf->{cpuunits
} : $defaults->{cpuunits
};
2293 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2295 # fixme: cpulimit is currently ignored
2296 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2300 if ($conf->{args
}) {
2301 my $aa = PVE
::Tools
::split_args
($conf->{args
});
2305 push @$cmd, @$devices;
2306 return wantarray ?
($cmd, $vollist) : $cmd;
2311 return "${var_run_tmpdir}/$vmid.vnc";
2316 return "${var_run_tmpdir}/$vmid.qmp";
2321 return "${var_run_tmpdir}/$vmid.pid";
2324 sub next_migrate_port
{
2326 for (my $p = 60000; $p < 60010; $p++) {
2328 my $sock = IO
::Socket
::INET-
>new(Listen
=> 5,
2329 LocalAddr
=> 'localhost',
2340 die "unable to find free migration port";
2343 sub vm_devices_list
{
2346 my $res = vm_mon_cmd
($vmid, 'query-pci');
2349 foreach my $pcibus (@$res) {
2350 foreach my $device (@{$pcibus->{devices
}}) {
2351 next if !$device->{'qdev_id'};
2352 $devices->{$device->{'qdev_id'}} = $device;
2360 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
2362 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2364 my $devices_list = vm_devices_list
($vmid);
2365 return 1 if defined($devices_list->{$deviceid});
2367 qemu_bridgeadd
($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
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);
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));
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);
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);
2408 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
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);
2419 sub vm_deviceunplug
{
2420 my ($vmid, $conf, $deviceid) = @_;
2422 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2424 my $devices_list = vm_devices_list
($vmid);
2425 return 1 if !defined($devices_list->{$deviceid});
2427 die "can't unplug bootdisk" if $conf->{bootdisk
} && $conf->{bootdisk
} eq $deviceid;
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);
2435 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2436 return undef if !qemu_devicedel
($vmid, $deviceid);
2439 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2440 return undef if !qemu_devicedel
($vmid, $deviceid);
2441 return undef if !qemu_drivedel
($vmid, $deviceid);
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);
2453 sub qemu_deviceadd
{
2454 my ($vmid, $devicefull) = @_;
2456 my $ret = vm_human_monitor_command
($vmid, "device_add $devicefull");
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");
2465 sub qemu_devicedel
{
2466 my($vmid, $deviceid) = @_;
2468 my $ret = vm_human_monitor_command
($vmid, "device_del $deviceid");
2470 return 1 if $ret eq "";
2471 syslog
("err", "detaching device $deviceid failed : $ret");
2476 my($storecfg, $vmid, $device) = @_;
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");
2489 my($vmid, $deviceid) = @_;
2491 my $ret = vm_human_monitor_command
($vmid, "drive_del drive-$deviceid");
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
2496 elsif ($ret ne "") {
2497 syslog
("err", "deleting drive $deviceid failed : $ret");
2503 sub qemu_deviceaddverify
{
2504 my ($vmid,$deviceid) = @_;
2506 for (my $i = 0; $i <= 5; $i++) {
2507 my $devices_list = vm_devices_list
($vmid);
2508 return 1 if defined($devices_list->{$deviceid});
2511 syslog
("err", "error on hotplug device $deviceid");
2516 sub qemu_devicedelverify
{
2517 my ($vmid,$deviceid) = @_;
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});
2525 syslog
("err", "error on hot-unplugging device $deviceid");
2529 sub qemu_findorcreatescsihw
{
2530 my ($storecfg, $conf, $vmid, $device) = @_;
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);
2537 if(!defined($devices_list->{$scsihwid})) {
2538 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $scsihwid);
2543 sub qemu_bridgeadd
{
2544 my ($storecfg, $conf, $vmid, $device) = @_;
2547 my $bridgeid = undef;
2548 print_pci_addr
($device, $bridges);
2550 while (my ($k, $v) = each %$bridges) {
2553 return if $bridgeid < 1;
2554 my $bridge = "pci.$bridgeid";
2555 my $devices_list = vm_devices_list
($vmid);
2557 if(!defined($devices_list->{$bridge})) {
2558 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $bridge);
2563 sub qemu_netdevadd
{
2564 my ($vmid, $conf, $device, $deviceid) = @_;
2566 my $netdev = print_netdev_full
($vmid, $conf, $device, $deviceid);
2567 my $ret = vm_human_monitor_command
($vmid, "netdev_add $netdev");
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");
2576 sub qemu_netdevdel
{
2577 my ($vmid, $deviceid) = @_;
2579 my $ret = vm_human_monitor_command
($vmid, "netdev_del $deviceid");
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");
2587 sub qemu_block_set_io_throttle
{
2588 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2590 return if !check_running
($vmid) ;
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;
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));
2603 # old code, only used to shutdown old VM after update
2605 my ($fh, $timeout) = @_;
2607 my $sel = new IO
::Select
;
2614 while (scalar (@ready = $sel->can_read($timeout))) {
2616 if ($count = $fh->sysread($buf, 8192)) {
2617 if ($buf =~ /^(.*)\(qemu\) $/s) {
2624 if (!defined($count)) {
2631 die "monitor read timeout\n" if !scalar(@ready);
2636 # old code, only used to shutdown old VM after update
2637 sub vm_monitor_command
{
2638 my ($vmid, $cmdstr, $nocheck) = @_;
2643 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2645 my $sname = "${var_run_tmpdir}/$vmid.mon";
2647 my $sock = IO
::Socket
::UNIX-
>new( Peer
=> $sname ) ||
2648 die "unable to connect to VM $vmid socket - $!\n";
2652 # hack: migrate sometime blocks the monitor (when migrate_downtime
2654 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2655 $timeout = 60*60; # 1 hour
2659 my $data = __read_avail
($sock, $timeout);
2661 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2662 die "got unexpected qemu monitor banner\n";
2665 my $sel = new IO
::Select
;
2668 if (!scalar(my @ready = $sel->can_write($timeout))) {
2669 die "monitor write error - timeout";
2672 my $fullcmd = "$cmdstr\r";
2674 # syslog('info', "VM $vmid monitor command: $cmdstr");
2677 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2678 die "monitor write error - $!";
2681 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
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
2690 if ($res = __read_avail
($sock, $timeout)) {
2692 my @lines = split("\r?\n", $res);
2694 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
2696 $res = join("\n", @lines);
2704 syslog
("err", "VM $vmid monitor command failed - $err");
2711 sub qemu_block_resize
{
2712 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2714 my $running = PVE
::QemuServer
::check_running
($vmid);
2716 return if !PVE
::Storage
::volume_resize
($storecfg, $volid, $size, $running);
2718 return if !$running;
2720 vm_mon_cmd
($vmid, "block_resize", device
=> $deviceid, size
=> int($size));
2725 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom) = @_;
2727 lock_config
($vmid, sub {
2728 my $conf = load_config
($vmid, $migratedfrom);
2730 check_lock
($conf) if !$skiplock;
2732 die "VM $vmid already running\n" if check_running
($vmid, undef, $migratedfrom);
2735 my $migrate_port = 0;
2738 if ($statefile eq 'tcp') {
2739 $migrate_port = next_migrate_port
();
2740 $migrate_uri = "tcp:localhost:${migrate_port}";
2742 if (-f
$statefile) {
2743 $migrate_uri = "exec:cat $statefile";
2745 warn "state file '$statefile' does not exist - doing normal startup\n";
2750 my $defaults = load_defaults
();
2752 # set environment variable useful inside network script
2753 $ENV{PVE_MIGRATED_FROM
} = $migratedfrom if $migratedfrom;
2755 my ($cmd, $vollist) = config_to_command
($storecfg, $vmid, $conf, $defaults, $migrate_uri);
2757 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2758 my $d = parse_hostpci
($conf->{"hostpci$i"});
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);
2767 PVE
::Storage
::activate_volumes
($storecfg, $vollist);
2769 eval { run_command
($cmd, timeout
=> $migrate_uri ?
undef : 30); };
2771 die "start failed: $err" if $err;
2775 if ($statefile eq 'tcp') {
2776 print "migration listens on port $migrate_port\n";
2779 # fixme: send resume - is that necessary ?
2780 eval { vm_mon_cmd
($vmid, "cont"); };
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;
2790 vm_mon_cmd
($vmid, "migrate_set_speed", value
=> $migrate_speed);
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); };
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]); };
2806 vm_balloonset
($vmid, $conf->{balloon
}) if $conf->{balloon
};
2812 my ($vmid, $execute, %params) = @_;
2814 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2815 vm_qmp_command
($vmid, $cmd);
2818 sub vm_mon_cmd_nocheck
{
2819 my ($vmid, $execute, %params) = @_;
2821 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2822 vm_qmp_command
($vmid, $cmd, 1);
2825 sub vm_qmp_command
{
2826 my ($vmid, $cmd, $nocheck) = @_;
2831 if ($cmd->{arguments
} && $cmd->{arguments
}->{timeout
}) {
2832 $timeout = $cmd->{arguments
}->{timeout
};
2833 delete $cmd->{arguments
}->{timeout
};
2837 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2838 my $sname = PVE
::QemuServer
::qmp_socket
($vmid);
2840 my $qmpclient = PVE
::QMPClient-
>new();
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);
2848 die "unable to open monitor socket\n";
2852 syslog
("err", "VM $vmid qmp command failed - $err");
2859 sub vm_human_monitor_command
{
2860 my ($vmid, $cmdline) = @_;
2865 execute
=> 'human-monitor-command',
2866 arguments
=> { 'command-line' => $cmdline},
2869 return vm_qmp_command
($vmid, $cmd);
2872 sub vm_commandline
{
2873 my ($storecfg, $vmid) = @_;
2875 my $conf = load_config
($vmid);
2877 my $defaults = load_defaults
();
2879 my $cmd = config_to_command
($storecfg, $vmid, $conf, $defaults);
2881 return join(' ', @$cmd);
2885 my ($vmid, $skiplock) = @_;
2887 lock_config
($vmid, sub {
2889 my $conf = load_config
($vmid);
2891 check_lock
($conf) if !$skiplock;
2893 vm_mon_cmd
($vmid, "system_reset");
2897 sub get_vm_volumes
{
2901 foreach_drive
($conf, sub {
2902 my ($ds, $drive) = @_;
2904 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
}, 1);
2907 my $volid = $drive->{file
};
2908 return if !$volid || $volid =~ m
|^/|;
2910 push @$vollist, $volid;
2916 sub vm_stop_cleanup
{
2917 my ($storecfg, $vmid, $conf, $keepActive) = @_;
2920 fairsched_rmnod
($vmid); # try to destroy group
2923 my $vollist = get_vm_volumes
($conf);
2924 PVE
::Storage
::deactivate_volumes
($storecfg, $vollist);
2927 foreach my $ext (qw(mon qmp pid vnc)) {
2928 unlink "/var/run/qemu-server/${vmid}.$ext";
2931 warn $@ if $@; # avoid errors - just warn
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
2938 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
2940 $force = 1 if !defined($force) && !$shutdown;
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);
2950 lock_config
($vmid, sub {
2952 my $pid = check_running
($vmid, $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
};
2965 $timeout = 60 if !defined($timeout);
2969 $nocheck ? vm_mon_cmd_nocheck
($vmid, "system_powerdown") : vm_mon_cmd
($vmid, "system_powerdown");
2972 $nocheck ? vm_mon_cmd_nocheck
($vmid, "quit") : vm_mon_cmd
($vmid, "quit");
2979 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
2984 if ($count >= $timeout) {
2986 warn "VM still running - terminating now with SIGTERM\n";
2989 die "VM quit/powerdown failed - got timeout\n";
2992 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
2997 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3000 die "VM quit/powerdown failed\n";
3008 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3013 if ($count >= $timeout) {
3014 warn "VM still running - terminating now with SIGKILL\n";
3019 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3024 my ($vmid, $skiplock) = @_;
3026 lock_config
($vmid, sub {
3028 my $conf = load_config
($vmid);
3030 check_lock
($conf) if !$skiplock;
3032 vm_mon_cmd
($vmid, "stop");
3037 my ($vmid, $skiplock) = @_;
3039 lock_config
($vmid, sub {
3041 my $conf = load_config
($vmid);
3043 check_lock
($conf) if !$skiplock;
3045 vm_mon_cmd
($vmid, "cont");
3050 my ($vmid, $skiplock, $key) = @_;
3052 lock_config
($vmid, sub {
3054 my $conf = load_config
($vmid);
3056 # there is no qmp command, so we use the human monitor command
3057 vm_human_monitor_command
($vmid, "sendkey $key");
3062 my ($storecfg, $vmid, $skiplock) = @_;
3064 lock_config
($vmid, sub {
3066 my $conf = load_config
($vmid);
3068 check_lock
($conf) if !$skiplock;
3070 if (!check_running
($vmid)) {
3071 fairsched_rmnod
($vmid); # try to destroy group
3072 destroy_vm
($storecfg, $vmid);
3074 die "VM $vmid is running - destroy failed\n";
3082 my ($filename, $buf) = @_;
3084 my $fh = IO
::File-
>new($filename, "w");
3085 return undef if !$fh;
3087 my $res = print $fh $buf;
3094 sub pci_device_info
{
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);
3102 my $irq = file_read_firstline
("$pcisysfs/devices/$name/irq");
3103 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3105 my $vendor = file_read_firstline
("$pcisysfs/devices/$name/vendor");
3106 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3108 my $product = file_read_firstline
("$pcisysfs/devices/$name/device");
3109 return undef if !defined($product) || $product !~ s/^0x//;
3114 product
=> $product,
3120 has_fl_reset
=> -f
"$pcisysfs/devices/$name/reset" || 0,
3129 my $name = $dev->{name
};
3131 my $fn = "$pcisysfs/devices/$name/reset";
3133 return file_write
($fn, "1");
3136 sub pci_dev_bind_to_stub
{
3139 my $name = $dev->{name
};
3141 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3142 return 1 if -d
$testdir;
3144 my $data = "$dev->{vendor} $dev->{product}";
3145 return undef if !file_write
("$pcisysfs/drivers/pci-stub/new_id", $data);
3147 my $fn = "$pcisysfs/devices/$name/driver/unbind";
3148 if (!file_write
($fn, $name)) {
3149 return undef if -f
$fn;
3152 $fn = "$pcisysfs/drivers/pci-stub/bind";
3153 if (! -d
$testdir) {
3154 return undef if !file_write
($fn, $name);
3160 sub print_pci_addr
{
3161 my ($id, $bridges) = @_;
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 },
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;
3238 my ($vmid, $value) = @_;
3240 vm_mon_cmd
($vmid, "balloon", value
=> $value);
3243 # vzdump restore implementaion
3245 sub archive_read_firstfile
{
3246 my $archive = shift;
3248 die "ERROR: file '$archive' does not exist\n" if ! -f
$archive;
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
>;
3257 die "ERROR: archive contaions no data\n" if !$firstfile;
3263 sub restore_cleanup
{
3264 my $statfile = shift;
3266 print STDERR
"starting cleanup\n";
3268 if (my $fd = IO
::File-
>new($statfile, "r")) {
3269 while (defined(my $line = <$fd>)) {
3270 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3273 if ($volid =~ m
|^/|) {
3274 unlink $volid || die 'unlink failed\n';
3276 my $cfg = cfs_read_file
('storage.cfg');
3277 PVE
::Storage
::vdisk_free
($cfg, $volid);
3279 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
3281 print STDERR
"unable to cleanup '$volid' - $@" if $@;
3283 print STDERR
"unable to parse line in statfile - $line";
3290 sub restore_archive
{
3291 my ($archive, $vmid, $user, $opts) = @_;
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';
3299 my $tocmd = "/usr/lib/qemu-server/qmextract";
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
};
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");
3311 my $tmpdir = "/var/tmp/vzdumptmp$$";
3314 local $ENV{VZDUMP_TMPDIR
} = $tmpdir;
3315 local $ENV{VZDUMP_VMID
} = $vmid;
3316 local $ENV{VZDUMP_USER
} = $user;
3318 my $conffile = PVE
::QemuServer
::config_file
($vmid);
3319 my $tmpfn = "$conffile.$$.tmp";
3321 # disable interrupts (always do cleanups)
3322 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
3323 print STDERR
"got interrupt - ignored\n";
3328 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
3329 die "interrupted by signal\n";
3332 if ($archive eq '-') {
3333 print "extracting archive from STDIN\n";
3334 run_command
($cmd, input
=> "<&STDIN");
3336 print "extracting archive '$archive'\n";
3340 return if $opts->{info
};
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;
3350 print STDERR
"unable to parse line in statfile - $line\n";
3356 my $confsrc = "$tmpdir/qemu-server.conf";
3358 my $srcfd = new IO
::File
($confsrc, "r") ||
3359 die "unable to open file '$confsrc'\n";
3361 my $outfd = new IO
::File
($tmpfn, "w") ||
3362 die "unable to write config for VM $vmid\n";
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+:/;
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
};
3379 bridge
=> "vmbr$ind",
3380 macaddr
=> $macaddr,
3382 my $netstr = print_net
($net);
3383 print $outfd "net${netcount}: $netstr\n";
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*$/) {
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";
3419 restore_cleanup
("$tmpdir/qmrestore.stat") if !$opts->{info
};
3426 rename $tmpfn, $conffile ||
3427 die "unable to commit configuration file '$conffile'\n";