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
=> "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
224 enum
=> [qw(other wxp w2k w2k3 w2k8 wvista win7 l24 l26)],
225 description
=> <<EODESC,
226 Used to enable special optimization/features for specific
229 other => unspecified OS
230 wxp => Microsoft Windows XP
231 w2k => Microsoft Windows 2000
232 w2k3 => Microsoft Windows 2003
233 w2k8 => Microsoft Windows 2008
234 wvista => Microsoft Windows Vista
235 win7 => Microsoft Windows 7
236 l24 => Linux 2.4 Kernel
237 l26 => Linux 2.6/3.X Kernel
239 other|l24|l26 ... no special behaviour
240 wxp|w2k|w2k3|w2k8|wvista|win7 ... use --localtime switch
246 description
=> "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
247 pattern
=> '[acdn]{1,4}',
252 type
=> 'string', format
=> 'pve-qm-bootdisk',
253 description
=> "Enable booting from specified disk.",
254 pattern
=> '(ide|scsi|virtio)\d+',
259 description
=> "The number of CPUs. Please use option -sockets instead.",
266 description
=> "The number of CPU sockets.",
273 description
=> "The number of cores per socket.",
280 description
=> "Enable/disable ACPI.",
286 description
=> "Enable/disable KVM hardware virtualization.",
292 description
=> "Enable/disable time drift fix. This is ignored for kvm versions newer that 1.0 (not needed anymore).",
298 description
=> "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
303 description
=> "Freeze CPU at startup (use 'c' monitor command to start execution).",
308 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",
309 enum
=> [qw(std cirrus vmware)],
313 type
=> 'string', format
=> 'pve-qm-watchdog',
314 typetext
=> '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
315 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)",
320 typetext
=> "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
321 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'.",
322 pattern
=> '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
327 type
=> 'string', format
=> 'pve-qm-startup',
328 typetext
=> '[[order=]\d+] [,up=\d+] [,down=\d+] ',
329 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.",
334 description
=> <<EODESCR,
335 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
337 args: -no-reboot -no-hpet
344 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.",
349 description
=> "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
353 migrate_downtime
=> {
356 description
=> "Set maximum tolerated downtime (in seconds) for migrations.",
362 type
=> 'string', format
=> 'pve-qm-drive',
363 typetext
=> 'volume',
364 description
=> "This is an alias for option -ide2",
368 description
=> "Emulated CPU type.",
370 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) ],
375 # what about other qemu settings ?
377 #machine => 'string',
390 ##soundhw => 'string',
392 while (my ($k, $v) = each %$confdesc) {
393 PVE
::JSONSchema
::register_standard_option
("pve-qm-$k", $v);
396 my $MAX_IDE_DISKS = 4;
397 my $MAX_SCSI_DISKS = 14;
398 my $MAX_VIRTIO_DISKS = 6;
399 my $MAX_SATA_DISKS = 6;
400 my $MAX_USB_DEVICES = 5;
402 my $MAX_UNUSED_DISKS = 8;
403 my $MAX_HOSTPCI_DEVICES = 2;
404 my $MAX_SERIAL_PORTS = 4;
405 my $MAX_PARALLEL_PORTS = 3;
407 my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
408 'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
409 my $nic_model_list_txt = join(' ', sort @$nic_model_list);
414 type
=> 'string', format
=> 'pve-qm-net',
415 typetext
=> "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>][,tag=<vlanid>]",
416 description
=> <<EODESCR,
417 Specify network devices.
419 MODEL is one of: $nic_model_list_txt
421 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
422 automatically generated if not specified.
424 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
426 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'.
428 If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
434 The DHCP server assign addresses to the guest starting from 10.0.2.15.
438 PVE
::JSONSchema
::register_standard_option
("pve-qm-net", $netdesc);
440 for (my $i = 0; $i < $MAX_NETS; $i++) {
441 $confdesc->{"net$i"} = $netdesc;
448 type
=> 'string', format
=> 'pve-qm-drive',
449 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]',
450 description
=> "Use volume as IDE hard disk or CD-ROM (n is 0 to 3).",
452 PVE
::JSONSchema
::register_standard_option
("pve-qm-ide", $idedesc);
456 type
=> 'string', format
=> 'pve-qm-drive',
457 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]',
458 description
=> "Use volume as SCSI hard disk or CD-ROM (n is 0 to 13).",
460 PVE
::JSONSchema
::register_standard_option
("pve-qm-scsi", $scsidesc);
464 type
=> 'string', format
=> 'pve-qm-drive',
465 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]',
466 description
=> "Use volume as SATA hard disk or CD-ROM (n is 0 to 5).",
468 PVE
::JSONSchema
::register_standard_option
("pve-qm-sata", $satadesc);
472 type
=> 'string', format
=> 'pve-qm-drive',
473 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]',
474 description
=> "Use volume as VIRTIO hard disk (n is 0 to 5).",
476 PVE
::JSONSchema
::register_standard_option
("pve-qm-virtio", $virtiodesc);
480 type
=> 'string', format
=> 'pve-qm-usb-device',
481 typetext
=> 'host=HOSTUSBDEVICE',
482 description
=> <<EODESCR,
483 Configure an USB device (n is 0 to 4). This can be used to
484 pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
486 'bus-port(.port)*' (decimal numbers) or
487 'vendor_id:product_id' (hexadeciaml numbers)
489 You can use the 'lsusb -t' command to list existing usb devices.
491 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
495 PVE
::JSONSchema
::register_standard_option
("pve-qm-usb", $usbdesc);
499 type
=> 'string', format
=> 'pve-qm-hostpci',
500 typetext
=> "HOSTPCIDEVICE",
501 description
=> <<EODESCR,
502 Map host pci devices. HOSTPCIDEVICE syntax is:
504 'bus:dev.func' (hexadecimal numbers)
506 You can us the 'lspci' command to list existing pci devices.
508 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
510 Experimental: user reported problems with this option.
513 PVE
::JSONSchema
::register_standard_option
("pve-qm-hostpci", $hostpcidesc);
518 pattern
=> '/dev/ttyS\d+',
519 description
=> <<EODESCR,
520 Map host serial devices (n is 0 to 3).
522 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
524 Experimental: user reported problems with this option.
531 pattern
=> '/dev/parport\d+',
532 description
=> <<EODESCR,
533 Map host parallel devices (n is 0 to 2).
535 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
537 Experimental: user reported problems with this option.
541 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
542 $confdesc->{"parallel$i"} = $paralleldesc;
545 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
546 $confdesc->{"serial$i"} = $serialdesc;
549 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
550 $confdesc->{"hostpci$i"} = $hostpcidesc;
553 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
554 $drivename_hash->{"ide$i"} = 1;
555 $confdesc->{"ide$i"} = $idedesc;
558 for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
559 $drivename_hash->{"sata$i"} = 1;
560 $confdesc->{"sata$i"} = $satadesc;
563 for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
564 $drivename_hash->{"scsi$i"} = 1;
565 $confdesc->{"scsi$i"} = $scsidesc ;
568 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
569 $drivename_hash->{"virtio$i"} = 1;
570 $confdesc->{"virtio$i"} = $virtiodesc;
573 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
574 $confdesc->{"usb$i"} = $usbdesc;
579 type
=> 'string', format
=> 'pve-volume-id',
580 description
=> "Reference to unused volumes.",
583 for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
584 $confdesc->{"unused$i"} = $unuseddesc;
587 my $kvm_api_version = 0;
591 return $kvm_api_version if $kvm_api_version;
593 my $fh = IO
::File-
>new("</dev/kvm") ||
596 if (my $v = $fh->ioctl(KVM_GET_API_VERSION
(), 0)) {
597 $kvm_api_version = $v;
602 return $kvm_api_version;
605 my $kvm_user_version;
607 sub kvm_user_version
{
609 return $kvm_user_version if $kvm_user_version;
611 $kvm_user_version = 'unknown';
613 my $tmp = `kvm -help 2>/dev/null`;
615 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?) /) {
616 $kvm_user_version = $2;
619 return $kvm_user_version;
623 my $kernel_has_vhost_net = -c
'/dev/vhost-net';
626 # order is important - used to autoselect boot disk
627 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
628 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
629 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
630 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
633 sub valid_drivename
{
636 return defined($drivename_hash->{$dev});
641 return defined($confdesc->{$key});
645 return $nic_model_list;
648 sub os_list_description
{
653 w2k
=> 'Windows 2000',
654 w2k3
=>, 'Windows 2003',
655 w2k8
=> 'Windows 2008',
656 wvista
=> 'Windows Vista',
663 sub disk_devive_info
{
666 die "unknown disk device format '$dev'" if $dev !~ m/^(ide|scsi|virtio)(\d+)$/;
674 } elsif ($bus eq 'scsi') {
678 my $controller = int($index / $maxdev);
679 my $unit = $index % $maxdev;
682 return { bus
=> $bus, desc
=> uc($bus) . " $controller:$unit",
683 controller
=> $controller, unit
=> $unit, index => $index };
687 sub qemu_drive_name
{
688 my ($dev, $media) = @_;
690 my $info = disk_devive_info
($dev);
693 if (($info->{bus
} eq 'ide') || ($info->{bus
} eq 'scsi')) {
694 $mediastr = ($media eq 'cdrom') ?
"-cd" : "-hd";
695 return sprintf("%s%i%s%i", $info->{bus
}, $info->{controller
},
696 $mediastr, $info->{unit
});
698 return sprintf("%s%i", $info->{bus
}, $info->{index});
706 return $cdrom_path if $cdrom_path;
708 return $cdrom_path = "/dev/cdrom" if -l
"/dev/cdrom";
709 return $cdrom_path = "/dev/cdrom1" if -l
"/dev/cdrom1";
710 return $cdrom_path = "/dev/cdrom2" if -l
"/dev/cdrom2";
714 my ($storecfg, $vmid, $cdrom) = @_;
716 if ($cdrom eq 'cdrom') {
717 return get_cdrom_path
();
718 } elsif ($cdrom eq 'none') {
720 } elsif ($cdrom =~ m
|^/|) {
723 return PVE
::Storage
::path
($storecfg, $cdrom);
727 # try to convert old style file names to volume IDs
728 sub filename_to_volume_id
{
729 my ($vmid, $file, $media) = @_;
731 if (!($file eq 'none' || $file eq 'cdrom' ||
732 $file =~ m
|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
734 return undef if $file =~ m
|/|;
736 if ($media && $media eq 'cdrom') {
737 $file = "local:iso/$file";
739 $file = "local:$vmid/$file";
746 sub verify_media_type
{
747 my ($opt, $vtype, $media) = @_;
752 if ($media eq 'disk') {
754 } elsif ($media eq 'cdrom') {
757 die "internal error";
760 return if ($vtype eq $etype);
762 raise_param_exc
({ $opt => "unexpected media type ($vtype != $etype)" });
765 sub cleanup_drive_path
{
766 my ($opt, $storecfg, $drive) = @_;
768 # try to convert filesystem paths to volume IDs
770 if (($drive->{file
} !~ m/^(cdrom|none)$/) &&
771 ($drive->{file
} !~ m
|^/dev/.+|) &&
772 ($drive->{file
} !~ m/^([^:]+):(.+)$/) &&
773 ($drive->{file
} !~ m/^\d+$/)) {
774 my ($vtype, $volid) = PVE
::Storage
::path_to_volume_id
($storecfg, $drive->{file
});
775 raise_param_exc
({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
776 $drive->{media
} = 'cdrom' if !$drive->{media
} && $vtype eq 'iso';
777 verify_media_type
($opt, $vtype, $drive->{media
});
778 $drive->{file
} = $volid;
781 $drive->{media
} = 'cdrom' if !$drive->{media
} && $drive->{file
} =~ m/^(cdrom|none)$/;
784 sub create_conf_nolock
{
785 my ($vmid, $settings) = @_;
787 my $filename = config_file
($vmid);
789 die "configuration file '$filename' already exists\n" if -f
$filename;
791 my $defaults = load_defaults
();
793 $settings->{name
} = "vm$vmid" if !$settings->{name
};
794 $settings->{memory
} = $defaults->{memory
} if !$settings->{memory
};
797 foreach my $opt (keys %$settings) {
798 next if !$confdesc->{$opt};
800 my $value = $settings->{$opt};
803 $data .= "$opt: $value\n";
806 PVE
::Tools
::file_set_contents
($filename, $data);
809 # ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
810 # [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
811 # [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
812 # [,aio=native|threads]
815 my ($key, $data) = @_;
819 # $key may be undefined - used to verify JSON parameters
820 if (!defined($key)) {
821 $res->{interface
} = 'unknown'; # should not harm when used to verify parameters
823 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
824 $res->{interface
} = $1;
830 foreach my $p (split (/,/, $data)) {
831 next if $p =~ m/^\s*$/;
833 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)=(.+)$/) {
834 my ($k, $v) = ($1, $2);
836 $k = 'file' if $k eq 'volume';
838 return undef if defined $res->{$k};
842 if (!$res->{file
} && $p !~ m/=/) {
850 return undef if !$res->{file
};
852 return undef if $res->{cache
} &&
853 $res->{cache
} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
854 return undef if $res->{snapshot
} && $res->{snapshot
} !~ m/^(on|off)$/;
855 return undef if $res->{cyls
} && $res->{cyls
} !~ m/^\d+$/;
856 return undef if $res->{heads
} && $res->{heads
} !~ m/^\d+$/;
857 return undef if $res->{secs
} && $res->{secs
} !~ m/^\d+$/;
858 return undef if $res->{media
} && $res->{media
} !~ m/^(disk|cdrom)$/;
859 return undef if $res->{trans
} && $res->{trans
} !~ m/^(none|lba|auto)$/;
860 return undef if $res->{format
} && $res->{format
} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
861 return undef if $res->{rerror
} && $res->{rerror
} !~ m/^(ignore|report|stop)$/;
862 return undef if $res->{werror
} && $res->{werror
} !~ m/^(enospc|ignore|report|stop)$/;
863 return undef if $res->{backup
} && $res->{backup
} !~ m/^(yes|no)$/;
864 return undef if $res->{aio
} && $res->{aio
} !~ m/^(native|threads)$/;
866 return undef if $res->{bps_rd
} && $res->{bps
};
867 return undef if $res->{bps_wr
} && $res->{bps
};
868 return undef if $res->{iops_rd
} && $res->{iops
};
869 return undef if $res->{iops_wr
} && $res->{iops
};
871 return undef if $res->{bps
} && $res->{bps
} !~ m/^\d+$/;
872 return undef if $res->{bps_rd
} && $res->{bps_rd
} !~ m/^\d+$/;
873 return undef if $res->{bps_wr
} && $res->{bps_wr
} !~ m/^\d+$/;
874 return undef if $res->{iops
} && $res->{iops
} !~ m/^\d+$/;
875 return undef if $res->{iops_rd
} && $res->{iops_rd
} !~ m/^\d+$/;
876 return undef if $res->{iops_wr
} && $res->{iops_wr
} !~ m/^\d+$/;
879 if ($res->{media
} && ($res->{media
} eq 'cdrom')) {
880 return undef if $res->{snapshot
} || $res->{trans
} || $res->{format
};
881 return undef if $res->{heads
} || $res->{secs
} || $res->{cyls
};
882 return undef if $res->{interface
} eq 'virtio';
885 # rerror does not work with scsi drives
886 if ($res->{rerror
}) {
887 return undef if $res->{interface
} eq 'scsi';
893 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);
896 my ($vmid, $drive) = @_;
899 foreach my $o (@qemu_drive_options, 'backup') {
900 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
903 return "$drive->{file}$opts";
907 my($fh, $noerr) = @_;
910 my $SG_GET_VERSION_NUM = 0x2282;
912 my $versionbuf = "\x00" x
8;
913 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
915 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
918 my $version = unpack("I", $versionbuf);
919 if ($version < 30000) {
920 die "scsi generic interface too old\n" if !$noerr;
924 my $buf = "\x00" x
36;
925 my $sensebuf = "\x00" x
8;
926 my $cmd = pack("C x3 C x11", 0x12, 36);
928 # see /usr/include/scsi/sg.h
929 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";
931 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
932 length($sensebuf), 0, length($buf), $buf,
933 $cmd, $sensebuf, 6000);
935 $ret = ioctl($fh, $SG_IO, $packet);
937 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
941 my @res = unpack($sg_io_hdr_t, $packet);
942 if ($res[17] || $res[18]) {
943 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
948 ($res->{device
}, $res->{removable
}, $res->{venodor
},
949 $res->{product
}, $res->{revision
}) = unpack("C C x6 A8 A16 A4", $buf);
957 my $fh = IO
::File-
>new("+<$path") || return undef;
958 my $res = scsi_inquiry
($fh, 1);
964 sub print_drivedevice_full
{
965 my ($storecfg, $vmid, $drive) = @_;
970 if ($drive->{interface
} eq 'virtio') {
971 my $pciaddr = print_pci_addr
("$drive->{interface}$drive->{index}");
972 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
973 } elsif ($drive->{interface
} eq 'scsi') {
975 my $controller = int($drive->{index} / $maxdev);
976 my $unit = $drive->{index} % $maxdev;
977 my $devicetype = 'hd';
979 if (drive_is_cdrom
($drive)) {
982 if ($drive->{file
} =~ m
|^/|) {
983 $path = $drive->{file
};
985 $path = PVE
::Storage
::path
($storecfg, $drive->{file
});
987 $devicetype = 'block' if path_is_scsi
($path);
990 $device = "scsi-$devicetype,bus=lsi$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
991 } elsif ($drive->{interface
} eq 'ide'){
993 my $controller = int($drive->{index} / $maxdev);
994 my $unit = $drive->{index} % $maxdev;
995 my $devicetype = ($drive->{media
} && $drive->{media
} eq 'cdrom') ?
"cd" : "hd";
997 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
998 } elsif ($drive->{interface
} eq 'sata'){
999 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1000 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1001 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1002 } elsif ($drive->{interface
} eq 'usb') {
1004 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1006 die "unsupported interface type";
1009 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex
};
1014 sub print_drive_full
{
1015 my ($storecfg, $vmid, $drive) = @_;
1018 foreach my $o (@qemu_drive_options) {
1019 next if $o eq 'bootindex';
1020 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1023 # use linux-aio by default (qemu default is threads)
1024 $opts .= ",aio=native" if !$drive->{aio
};
1027 my $volid = $drive->{file
};
1028 if (drive_is_cdrom
($drive)) {
1029 $path = get_iso_path
($storecfg, $vmid, $volid);
1031 if ($volid =~ m
|^/|) {
1034 $path = PVE
::Storage
::path
($storecfg, $volid);
1036 if (!$drive->{cache
} && ($path =~ m
|^/dev/| || $path =~ m
|\
.raw
$|)) {
1037 $opts .= ",cache=none";
1041 my $pathinfo = $path ?
"file=$path," : '';
1043 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1046 sub print_netdevice_full
{
1047 my ($vmid, $conf, $net, $netid) = @_;
1049 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
1051 my $device = $net->{model
};
1052 if ($net->{model
} eq 'virtio') {
1053 $device = 'virtio-net-pci';
1056 # qemu > 0.15 always try to boot from network - we disable that by
1057 # not loading the pxe rom file
1058 my $extra = ($bootorder !~ m/n/) ?
"romfile=," : '';
1059 my $pciaddr = print_pci_addr
("$netid");
1060 my $tmpstr = "$device,${extra}mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1061 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex
} ;
1065 sub print_netdev_full
{
1066 my ($vmid, $conf, $net, $netid) = @_;
1069 if ($netid =~ m/^net(\d+)$/) {
1073 die "got strange net id '$i'\n" if $i >= ${MAX_NETS
};
1075 my $ifname = "tap${vmid}i$i";
1077 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1078 die "interface name '$ifname' is too long (max 15 character)\n"
1079 if length($ifname) >= 16;
1081 my $vhostparam = '';
1082 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model
} eq 'virtio';
1084 my $vmname = $conf->{name
} || "vm$vmid";
1086 if ($net->{bridge
}) {
1087 return "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
1089 return "type=user,id=$netid,hostname=$vmname";
1093 sub drive_is_cdrom
{
1096 return $drive && $drive->{media
} && ($drive->{media
} eq 'cdrom');
1103 return undef if !$value;
1107 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
1108 $res->{pciid
} = $value;
1116 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1122 foreach my $kvp (split(/,/, $data)) {
1124 if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
1126 my $mac = uc($3) || PVE
::Tools
::random_ether_addr
();
1127 $res->{model
} = $model;
1128 $res->{macaddr
} = $mac;
1129 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1130 $res->{bridge
} = $1;
1131 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1133 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1141 return undef if !$res->{model
};
1149 my $res = "$net->{model}";
1150 $res .= "=$net->{macaddr}" if $net->{macaddr
};
1151 $res .= ",bridge=$net->{bridge}" if $net->{bridge
};
1152 $res .= ",rate=$net->{rate}" if $net->{rate
};
1153 $res .= ",tag=$net->{tag}" if $net->{tag
};
1158 sub add_random_macs
{
1159 my ($settings) = @_;
1161 foreach my $opt (keys %$settings) {
1162 next if $opt !~ m/^net(\d+)$/;
1163 my $net = parse_net
($settings->{$opt});
1165 $settings->{$opt} = print_net
($net);
1169 sub add_unused_volume
{
1170 my ($config, $volid) = @_;
1173 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1174 my $test = "unused$ind";
1175 if (my $vid = $config->{$test}) {
1176 return if $vid eq $volid; # do not add duplicates
1182 die "To many unused volume - please delete them first.\n" if !$key;
1184 $config->{$key} = $volid;
1189 # fixme: remove all thos $noerr parameters?
1191 PVE
::JSONSchema
::register_format
('pve-qm-bootdisk', \
&verify_bootdisk
);
1192 sub verify_bootdisk
{
1193 my ($value, $noerr) = @_;
1195 return $value if valid_drivename
($value);
1197 return undef if $noerr;
1199 die "invalid boot disk '$value'\n";
1202 PVE
::JSONSchema
::register_format
('pve-qm-net', \
&verify_net
);
1204 my ($value, $noerr) = @_;
1206 return $value if parse_net
($value);
1208 return undef if $noerr;
1210 die "unable to parse network options\n";
1213 PVE
::JSONSchema
::register_format
('pve-qm-drive', \
&verify_drive
);
1215 my ($value, $noerr) = @_;
1217 return $value if parse_drive
(undef, $value);
1219 return undef if $noerr;
1221 die "unable to parse drive options\n";
1224 PVE
::JSONSchema
::register_format
('pve-qm-hostpci', \
&verify_hostpci
);
1225 sub verify_hostpci
{
1226 my ($value, $noerr) = @_;
1228 return $value if parse_hostpci
($value);
1230 return undef if $noerr;
1232 die "unable to parse pci id\n";
1235 PVE
::JSONSchema
::register_format
('pve-qm-watchdog', \
&verify_watchdog
);
1236 sub verify_watchdog
{
1237 my ($value, $noerr) = @_;
1239 return $value if parse_watchdog
($value);
1241 return undef if $noerr;
1243 die "unable to parse watchdog options\n";
1246 sub parse_watchdog
{
1249 return undef if !$value;
1253 foreach my $p (split(/,/, $value)) {
1254 next if $p =~ m/^\s*$/;
1256 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1258 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1259 $res->{action
} = $2;
1268 PVE
::JSONSchema
::register_format
('pve-qm-startup', \
&verify_startup
);
1269 sub verify_startup
{
1270 my ($value, $noerr) = @_;
1272 return $value if parse_startup
($value);
1274 return undef if $noerr;
1276 die "unable to parse startup options\n";
1282 return undef if !$value;
1286 foreach my $p (split(/,/, $value)) {
1287 next if $p =~ m/^\s*$/;
1289 if ($p =~ m/^(order=)?(\d+)$/) {
1291 } elsif ($p =~ m/^up=(\d+)$/) {
1293 } elsif ($p =~ m/^down=(\d+)$/) {
1303 sub parse_usb_device
{
1306 return undef if !$value;
1308 my @dl = split(/,/, $value);
1312 foreach my $v (@dl) {
1313 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1315 $res->{vendorid
} = $2;
1316 $res->{productid
} = $4;
1317 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1319 $res->{hostbus
} = $1;
1320 $res->{hostport
} = $2;
1325 return undef if !$found;
1330 PVE
::JSONSchema
::register_format
('pve-qm-usb-device', \
&verify_usb_device
);
1331 sub verify_usb_device
{
1332 my ($value, $noerr) = @_;
1334 return $value if parse_usb_device
($value);
1336 return undef if $noerr;
1338 die "unable to parse usb device\n";
1341 # add JSON properties for create and set function
1342 sub json_config_properties
{
1345 foreach my $opt (keys %$confdesc) {
1346 $prop->{$opt} = $confdesc->{$opt};
1353 my ($key, $value) = @_;
1355 die "unknown setting '$key'\n" if !$confdesc->{$key};
1357 my $type = $confdesc->{$key}->{type
};
1359 if (!defined($value)) {
1360 die "got undefined value\n";
1363 if ($value =~ m/[\n\r]/) {
1364 die "property contains a line feed\n";
1367 if ($type eq 'boolean') {
1368 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1369 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1370 die "type check ('boolean') failed - got '$value'\n";
1371 } elsif ($type eq 'integer') {
1372 return int($1) if $value =~ m/^(\d+)$/;
1373 die "type check ('integer') failed - got '$value'\n";
1374 } elsif ($type eq 'string') {
1375 if (my $fmt = $confdesc->{$key}->{format
}) {
1376 if ($fmt eq 'pve-qm-drive') {
1377 # special case - we need to pass $key to parse_drive()
1378 my $drive = parse_drive
($key, $value);
1379 return $value if $drive;
1380 die "unable to parse drive options\n";
1382 PVE
::JSONSchema
::check_format
($fmt, $value);
1385 $value =~ s/^\"(.*)\"$/$1/;
1388 die "internal error"
1392 sub lock_config_full
{
1393 my ($vmid, $timeout, $code, @param) = @_;
1395 my $filename = config_file_lock
($vmid);
1397 my $res = lock_file
($filename, $timeout, $code, @param);
1405 my ($vmid, $code, @param) = @_;
1407 return lock_config_full
($vmid, 10, $code, @param);
1410 sub cfs_config_path
{
1411 my ($vmid, $node) = @_;
1413 $node = $nodename if !$node;
1414 return "nodes/$node/qemu-server/$vmid.conf";
1417 sub check_iommu_support
{
1418 #fixme : need to check IOMMU support
1419 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1427 my ($vmid, $node) = @_;
1429 my $cfspath = cfs_config_path
($vmid, $node);
1430 return "/etc/pve/$cfspath";
1433 sub config_file_lock
{
1436 return "$lock_dir/lock-$vmid.conf";
1442 my $conf = config_file
($vmid);
1443 utime undef, undef, $conf;
1447 my ($storecfg, $vmid, $keep_empty_config) = @_;
1449 my $conffile = config_file
($vmid);
1451 my $conf = load_config
($vmid);
1455 # only remove disks owned by this VM
1456 foreach_drive
($conf, sub {
1457 my ($ds, $drive) = @_;
1459 return if drive_is_cdrom
($drive);
1461 my $volid = $drive->{file
};
1462 return if !$volid || $volid =~ m
|^/|;
1464 my ($path, $owner) = PVE
::Storage
::path
($storecfg, $volid);
1465 return if !$path || !$owner || ($owner != $vmid);
1467 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1470 if ($keep_empty_config) {
1471 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
1476 # also remove unused disk
1478 my $dl = PVE
::Storage
::vdisk_list
($storecfg, undef, $vmid);
1481 PVE
::Storage
::foreach_volid
($dl, sub {
1482 my ($volid, $sid, $volname, $d) = @_;
1483 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1493 sub load_diskinfo_old
{
1494 my ($storecfg, $vmid, $conf) = @_;
1500 foreach_drive
($conf, sub {
1505 return if drive_is_cdrom
($di);
1507 if ($di->{file
} =~ m
|^/dev/.+|) {
1508 $info->{$di->{file
}}->{size
} = PVE
::Storage
::file_size_info
($di->{file
});
1510 push @$vollist, $di->{file
};
1515 my $dl = PVE
::Storage
::vdisk_list
($storecfg, undef, $vmid, $vollist);
1517 PVE
::Storage
::foreach_volid
($dl, sub {
1518 my ($volid, $sid, $volname, $d) = @_;
1519 $info->{$volid} = $d;
1524 foreach my $ds (keys %$res) {
1525 my $di = $res->{$ds};
1527 $res->{$ds}->{disksize
} = $info->{$di->{file
}} ?
1528 $info->{$di->{file
}}->{size
} / (1024*1024) : 0;
1537 my $cfspath = cfs_config_path
($vmid);
1539 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath);
1541 die "no such VM ('$vmid')\n" if !defined($conf);
1546 sub parse_vm_config
{
1547 my ($filename, $raw) = @_;
1549 return undef if !defined($raw);
1552 digest
=> Digest
::SHA
::sha1_hex
($raw),
1555 $filename =~ m
|/qemu-server/(\d
+)\
.conf
$|
1556 || die "got strange filename '$filename'";
1562 while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
1565 next if $line =~ m/^\s*$/;
1567 if ($line =~ m/^\#(.*)\s*$/) {
1568 $descr .= PVE
::Tools
::decode_text
($1) . "\n";
1572 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1573 $descr .= PVE
::Tools
::decode_text
($2);
1574 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1577 $res->{$key} = $value;
1578 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1581 eval { $value = check_type
($key, $value); };
1583 warn "vm $vmid - unable to parse value of '$key' - $@";
1585 my $fmt = $confdesc->{$key}->{format
};
1586 if ($fmt && $fmt eq 'pve-qm-drive') {
1587 my $v = parse_drive
($key, $value);
1588 if (my $volid = filename_to_volume_id
($vmid, $v->{file
}, $v->{media
})) {
1589 $v->{file
} = $volid;
1590 $value = print_drive
($vmid, $v);
1592 warn "vm $vmid - unable to parse value of '$key'\n";
1597 if ($key eq 'cdrom') {
1598 $res->{ide2
} = $value;
1600 $res->{$key} = $value;
1606 $res->{description
} = $descr if $descr;
1608 # convert old smp to sockets
1609 if ($res->{smp
} && !$res->{sockets
}) {
1610 $res->{sockets
} = $res->{smp
};
1617 sub write_vm_config
{
1618 my ($filename, $conf) = @_;
1620 if ($conf->{cdrom
}) {
1621 die "option ide2 conflicts with cdrom\n" if $conf->{ide2
};
1622 $conf->{ide2
} = $conf->{cdrom
};
1623 delete $conf->{cdrom
};
1626 # we do not use 'smp' any longer
1627 if ($conf->{sockets
}) {
1628 delete $conf->{smp
};
1629 } elsif ($conf->{smp
}) {
1630 $conf->{sockets
} = $conf->{smp
};
1631 delete $conf->{cores
};
1632 delete $conf->{smp
};
1635 my $new_volids = {};
1636 foreach my $key (keys %$conf) {
1637 next if $key eq 'digest' || $key eq 'description';
1638 my $value = $conf->{$key};
1639 eval { $value = check_type
($key, $value); };
1640 die "unable to parse value of '$key' - $@" if $@;
1642 $conf->{$key} = $value;
1644 if (valid_drivename
($key)) {
1645 my $drive = PVE
::QemuServer
::parse_drive
($key, $value);
1646 $new_volids->{$drive->{file
}} = 1 if $drive && $drive->{file
};
1650 # remove 'unusedX' settings if we re-add a volume
1651 foreach my $key (keys %$conf) {
1652 my $value = $conf->{$key};
1653 if ($key =~ m/^unused/ && $new_volids->{$value}) {
1654 delete $conf->{$key};
1661 # add description as comment to top of file
1662 my $descr = $conf->{description
} || '';
1663 foreach my $cl (split(/\n/, $descr)) {
1664 $raw .= '#' . PVE
::Tools
::encode_text
($cl) . "\n";
1667 foreach my $key (sort keys %$conf) {
1668 next if $key eq 'digest' || $key eq 'description';
1669 $raw .= "$key: $conf->{$key}\n";
1675 sub update_config_nolock
{
1676 my ($vmid, $conf, $skiplock) = @_;
1678 check_lock
($conf) if !$skiplock;
1680 my $cfspath = cfs_config_path
($vmid);
1682 PVE
::Cluster
::cfs_write_file
($cfspath, $conf);
1686 my ($vmid, $conf, $skiplock) = @_;
1688 lock_config
($vmid, &update_config_nolock
, $conf, $skiplock);
1695 # we use static defaults from our JSON schema configuration
1696 foreach my $key (keys %$confdesc) {
1697 if (defined(my $default = $confdesc->{$key}->{default})) {
1698 $res->{$key} = $default;
1702 my $conf = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
1703 $res->{keyboard
} = $conf->{keyboard
} if $conf->{keyboard
};
1709 my $vmlist = PVE
::Cluster
::get_vmlist
();
1711 return $res if !$vmlist || !$vmlist->{ids
};
1712 my $ids = $vmlist->{ids
};
1714 foreach my $vmid (keys %$ids) {
1715 my $d = $ids->{$vmid};
1716 next if !$d->{node
} || $d->{node
} ne $nodename;
1717 next if !$d->{type
} || $d->{type
} ne 'qemu';
1718 $res->{$vmid}->{exists} = 1;
1723 # test if VM uses local resources (to prevent migration)
1724 sub check_local_resources
{
1725 my ($conf, $noerr) = @_;
1729 $loc_res = 1 if $conf->{hostusb
}; # old syntax
1730 $loc_res = 1 if $conf->{hostpci
}; # old syntax
1732 foreach my $k (keys %$conf) {
1733 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
1736 die "VM uses local resources\n" if $loc_res && !$noerr;
1741 # check is used storages are available on all nodes (use by migrate)
1742 sub check_storage_availability
{
1743 my ($storecfg, $conf, $node) = @_;
1745 foreach_drive
($conf, sub {
1746 my ($ds, $drive) = @_;
1748 my $volid = $drive->{file
};
1751 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
1754 # check if storage is available on both nodes
1755 my $scfg = PVE
::Storage
::storage_check_node
($storecfg, $sid);
1756 PVE
::Storage
::storage_check_node
($storecfg, $sid, $node);
1763 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1767 my ($pidfile, $pid) = @_;
1769 my $fh = IO
::File-
>new("/proc/$pid/cmdline", "r");
1773 return undef if !$line;
1774 my @param = split(/\0/, $line);
1776 my $cmd = $param[0];
1777 return if !$cmd || ($cmd !~ m
|kvm
$|);
1779 for (my $i = 0; $i < scalar (@param); $i++) {
1782 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1783 my $p = $param[$i+1];
1784 return 1 if $p && ($p eq $pidfile);
1793 my ($vmid, $nocheck) = @_;
1795 my $filename = config_file
($vmid);
1797 die "unable to find configuration file for VM $vmid - no such machine\n"
1798 if !$nocheck && ! -f
$filename;
1800 my $pidfile = pidfile_name
($vmid);
1802 if (my $fd = IO
::File-
>new("<$pidfile")) {
1807 my $mtime = $st->mtime;
1808 if ($mtime > time()) {
1809 warn "file '$filename' modified in future\n";
1812 if ($line =~ m/^(\d+)$/) {
1814 if (check_cmdline
($pidfile, $pid)) {
1815 if (my $pinfo = PVE
::ProcFSTools
::check_process_running
($pid)) {
1827 my $vzlist = config_list
();
1829 my $fd = IO
::Dir-
>new($var_run_tmpdir) || return $vzlist;
1831 while (defined(my $de = $fd->read)) {
1832 next if $de !~ m/^(\d+)\.pid$/;
1834 next if !defined($vzlist->{$vmid});
1835 if (my $pid = check_running
($vmid)) {
1836 $vzlist->{$vmid}->{pid
} = $pid;
1843 my $storage_timeout_hash = {};
1846 my ($storecfg, $conf) = @_;
1848 my $bootdisk = $conf->{bootdisk
};
1849 return undef if !$bootdisk;
1850 return undef if !valid_drivename
($bootdisk);
1852 return undef if !$conf->{$bootdisk};
1854 my $drive = parse_drive
($bootdisk, $conf->{$bootdisk});
1855 return undef if !defined($drive);
1857 return undef if drive_is_cdrom
($drive);
1859 my $volid = $drive->{file
};
1860 return undef if !$volid;
1866 if ($volid =~ m
|^/|) {
1867 $path = $timeoutid = $volid;
1870 $storeid = $timeoutid = PVE
::Storage
::parse_volume_id
($volid);
1871 $path = PVE
::Storage
::path
($storecfg, $volid);
1879 my $last_timeout = $storage_timeout_hash->{$timeoutid};
1880 if ($last_timeout) {
1881 if ((time() - $last_timeout) < 30) {
1882 # skip storage with errors
1885 delete $storage_timeout_hash->{$timeoutid};
1888 my ($size, $format, $used);
1890 ($size, $format, $used) = PVE
::Storage
::file_size_info
($path, 1);
1892 if (!defined($format)) {
1894 $storage_timeout_hash->{$timeoutid} = time();
1898 return wantarray ?
($size, $used) : $size;
1901 my $last_proc_pid_stat;
1903 # get VM status information
1904 # This must be fast and should not block ($full == false)
1905 # We only query KVM using QMP if $full == true (this can be slow)
1907 my ($opt_vmid, $full) = @_;
1911 my $storecfg = PVE
::Storage
::config
();
1913 my $list = vzlist
();
1914 my ($uptime) = PVE
::ProcFSTools
::read_proc_uptime
(1);
1916 my $cpucount = $cpuinfo->{cpus
} || 1;
1918 foreach my $vmid (keys %$list) {
1919 next if $opt_vmid && ($vmid ne $opt_vmid);
1921 my $cfspath = cfs_config_path
($vmid);
1922 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath) || {};
1925 $d->{pid
} = $list->{$vmid}->{pid
};
1927 # fixme: better status?
1928 $d->{status
} = $list->{$vmid}->{pid
} ?
'running' : 'stopped';
1930 my ($size, $used) = disksize
($storecfg, $conf);
1931 if (defined($size) && defined($used)) {
1933 $d->{maxdisk
} = $size;
1939 $d->{cpus
} = ($conf->{sockets
} || 1) * ($conf->{cores
} || 1);
1940 $d->{cpus
} = $cpucount if $d->{cpus
} > $cpucount;
1942 $d->{name
} = $conf->{name
} || "VM $vmid";
1943 $d->{maxmem
} = $conf->{memory
} ?
$conf->{memory
}*(1024*1024) : 0;
1953 $d->{diskwrite
} = 0;
1958 my $netdev = PVE
::ProcFSTools
::read_proc_net_dev
();
1959 foreach my $dev (keys %$netdev) {
1960 next if $dev !~ m/^tap([1-9]\d*)i/;
1962 my $d = $res->{$vmid};
1965 $d->{netout
} += $netdev->{$dev}->{receive
};
1966 $d->{netin
} += $netdev->{$dev}->{transmit
};
1969 my $ctime = gettimeofday
;
1971 foreach my $vmid (keys %$list) {
1973 my $d = $res->{$vmid};
1974 my $pid = $d->{pid
};
1977 my $pstat = PVE
::ProcFSTools
::read_proc_pid_stat
($pid);
1978 next if !$pstat; # not running
1980 my $used = $pstat->{utime} + $pstat->{stime
};
1982 $d->{uptime
} = int(($uptime - $pstat->{starttime
})/$cpuinfo->{user_hz
});
1984 if ($pstat->{vsize
}) {
1985 $d->{mem
} = int(($pstat->{rss
}/$pstat->{vsize
})*$d->{maxmem
});
1988 my $old = $last_proc_pid_stat->{$pid};
1990 $last_proc_pid_stat->{$pid} = {
1998 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz
};
2000 if ($dtime > 1000) {
2001 my $dutime = $used - $old->{used
};
2003 $d->{cpu
} = (($dutime/$dtime)* $cpucount) / $d->{cpus
};
2004 $last_proc_pid_stat->{$pid} = {
2010 $d->{cpu
} = $old->{cpu
};
2014 return $res if !$full;
2016 my $qmpclient = PVE
::QMPClient-
>new();
2018 my $blockstatscb = sub {
2019 my ($vmid, $resp) = @_;
2020 my $data = $resp->{'return'} || [];
2021 my $totalrdbytes = 0;
2022 my $totalwrbytes = 0;
2023 for my $blockstat (@$data) {
2024 $totalrdbytes = $totalrdbytes + $blockstat->{stats
}->{rd_bytes
};
2025 $totalwrbytes = $totalwrbytes + $blockstat->{stats
}->{wr_bytes
};
2027 $res->{$vmid}->{diskread
} = $totalrdbytes;
2028 $res->{$vmid}->{diskwrite
} = $totalwrbytes;
2031 my $statuscb = sub {
2032 my ($vmid, $resp) = @_;
2033 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
2035 my $status = 'unknown';
2036 if (!defined($status = $resp->{'return'}->{status
})) {
2037 warn "unable to get VM status\n";
2041 $res->{$vmid}->{qmpstatus
} = $resp->{'return'}->{status
};
2044 foreach my $vmid (keys %$list) {
2045 next if $opt_vmid && ($vmid ne $opt_vmid);
2046 next if !$res->{$vmid}->{pid
}; # not running
2047 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2050 $qmpclient->queue_execute();
2052 foreach my $vmid (keys %$list) {
2053 next if $opt_vmid && ($vmid ne $opt_vmid);
2054 $res->{$vmid}->{qmpstatus
} = $res->{$vmid}->{status
} if !$res->{$vmid}->{qmpstatus
};
2061 my ($conf, $func) = @_;
2063 foreach my $ds (keys %$conf) {
2064 next if !valid_drivename
($ds);
2066 my $drive = parse_drive
($ds, $conf->{$ds});
2069 &$func($ds, $drive);
2073 sub config_to_command
{
2074 my ($storecfg, $vmid, $conf, $defaults, $migrate_uri) = @_;
2078 my $kvmver = kvm_user_version
();
2079 my $vernum = 0; # unknown
2080 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2081 $vernum = $1*1000000+$2*1000;
2082 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
2083 $vernum = $1*1000000+$2*1000+$3;
2086 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
2088 my $have_ovz = -f
'/proc/vz/vestat';
2090 push @$cmd, '/usr/bin/kvm';
2092 push @$cmd, '-id', $vmid;
2096 my $qmpsocket = qmp_socket
($vmid);
2097 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2098 push @$cmd, '-mon', "chardev=qmp,mode=control";
2100 my $socket = vnc_socket
($vmid);
2101 push @$cmd, '-vnc', "unix:$socket,x509,password";
2103 push @$cmd, '-pidfile' , pidfile_name
($vmid);
2105 push @$cmd, '-daemonize';
2107 push @$cmd, '-incoming', $migrate_uri if $migrate_uri;
2110 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2111 next if !$conf->{"usb$i"};
2114 # include usb device config
2115 push @$cmd, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
2117 # enable absolute mouse coordinates (needed by vnc)
2118 my $tablet = defined($conf->{tablet
}) ?
$conf->{tablet
} : $defaults->{tablet
};
2121 push @$cmd, '-device', 'usb-tablet,bus=ehci.0,port=6';
2123 push @$cmd, '-usbdevice', 'tablet';
2128 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2129 my $d = parse_hostpci
($conf->{"hostpci$i"});
2131 $pciaddr = print_pci_addr
("hostpci$i");
2132 push @$cmd, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
2136 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2137 my $d = parse_usb_device
($conf->{"usb$i"});
2139 if ($d->{vendorid
} && $d->{productid
}) {
2140 push @$cmd, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
2141 } elsif (defined($d->{hostbus
}) && defined($d->{hostport
})) {
2142 push @$cmd, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2147 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
2148 if (my $path = $conf->{"serial$i"}) {
2149 die "no such serial device\n" if ! -c
$path;
2150 push @$cmd, '-chardev', "tty,id=serial$i,path=$path";
2151 push @$cmd, '-device', "isa-serial,chardev=serial$i";
2156 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
2157 if (my $path = $conf->{"parallel$i"}) {
2158 die "no such parallel device\n" if ! -c
$path;
2159 push @$cmd, '-chardev', "parport,id=parallel$i,path=$path";
2160 push @$cmd, '-device', "isa-parallel,chardev=parallel$i";
2164 my $vmname = $conf->{name
} || "vm$vmid";
2166 push @$cmd, '-name', $vmname;
2169 $sockets = $conf->{smp
} if $conf->{smp
}; # old style - no longer iused
2170 $sockets = $conf->{sockets
} if $conf->{sockets
};
2172 my $cores = $conf->{cores
} || 1;
2174 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2176 push @$cmd, '-cpu', $conf->{cpu
} if $conf->{cpu
};
2178 push @$cmd, '-nodefaults';
2180 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
2182 my $bootindex_hash = {};
2184 foreach my $o (split(//, $bootorder)) {
2185 $bootindex_hash->{$o} = $i*100;
2189 push @$cmd, '-boot', "menu=on";
2191 push @$cmd, '-no-acpi' if defined($conf->{acpi
}) && $conf->{acpi
} == 0;
2193 push @$cmd, '-no-reboot' if defined($conf->{reboot
}) && $conf->{reboot
} == 0;
2195 my $vga = $conf->{vga
};
2197 if ($conf->{ostype
} && ($conf->{ostype
} eq 'win7' || $conf->{ostype
} eq 'w2k8')) {
2204 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2207 my $tdf = defined($conf->{tdf
}) ?
$conf->{tdf
} : $defaults->{tdf
};
2208 # ignore - no longer supported by newer kvm
2209 # push @$cmd, '-tdf' if $tdf;
2211 my $nokvm = defined($conf->{kvm
}) && $conf->{kvm
} == 0 ?
1 : 0;
2213 if (my $ost = $conf->{ostype
}) {
2214 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2216 if ($ost =~ m/^w/) { # windows
2217 push @$cmd, '-localtime' if !defined($conf->{localtime});
2219 # use rtc-td-hack when acpi is enabled
2220 if (!(defined($conf->{acpi
}) && $conf->{acpi
} == 0)) {
2221 push @$cmd, '-rtc-td-hack';
2225 if ($ost eq 'win7' || $ost eq 'w2k8' || $ost eq 'wvista') {
2226 push @$cmd, '-no-kvm-pit-reinjection';
2227 push @$cmd, '-no-hpet';
2237 push @$cmd, '-no-kvm';
2239 die "No accelerator found!\n" if !$cpuinfo->{hvm
};
2242 push @$cmd, '-localtime' if $conf->{localtime};
2244 push @$cmd, '-startdate', $conf->{startdate
} if $conf->{startdate
};
2246 push @$cmd, '-S' if $conf->{freeze
};
2248 # set keyboard layout
2249 my $kb = $conf->{keyboard
} || $defaults->{keyboard
};
2250 push @$cmd, '-k', $kb if $kb;
2253 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2254 #push @$cmd, '-soundhw', 'es1370';
2255 #push @$cmd, '-soundhw', $soundhw if $soundhw;
2256 $pciaddr = print_pci_addr
("balloon0");
2257 push @$cmd, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon
};
2259 if ($conf->{watchdog
}) {
2260 my $wdopts = parse_watchdog
($conf->{watchdog
});
2261 $pciaddr = print_pci_addr
("watchdog");
2262 my $watchdog = $wdopts->{model
} || 'i6300esb';
2263 push @$cmd, '-device', "$watchdog$pciaddr";
2264 push @$cmd, '-watchdog-action', $wdopts->{action
} if $wdopts->{action
};
2268 my $scsicontroller = {};
2269 my $ahcicontroller = {};
2271 foreach_drive
($conf, sub {
2272 my ($ds, $drive) = @_;
2274 if (PVE
::Storage
::parse_volume_id
($drive->{file
}, 1)) {
2275 push @$vollist, $drive->{file
};
2278 $use_virtio = 1 if $ds =~ m/^virtio/;
2280 if (drive_is_cdrom
($drive)) {
2281 if ($bootindex_hash->{d
}) {
2282 $drive->{bootindex
} = $bootindex_hash->{d
};
2283 $bootindex_hash->{d
} += 1;
2286 if ($bootindex_hash->{c
}) {
2287 $drive->{bootindex
} = $bootindex_hash->{c
} if $conf->{bootdisk
} && ($conf->{bootdisk
} eq $ds);
2288 $bootindex_hash->{c
} += 1;
2292 if ($drive->{interface
} eq 'scsi') {
2294 my $controller = int($drive->{index} / $maxdev);
2295 $pciaddr = print_pci_addr
("lsi$controller");
2296 push @$cmd, '-device', "lsi,id=lsi$controller$pciaddr" if !$scsicontroller->{$controller};
2297 $scsicontroller->{$controller}=1;
2300 if ($drive->{interface
} eq 'sata') {
2301 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
2302 $pciaddr = print_pci_addr
("ahci$controller");
2303 push @$cmd, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
2304 $ahcicontroller->{$controller}=1;
2307 push @$cmd, '-drive',print_drive_full
($storecfg, $vmid, $drive);
2308 push @$cmd, '-device',print_drivedevice_full
($storecfg,$vmid, $drive);
2311 push @$cmd, '-m', $conf->{memory
} || $defaults->{memory
};
2313 for (my $i = 0; $i < $MAX_NETS; $i++) {
2314 next if !$conf->{"net$i"};
2315 my $d = parse_net
($conf->{"net$i"});
2318 $use_virtio = 1 if $d->{model
} eq 'virtio';
2320 if ($bootindex_hash->{n
}) {
2321 $d->{bootindex
} = $bootindex_hash->{n
};
2322 $bootindex_hash->{n
} += 1;
2325 my $netdevfull = print_netdev_full
($vmid,$conf,$d,"net$i");
2326 push @$cmd, '-netdev', $netdevfull;
2328 my $netdevicefull = print_netdevice_full
($vmid,$conf,$d,"net$i");
2329 push @$cmd, '-device', $netdevicefull;
2333 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2334 # when the VM uses virtio devices.
2335 if (!$use_virtio && $have_ovz) {
2337 my $cpuunits = defined($conf->{cpuunits
}) ?
2338 $conf->{cpuunits
} : $defaults->{cpuunits
};
2340 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2342 # fixme: cpulimit is currently ignored
2343 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2347 if ($conf->{args
}) {
2348 my $aa = PVE
::Tools
::split_args
($conf->{args
});
2352 return wantarray ?
($cmd, $vollist) : $cmd;
2357 return "${var_run_tmpdir}/$vmid.vnc";
2362 return "${var_run_tmpdir}/$vmid.qmp";
2367 return "${var_run_tmpdir}/$vmid.pid";
2370 sub next_migrate_port
{
2372 for (my $p = 60000; $p < 60010; $p++) {
2374 my $sock = IO
::Socket
::INET-
>new(Listen
=> 5,
2375 LocalAddr
=> 'localhost',
2386 die "unable to find free migration port";
2389 sub vm_devices_list
{
2392 my $res = vm_mon_cmd
($vmid, 'query-pci');
2395 foreach my $pcibus (@$res) {
2396 foreach my $device (@{$pcibus->{devices
}}) {
2397 next if !$device->{'qdev_id'};
2398 $devices->{$device->{'qdev_id'}} = $device;
2406 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
2408 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2410 my $devices_list = vm_devices_list
($vmid);
2411 return 1 if defined($devices_list->{$deviceid});
2413 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2414 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2415 my $devicefull = print_drivedevice_full
($storecfg, $vmid, $device);
2416 qemu_deviceadd
($vmid, $devicefull);
2417 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2418 qemu_drivedel
($vmid, $deviceid);
2423 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2424 my $pciaddr = print_pci_addr
($deviceid);
2425 my $devicefull = "lsi,id=$deviceid$pciaddr";
2426 qemu_deviceadd
($vmid, $devicefull);
2427 return undef if(!qemu_deviceaddverify
($vmid, $deviceid));
2430 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2431 return undef if !qemu_findorcreatelsi
($storecfg,$conf, $vmid, $device);
2432 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2433 my $devicefull = print_drivedevice_full
($storecfg, $vmid, $device);
2434 if(!qemu_deviceadd
($vmid, $devicefull)) {
2435 qemu_drivedel
($vmid, $deviceid);
2440 if ($deviceid =~ m/^(net)(\d+)$/) {
2441 return undef if !qemu_netdevadd
($vmid, $conf, $device, $deviceid);
2442 my $netdevicefull = print_netdevice_full
($vmid, $conf, $device, $deviceid);
2443 qemu_deviceadd
($vmid, $netdevicefull);
2444 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2445 qemu_netdevdel
($vmid, $deviceid);
2453 sub vm_deviceunplug
{
2454 my ($vmid, $conf, $deviceid) = @_;
2456 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2458 my $devices_list = vm_devices_list
($vmid);
2459 return 1 if !defined($devices_list->{$deviceid});
2461 die "can't unplug bootdisk" if $conf->{bootdisk
} && $conf->{bootdisk
} eq $deviceid;
2463 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2464 return undef if !qemu_drivedel
($vmid, $deviceid);
2465 qemu_devicedel
($vmid, $deviceid);
2466 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2469 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2470 return undef if !qemu_devicedel
($vmid, $deviceid);
2473 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2474 return undef if !qemu_devicedel
($vmid, $deviceid);
2475 return undef if !qemu_drivedel
($vmid, $deviceid);
2478 if ($deviceid =~ m/^(net)(\d+)$/) {
2479 return undef if !qemu_netdevdel
($vmid, $deviceid);
2480 qemu_devicedel
($vmid, $deviceid);
2481 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2487 sub qemu_deviceadd
{
2488 my ($vmid, $devicefull) = @_;
2490 my $ret = vm_human_monitor_command
($vmid, "device_add $devicefull");
2492 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
2493 return 1 if $ret eq "";
2494 syslog
("err", "error on hotplug device : $ret");
2499 sub qemu_devicedel
{
2500 my($vmid, $deviceid) = @_;
2502 my $ret = vm_human_monitor_command
($vmid, "device_del $deviceid");
2504 return 1 if $ret eq "";
2505 syslog
("err", "detaching device $deviceid failed : $ret");
2510 my($storecfg, $vmid, $device) = @_;
2512 my $drive = print_drive_full
($storecfg, $vmid, $device);
2513 my $ret = vm_human_monitor_command
($vmid, "drive_add auto $drive");
2514 # If the command succeeds qemu prints: "OK"
2515 if ($ret !~ m/OK/s) {
2516 syslog
("err", "adding drive failed: $ret");
2523 my($vmid, $deviceid) = @_;
2525 my $ret = vm_human_monitor_command
($vmid, "drive_del drive-$deviceid");
2527 if ($ret =~ m/Device \'.*?\' not found/s) {
2528 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
2530 elsif ($ret ne "") {
2531 syslog
("err", "deleting drive $deviceid failed : $ret");
2537 sub qemu_deviceaddverify
{
2538 my ($vmid,$deviceid) = @_;
2540 for (my $i = 0; $i <= 5; $i++) {
2541 my $devices_list = vm_devices_list
($vmid);
2542 return 1 if defined($devices_list->{$deviceid});
2545 syslog
("err", "error on hotplug device $deviceid");
2550 sub qemu_devicedelverify
{
2551 my ($vmid,$deviceid) = @_;
2553 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2554 for (my $i = 0; $i <= 5; $i++) {
2555 my $devices_list = vm_devices_list
($vmid);
2556 return 1 if !defined($devices_list->{$deviceid});
2559 syslog
("err", "error on hot-unplugging device $deviceid");
2563 sub qemu_findorcreatelsi
{
2564 my ($storecfg, $conf, $vmid, $device) = @_;
2567 my $controller = int($device->{index} / $maxdev);
2568 my $lsiid="lsi$controller";
2569 my $devices_list = vm_devices_list
($vmid);
2571 if(!defined($devices_list->{$lsiid})) {
2572 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $lsiid);
2577 sub qemu_netdevadd
{
2578 my ($vmid, $conf, $device, $deviceid) = @_;
2580 my $netdev = print_netdev_full
($vmid, $conf, $device, $deviceid);
2581 my $ret = vm_human_monitor_command
($vmid, "netdev_add $netdev");
2584 #if the command succeeds, no output is sent. So any non-empty string shows an error
2585 return 1 if $ret eq "";
2586 syslog
("err", "adding netdev failed: $ret");
2590 sub qemu_netdevdel
{
2591 my ($vmid, $deviceid) = @_;
2593 my $ret = vm_human_monitor_command
($vmid, "netdev_del $deviceid");
2595 #if the command succeeds, no output is sent. So any non-empty string shows an error
2596 return 1 if $ret eq "";
2597 syslog
("err", "deleting netdev failed: $ret");
2601 sub qemu_block_set_io_throttle
{
2602 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2605 $bps_rd = 0 if !$bps_rd;
2606 $bps_wr = 0 if !$bps_wr;
2607 $iops = 0 if !$iops;
2608 $iops_rd = 0 if !$iops_rd;
2609 $iops_wr = 0 if !$iops_wr;
2611 my $ret = vm_mon_cmd
($vmid, "block_set_io_throttle", device
=> $deviceid, bps
=> $bps, bps_rd
=> $bps_rd, bps_wr
=> $bps_wr, iops
=> $iops, iops_rd
=> $iops_rd, iops_wr
=> $iops_wr);
2613 return 1 if $ret eq "";
2614 syslog
("err", "error setting block_set_io_throttle: $ret");
2619 my ($storecfg, $vmid, $statefile, $skiplock) = @_;
2621 lock_config
($vmid, sub {
2622 my $conf = load_config
($vmid);
2624 check_lock
($conf) if !$skiplock;
2626 die "VM $vmid already running\n" if check_running
($vmid);
2629 my $migrate_port = 0;
2632 if ($statefile eq 'tcp') {
2633 $migrate_port = next_migrate_port
();
2634 $migrate_uri = "tcp:localhost:${migrate_port}";
2636 if (-f
$statefile) {
2637 $migrate_uri = "exec:cat $statefile";
2639 warn "state file '$statefile' does not exist - doing normal startup\n";
2644 my $defaults = load_defaults
();
2646 my ($cmd, $vollist) = config_to_command
($storecfg, $vmid, $conf, $defaults, $migrate_uri);
2648 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2649 my $d = parse_hostpci
($conf->{"hostpci$i"});
2651 my $info = pci_device_info
("0000:$d->{pciid}");
2652 die "IOMMU not present\n" if !check_iommu_support
();
2653 die "no pci device info for device '$d->{pciid}'\n" if !$info;
2654 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub
($info);
2655 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset
($info);
2658 PVE
::Storage
::activate_volumes
($storecfg, $vollist);
2660 eval { run_command
($cmd, timeout
=> $migrate_uri ?
undef : 30); };
2662 die "start failed: $err" if $err;
2666 if ($statefile eq 'tcp') {
2667 print "migration listens on port $migrate_port\n";
2670 # fixme: send resume - is that necessary ?
2671 eval { vm_mon_cmd
($vmid, "cont"); };
2675 # always set migrate speed (overwrite kvm default of 32m)
2676 # we set a very hight default of 8192m which is basically unlimited
2677 my $migrate_speed = $defaults->{migrate_speed
} || 8192;
2678 $migrate_speed = $conf->{migrate_speed
} || $migrate_speed;
2679 $migrate_speed = $migrate_speed * 1048576;
2681 vm_mon_cmd
($vmid, "migrate_set_speed", value
=> $migrate_speed);
2684 my $migrate_downtime = $defaults->{migrate_downtime
};
2685 $migrate_downtime = $conf->{migrate_downtime
} if defined($conf->{migrate_downtime
});
2686 if (defined($migrate_downtime)) {
2687 eval { vm_mon_cmd
($vmid, "migrate_set_downtime", value
=> $migrate_downtime); };
2690 vm_balloonset
($vmid, $conf->{balloon
}) if $conf->{balloon
};
2696 my ($vmid, $execute, %params) = @_;
2698 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2699 vm_qmp_command
($vmid, $cmd);
2702 sub vm_mon_cmd_nocheck
{
2703 my ($vmid, $execute, %params) = @_;
2705 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2706 vm_qmp_command
($vmid, $cmd, 1);
2709 sub vm_qmp_command
{
2710 my ($vmid, $cmd, $nocheck) = @_;
2715 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2717 my $qmpclient = PVE
::QMPClient-
>new();
2719 $res = $qmpclient->cmd($vmid, $cmd);
2723 syslog
("err", "VM $vmid qmp command failed - $err");
2730 sub vm_human_monitor_command
{
2731 my ($vmid, $cmdline) = @_;
2736 execute
=> 'human-monitor-command',
2737 arguments
=> { 'command-line' => $cmdline},
2740 return vm_qmp_command
($vmid, $cmd);
2743 sub vm_commandline
{
2744 my ($storecfg, $vmid) = @_;
2746 my $conf = load_config
($vmid);
2748 my $defaults = load_defaults
();
2750 my $cmd = config_to_command
($storecfg, $vmid, $conf, $defaults);
2752 return join(' ', @$cmd);
2756 my ($vmid, $skiplock) = @_;
2758 lock_config
($vmid, sub {
2760 my $conf = load_config
($vmid);
2762 check_lock
($conf) if !$skiplock;
2764 vm_mon_cmd
($vmid, "system_reset");
2768 sub get_vm_volumes
{
2772 foreach_drive
($conf, sub {
2773 my ($ds, $drive) = @_;
2775 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
}, 1);
2778 my $volid = $drive->{file
};
2779 return if !$volid || $volid =~ m
|^/|;
2781 push @$vollist, $volid;
2787 sub vm_stop_cleanup
{
2788 my ($storecfg, $vmid, $conf, $keepActive) = @_;
2791 fairsched_rmnod
($vmid); # try to destroy group
2794 my $vollist = get_vm_volumes
($conf);
2795 PVE
::Storage
::deactivate_volumes
($storecfg, $vollist);
2798 foreach my $ext (qw(mon pid vnc)) {
2799 unlink "/var/run/qemu-server/${vmid}.$ext";
2802 warn $@ if $@; # avoid errors - just warn
2805 # Note: use $nockeck to skip tests if VM configuration file exists.
2806 # We need that when migration VMs to other nodes (files already moved)
2807 # Note: we set $keepActive in vzdump stop mode - volumes need to stay active
2809 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive) = @_;
2811 $timeout = 60 if !defined($timeout);
2813 $force = 1 if !defined($force) && !$shutdown;
2815 lock_config
($vmid, sub {
2817 my $pid = check_running
($vmid, $nocheck);
2822 $conf = load_config
($vmid);
2823 check_lock
($conf) if !$skiplock;
2828 $nocheck ? vm_mon_cmd_nocheck
($vmid, "system_powerdown") : vm_mon_cmd
($vmid, "system_powerdown");
2831 $nocheck ? vm_mon_cmd_nocheck
($vmid, "quit") : vm_mon_cmd
($vmid, "quit");
2838 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
2843 if ($count >= $timeout) {
2845 warn "VM still running - terminating now with SIGTERM\n";
2848 die "VM quit/powerdown failed - got timeout\n";
2851 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
2856 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
2859 die "VM quit/powerdown failed\n";
2867 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
2872 if ($count >= $timeout) {
2873 warn "VM still running - terminating now with SIGKILL\n";
2878 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
2883 my ($vmid, $skiplock) = @_;
2885 lock_config
($vmid, sub {
2887 my $conf = load_config
($vmid);
2889 check_lock
($conf) if !$skiplock;
2891 vm_mon_cmd
($vmid, "stop");
2896 my ($vmid, $skiplock) = @_;
2898 lock_config
($vmid, sub {
2900 my $conf = load_config
($vmid);
2902 check_lock
($conf) if !$skiplock;
2904 vm_mon_cmd
($vmid, "cont");
2909 my ($vmid, $skiplock, $key) = @_;
2911 lock_config
($vmid, sub {
2913 my $conf = load_config
($vmid);
2915 # there is no qmp command, so we use the human monitor command
2916 vm_human_monitor_command
($vmid, "sendkey $key");
2921 my ($storecfg, $vmid, $skiplock) = @_;
2923 lock_config
($vmid, sub {
2925 my $conf = load_config
($vmid);
2927 check_lock
($conf) if !$skiplock;
2929 if (!check_running
($vmid)) {
2930 fairsched_rmnod
($vmid); # try to destroy group
2931 destroy_vm
($storecfg, $vmid);
2933 die "VM $vmid is running - destroy failed\n";
2941 my ($filename, $buf) = @_;
2943 my $fh = IO
::File-
>new($filename, "w");
2944 return undef if !$fh;
2946 my $res = print $fh $buf;
2953 sub pci_device_info
{
2958 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
2959 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
2961 my $irq = file_read_firstline
("$pcisysfs/devices/$name/irq");
2962 return undef if !defined($irq) || $irq !~ m/^\d+$/;
2964 my $vendor = file_read_firstline
("$pcisysfs/devices/$name/vendor");
2965 return undef if !defined($vendor) || $vendor !~ s/^0x//;
2967 my $product = file_read_firstline
("$pcisysfs/devices/$name/device");
2968 return undef if !defined($product) || $product !~ s/^0x//;
2973 product
=> $product,
2979 has_fl_reset
=> -f
"$pcisysfs/devices/$name/reset" || 0,
2988 my $name = $dev->{name
};
2990 my $fn = "$pcisysfs/devices/$name/reset";
2992 return file_write
($fn, "1");
2995 sub pci_dev_bind_to_stub
{
2998 my $name = $dev->{name
};
3000 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3001 return 1 if -d
$testdir;
3003 my $data = "$dev->{vendor} $dev->{product}";
3004 return undef if !file_write
("$pcisysfs/drivers/pci-stub/new_id", $data);
3006 my $fn = "$pcisysfs/devices/$name/driver/unbind";
3007 if (!file_write
($fn, $name)) {
3008 return undef if -f
$fn;
3011 $fn = "$pcisysfs/drivers/pci-stub/bind";
3012 if (! -d
$testdir) {
3013 return undef if !file_write
($fn, $name);
3019 sub print_pci_addr
{
3024 #addr1 : ide,parallel,serial (motherboard)
3025 #addr2 : first videocard
3026 balloon0
=> { bus
=> 0, addr
=> 3 },
3027 watchdog
=> { bus
=> 0, addr
=> 4 },
3028 lsi0
=> { bus
=> 0, addr
=> 5 },
3029 lsi1
=> { bus
=> 0, addr
=> 6 },
3030 ahci0
=> { bus
=> 0, addr
=> 7 },
3031 virtio0
=> { bus
=> 0, addr
=> 10 },
3032 virtio1
=> { bus
=> 0, addr
=> 11 },
3033 virtio2
=> { bus
=> 0, addr
=> 12 },
3034 virtio3
=> { bus
=> 0, addr
=> 13 },
3035 virtio4
=> { bus
=> 0, addr
=> 14 },
3036 virtio5
=> { bus
=> 0, addr
=> 15 },
3037 hostpci0
=> { bus
=> 0, addr
=> 16 },
3038 hostpci1
=> { bus
=> 0, addr
=> 17 },
3039 net0
=> { bus
=> 0, addr
=> 18 },
3040 net1
=> { bus
=> 0, addr
=> 19 },
3041 net2
=> { bus
=> 0, addr
=> 20 },
3042 net3
=> { bus
=> 0, addr
=> 21 },
3043 net4
=> { bus
=> 0, addr
=> 22 },
3044 net5
=> { bus
=> 0, addr
=> 23 },
3045 #addr29 : usb-host (pve-usb.cfg)
3048 if (defined($devices->{$id}->{bus
}) && defined($devices->{$id}->{addr
})) {
3049 my $addr = sprintf("0x%x", $devices->{$id}->{addr
});
3050 $res = ",bus=pci.$devices->{$id}->{bus},addr=$addr";
3057 my ($vmid, $value) = @_;
3059 vm_mon_cmd
($vmid, "balloon", value
=> $value);
3062 # vzdump restore implementaion
3064 sub archive_read_firstfile
{
3065 my $archive = shift;
3067 die "ERROR: file '$archive' does not exist\n" if ! -f
$archive;
3069 # try to detect archive type first
3070 my $pid = open (TMP
, "tar tf '$archive'|") ||
3071 die "unable to open file '$archive'\n";
3072 my $firstfile = <TMP
>;
3076 die "ERROR: archive contaions no data\n" if !$firstfile;
3082 sub restore_cleanup
{
3083 my $statfile = shift;
3085 print STDERR
"starting cleanup\n";
3087 if (my $fd = IO
::File-
>new($statfile, "r")) {
3088 while (defined(my $line = <$fd>)) {
3089 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3092 if ($volid =~ m
|^/|) {
3093 unlink $volid || die 'unlink failed\n';
3095 my $cfg = cfs_read_file
('storage.cfg');
3096 PVE
::Storage
::vdisk_free
($cfg, $volid);
3098 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
3100 print STDERR
"unable to cleanup '$volid' - $@" if $@;
3102 print STDERR
"unable to parse line in statfile - $line";
3109 sub restore_archive
{
3110 my ($archive, $vmid, $user, $opts) = @_;
3112 if ($archive ne '-') {
3113 my $firstfile = archive_read_firstfile
($archive);
3114 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
3115 if $firstfile ne 'qemu-server.conf';
3118 my $tocmd = "/usr/lib/qemu-server/qmextract";
3120 $tocmd .= " --storage " . PVE
::Tools
::shellquote
($opts->{storage
}) if $opts->{storage
};
3121 $tocmd .= " --pool " . PVE
::Tools
::shellquote
($opts->{pool
}) if $opts->{pool
};
3122 $tocmd .= ' --prealloc' if $opts->{prealloc
};
3123 $tocmd .= ' --info' if $opts->{info
};
3125 # tar option "xf" does not autodetect compression when read from STDIN,
3126 # so we pipe to zcat
3127 my $cmd = "zcat -f|tar xf " . PVE
::Tools
::shellquote
($archive) . " " .
3128 PVE
::Tools
::shellquote
("--to-command=$tocmd");
3130 my $tmpdir = "/var/tmp/vzdumptmp$$";
3133 local $ENV{VZDUMP_TMPDIR
} = $tmpdir;
3134 local $ENV{VZDUMP_VMID
} = $vmid;
3135 local $ENV{VZDUMP_USER
} = $user;
3137 my $conffile = PVE
::QemuServer
::config_file
($vmid);
3138 my $tmpfn = "$conffile.$$.tmp";
3140 # disable interrupts (always do cleanups)
3141 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
3142 print STDERR
"got interrupt - ignored\n";
3147 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
3148 die "interrupted by signal\n";
3151 if ($archive eq '-') {
3152 print "extracting archive from STDIN\n";
3153 run_command
($cmd, input
=> "<&STDIN");
3155 print "extracting archive '$archive'\n";
3159 return if $opts->{info
};
3163 my $statfile = "$tmpdir/qmrestore.stat";
3164 if (my $fd = IO
::File-
>new($statfile, "r")) {
3165 while (defined (my $line = <$fd>)) {
3166 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3167 $map->{$1} = $2 if $1;
3169 print STDERR
"unable to parse line in statfile - $line\n";
3175 my $confsrc = "$tmpdir/qemu-server.conf";
3177 my $srcfd = new IO
::File
($confsrc, "r") ||
3178 die "unable to open file '$confsrc'\n";
3180 my $outfd = new IO
::File
($tmpfn, "w") ||
3181 die "unable to write config for VM $vmid\n";
3185 while (defined (my $line = <$srcfd>)) {
3186 next if $line =~ m/^\#vzdump\#/;
3187 next if $line =~ m/^lock:/;
3188 next if $line =~ m/^unused\d+:/;
3190 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3191 # try to convert old 1.X settings
3192 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3193 foreach my $devconfig (PVE
::Tools
::split_list
($ethcfg)) {
3194 my ($model, $macaddr) = split(/\=/, $devconfig);
3195 $macaddr = PVE
::Tools
::random_ether_addr
() if !$macaddr || $opts->{unique
};
3198 bridge
=> "vmbr$ind",
3199 macaddr
=> $macaddr,
3201 my $netstr = print_net
($net);
3202 print $outfd "net${netcount}: $netstr\n";
3205 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && ($opts->{unique
})) {
3206 my ($id, $netstr) = ($1, $2);
3207 my $net = parse_net
($netstr);
3208 $net->{macaddr
} = PVE
::Tools
::random_ether_addr
() if $net->{macaddr
};
3209 $netstr = print_net
($net);
3210 print $outfd "$id: $netstr\n";
3211 } elsif ($line =~ m/^((ide|scsi|virtio)\d+):\s*(\S+)\s*$/) {
3214 if ($line =~ m/backup=no/) {
3215 print $outfd "#$line";
3216 } elsif ($virtdev && $map->{$virtdev}) {
3217 my $di = PVE
::QemuServer
::parse_drive
($virtdev, $value);
3218 $di->{file
} = $map->{$virtdev};
3219 $value = PVE
::QemuServer
::print_drive
($vmid, $di);
3220 print $outfd "$virtdev: $value\n";
3238 restore_cleanup
("$tmpdir/qmrestore.stat") if !$opts->{info
};
3245 rename $tmpfn, $conffile ||
3246 die "unable to commit configuration file '$conffile'\n";