Commit 396b1289 authored by Dietmar Maurer's avatar Dietmar Maurer

implement auto_balloning

bump version to 2.3-3
parent 5b6237dd
......@@ -174,12 +174,157 @@ sub update_node_status {
PVE::Cluster::broadcast_rrd("pve2-node/$nodename", $data);
}
sub auto_balloning {
my ($vmstatus) = @_;
my $log = sub {
return if !$opt_debug;
print @_;
};
my $hostmeminfo = PVE::ProcFSTools::read_meminfo();
# to debug, run 'pvestatd -d' and set memtotal here
#$hostmeminfo->{memtotal} = int(3*1024*1024*1024/0.8); # you can set this to test
my $hostfreemem = $hostmeminfo->{memtotal} - $hostmeminfo->{memused};
# we try to use about 80% host memory
# goal: we want to change memory usage by this amount (positive or negative)
my $goal = int($hostmeminfo->{memtotal}*0.8 - $hostmeminfo->{memused});
&$log("host goal: $goal free: $hostfreemem total: $hostmeminfo->{memtotal}\n");
my $maxchange = 100*1024*1024;
my $get_summary = sub {
my ($idlist) = @_;
my $shares = 0;
my $freeshares = 0;
my $alloc = 0;
my $free = 0;
foreach my $vmid (@$idlist) {
my $d = $vmstatus->{$vmid};
$shares += $d->{shares} || 1000;
$freeshares += 1/($d->{shares} || 1000);
if ($d->{balloon} > $d->{balloon_min}) { # just to be sure
$alloc += $d->{balloon} - $d->{balloon_min}
}
if ($d->{maxmem} > $d->{balloon}) { # just to be sure
$free += $d->{maxmem} - $d->{balloon};
}
}
return ($shares, $freeshares, $alloc, $free);
};
my $grow_func = sub {
my ($res, $idlist, $bytes) = @_;
my $changes = 0;
my (undef, $shares_total, undef, $free_total) = &$get_summary($idlist);
return $changes if !$shares_total;
&$log("grow $goal\n");
my $target = $bytes < $free_total ? $free_total - $bytes : 0;
&$log("shares_total: $shares_total\n");
&$log("free_total: $free_total\n");
&$log("target: $target\n");
foreach my $vmid (@$idlist) {
my $d = $vmstatus->{$vmid};
my $shares = 1/($d->{shares} || 1000);
&$log("shares $vmid: $shares\n");
next if $shares < 0; # just to be sure
my $max = $d->{maxmem} - int(($target/$shares_total)*$shares);
$max = $d->{balloon_min} if $max < $d->{balloon_min};
my $new = $d->{balloon} + $maxchange;
my $balloon = $new > $max ? $max : $new;
my $diff = $balloon - $d->{balloon};
if ($diff > 0) {
$res->{$vmid} = $balloon;
$changes += $diff;
&$log("grow request for $vmid ($res->{$vmid}, $diff, $max, $new)\n");
}
}
return $changes;
};
my $idlist = []; # list of VMs with working balloon river
my $idlist1 = []; # list of VMs with memory pressure
my $idlist2 = []; # list of VMs with enough free memory
foreach my $vmid (keys %$vmstatus) {
my $d = $vmstatus->{$vmid};
next if !$d->{balloon}; # skip if balloon driver not running
next if !$d->{balloon_min}; # skip if balloon value not set in config
push @$idlist, $vmid;
if (($goal > 0) && $d->{freemem} &&
($d->{freemem} > $d->{maxmem}*0.25) &&
($d->{balloon} >= $d->{balloon_min})) {
push @$idlist2, $vmid;
&$log("idlist2 $vmid $d->{balloon}, $d->{balloon_min}, $d->{freemem}\n");
} else {
push @$idlist1, $vmid;
&$log("idlist1 $vmid $d->{balloon}, $d->{balloon_min}, $d->{freemem}\n");
}
}
my $res = {};
if ($goal > 10*1024*1024) {
&$log("grow request $goal\n");
# we priorize VMs with memory pressure
if (!&$grow_func($res, $idlist1, $goal)) {
&$grow_func($res, $idlist2, $goal);
}
} elsif ($goal < -10*1024*1024) {
&$log("shrink request $goal\n");
my ($shares_total, undef, $alloc_old) = &$get_summary($idlist);
my $alloc_new = $alloc_old + $goal;
$alloc_new = 0 if $alloc_new < 0;
&$log("shares_total: $shares_total $alloc_new\n");
foreach my $vmid (@$idlist) {
my $d = $vmstatus->{$vmid};
my $shares = $d->{shares} || 1000;
next if $shares < 0; # just to be sure
my $min = $d->{balloon_min} + int(($alloc_new/$shares_total)*$shares);
my $new = $d->{balloon} - $maxchange;
$res->{$vmid} = $new > $min ? $new : $min;
}
} else {
&$log("do nothing\n");
# do nothing - requested change to small
}
foreach my $vmid (@$idlist) {
next if !$res->{$vmid};
my $d = $vmstatus->{$vmid};
my $diff = int($res->{$vmid} - $d->{balloon});
my $absdiff = $diff < 0 ? -$diff : $diff;
if ($absdiff > 0) {
&$log("BALLOON $vmid to $res->{$vmid} ($diff)\n");
eval {
PVE::QemuServer::vm_mon_cmd($vmid, "balloon",
value => int($res->{$vmid}));
};
warn $@ if $@;
}
}
}
sub update_qemu_status {
my $ctime = time();
my $vmstatus = PVE::QemuServer::vmstatus(undef, 1);
eval { auto_balloning($vmstatus); };
syslog('err', "auto ballooning error: $@") if $@;
foreach my $vmid (keys %$vmstatus) {
my $d = $vmstatus->{$vmid};
my $data;
......
pve-manager (2.3-3) unstable; urgency=low
* implement auto-ballooning
-- Proxmox Support Team <support@proxmox.com> Thu, 20 Dec 2012 13:44:53 +0100
pve-manager (2.3-2) unstable; urgency=low
* add HD resize feature to expand disks.
......
......@@ -2,7 +2,7 @@ RELEASE=2.3
VERSION=2.3
PACKAGE=pve-manager
PACKAGERELEASE=2
PACKAGERELEASE=3
BINDIR=${DESTDIR}/usr/bin
PERLLIBDIR=${DESTDIR}/usr/share/perl5
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment