Index: ossp-pkg/snmpdx/snmpdx.d/sysVM.pm RCS File: /v/ossp/cvs/ossp-pkg/snmpdx/snmpdx.d/sysVM.pm,v co -q -kk -p'1.11' '/v/ossp/cvs/ossp-pkg/snmpdx/snmpdx.d/sysVM.pm,v' | diff -u /dev/null - -L'ossp-pkg/snmpdx/snmpdx.d/sysVM.pm' 2>/dev/null --- ossp-pkg/snmpdx/snmpdx.d/sysVM.pm +++ - 2025-05-20 20:54:08.362937392 +0200 @@ -0,0 +1,371 @@ +## +## OSSP snmpdx - SNMP Daemon Extension +## Copyright (c) 2003 The OSSP Project +## Copyright (c) 2003 Ralf S. Engelschall +## Copyright (c) 2003 Cable & Wireless +## +## This file is part of OSSP snmpdx, a SNMP daemon extension which +## can be found at http://www.ossp.org/pkg/tool/snmpdx/. +## +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either version +## 2.0 of the License, or (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this file; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +## USA, or contact Ralf S. Engelschall . +## +## sysVM.pm: probe for System Virtual Memory +## + +package My::Probe::sysVM; +our @ISA = qw(My::Probe); + +sub oids ($) { + my ($self) = @_; + return $self->{-ctx}->{-mib}->oids("*.snmpdx.host.system.sysVM.*"); +} + +sub probe ($$) { + my ($self, $obj) = @_; + + if ($self->{-ctx}->{-platform}->id() =~ m/FreeBSD/i) { + ## + ## FreeBSD 4/5 + ## + ## sysVMRamMax "/sbin/sysctl -a", "hw.physmem", convert bytes to MB + ## sysVMRamUsed sysVMRamMax - sysVMRamFree + ## sysVMRamFree "/sbin/sysctl -a", "vm.stats.vm.*", convert pages to MB + ## sysVMSwapMax "/usr/sbin/swapinfo -k", 1K-blocks, last line, convert KB to MB + ## sysVMSwapUsed "/usr/sbin/swapinfo -k", Used, last line, convert KB to MB + ## sysVMSwapFree sysVMSwapMax - sysVMSwapUsed + ## sysVMActivity "/usr/bin/vmstat", add pi and po column + ## + if ($obj->{-name} =~ m/\.sysVMRam(Max|Used|Free)$/) { + my $sysVMRamMax; + my $sysVMRamUsed; + my $sysVMRamFree; + + # query system for sysctl(8) variables + my $out = $self->{-ctx}->{-sys}->run("/sbin/sysctl -a", "1m"); + my $sysctl = {}; + foreach my $line (split(/\n/, $out->{-stdout})) { + $sysctl->{$1} = $2 if ($line =~ m/^([^:]+):\s+(.+)\s*$/s); + } + + # determine sysVMRamMax + $sysVMRamMax = int(&mem_rounded($sysctl->{"hw.physmem"}) / (1024*1024)); + + # determine sysVMRamFree + $sysVMRamFree = + int(( $sysctl->{"hw.pagesize"} + * ( $sysctl->{"vm.stats.vm.v_inactive_count"} + + $sysctl->{"vm.stats.vm.v_cache_count"} + + $sysctl->{"vm.stats.vm.v_free_count"} )) / (1024*1024)); + + # determine sysVMRamUsed + if (defined($sysVMRamMax) and defined($sysVMRamFree)) { + $sysVMRamUsed = ($sysVMRamMax - $sysVMRamFree); + } + + # provide result + $obj->{-value} = $sysVMRamMax if ($obj->{-name} =~ m/\.sysVMRamMax$/); + $obj->{-value} = $sysVMRamUsed if ($obj->{-name} =~ m/\.sysVMRamUsed$/); + $obj->{-value} = $sysVMRamFree if ($obj->{-name} =~ m/\.sysVMRamFree$/); + } + elsif ($obj->{-name} =~ m/\.sysVMSwap(Max|Used|Free)$/) { + my $sysVMSwapMax; + my $sysVMSwapUsed; + my $sysVMSwapFree; + + # determine sysVMSwapMax and sysVMSwapUsed + my $out = $self->{-ctx}->{-sys}->run("/usr/sbin/swapinfo -k", "1m"); + my $raw = $out->{-stdout}; + my $n2i = {}; + if ($raw =~ m/^\s*([^\n]*\b1K-blocks[^\n]*\bUsed[^\n]*).*\n([^\n]+)$/s) { + $n2i = &mkn2i(split(/\s+/, $1)); + } + my @dat = split(/\s+/, $2); + if (defined($n2i->{_1K_blocks})) { + $sysVMSwapMax = int(@dat[$n2i->{_1K_blocks}] / 1024) + } + if (defined($n2i->{Used})) { + $sysVMSwapUsed = int(@dat[$n2i->{Used}] / 1024) + } + + # determine sysVMSwapFree + if (defined($sysVMSwapMax) and defined($sysVMSwapUsed)) { + $sysVMSwapFree = $sysVMSwapMax - $sysVMSwapUsed; + } + + # provide result + $obj->{-value} = $sysVMSwapMax if ($obj->{-name} =~ m/\.sysVMSwapMax$/); + $obj->{-value} = $sysVMSwapUsed if ($obj->{-name} =~ m/\.sysVMSwapUsed$/); + $obj->{-value} = $sysVMSwapFree if ($obj->{-name} =~ m/\.sysVMSwapFree$/); + } + elsif ($obj->{-name} =~ m/\.sysVMActivity$/) { + my $sysVMActivity; + + my $out = $self->{-ctx}->{-sys}->run("/usr/bin/vmstat", "1m"); + my $raw = $out->{-stdout}; + my $n2i = {}; + if ($raw =~ m/^[^\n]*\n *([^\n]*(\bp[io]\b[^\n]*){2})\n *([^\n]*)\n$/s) { + $n2i = &mkn2i(split / +/, $1); + } + if (defined($n2i->{pi}) and defined($n2i->{po})) { + my @dat = split(/ +/, $3); + $sysVMActivity = @dat[$n2i->{pi}] + @dat[$n2i->{po}]; + } + $obj->{-value} = $sysVMActivity; + } + } + elsif ($self->{-ctx}->{-platform}->id() =~ m/Linux/i) { + ## + ## Linux 2.2/2.4 + ## + ## sysVMRamMax "/bin/cat /proc/meminfo", MemTotal, convert KB to MB + ## sysVMRamUsed "/bin/cat /proc/meminfo", MemTotal-Buffers-Cached-MemFree, convert KB to MB + ## sysVMRamFree sysVMRamMax - sysVMRamUsed + ## sysVMSwapMax "/bin/cat /proc/meminfo", SwapTotal, convert KB to MB + ## sysVMSwapUsed sysVMSwapMax - sysVMSwapFree + ## sysVMSwapFree "/bin/cat /proc/meminfo", SwapFree, convert KB to MB + ## sysVMActivity "/usr/bin/vmstat", add si and so column + ## + ## FIXME: sysVMRamMax does not include the kernel and some of + ## its structures so it is not pyhsical RAM, see dmesg | egrep + ## '^Memory:'. Additionally, /bin/cat is used here but could be + ## replaced by native Perl code to improve performance... + ## + if ($obj->{-name} =~ m/\.sysVMRam(Max|Used|Free)$/) { + my $sysVMRamMax; + my $sysVMRamUsed; + my $sysVMRamFree; + + # determine sysVMRamMax and sysVMRamUsed + my $out = $self->{-ctx}->{-sys}->run("/bin/cat /proc/meminfo", "1m"); + my $raw = $out->{-stdout}; + my $tmp = {}; + $tmp->{MemTotal} = $1 if ($raw =~ m/\nMemTotal:[^\n]*\b(\d+)\b[^\n]*kB\n/s); + $tmp->{Buffers} = $1 if ($raw =~ m/\nBuffers:[^\n]*\b(\d+)\b[^\n]*kB\n/s); + $tmp->{Cached} = $1 if ($raw =~ m/\nCached:[^\n]*\b(\d+)\b[^\n]*kB\n/s); + $tmp->{MemFree} = $1 if ($raw =~ m/\nMemFree:[^\n]*\b(\d+)\b[^\n]*kB\n/s); + if (defined($tmp->{MemTotal})) { + $sysVMRamMax = int($tmp->{MemTotal} / 1024); + } + if ( defined($tmp->{MemTotal}) + and defined($tmp->{Buffers}) + and defined($tmp->{Cached}) + and defined($tmp->{MemFree}) ) { + $sysVMRamUsed = int (( $tmp->{MemTotal} + - $tmp->{Buffers} + - $tmp->{Cached} + - $tmp->{MemFree} ) / 1024 ); + } + + # determine sysVMRamFree + if (defined $sysVMRamMax and defined $sysVMRamUsed) { + $sysVMRamFree = $sysVMRamMax - $sysVMRamUsed; + } + + # provide result + $obj->{-value} = $sysVMRamMax if ($obj->{-name} =~ m/\.sysVMRamMax$/); + $obj->{-value} = $sysVMRamUsed if ($obj->{-name} =~ m/\.sysVMRamUsed$/); + $obj->{-value} = $sysVMRamFree if ($obj->{-name} =~ m/\.sysVMRamFree$/); + } + elsif ($obj->{-name} =~ m/\.sysVMSwap(Max|Used|Free)$/) { + my $sysVMSwapMax; + my $sysVMSwapUsed; + my $sysVMSwapFree; + + # determine sysVMSwapMax and sysVMSwapFree + my $out = $self->{-ctx}->{-sys}->run("/bin/cat /proc/meminfo", "1m"); + my $raw = $out->{-stdout}; + if ($raw =~ m/\nSwapTotal:[^\n]*\b(\d+)\b[^\n]*kB\n/s) { + $sysVMSwapMax = int($1 / 1024); + } + if ($raw =~ m/\nSwapFree:[^\n]*\b(\d+)\b[^\n]*kB\n/s) { + $sysVMSwapFree = int($1 / 1024); + } + + # determine sysVMSwapUsed + if (defined($sysVMSwapMax) and defined($sysVMSwapFree)) { + $sysVMSwapUsed = $sysVMSwapMax - $sysVMSwapFree; + } + + # provide result + $obj->{-value} = $sysVMSwapMax if ($obj->{-name} =~ m/\.sysVMSwapMax$/); + $obj->{-value} = $sysVMSwapUsed if ($obj->{-name} =~ m/\.sysVMSwapUsed$/); + $obj->{-value} = $sysVMSwapFree if ($obj->{-name} =~ m/\.sysVMSwapFree$/); + } + elsif ($obj->{-name} =~ m/\.sysVMActivity$/) { + my $sysVMActivity; + + my $out = $self->{-ctx}->{-sys}->run("/usr/bin/vmstat", "1m"); + my $raw = $out->{-stdout}; + my $n2i = {}; + if ($raw =~ m/^[^\n]*\n *([^\n]*(\bs[io]\b[^\n]*){2})\n *([^\n]*)\n$/s) { + $n2i = &mkn2i(split(/\s+/, $1)) if (not defined($n2i->{sr})); + } + if (defined($n2i->{si}) and defined($n2i->{so})) { + my @dat = split(/\s+/, $3); + $sysVMActivity = @dat[$n2i->{si}] + @dat[$n2i->{so}]; + } + $obj->{-value} = $sysVMActivity; + } + } + elsif ($self->{-ctx}->{-platform}->id() =~ m/SunOS/i) { + ## + ## Sun Solaris 2.x (SunOS 5.x) + ## + ## sysVMRamMax "/usr/platform/$arch/sbin/prtdiag", Memory size + ## sysVMRamUsed sysVMRamMax - sysVMRamFree + ## sysVMRamFree "/bin/pagesize" * "/bin/sar -r 1 1", freemem, convert bytes to MB + ## sysVMSwapMax "swap -l", egrep ^/ and accumulate, convert 512byte blocks to MB + ## sysVMSwapUsed sysVMSwapMax - sysVMSwapFree + ## sysVMSwapFree "swap -l", egrep ^/ and accumulate, convert 512byte blocks to MB + ## sysVMActivity "/bin/vmstat", sr column + ## + if ($obj->{-name} =~ m/\.sysVMRam(Max|Used|Free)$/) { + my $sysVMRamMax; + my $sysVMRamUsed; + my $sysVMRamFree; + + # determine architecture + my $arch = $self->{-ctx}->{-platform}->arch(); + + # determine page size + my $out = $self->{-ctx}->{-sys}->run("/bin/pagesize", "forever"); + my $raw = $out->{-stdout}; + my $pagesize = 4096; + if ($raw =~ m/^(\d+)$/) { + $pagesize = $1; + } + + # determine sysVMRamMax + $out = $self->{-ctx}->{-sys}->run("/usr/platform/$arch/sbin/prtdiag -v", "1m"); + $raw = $out->{-stdout}; + if ($raw =~ m/\nMemory size: (\d+) Megabytes/s) { + $sysVMRamMax = $1; + } + + # determine sysVMRamFree + $out = $self->{-ctx}->{-sys}->run("/bin/sar -r 1 1", "1m"); + $raw = $out->{-stdout}; + my $n2i = {}; + if ($raw =~ m/^.*\n([^\n]*\bfreemem[^\n]*)\n(.*)$/s) { + $n2i = &mkn2i(split(/\s+/, $1)); + } + my @dat = split(/\s+/, $2); + if (defined($n2i->{freemem})) { + $tmp = @dat[$n2i->{freemem}]; + } + $sysVMRamFree = int($tmp * $pagesize / (1024*1024)) if (defined($tmp)); + + # determine sysVMRamUsed + if (defined($sysVMRamMax) and defined($sysVMRamFree)) { + $sysVMRamUsed = $sysVMRamMax - $sysVMRamFree; + } + + # provide result + $obj->{-value} = $sysVMRamMax if ($obj->{-name} =~ m/\.sysVMRamMax$/); + $obj->{-value} = $sysVMRamUsed if ($obj->{-name} =~ m/\.sysVMRamUsed$/); + $obj->{-value} = $sysVMRamFree if ($obj->{-name} =~ m/\.sysVMRamFree$/); + } + elsif ($obj->{-name} =~ m/\.sysVMSwap(Max|Used|Free)$/) { + my $sysVMSwapMax; + my $sysVMSwapUsed; + my $sysVMSwapFree; + + # determine sysVMSwapMax, sysVMSwapFree + my $out = $self->{-ctx}->{-sys}->run("/usr/sbin/swap -l", "1m"); + my $raw = $out->{-stdout}; + my $n2i = {}; + if ($raw =~ m/^\s*([^\n]*\bblocks[^\n]*\bfree[^\n]*)\n(.*)$/s) { + $n2i = &mkn2i(split(/\s+/, $1)) if (scalar(keys(%{$n2i})) == 0); + } + my $tmpMax; + my $tmpFree; + foreach my $r (split(/\n/, $2)) { + if ($r =~ m/^\//) { + my @dat = split(/\s+/, $r); + if (defined($n2i->{blocks})) { + $tmpMax = 0 if (not defined($tmpMax)); + $tmpMax += @dat[$n2i->{blocks}]; + } + if (defined($n2i->{free})) { + $tmpFree = 0 if (not defined($tmpFree)); + $tmpFree += @dat[$n2i->{free}]; + } + } + } + $sysVMSwapMax = int($tmpMax * 512 / 1024 / 1024) if (defined($tmpMax)); + $sysVMSwapFree = int($tmpFree * 512 / 1024 / 1024) if (defined($tmpFree)); + + # determine sysVMSwapUsed + if (defined($sysVMSwapMax) and defined($sysVMSwapFree)) { + $sysVMSwapUsed = $sysVMSwapMax - $sysVMSwapFree; + } + + # provide result + $obj->{-value} = $sysVMSwapMax if ($obj->{-name} =~ m/\.sysVMSwapMax$/); + $obj->{-value} = $sysVMSwapUsed if ($obj->{-name} =~ m/\.sysVMSwapUsed$/); + $obj->{-value} = $sysVMSwapFree if ($obj->{-name} =~ m/\.sysVMSwapFree$/); + } + elsif ($obj->{-name} =~ m/\.sysVMActivity$/) { + my $sysVMActivity; + + my $out = $self->{-ctx}->{-sys}->run("/bin/vmstat", "1m"); + my $raw = $out->{-stdout}; + my $n2i = {}; + if ($raw =~ m/^[^\n]*\n *([^\n]*\bsr\b[^\n]*)\n *([^\n]*)\n$/s) { + $n2i = &mkn2i(split(/\s+/, $1)) if (not defined($n2i->{sr})); + } + if (defined $n2i->{sr}) { + my @dat = split(/\s+/, $2); + $sysVMActivity = @dat[$n2i->{sr}]; + } + $obj->{-value} = $sysVMActivity; + } + } + return; +} + +# table row name to index mapping +sub mkn2i ($) { + my (@name) = @_; + my $rc = {}; + my $i = 0; + foreach my $f (@name) { + $f =~ s/[^\w]/_/; + $f =~ s/^([^a-zA-Z_])/_$1/; + $rc->{$f} = $i++; + }; + return $rc; +} + +# round the physical memory size to the next power of two which is +# reasonable for memory cards. We do this by first determining the +# guessed memory card size under the assumption that usual computer +# hardware has an average of a maximally eight memory cards installed +# and those are usually of equal size. +sub mem_rounded { + my ($mem_size) = @_; + my $chip_size = 1; + my $chip_guess = ($mem_size / 8) - 1; + while ($chip_guess != 0) { + $chip_guess >>= 1; + $chip_size <<= 1; + } + my $mem_round = (int($mem_size / $chip_size) + 1) * $chip_size; + return $mem_round; +} + +1; +