// // 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