//
// Copyright (c) 1994, 1995, 2002, 2006 by Mike Romberg ( mike.romberg@noaa.gov )
//
// Modifications to support dynamic addresses by:
// Michael N. Lipp (mnl@dtro.e-technik.th-darmstadt.de)
//
// This file may be distributed under terms of the GPL
//
//
// $Id$
//
#include "nfsmeter.h"
#include "xosview.h"
#include <unistd.h>
#include <fstream>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#if defined(GNULIBC) || defined(__GLIBC__)
#include <net/if.h>
#else
#include <linux/if.h>
#endif
#include <netinet/in.h>
#include <errno.h>
#include <iostream>
#include <iomanip>
#ifndef MAX
#define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#endif
#define NFSSVCSTAT "/proc/net/rpc/nfsd"
#define NFSCLTSTAT "/proc/net/rpc/nfs"
NFSMeter::NFSMeter(XOSView *parent, const char *name, int nfields,
char *fields, const char *statfile)
: FieldMeterGraph( parent, nfields, name, fields ){
_statfile = statfile;
_statname = name;
}
NFSMeter::~NFSMeter( void ){
}
void NFSMeter::checkResources( void ){
FieldMeterGraph::checkResources();
}
NFSDStats::NFSDStats(XOSView *parent)
: NFSMeter(parent, "NFSD", 4, "BAD/UDP/TCP/IDLE", NFSSVCSTAT ){
starttimer();
}
NFSDStats::~NFSDStats( void ) {
}
void NFSDStats::checkResources( void ){
NFSMeter::checkResources();
setfieldcolor( 0, parent_->getResource( "NFSDStatBadCallsColor" ) );
setfieldcolor( 1, parent_->getResource( "NFSDStatUDPColor" ) );
setfieldcolor( 2, parent_->getResource( "NFSDStatTCPColor" ) );
setfieldcolor( 3, parent_->getResource( "NFSDStatIdleColor" ) );
useGraph_ = parent_->isResourceTrue( "NFSDStatGraph" );
dodecay_ = parent_->isResourceTrue( "NFSDStatDecay" );
SetUsedFormat (parent_->getResource("NFSDStatUsedFormat"));
//useGraph_ = 1;
//dodecay_ = 1;
//SetUsedFormat ("autoscale");
//SetUsedFormat ("percent");
}
void NFSDStats::checkevent(void)
{
char buf[4096], name[64];
unsigned long netcnt, netudpcnt, nettcpcnt, nettcpconn;
unsigned long calls, badcalls;
int found;
std::ifstream ifs(_statfile);
if (!ifs) {
// cerr <<"Can not open file : " <<_statfile <<endl;
// parent_->done(1);
return;
}
fields_[0] = fields_[1] = fields_[2] = 0; // network activity
stoptimer();
name[0] = '\0';
found = 0;
while (!ifs.eof() && found != 2) {
ifs.getline(buf, 4096, '\n');
if (strncmp("net", buf, strlen("net")) == 0) {
sscanf(buf, "%s %lu %lu %lu %lu\n", name,
&netcnt, &netudpcnt, &nettcpcnt, &nettcpconn);
found++;
}
if (strncmp("rpc", buf, strlen("rpc")) == 0) {
sscanf(buf, "%s %lu %lu\n", name, &calls, &badcalls);
found++;
}
}
float t = 1000000.0 / usecs();
if (t < 0)
t = 0.1;
maxpackets_ = MAX(netcnt, calls) - _lastNetCnt;
if (maxpackets_ == 0) {
maxpackets_ = netcnt;
} else {
fields_[0] = (badcalls - _lastBad) * t;
fields_[1] = (netudpcnt - _lastUdp) * t;
fields_[2] = (nettcpcnt - _lastTcp) * t;
}
total_ = fields_[0] + fields_[1] + fields_[2];
if (total_ > maxpackets_)
fields_[3] = 0;
else {
total_ = maxpackets_;
fields_[3] = total_ - fields_[0] - fields_[1] - fields_[2];
}
if (total_)
setUsed(fields_[0] + fields_[1] + fields_[2], total_);
starttimer();
drawfields();
_lastNetCnt = MAX(netcnt, calls);
_lastTcp = nettcpcnt;
_lastUdp = netudpcnt;
_lastBad = badcalls;
}
NFSStats::NFSStats(XOSView *parent)
: NFSMeter(parent, "NFS", 4, "RETRY/AUTH/CALL/IDLE", NFSCLTSTAT ){
starttimer();
}
NFSStats::~NFSStats( void ) {
}
void NFSStats::checkResources( void ){
NFSMeter::checkResources();
setfieldcolor( 0, parent_->getResource( "NFSStatReTransColor" ) );
setfieldcolor( 1, parent_->getResource( "NFSStatAuthRefrshColor" ) );
setfieldcolor( 2, parent_->getResource( "NFSStatCallsColor" ) );
setfieldcolor( 3, parent_->getResource( "NFSStatIdleColor" ) );
useGraph_ = parent_->isResourceTrue( "NFSStatGraph" );
dodecay_ = parent_->isResourceTrue( "NFSStatDecay" );
SetUsedFormat (parent_->getResource("NFSStatUsedFormat"));
//SetUsedFormat ("autoscale");
//SetUsedFormat ("percent");
}
void NFSStats::checkevent(void)
{
char buf[4096], name[64];
unsigned long calls, retrns, authrefresh, maxpackets_;
std::ifstream ifs(_statfile);
if (!ifs) {
// cerr <<"Can not open file : " <<_statfile <<endl;
// parent_->done(1);
return;
}
fields_[0] = fields_[1] = fields_[2] = 0;
stoptimer();
name[0] = '\0';
while (!ifs.eof()) {
ifs.getline(buf, 4096, '\n');
if (strncmp("rpc", buf, strlen("rpc")))
continue;
sscanf(buf, "%s %lu %lu %lu\n", name, &calls, &retrns, &authrefresh);
break;
}
float t = 1000000.0 / usecs();
if (t < 0)
t = 0.1;
maxpackets_ = calls - _lastcalls;
if (maxpackets_ == 0) {
maxpackets_ = calls;
} else {
fields_[2] = (calls - _lastcalls) * t;
fields_[1] = (authrefresh - _lastauthrefresh) * t;
fields_[0] = (retrns - _lastretrns) * t;
}
total_ = fields_[0] + fields_[1] + fields_[2];
if (total_ > maxpackets_)
fields_[3] = 0;
else {
total_ = maxpackets_;
fields_[3] = total_ - fields_[2] - fields_[1] - fields_[0];
}
if (total_)
setUsed(fields_[0] + fields_[1] + fields_[2], total_);
starttimer();
drawfields();
_lastcalls = calls;
_lastretrns = retrns;
_lastauthrefresh = authrefresh;
}
#if 0
NFSV3::NFSV3( XOSView *parent)
: BitMeter( parent, "NFSv3", "", 1, 0, 0 ) {
setNumBits(23);
legend("Version 3");
for ( int i = 0 ; i < numBits() ; i++ )
procs[i] = lastprocs[i] = 0;
}
NFSV3::~NFSV3( void ) {
}
void NFSV3::checkResources( void ){
BitMeter::checkResources();
onColor_ = parent_->allocColor( parent_->getResource( "NFSv3OnColor" ) );
offColor_ = parent_->allocColor( parent_->getResource( "NFSv3OffColor" ) );
}
void NFSV3::checkevent( void ){
getirqs();
for ( int i = 0 ; i < numBits() ; i++ ){
bits_[i] = ((irqs_[i] - lastirqs_[i]) != 0);
lastirqs_[i] = irqs_[i];
}
BitMeter::checkevent();
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1