#!/usr/bin/perl -w use POSIX; open FILE, "/proc/user_beancounters" or die "Cannot open beancounters"; while () { next if /^Version/; next if /failcnt/; @line = split; if (scalar @line == 7) { $id = shift @line; $id =~ s/://; } $hash{$id}->{$line[0]}->{'held'} = $line[1]; $hash{$id}->{$line[0]}->{'maxheld'} = $line[2]; $hash{$id}->{$line[0]}->{'barrier'} = $line[3]; $hash{$id}->{$line[0]}->{'limit'} = $line[4]; $hash{$id}->{$line[0]}->{'failcnt'} = $line[5]; } close FILE; open FILE, "/proc/meminfo" or die "Cannot open meminfo"; while () { @line = split; $line[0] =~ s/://; next if !defined $line[2]; if ($line[2] eq 'kB') { $line[1] *= 1024; } $mem{$line[0]} = $line[1]; } close FILE; # Barrier of numproc, numtcpsock, numothersock, dgramrcvbuf should be set to the limit: $URL="http://wiki.openvz.org/UBC_primary_parameters"; foreach $id (keys %hash) { next if $id == 0; foreach $param ('numproc', 'numtcpsock', 'numothersock', 'dgramrcvbuf') { $l = $hash{$id}->{$param}->{'limit'}; $b = $hash{$id}->{$param}->{'barrier'}; if ($l != $b) { print "VEID $id: Should set $param barrier equal to limit $l (is $b)\n\t$URL\n"; printValues($id, $param); } } } # Limit of numproc about 16000 $URL="http://wiki.openvz.org/UBC_primary_parameters#numproc"; foreach $id (keys %hash) { next if $id == 0; $l = $hash{$id}->{'numproc'}->{'limit'}; if ($l > 16000) { print "VEID $id: Should set numproc limit to about 16000 (is $l)\n\t$URL\n"; } } # limit of vmguarpages should be MAX_ULONG $URL="http://wiki.openvz.org/UBC_primary_parameters#vmguarpages"; foreach $id (keys %hash) { next if $id == 0; $l = $hash{$id}->{'vmguarpages'}->{'limit'}; if ($l != LONG_MAX) { printOut ( "VEID $id: Should set vmguarpages limit to ".LONG_MAX ); printValues($id, 'vmguarpages'); } } # kmemsize limit 10% more than barrier $URL="http://wiki.openvz.org/UBC_secondary_parameters#kmemsize"; foreach $id (keys %hash) { next if $id == 0; $l = $hash{$id}->{'kmemsize'}->{'limit'}; $b = $hash{$id}->{'kmemsize'}->{'barrier'}; if ($l < $b*1.1) { print "VEID $id: Should set kmemsize limit to 1.1*barrier (currently $b:$l)\n\t$URL\n"; } } # tcpsndbuf, tcprcvbuf, othersockbuf limits $URL="http://wiki.openvz.org/UBC_secondary_parameters#tcpsndbuf"; foreach $id (keys %hash) { next if $id == 0; $map = { 'tcpsndbuf' => 'numtcpsock', 'tcprcvbuf' => 'numtcpsock', 'othersockbuf' => 'numothersock', }; foreach $param (keys %$map) { $rhs = $map->{$param}; $num = $hash{$id}->{$rhs}->{'barrier'}*2.5*1024; $l = $hash{$id}->{$param}->{'limit'}; $b = $hash{$id}->{$param}->{'barrier'}; if ($l - $b < $num) { printOut( "VEID $id: $param limit too low", $URL, "Formula: ${param}[limit-barrier] > 2.5Kb*$rhs", "\t${param}[limit-barrier] = ".niceSize($l-$b), "\t 2.5Kb*$rhs = ".niceSize($num), "Either raise ${param}[limit] to ".($b+$num), "or lower ${param}[barrier] to ".($l-$num), "or lower $rhs to ".($l-$b)/$num ); printValues($id, $param); printValues($id, $rhs); } } } # privvmpages limit more than barrier $URL="http://wiki.openvz.org/UBC_secondary_parameters#privvmpages"; foreach $id (keys %hash) { next if $id == 0; $l = $hash{$id}->{'privvmpages'}->{'limit'}; $b = $hash{$id}->{'privvmpages'}->{'barrier'}; if ($l <= $b) { print "VEID $id: Should set privvmpages limit to more than barrier (currently $b:$l)\n\t$URL\n"; } } # kmemsize large enough for all processes $URL="http://wiki.openvz.org/UBC_consistency_check#kmemsize_should_be_enough_for_the_expected_number_of_processes"; foreach $id (keys %hash) { next if $id == 0; $k = $hash{$id}->{'kmemsize'}->{'barrier'}; $d = $hash{$id}->{'dcachesize'}->{'limit'}; $a = $hash{$id}->{'numproc'}->{'maxheld'}; if ($k < 40*1024*$a+$d) { print "VEID $id: Should set kmemsize barrier >= ".(40*1024*$a+$d)." (currently $k)\n\t$URL\n"; } } # Mem alloc limits: $URL="http://wiki.openvz.org/UBC_consistency_check#Memory_allocation_limits_should_not_be_less_than_the_guarantee"; foreach $id (keys %hash) { next if $id == 0; $p = $hash{$id}->{'privvmpages'}->{'barrier'}; $v = $hash{$id}->{'vmguarpages'}->{'barrier'}; if ($p < $v) { print "VEID $id: Should set privvmpages >= vmguarpages (currently $p and $v)\n\t$URL\n"; } } # Buffer sizes $URL="http://wiki.openvz.org/UBC_consistency_check#Other_TCP_socket_buffers_should_be_big_enough"; foreach $id (keys %hash) { next if $id == 0; $map = { 'tcprcvbuf' => 64*1024, 'tcpsndbuf' => 64*1024, 'dgramrcvbuf' => 129*1024, 'othersockbuf' => 129*1024, }; foreach $param (keys %$map) { $v = $hash{$id}->{$param}->{'barrier'}; if ($v < $map->{$param}) { print "VEID $id: Should set $param > ".$map->{$param}." (currently $v)\n\t$URL\n"; } } } # File limit $URL="http://wiki.openvz.org/UBC_consistency_check#Number_of_files_limit_should_be_adequate_for_the_expected_number_of_processes"; foreach $id (keys %hash) { next if $id == 0; $f = $hash{$id}->{'numfile'}->{'barrier'}; $p = $hash{$id}->{'numproc'}->{'maxheld'}; if ($f < $p*32) { print "VEID $id: Should set numfile to at least ".($p*32)." (currently $f)\n\t$URL\n"; } } # dentry and inode $URL="http://wiki.openvz.org/UBC_consistency_check#The_limit_on_the_total_size_of_dentry_and_inode_structures_locked_in_memory_should_be_adequate_for_allowed_number_of_files"; foreach $id (keys %hash) { next if $id == 0; $d = $hash{$id}->{'dcachesize'}->{'barrier'}; $n = $hash{$id}->{'numfile'}->{'maxheld'}; if ($d < $n * 384) { print "VEID $id: Should set dcachesize to at least ".($n*386)." (currently $d)\n\t$URL\n"; } } # General barrier/limit $URL="http://wiki.openvz.org/UBC_consistency_check#Barrier_should_be_less_or_equal_than_limit"; foreach $id (keys %hash) { next if $id == 0; foreach $param (keys %{$hash{$id}}) { $b = $hash{$id}->{$param}->{'barrier'}; $l = $hash{$id}->{$param}->{'limit'}; if ($b > $l) { print "VEID $id: Should set $param limit >= $b (currently $l)\n\t$URL\n"; } } } # RAM limits $URL="http://wiki.openvz.org/UBC_systemwide_configuration#Limiting_memory_allocations"; foreach $id (keys %hash) { next if $id == 0; $p = $hash{$id}->{'privvmpages'}->{'limit'}; if ($p*4096 > $mem{'MemTotal'}*0.6) { printOut( "VEID $id: RAM Allocation set too high.", $URL, "Formula: privvmpages[limit]*4096 <= 0.6*RAM", "\tprivvmpages[limit]*4096 = ".niceSize($p*4096), "\t0.6*RAM = ".niceSize($mem{'MemTotal'}*0.6), "Consider Dropping privvmpages to ".($mem{'MemTotal'}*0.6/4096)." (".niceSize($mem{'MemTotal'}*0.6).")", "unless you know what you are doing or are only running one VE" ); printValues($id, 'privvmpages'); } } print "\nSystem parameters\n-------------------\n"; print "http://wiki.openvz.org/UBC_systemwide_configuration\n"; print "---------------------------------------------------\n"; $lowutil = 0; $lowcomm = 0; $ramutil = 0; $allutil = 0; $allcomm = 0; $memutil = 0; $memcomm = 0; $memlimit = 0; foreach $id (keys %hash) { next if $id == 0; foreach $param ('kmemsize', 'tcprcvbuf', 'tcpsndbuf', 'dgramrcvbuf', 'othersockbuf') { $lowutil += $hash{$id}->{$param}->{'held'}; $lowcomm += $hash{$id}->{$param}->{'limit'}; } $ramutil += $hash{$id}->{'physpages'}->{'held'}*4096; $allutil += $hash{$id}->{'oomguarpages'}->{'held'}*4096; $allcomm += $hash{$id}->{'oomguarpages'}->{'barrier'}*4096; $memutil += $hash{$id}->{'privvmpages'}->{'held'}*4096; $memcomm += $hash{$id}->{'vmguarpages'}->{'barrier'}*4096; $memlimit += $hash{$id}->{'privvmpages'}->{'limit'}*4096; } $ramutil += $lowutil; $allutil += $lowutil; $allcomm += $lowcomm; $memutil += $lowutil; $memcomm += $lowcomm; $p = sprintf("%5.3f", $lowutil/0.4/832/1024/1024); print "Low Memory Utilisation: $p (out of 1)\n"; $p = sprintf("%5.3f", $lowcomm/0.4/832/1024/1024); print "Low Memory Commitment: $p (out of 2)\n"; $p = sprintf("%5.3f", $ramutil/$mem{'MemTotal'}); print "Total RAM Memory Utilisation: $p (out of 1)\n"; $p = sprintf("%5.3f", $allutil/($mem{'MemTotal'} + $mem{'SwapTotal'})); print "RAM + SWAP Utilization: $p (out of 1)\n"; $p = sprintf("%5.3f", $allcomm/($mem{'MemTotal'} + $mem{'SwapTotal'})); print "RAM + SWAP Commitment: $p (out of about 0.8 - 1)\n"; $p = sprintf("%5.3f", $memutil/($mem{'MemTotal'} + $mem{'SwapTotal'})); print "Allocated Utilization: $p (out of unknown)\n"; $p = sprintf("%5.3f", $memcomm/($mem{'MemTotal'} + $mem{'SwapTotal'})); print "Allocated Commitment: $p (out of 1)\n"; $p = sprintf("%5.3f", $memlimit/($mem{'MemTotal'} + $mem{'SwapTotal'})); print "Memory Allocation Limit: $p (out of 1 to 1.5)\n"; sub printValues { my $id = shift; my $param = shift; my $h = $hash{$id}->{$param}->{'held'}; my $m = $hash{$id}->{$param}->{'maxheld'}; my $b = $hash{$id}->{$param}->{'barrier'}; my $l = $hash{$id}->{$param}->{'limit'}; print "$param\tcur:$h\tmax:$m\tbar:$b\tlim:$l\n"; } sub printOut { print "\n$_[0]\n"; shift; foreach (@_) { print "\t$_\n"; } } sub niceSize { my $num = shift; return sprintf("%0.2fG", $num/1024/1024/1024) if $num > 1024*1024*1024; return sprintf("%0.2fM", $num/1024/1024) if $num > 1024*1024; return sprintf("%0.2fK", $num/1024) if $num > 1024; return $num; }