Open main menu

OpenVZ Virtuozzo Containers Wiki β

User:Grin/openvz checker.pl

< User:Grin
#!/usr/bin/perl
#$Id: openvz_checker.pl,v 1c29ac915688 2009/12/09 21:17:13 grin $
#(c)Peter "grin" Gervai, 2009; grin(a)grin(dot)hu
# GPLv2 / CC-BY-SA 3.0
#
# check openvz resource settings
# based on wiki pages
#
# Usage: just run it on the VE0 (host) system as root.

use strict;
use warnings;

use IO::File;
use Data::Dumper;

my $dir_bc = "/proc/bc";

my $CUR=0;
my $MAX=1;
my $BAR=2;
my $LIM=3;

# ia32...
my $PAGESIZE=4096;

my @allsocketbuf = qw( tcprcvbuf  tcpsndbuf  dgramrcvbuf  othersockbuf );

opendir( DIR, $dir_bc );
my @veids = grep { /^\d+/ && -d "$dir_bc/$_" }  readdir(DIR);
closedir( DIR );

my %res;
for my $veid ( @veids ) {
    next if $veid == 0;
    my $f = new IO::File "< $dir_bc/$veid/resources" or next;
    while( <$f> ) {
        chomp;
        # trim spaces
        s/^\s*(.*?)\s*$/$1/;
        my @data = split /\s+/;
        #                        held, maxheld, barrier, limit, failcnt
        $res{$veid}{$data[0]} = [ @data[1..5] ];
    }
}

## total ram
my $ram = qx( free | grep Mem: ); chomp $ram;
$ram = (split /\s+/, $ram)[1];
print "RAM=$ram\n";
$ram *= 1024;

## swap
my $swap = qx( free | grep Swap: ); chomp $swap;
$swap = (split /\s+/, $swap)[1];
print "SWAP=$swap\n";
$swap *= 1024;


my $sum;
### low mem x86_32
# max lowram 832MB
my $lowram = $ram > 832000000 ? 832000000 : $ram;


###############################
####### system wide config
###############################


###############################
## utilisation
$sum=0;
foreach my $veid (keys %res) {
    my $b = $res{$veid}{'kmemsize'}->[$CUR];
    foreach my $sb (@allsocketbuf) {
        $b += $res{$veid}{$sb}->[$CUR];
    }
    $sum += $b;
}

print "Low memory (x86_32) Utilisation: ", &pretty($sum / (0.4 * $lowram));
print "  ( <1 OK; <2 unsafe; >2 dangerous)\n";


###############################
## commitment level
$sum=0;
foreach my $veid (keys %res) {
    my $b = $res{$veid}{'kmemsize'}->[$LIM];
    foreach my $sb (@allsocketbuf) {
        $b += $res{$veid}{$sb}->[$LIM];
    }
    $sum += $b;
}

print "Low memory (x86_32) Commitment: ", &pretty($sum / (0.4 * $lowram));
print "  ( <1 OK; <1.5 acceptable; >2 not recommended)\n";


############################
#### total ram
## utilisation
$sum=0;
foreach my $veid (keys %res) {
    my $b = $res{$veid}{'physpages'}->[$CUR] * $PAGESIZE;
    $b += $res{$veid}{'kmemsize'}->[$CUR];
    foreach my $sb (@allsocketbuf) {
        $b += $res{$veid}{$sb}->[$CUR];
    }
    $sum += $b;
}
print "Total RAM utilisation: ", &pretty($sum / $ram);
print "  ( <0.8 low; <1 ok; >1 impossible)\n";


############################
#### total ram+swap
## utilisation
$sum=0;
foreach my $veid (keys %res) {
    my $b = $res{$veid}{'oomguarpages'}->[$CUR] * $PAGESIZE;
    $b += $res{$veid}{'kmemsize'}->[$CUR];
    foreach my $sb (@allsocketbuf) {
        $b += $res{$veid}{$sb}->[$CUR];
    }
    $sum += $b;
}
print "RAM+swap utilisation: ", &pretty($sum / ($ram+$swap));
my $low_bound = &pretty($ram / ($ram+$swap));
my $hi_bound  = &pretty(($ram + 0.5*$swap) / ($ram+$swap));
print "  ( <$low_bound low; between ok; >$hi_bound bad)\n";


## commitment
$sum=0;
foreach my $veid (keys %res) {
    my $b = $res{$veid}{'oomguarpages'}->[$BAR] * $PAGESIZE;
    $b += $res{$veid}{'kmemsize'}->[$LIM];
    foreach my $sb (@allsocketbuf) {
        $b += $res{$veid}{$sb}->[$LIM];
    }
    $sum += $b;
}
print "RAM+swap commitment: ", &pretty($sum / ($ram+$swap));
print "  ( <0.8 low; <1 ok; >1 not recommended)\n";


## allocations
$sum=0;
foreach my $veid (keys %res) {
    my $b = $res{$veid}{'privvmpages'}->[$LIM] * $PAGESIZE;
    $b += $res{$veid}{'kmemsize'}->[$LIM];
    foreach my $sb (@allsocketbuf) {
        $b += $res{$veid}{$sb}->[$LIM];
    }
    $sum += $b;
}
print "RAM+swap allocations: ", &pretty($sum / ($ram+$swap));
print "  ( <1.5 low; <4 ok; >4 not recommended [oom])\n";


###############################
####### per VE configs
###############################
foreach my $veid (sort { $a <=> $b }  keys %res) {
    #            <numproc> should be average process num
    &compare( $veid, $res{$veid}{'kmemsize'}->[$BAR],
    40*1024*$res{$veid}{'numproc'}->[$CUR] + $res{$veid}{'dcachesize'}->[$LIM],
            "kmemsize(bar)", "numproc~dcachesize", "kmemsize low for # of processes" );
    
    &compare( $veid, $res{$veid}{'privvmpages'}->[$BAR], $res{$veid}{'vmguarpages'}->[$BAR],
    "privvmpages","vmguarpages", "mem alloc less than guarantee" );

    
    &compare( $veid, $res{$veid}{'tcpsndbuf'}->[$LIM] - $res{$veid}{'tcpsndbuf'}->[$BAR], 
    2.5*1024*$res{$veid}{'numtcpsock'}->[$LIM], 
    "tcpsndbuf(lim-bar)", "numtcpsock(lim{bytes})", "tcp may hang");
    
    
    &compare( $veid, $res{$veid}{'othersockbuf'}->[$LIM] - $res{$veid}{'othersockbuf'}->[$BAR],
    2.5*1024*$res{$veid}{'numothersock'}->[$LIM],
    "othersockbuf(lim-bar)", "numothersock{bytes}", "othersock may hang");
    
    
    &compare( $veid, $res{$veid}{'tcprcvbuf'}->[$LIM] - $res{$veid}{'tcprcvbuf'}->[$BAR],
    2.5*1024*$res{$veid}{'numothersock'}->[$LIM],
    "tcprcvbuf(lim-bar)","numothersock{bytes}","may slow tcp" );
    
    
    if( $res{$veid}{'tcprcvbuf'}->[$BAR] < 65535 ) {
        print "$veid: tcprcvbuf too low (<64k)\n";
    }
    
    
    if( $res{$veid}{'tcpsndbuf'}->[$BAR] < 65535 ) {
        print "$veid: tcpsndbuf too low (<64k)\n";
    }
    
    
    if( $res{$veid}{'dgramrcvbuf'}->[$BAR] < 131200 ) {
        print "$veid: dgramrcvbuf too low (<129k)\n";
    }
    
    
    if( $res{$veid}{'othersockbuf'}->[$BAR] < 131200 ) {
        print "$veid: othersockbuf too low (<129k)\n";
    }
    
    
    # numfile < avgnumproc*32
    # ...
    
    if( $res{$veid}{'dcachesize'}->[$BAR] < 
      $res{$veid}{'numfile'}->[$MAX] * 384 ) {
        print "$veid: dcachesize likely low for dentry and inode allocs\n";
    }
    
    
    foreach my $param (keys %{$res{$veid}}) {
        &compare( $veid, $res{$veid}{$param}->[$LIM], $res{$veid}{$param}->[$BAR],
                "limit", "barrier", "problem with $param" );
    }
}



sub compare {
    my ($veid, $large, $small, $ltext, $stext, $text) = @_;
    
    if( $large < $small ) {
        # bad...
        print "VE $veid: $text ($ltext=$large < $stext=$small)\n";
    }
    return;
}



sub pretty($) {
    return sprintf("%6.4f", shift);
}