AFS-Monitor

 view release on metacpan or  search on metacpan

src/Monitor.xs  view on Meta::CPAN

/***********************************************************************
 *
 * AFS.xs - AFS extensions for Perl
 *
 * RCS-Id: @(#)$Id: Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $
 *
 * Copyright (c) 2003, International Business Machines Corporation and others.
 *
 * This software has been released under the terms of the IBM Public
 * License.  For details, see the IBM-LICENSE file in the LICENCES
 * directory or online at http://www.openafs.org/dl/license10.html
 *
 * Contributors
 *         2004-2006: Elizabeth Cassell <e_a_c@mailsnare.net>
 *                    Alf Wachsmann <alfw@slac.stanford.edu>
 *
 * The code for the original library were mainly taken from the AFS
 * source distribution, which comes with this message:
 *
 *    Copyright (C) 1989-1994 Transarc Corporation - All rights reserved
 *    P_R_P_Q_# (C) COPYRIGHT IBM CORPORATION 1987, 1988, 1989
 *
 ***********************************************************************/

#include "EXTERN.h"

#ifdef __sgi    /* needed to get a clean compile */
#include <setjmp.h>
#endif

#include <stdarg.h>

#include "perl.h"
#include "XSUB.h"
#include "ppport.h"

#include <afs/afsint.h>

#include <afs/kautils.h>

#include <afs/xstat_fs.h>
#include <afs/xstat_cm.h>
#include "afsmon-labels.h"  /* labels for afsmonitor variables */

#include <afs/fsprobe.h>

/* from volser/volser_prototypes.h */
extern void MapPartIdIntoName(afs_int32 partId, char *partName);


#if defined(AFS_3_4) || defined(AFS_3_5)
#else
#define int32 afs_int32
#define uint32 afs_uint32
#endif

const char *const xs_version = "Monitor.xs (Major Version 0.2 $Rev: 609 $)";

extern char *error_message();
extern struct hostent *hostutil_GetHostByName();
extern char *hostutil_GetNameByINet();

/* error handling macros */

#define SETCODE(code) set_code(code)
#define FSSETCODE(code) {if (code == -1) set_code(errno); else set_code(code);}
#define BSETCODE(code, msg) bv_set_code(code, msg)
#define VSETCODE(code, msg) bv_set_code(code, msg)

static int32 raise_exception = 0;


static void
bv_set_code(code, msg)
   int32 code;
   const char *msg;
{
   SV *sv = perl_get_sv("AFS::CODE", TRUE);
   sv_setiv(sv, (IV) code);
   if (code == 0) {
      sv_setpv(sv, "");
   }
   else {
      if (raise_exception) {
         char buffer[1024];
         sprintf(buffer, "AFS exception: %s (%d)", msg, code);
         croak(buffer);
      }
      sv_setpv(sv, (char *)msg);
   }
   SvIOK_on(sv);
}

static void
set_code(code)
   int32 code;
{
   SV *sv = perl_get_sv("AFS::CODE", TRUE);
   sv_setiv(sv, (IV) code);
   if (code == 0) {
      sv_setpv(sv, "");
   }
   else {
      if (raise_exception) {
         char buffer[1024];
         sprintf(buffer, "AFS exception: %s (%d)", error_message(code), code);
         croak(buffer);

src/Monitor.xs  view on Meta::CPAN


static short
rxdebug_PortName(char *aname)
{
   register struct servent *ts;
   ts = getservbyname(aname, (char *) NULL);
   if (!ts)
      return -1;
   return ts->s_port;   /* returns it in network byte order */
}


/*
 * replaces rx_PrintTheseStats() in original c code.
 * places stats in RXSTATS instead of printing them
 * from src/rx/rx.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

static void
myPrintTheseStats(HV *RXSTATS, struct rx_statistics *rxstats)
{
   HV *PACKETS;
   HV *TYPE;
   HV *TOTALRTT;
   HV *MINRTT;
   HV *MAXRTT;
   int i;
   int num_unused;

   hv_store(RXSTATS, "packetRequests", 14, newSViv(rxstats->packetRequests),
            0);

   hv_store(RXSTATS, "receivePktAllocFailures", 23,
            newSViv(rxstats->receivePktAllocFailures), 0);
   hv_store(RXSTATS, "receiveCbufPktAllocFailures", 27,
            newSViv(rxstats->receiveCbufPktAllocFailures), 0);
   hv_store(RXSTATS, "sendPktAllocFailures", 20,
            newSViv(rxstats->sendPktAllocFailures), 0);
   hv_store(RXSTATS, "sendCbufPktAllocFailures", 24,
            newSViv(rxstats->sendCbufPktAllocFailures), 0);
   hv_store(RXSTATS, "specialPktAllocFailures", 23,
            newSViv(rxstats->specialPktAllocFailures), 0);

   hv_store(RXSTATS, "socketGreedy", 12, newSViv(rxstats->socketGreedy), 0);
   hv_store(RXSTATS, "bogusPacketOnRead", 17,
            newSViv(rxstats->bogusPacketOnRead), 0);
   hv_store(RXSTATS, "bogusHost", 9, newSViv(rxstats->bogusHost), 0);
   hv_store(RXSTATS, "noPacketOnRead", 14, newSViv(rxstats->noPacketOnRead),
            0);
   hv_store(RXSTATS, "noPacketBuffersOnRead", 21,
            newSViv(rxstats->noPacketBuffersOnRead), 0);
   hv_store(RXSTATS, "selects", 7, newSViv(rxstats->selects), 0);
   hv_store(RXSTATS, "sendSelects", 11, newSViv(rxstats->sendSelects), 0);


   PACKETS = newHV();
   num_unused = 0;

   for (i = 0; i < RX_N_PACKET_TYPES; i++) {
      char *packet_type = rx_packetTypes[i];
      TYPE = newHV();
      hv_store(TYPE, "packetsRead", 11, newSViv(rxstats->packetsRead[i]), 0);
      hv_store(TYPE, "packetsSent", 11, newSViv(rxstats->packetsSent[i]), 0);
      if (packet_type == "unused") {
         /* rename "unused" types */
         /* can't have several entries in a hash with same name */
         char packet_type_unused[7];
         sprintf(packet_type_unused, "unused%d", num_unused);
         packet_type = packet_type_unused;
         num_unused++;
      }
      hv_store(PACKETS, packet_type, strlen(packet_type),
               newRV_inc((SV *) (TYPE)), 0);
   }
   hv_store(RXSTATS, "packets", 7, newRV_inc((SV *) (PACKETS)), 0);

   hv_store(RXSTATS, "dataPacketsRead", 15, newSViv(rxstats->dataPacketsRead),
            0);
   hv_store(RXSTATS, "ackPacketsRead", 14, newSViv(rxstats->ackPacketsRead),
            0);
   hv_store(RXSTATS, "dupPacketsRead", 14, newSViv(rxstats->dupPacketsRead),
            0);
   hv_store(RXSTATS, "spuriousPacketsRead", 19,
            newSViv(rxstats->spuriousPacketsRead), 0);
   hv_store(RXSTATS, "ignorePacketDally", 17,
            newSViv(rxstats->ignorePacketDally), 0);

   hv_store(RXSTATS, "pingPacketsSent", 15, newSViv(rxstats->pingPacketsSent),
            0);
   hv_store(RXSTATS, "abortPacketsSent", 16,
            newSViv(rxstats->abortPacketsSent), 0);
   hv_store(RXSTATS, "busyPacketsSent", 15, newSViv(rxstats->busyPacketsSent),
            0);

   hv_store(RXSTATS, "ackPacketsSent", 14, newSViv(rxstats->ackPacketsSent),
            0);
   hv_store(RXSTATS, "dataPacketsSent", 15, newSViv(rxstats->dataPacketsSent),
            0);
   hv_store(RXSTATS, "dataPacketsReSent", 17,
            newSViv(rxstats->dataPacketsReSent), 0);
   hv_store(RXSTATS, "dataPacketsPushed", 17,
            newSViv(rxstats->dataPacketsPushed), 0);
   hv_store(RXSTATS, "ignoreAckedPacket", 17,
            newSViv(rxstats->ignoreAckedPacket), 0);

   hv_store(RXSTATS, "netSendFailures", 15, newSViv(rxstats->netSendFailures),
            0);
   hv_store(RXSTATS, "fatalErrors", 11, newSViv(rxstats->fatalErrors), 0);

   hv_store(RXSTATS, "nServerConns", 12, newSViv(rxstats->nServerConns), 0);
   hv_store(RXSTATS, "nClientConns", 12, newSViv(rxstats->nClientConns), 0);
   hv_store(RXSTATS, "nPeerStructs", 12, newSViv(rxstats->nPeerStructs), 0);
   hv_store(RXSTATS, "nCallStructs", 12, newSViv(rxstats->nCallStructs), 0);
   hv_store(RXSTATS, "nFreeCallStructs", 16,
            newSViv(rxstats->nFreeCallStructs), 0);

   hv_store(RXSTATS, "nRttSamples", 11, newSViv(rxstats->nRttSamples), 0);

   TOTALRTT = newHV();
   hv_store(TOTALRTT, "sec", 3, newSViv(rxstats->totalRtt.sec), 0);
   hv_store(TOTALRTT, "usec", 4, newSViv(rxstats->totalRtt.usec), 0);
   hv_store(RXSTATS, "totalRtt", 8, newRV_inc((SV *) (TOTALRTT)), 0);
   MINRTT = newHV();
   hv_store(MINRTT, "sec", 3, newSViv(rxstats->minRtt.sec), 0);
   hv_store(MINRTT, "usec", 4, newSViv(rxstats->minRtt.usec), 0);
   hv_store(RXSTATS, "minRtt", 6, newRV_inc((SV *) (MINRTT)), 0);
   MAXRTT = newHV();
   hv_store(MAXRTT, "sec", 3, newSViv(rxstats->maxRtt.sec), 0);
   hv_store(MAXRTT, "usec", 4, newSViv(rxstats->maxRtt.usec), 0);
   hv_store(RXSTATS, "maxRtt", 6, newRV_inc((SV *) (MAXRTT)), 0);

#if !defined(AFS_PTHREAD_ENV) && !defined(AFS_USE_GETTIMEOFDAY)

src/Monitor.xs  view on Meta::CPAN

struct cm_Display_Data {
   char hostName[HOST_NAME_LEN];
   int probeOK;                 /* 0 => probe failed */
   char data[NUM_CM_STAT_ENTRIES][CM_STAT_STRING_LEN];
   short threshOvf[NUM_CM_STAT_ENTRIES];    /* overflow flags */
   int ovfCount;                /* overflow count */
};



/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

/* wouldn't compile without this, but it wasn't in original afsmonitor.c */
#if !defined(__USE_GNU) && !defined(__APPLE_CC__)
char *
strcasestr(char *s1, char *s2)
{
   char *ptr;
   int len1, len2;

   len1 = strlen(s1);
   len2 = strlen(s2);

   if (len1 < len2)
      return ((char *)NULL);

   ptr = s1;

   while (len1 >= len2 && len1 > 0) {
      if ((strncasecmp(ptr, s2, len2)) == 0)
         return (ptr);
      ptr++;
      len1--;
   }
   return ((char *)NULL);
}
#endif           /* __USE_GNU */


/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

struct hostent *
GetHostByName(char *name)
{
   struct hostent *he;
#ifdef AFS_SUN5_ENV
   char ip_addr[32];
#endif

   he = gethostbyname(name);
#ifdef AFS_SUN5_ENV
   /* On solaris the above does not resolve hostnames to full names */
   if (he != NULL) {
      memcpy(ip_addr, he->h_addr, he->h_length);
      he = gethostbyaddr(ip_addr, he->h_length, he->h_addrtype);
   }
#endif
   return (he);
}


/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

/*
 * Constructs a string to pass back to Perl for easy execution of the threshold handler.
 * DOES NOT execute the threshold handler.
 *
 * from src/afsmonitor/afsmonitor.c
 *
 * int
 * execute_thresh_handler(a_handler, a_hostName, a_hostType,
 *                         a_threshName,a_threshValue, a_actValue)
 * char *a_handler;
 * char *a_hostName;
 * int a_hostType;
 * char *a_threshName;
 * char *a_threshValue;
 * char *a_actValue;
 */

int
my_execute_thresh_handler(a_handler, a_hostName, a_hostType, a_threshName,
                          a_threshValue, a_actValue,
                          ENTRY, buffer)
   char *a_handler;             /* ptr to handler function + args */
   char *a_hostName;            /* host name for which threshold crossed */
   int a_hostType;              /* fs or cm ? */
   char *a_threshName;          /* threshold variable name */
   char *a_threshValue;         /* threshold value */
   char *a_actValue;            /* actual value */
   HV *ENTRY;
   char *buffer;
{
   char fileName[256];          /* file name to execute */
   int i;
   char *ch;
   int argNum;
   int anotherArg;              /* boolean used to flag if another arg is available */
   char args[20 * 256] = "";
   char fsHandler_args[20][256];


   /* get the filename to execute - the first argument */
   sscanf(a_handler, "%s", fileName);

   /* construct the contents of *argv[] */

   strncpy(fsHandler_args[0], fileName, 256);
   strncpy(fsHandler_args[1], a_hostName, HOST_NAME_LEN);
   if (a_hostType == FS)
      strcpy(fsHandler_args[2], "fs");
   else

src/Monitor.xs  view on Meta::CPAN

      switch (lastHostType) {
        case 0:    /* its a global threshold */
           (*global_fsThreshCount)++;
           break;
        case 1:    /* inc thresh count of last file server */
           last_hostEntry->numThresh++;
           break;
        case 2:
           sprintf(buffer,
                   "A threshold for a File Server cannot be placed after a Cache Manager host entry in the config file");
           return (-1);
        default:
           sprintf(buffer, "Programming error 1");
           return (-1);
      }
   }
   else if ((strcasecmp(arg1, "cm")) == 0) {
      switch (lastHostType) {
        case 0:    /* its a global threshold */
           (*global_cmThreshCount)++;
           break;
        case 2:    /* inc thresh count of last cache manager */
           last_hostEntry->numThresh++;
           break;
        case 1:
           sprintf(buffer,
                   "A threshold for a Cache Manager cannot be placed after a File Server host entry in the config file");
           return (-1);
        default:
           sprintf(buffer, "Programming error 2");
           return (-1);
      }
   }
   else {
      sprintf(buffer,
              "Syntax error. Second argument should be \"fs\" or \"cm\"");
      return (-1);
   }

   return (0);
}   /* my_parse_threshEntry() */



/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

int
my_parse_showEntry(a_line, fs_showDefault, cm_showDefault, fs_showFlags,
                   cm_showFlags, buffer)
   char *a_line;
   int *fs_showDefault;
   int *cm_showDefault;
   short *fs_showFlags;
   short *cm_showFlags;
   char *buffer;
{

   char opcode[CFG_STR_LEN];    /* specifies type of config entry */
   char arg1[CFG_STR_LEN];      /* show fs or cm entry ? */
   char arg2[CFG_STR_LEN];      /* what we gotta show  */
   char arg3[CFG_STR_LEN];      /* junk */
   char catName[CFG_STR_LEN];   /* for category names */
   int numGroups = 0;           /* number of groups in a section */
   int fromIdx = 0;
   int toIdx = 0;
   int found = 0;
   int idx = 0;                 /* index to fs_categories[] */
   int i = 0;
   int j = 0;

   extern char *fs_varNames[];
   extern char *cm_varNames[];
   extern char *fs_categories[];    /* file server data category names */
   extern char *cm_categories[];    /* cache manager data category names */

   opcode[0] = 0;
   arg1[0] = 0;
   arg2[0] = 0;
   arg3[0] = 0;
   sscanf(a_line, "%s %s %s %s", opcode, arg1, arg2, arg3);

   if (arg3[0] != '\0') {
      sprintf(buffer, "Extraneous characters at end of line");
      return (-1);
   }

   if ((strcasecmp(arg1, "fs") != 0) && (strcasecmp(arg1, "cm") != 0)) {
      sprintf(buffer,
              "Second argument of \"show\" directive should be \"fs\" or \"cm\"");
      return (-1);
   }

   /* Each entry can either be a variable name or a section/group name. Variable
    * names are listed in xx_varNames[] and section/group names in xx_categories[].
    * The section/group names in xx_categiries[] also give the starting/ending
    * indices of the variables belonging to that section/group. These indices
    * are stored in order in xx_Display_map[] and displayed to the screen in that
    * order. */

   /* To handle duplicate "show" entries we keep track of what what we have
    * already marked to show in the xx_showFlags[] */

   if (strcasecmp(arg1, "fs") == 0) {   /* its a File Server entry */
      /* mark that we have to show only what the user wants */
      *fs_showDefault = 0;

      /* if it is a section/group name, find it in the fs_categories[] array */

      found = 0;
      if (strcasestr(arg2, "_section") != (char *)NULL
          || strcasestr(arg2, "_group") != (char *)NULL) {
         idx = 0;
         while (idx < FS_NUM_DATA_CATEGORIES) {
            sscanf(fs_categories[idx], "%s %d %d", catName, &fromIdx, &toIdx);
            idx++;
            if (strcasecmp(arg2, catName) == 0) {
               found = 1;
               break;

src/Monitor.xs  view on Meta::CPAN

   struct afsmon_hostEntry **FSnameList;
   struct afsmon_hostEntry **CMnameList;
   char *buffer;
{
   char opcode[CFG_STR_LEN];
   char arg1[CFG_STR_LEN];
   char arg2[CFG_STR_LEN];
   struct hostent *he = 0;
   int code = 0;

   opcode[0] = 0;
   arg1[0] = 0;
   arg2[0] = 0;

   sscanf(a_line, "%s %s %s", opcode, arg1, arg2);
   if ((strlen(arg2)) != 0) {
      sprintf(buffer, "Extraneous characters at end of line");
      return (-1);
   }

   he = GetHostByName(arg1);
   if (he == NULL) {
      sprintf(buffer, "Unable to resolve hostname %s", arg1);
      return (-1);
   }

   if ((strcasecmp(opcode, "fs")) == 0) {
      /* use the complete host name to insert in the file server names list */
      code = my_insert_FS(he->h_name, FSnameList, last_hostEntry);
      if (code) {
         return (-1);
      }
      /* note that last host entry in the config file was fs */
      (*lastHostType) = 1;
      (*numFS)++;
   }
   else if ((strcasecmp(opcode, "cm")) == 0) {
      /* use the complete host name to insert in the CM names list */
      code = my_insert_CM(he->h_name, CMnameList, last_hostEntry);
      if (code)
         return (-1);
      /* last host entry in the config file was cm */
      (*lastHostType) = 2;
      (*numCM)++;
   }
   else {
      return (-1);
   }

   return (0);
}   /* my_parse_hostEntry() */



/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

int
my_store_threshold(a_type, a_varName, a_value, a_handler, global_TC,
                   Header, hostname, srvCount, buffer)
   int a_type;                  /* 1 = fs , 2 = cm */
   char *a_varName;             /* threshold name */
   char *a_value;               /* threshold value */
   char *a_handler;             /* threshold overflow handler */
   int *global_TC;              /* ptr to global_xxThreshCount */
   struct afsmon_hostEntry *Header; /* tmp ptr to hostEntry list header */
   char *hostname;
   int srvCount;                /* tmp count of host names */
   char *buffer;
{

   struct afsmon_hostEntry *tmp_host = 0;   /* tmp ptr to hostEntry */
   struct Threshold *threshP = 0;   /* tmp ptr to threshold list */
   int index = 0;               /* index to fs_varNames or cm_varNames */
   int found = 0;
   int done = 0;
   int i = 0, j = 0;

   /* resolve the threshold variable name */
   found = 0;
   if (a_type == FS) {  /* fs threshold */
      for (index = 0; index < NUM_FS_STAT_ENTRIES; index++) {
         if (strcasecmp(a_varName, fs_varNames[index]) == 0) {
            found = 1;
            break;
         }
      }
      if (!found) {
         sprintf(buffer, "Unknown FS threshold variable name %s", a_varName);
         return (-1);
      }
   }
   else if (a_type == CM) { /* cm threshold */
      for (index = 0; index < NUM_CM_STAT_ENTRIES; index++) {
         if (strcasecmp(a_varName, cm_varNames[index]) == 0) {
            found = 1;
            break;
         }
      }
      if (!found) {
         sprintf(buffer, "Unknown CM threshold variable name %s", a_varName);
         return (-1);
      }
   }
   else
      return (-1);

   /* if the global thresh count is not zero, place this threshold on
    * all the host entries  */

   if (*global_TC) {
      tmp_host = Header;
      for (i = 0; i < srvCount; i++) {
         threshP = tmp_host->thresh;
         done = 0;
         for (j = 0; j < tmp_host->numThresh; j++) {
            if ((threshP->itemName[0] == '\0') ||
                (strcasecmp(threshP->itemName, a_varName) == 0)) {
               strncpy(threshP->itemName, a_varName, THRESH_VAR_NAME_LEN);
               strncpy(threshP->threshVal, a_value, THRESH_VAR_LEN);
               strcpy(threshP->handler, a_handler);
               threshP->index = index;
               done = 1;
               break;
            }
            threshP++;
         }
         if (!done) {
            sprintf(buffer,
                    "Could not insert threshold entry for %s in thresh list of host %s",
                    a_varName, tmp_host->hostName);
            return (-1);
         }
         tmp_host = tmp_host->next;
      }
      (*global_TC)--;
      return (0);
   }

   /* it is not a global threshold, insert it in the thresh list of this
    * host only. We overwrite the global threshold if it was already set */

   if (*hostname == '\0') {
      sprintf(buffer, "Programming error 3");
      return (-1);
   }

   /* get the hostEntry that this threshold belongs to */
   tmp_host = Header;
   found = 0;
   for (i = 0; i < srvCount; i++) {
      if (strcasecmp(tmp_host->hostName, hostname) == 0) {
         found = 1;
         break;
      }
      tmp_host = tmp_host->next;
   }
   if (!found) {
      sprintf(buffer, "Unable to find host %s in %s hostEntry list", hostname,
              (a_type - 1) ? "CM" : "FS");
      return (-1);
   }

   /* put this entry on the thresh list of this host, overwrite global value
    * if needed */

   threshP = tmp_host->thresh;
   done = 0;
   for (i = 0; i < tmp_host->numThresh; i++) {
      if ((threshP->itemName[0] == '\0') ||
          (strcasecmp(threshP->itemName, a_varName) == 0)) {
         strncpy(threshP->itemName, a_varName, THRESH_VAR_NAME_LEN);
         strncpy(threshP->threshVal, a_value, THRESH_VAR_LEN);
         strcpy(threshP->handler, a_handler);
         threshP->index = index;
         done = 1;
         break;
      }
      threshP++;
   }

   if (!done) {
      sprintf(buffer, "Unable to insert threshold %s for %s host %s",
              a_varName, (a_type - 1) ? "CM" : "FS", tmp_host->hostName);
      return (-1);
   }

   return (0);

}   /* my_store_threshold() */



/*
 * from /src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 *
 * int
 * check_fs_thresholds(a_hostEntry, a_Data)
 * struct afsmon_hostEntry *a_hostEntry;
 * struct fs_Display_Data *a_Data;
 *
 * and
 *
 * int
 * check_cm_thresholds(a_hostEntry, a_Data)
 * struct afsmon_hostEntry *a_hostEntry;
 * struct cm_Display_Data *a_Data;
 */

int
my_check_thresholds(a_hostEntry, HOSTINFO, type, buffer)
   struct afsmon_hostEntry *a_hostEntry;    /* ptr to hostEntry */
   HV *HOSTINFO;                /* ptr to data to be displayed */
   int type;
   char *buffer;
{

   struct Threshold *threshP;
   double tValue = 0;           /* threshold value */
   double pValue = 0;           /* probe value */
   int i;
   int idx;
   int count;                   /* number of thresholds exceeded */
   HV *SECTION;
   HV *GROUP;
   HV *VALUE;
   int found;
   char *key;
   I32 keylen;
   char strval[256];
   int code = 0;
   char *varName;

   if (a_hostEntry->numThresh == 0) {
      /* store in ovf count ?? */
      return (0);
   }

   count = 0;
   threshP = a_hostEntry->thresh;
   for (i = 0; i < a_hostEntry->numThresh; i++) {
      found = 0;

      if (threshP->itemName[0] == '\0') {
         threshP++;
         continue;
      }

      idx = threshP->index; /* positional index to the data array */
      tValue = atof(threshP->threshVal);    /* threshold value */
      hv_iterinit(HOSTINFO);


      while ((SECTION = (HV *) hv_iternextsv(HOSTINFO, &key, &keylen))) {

         if (!SvROK(SECTION)
             || SvTYPE(SECTION = (HV *) SvRV(SECTION)) != SVt_PVHV) {
            continue;
         }
         hv_iterinit(SECTION);

         while ((GROUP = (HV *) hv_iternextsv(SECTION, &key, &keylen))) {
            if (!SvROK(GROUP)
                || SvTYPE(GROUP = (HV *) SvRV(GROUP)) != SVt_PVHV) {
               continue;
            }
            if (type == FS)
               varName = fs_varNames[idx];
            else if (type == CM)
               varName = cm_varNames[idx];
            else
               return (-1);

            if (hv_exists(GROUP, varName, strlen(varName))) {
               VALUE = (HV *)
                  SvRV(*hv_fetch(GROUP, varName, strlen(varName), FALSE));
               pValue = SvIV(*hv_fetch(VALUE, "value", 5, FALSE));
               found = 1;
               break;
            }
         }
         if (found)
            break;
      }

      if (!found) {
         threshP++;
         continue;
      }

      if (pValue > tValue) {
         hv_store(VALUE, "overflow", 8, newSViv(1), 0);
         hv_store(VALUE, "threshold", 9, newSVnv(tValue), 0);

         if (threshP->handler[0] != '\0') {
            sprintf(strval, "%g", pValue);
            code = my_execute_thresh_handler(threshP->handler,
                                             a_hostEntry->hostName, type,
                                             threshP->itemName,
                                             threshP->threshVal, strval,
                                             VALUE, buffer);
            if (code) {
               return (code);
            }
         }

         count++;
      }
      threshP++;
   }

   return (0);
}   /* my_check_thresholds() */




/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

int
my_process_config_file(a_config_filename, numFS, numCM, lastHostType,
                       last_hostEntry, fs_showDefault, cm_showDefault,
                       fs_showFlags, cm_showFlags, FSnameList, CMnameList)
   char *a_config_filename;
   int *numFS;
   int *numCM;
   int *lastHostType;
   struct afsmon_hostEntry **last_hostEntry;
   int *fs_showDefault;
   int *cm_showDefault;
   short *fs_showFlags;
   short *cm_showFlags;
   struct afsmon_hostEntry **FSnameList;
   struct afsmon_hostEntry **CMnameList;
{
   char buff1[256] = "";        /* for error messages */
   char buff2[256] = "";        /* for error messages returned from subroutines */
   FILE *configFD = 0;          /* config file descriptor */
   char line[4 * CFG_STR_LEN];  /* a line of config file */
   char opcode[CFG_STR_LEN];    /* specifies type of config entry */
   char arg1[CFG_STR_LEN];      /* hostname or qualifier (fs/cm?)  */
   char arg2[CFG_STR_LEN];      /* threshold variable */
   char arg3[CFG_STR_LEN];      /* threshold value */
   char arg4[CFG_STR_LEN];      /* user's handler  */
   struct afsmon_hostEntry *curr_host = 0;
   struct hostent *he = 0;      /* hostentry to resolve host name */
   char *handlerPtr = 0;        /* ptr to pass theresh handler string */
   int code = 0;                /* error code */
   int linenum = 0;             /* config file line number */
   int threshCount = 0;         /* count of thresholds for each server */
   int error_in_config = 0;     /* syntax errors in config file  ?? */
   int i = 0;
   int numBytes = 0;
   /* int global_ThreshFlag = 1; */
   int global_fsThreshCount = 0;
   int global_cmThreshCount = 0;
   static char last_fsHost[HOST_NAME_LEN];
   static char last_cmHost[HOST_NAME_LEN];

   /* open config file */
   configFD = fopen(a_config_filename, "r");
   if (configFD == (FILE *) NULL) {
      sprintf(buff1, "Failed to open config file %s", a_config_filename);
      BSETCODE(5, buff1);
      return (-1);
   }

   /* parse config file */

   /* First Pass - check syntax and count number of servers and thresholds to monitor */

   *numFS = 0;
   *numCM = 0;
   threshCount = 0;
   error_in_config = 0; /* flag to note if config file has syntax errors */

   while ((fgets(line, CFG_STR_LEN, configFD)) != NULL) {
      opcode[0] = 0;
      arg1[0] = 0;
      arg2[0] = 0;
      arg3[0] = 0;
      arg4[0] = 0;
      sscanf(line, "%s %s %s %s %s", opcode, arg1, arg2, arg3, arg4);
      linenum++;
      /* fprintf(STDERR, "Got line %d: \"%s %s %s %s %s\"\n",
       * linenum, opcode, arg1, arg2, arg3, arg4); */
      /* skip blank lines and comment lines */
      if ((strlen(opcode) == 0) || line[0] == '#') {
         /* fprintf(STDERR, " - skipping line %d\n", linenum); */
         continue;
      }
      if ((strcasecmp(opcode, "fs") == 0) || (strcasecmp(opcode, "cm")) == 0) {
         /* fprintf(STDERR, " - parsing host entry\n"); */
         code =
            my_parse_hostEntry(line, numFS, numCM, lastHostType,
                               last_hostEntry, FSnameList, CMnameList, buff2);
         /* thresholds are not global anymore */
         /* if (global_ThreshFlag) global_ThreshFlag = 0; */
      }
      else if ((strcasecmp(opcode, "thresh")) == 0) {

src/Monitor.xs  view on Meta::CPAN

       code = rx_GetServerVersion(s, host, port, length, version);
       if (code < 0)
       {
          sprintf(buffer, "get version call failed with code %d, errno %d",code,errno);
          BSETCODE(code, buffer);
          XSRETURN_UNDEF;
       }
       hv_store(RETVAL, "version", 7, newSVpv(version, 0), 0);
       goto done;
    }

    code = rx_GetServerDebug(s, host, port, &tstats, &supportedDebugValues);

    if (code < 0) {
      sprintf(buffer, "getstats call failed with code %d", code);
      BSETCODE(code, buffer);
      XSRETURN_UNDEF;
    }

    withSecStats = (supportedDebugValues & RX_SERVER_DEBUG_SEC_STATS);
    withAllConn = (supportedDebugValues & RX_SERVER_DEBUG_ALL_CONN);
    withRxStats = (supportedDebugValues & RX_SERVER_DEBUG_RX_STATS);
    withWaiters = (supportedDebugValues & RX_SERVER_DEBUG_WAITER_CNT);
    withIdleThreads = (supportedDebugValues & RX_SERVER_DEBUG_IDLE_THREADS);
    withPeers = (supportedDebugValues & RX_SERVER_DEBUG_ALL_PEER);

    TSTATS = newHV();
    hv_store(TSTATS, "nFreePackets", 12, newSViv(tstats.nFreePackets), 0);
    hv_store(TSTATS, "packetReclaims", 14, newSViv(tstats.packetReclaims), 0);
    hv_store(TSTATS, "callsExecuted", 13, newSViv(tstats.callsExecuted), 0);
    hv_store(TSTATS, "usedFDs", 7, newSViv(tstats.usedFDs), 0);
    hv_store(TSTATS, "waitingForPackets", 17, newSViv(tstats.waitingForPackets), 0);
    hv_store(TSTATS, "version", 7, newSViv(tstats.version), 0);
    if (withWaiters)
       hv_store(TSTATS, "nWaiting", 8, newSViv(tstats.nWaiting), 0);
    if ( withIdleThreads )
       hv_store(TSTATS, "idleThreads", 11, newSViv(tstats.idleThreads), 0);
    hv_store(RETVAL, "tstats", 6, newRV_inc((SV*)(TSTATS)), 0);

    /* get rxstats if requested, and supported by the server */
    /* hash containing stats added at key 'rxstats' in RETVAL */
    if (rxstats)
    {
      if (!withRxStats)
      {
        noRxStats:
        withRxStats = 0;
        warn("WARNING: Server doesn't support retrieval of Rx statistics\n");
      }
      else {
        struct rx_statistics rxstats;

        /* should gracefully handle the case where rx_statistics grows */
        code = rx_GetServerStats(s, host, port, &rxstats, &supportedStatValues);
        if (code < 0) {
          sprintf(buffer, "rxstats call failed with code %d", code);
          VSETCODE(code, buffer);
          XSRETURN_UNDEF;
        }
        if (code != sizeof(rxstats)) {
          if ((((struct rx_debugIn *)(&rxstats))->type == RX_DEBUGI_BADTYPE))
            goto noRxStats;
          warn("WARNING: returned Rx statistics of unexpected size (got %d)\n", code);
          /* handle other versions?... */
        }

        RXSTATS = newHV();

        myPrintTheseStats(RXSTATS, &rxstats);

        hv_store(RETVAL, "rxstats", 7, newRV_inc((SV*)(RXSTATS)), 0);

      }
    }

    /* get connections unless -noconns flag was set */
    /* array of connections added at key 'connections' in RETVAL hash */
    if (!noConns) {
      if (allconns) {
        if (!withAllConn) {
          warn("WARNING: Server doesn't support retrieval of all connections,\n");
          warn("         getting only interesting instead.\n");
          }
      }

      CONNECTIONS = newAV();
      index = 0;
      for ( i = 0; ; i++) {
        code = rx_GetServerConnections(s, host, port, &nextconn, allconns,
                      supportedDebugValues, &tconn,
                      &supportedConnValues);
        if (code < 0) {
          warn("getconn call failed with code %d\n", code);
          break;
        }
        if (tconn.cid == 0xffffffff) {
          break;
        }

        /* see if we're in nodally mode and all calls are dallying */
        if (nodally) {
          flag = 0;
          for (j = 0; j < RX_MAXCALLS; j++) {
             if (tconn.callState[j] != RX_STATE_NOTINIT &&
                 tconn.callState[j] != RX_STATE_DALLY) {
               flag = 1;
               break;
             }
          }
          if (flag == 0) {
            /* this call looks too ordinary, bump skipped count and go
             * around again */
            dallyCounter++;
            continue;
          }
        }
        if ((onlyHost != -1) && (onlyHost != tconn.host)) continue;
        if ((onlyPort != -1) && (onlyPort != tconn.port)) continue;
        if (onlyServer && (tconn.type != RX_SERVER_CONNECTION)) continue;
        if (onlyClient && (tconn.type != RX_CLIENT_CONNECTION)) continue;
        if (onlyAuth != 999) {
          if (onlyAuth == -1) {
            if (tconn.securityIndex != 0) continue;
          }
          else {
            if (tconn.securityIndex != 2) continue;
            if (withSecStats && (tconn.secStats.type == 3) &&
             (tconn.secStats.level != onlyAuth)) continue;
          }
        }
        TCONN = newHV();
        hostAddr.s_addr = tconn.host;
        hv_store(TCONN, "host", 4, newSVpv(inet_ntoa(hostAddr), 0), 0);
        hv_store(TCONN, "port", 4, newSViv(ntohs(tconn.port)), 0);

        hv_store(TCONN, "cid", 3, newSViv(tconn.cid), 0);
        hv_store(TCONN, "epoch", 5, newSViv(tconn.epoch), 0);
        hv_store(TCONN, "error", 5, newSViv(tconn.error), 0);
        hv_store(TCONN, "serial", 6, newSViv(tconn.serial), 0);
        hv_store(TCONN, "natMTU", 6, newSViv(tconn.natMTU), 0);

        hv_store(TCONN, "flags", 5, newSViv(tconn.flags), 0);

        hv_store(TCONN, "securityIndex", 13, newSViv(tconn.securityIndex), 0);

        hv_store(TCONN, "type", 4, newSViv(tconn.type), 0);

        if (withSecStats) {
          HV* SECSTATS = newHV();
          hv_store(SECSTATS, "type", 4,
                   newSViv(tconn.secStats.type), 0);
          hv_store(SECSTATS, "level", 5,
                   newSViv(tconn.secStats.level), 0);
          hv_store(SECSTATS, "flags", 5,
                   newSViv(tconn.secStats.flags), 0);
          hv_store(SECSTATS, "expires", 7,
                   newSViv(tconn.secStats.expires), 0);
          hv_store(SECSTATS, "packetsReceived", 15,
                   newSViv(tconn.secStats.packetsReceived), 0);
          hv_store(SECSTATS, "packetsSent", 11,
                   newSViv(tconn.secStats.packetsSent), 0);
          hv_store(SECSTATS, "bytesReceived", 13,
                   newSViv(tconn.secStats.bytesReceived), 0);
          hv_store(SECSTATS, "bytesSent", 9,
                   newSViv(tconn.secStats.bytesSent), 0);
          hv_store(TCONN, "secStats", 8, newRV_inc((SV*)(SECSTATS)), 0);
        }

        CALLSTATE = newAV();
        av_fill(CALLSTATE, RX_MAXCALLS-1);
        CALLMODE = newAV();
        av_fill(CALLMODE, RX_MAXCALLS-1);
        CALLFLAGS = newAV();
        av_fill(CALLFLAGS, RX_MAXCALLS-1);
        CALLOTHER = newAV();
        av_fill(CALLOTHER, RX_MAXCALLS-1);
        CALLNUMBER = newAV();
        av_fill(CALLNUMBER, RX_MAXCALLS-1);

        for (j = 0; j < RX_MAXCALLS; j++) {
          av_store(CALLSTATE, j, newSViv(tconn.callState[j]));
          av_store(CALLMODE, j, newSViv(tconn.callMode[j]));
          av_store(CALLFLAGS, j, newSViv(tconn.callFlags[j]));
          av_store(CALLOTHER, j, newSViv(tconn.callOther[j]));
          av_store(CALLNUMBER, j, newSViv(tconn.callNumber[j]));
        }

        hv_store(TCONN, "callState", 9, newRV_inc((SV*)(CALLSTATE)), 0);
        hv_store(TCONN, "callMode", 8, newRV_inc((SV*)(CALLMODE)), 0);
        hv_store(TCONN, "callFlags", 9, newRV_inc((SV*)(CALLFLAGS)), 0);
        hv_store(TCONN, "callOther", 9, newRV_inc((SV*)(CALLOTHER)), 0);
        hv_store(TCONN, "callNumber", 10, newRV_inc((SV*)(CALLNUMBER)), 0);

        av_store(CONNECTIONS, index, newRV_inc((SV*)(TCONN)));
        index++;
      } /* end of for loop */
      if (nodally) hv_store(RETVAL, "dallyCounter", 12, newSViv(dallyCounter), 0);
      hv_store(RETVAL, "connections", 11, newRV_inc((SV*)(CONNECTIONS)), 0);
    } /* end of if (!noConns) */

    /* get peers if requested */
    /* array of peers added at key 'peers' in RETVAL hash */
    if (showPeers && withPeers) {
      PEERS = newAV();
      index = 0;
      for (i = 0; ; i++) {
        struct rx_debugPeer tpeer;
        code = rx_GetServerPeers(s, host, port, &nextpeer, allconns,
                                 &tpeer, &supportedPeerValues);
        if (code < 0) {
          warn("getpeer call failed with code %d\n", code);

src/Monitor.xs  view on Meta::CPAN

        hv_store(BYTESRECEIVED, "high", 4, newSViv(tpeer.bytesReceived.high), 0);
        hv_store(BYTESRECEIVED, "low", 3, newSViv(tpeer.bytesReceived.low), 0);
        hv_store(TPEER, "bytesReceived", 13, newRV_inc((SV*)(BYTESRECEIVED)), 0);

        hv_store(TPEER, "rtt", 3, newSViv(tpeer.rtt), 0);
        hv_store(TPEER, "rtt_dev", 7, newSViv(tpeer.rtt_dev), 0);

        TIMEOUT = newHV();
        hv_store(TIMEOUT, "sec", 3, newSViv(tpeer.timeout.sec), 0);
        hv_store(TIMEOUT, "usec", 4, newSViv(tpeer.timeout.usec), 0);
        hv_store(TPEER, "timeout", 7, newRV_inc((SV*)(TIMEOUT)), 0);

        if (showLong) {
          hv_store(TPEER, "inPacketSkew", 12,
                   newSViv(tpeer.inPacketSkew), 0);
          hv_store(TPEER, "outPacketSkew", 13,
                   newSViv(tpeer.outPacketSkew), 0);
          hv_store(TPEER, "cwind", 5,
                   newSViv(tpeer.cwind), 0);
          hv_store(TPEER, "MTU", 3,
                   newSViv(tpeer.MTU), 0);
          hv_store(TPEER, "nDgramPackets", 13,
                   newSViv(tpeer.nDgramPackets), 0);
          hv_store(TPEER, "ifDgramPackets", 14,
                   newSViv(tpeer.ifDgramPackets), 0);
          hv_store(TPEER, "maxDgramPackets", 15,
                   newSViv(tpeer.maxDgramPackets), 0);
        }

        av_store(PEERS, index, newRV_inc((SV*)(TPEER)));
        index++;
      }

      hv_store(RETVAL, "peers", 5, newRV_inc((SV*)(PEERS)), 0);
    }

    done:
    /* return RETVAL */
    ST(0) = sv_2mortal(newRV_inc((SV*)RETVAL));
    SETCODE(0);
    XSRETURN(1);
}





void
afs_error_message(code)
        int32   code
    PPCODE:
    {
        ST(0) = sv_newmortal();
        sv_setpv(ST(0), (char *) error_message(code));
        XSRETURN(1);
    }



  /* this function is generated automatically by constant_gen */
  /* You didn't think I would type in this crap did you? */
  /* thats what perl is for :-) */

void
constant(name, arg=0)
	char *	name
        int     arg
   PPCODE:
   {
  ST(0) = sv_newmortal();

  errno = EINVAL;

  switch (name[0]) {
  case 'A':
	switch (name[1]) {
	case 'F':
		switch (name[2]) {
		case 'S':
		if (strEQ(name,"AFSCB_MAX_XSTAT_LONGS"))
                    sv_setiv(ST(0),AFSCB_MAX_XSTAT_LONGS);
		else if (strEQ(name,"AFSCB_XSTATSCOLL_CALL_INFO"))
                    sv_setiv(ST(0),AFSCB_XSTATSCOLL_CALL_INFO);
		else if (strEQ(name,"AFSCB_XSTATSCOLL_FULL_PERF_INFO"))
                    sv_setiv(ST(0),AFSCB_XSTATSCOLL_FULL_PERF_INFO);
		else if (strEQ(name,"AFSCB_XSTATSCOLL_PERF_INFO"))
                    sv_setiv(ST(0),AFSCB_XSTATSCOLL_PERF_INFO);
		else if (strEQ(name,"AFSCB_XSTAT_VERSION"))
                    sv_setiv(ST(0),AFSCB_XSTAT_VERSION);
		else if (strEQ(name,"AFSCONF_VOLUMEPORT"))
                    sv_setiv(ST(0),AFSCONF_VOLUMEPORT);
		else if (strEQ(name,"AFS_MAX_XSTAT_LONGS"))
                    sv_setiv(ST(0),AFS_MAX_XSTAT_LONGS);
		else if (strEQ(name,"AFS_STATS_NUM_CM_RPC_OPS"))
                    sv_setiv(ST(0),AFS_STATS_NUM_CM_RPC_OPS);
		else if (strEQ(name,"AFS_STATS_NUM_FS_RPC_OPS"))
                    sv_setiv(ST(0),AFS_STATS_NUM_FS_RPC_OPS);
		else if (strEQ(name,"AFS_STATS_NUM_FS_XFER_OPS"))
                    sv_setiv(ST(0),AFS_STATS_NUM_FS_XFER_OPS);
		else if (strEQ(name,"AFS_XSTATSCOLL_CALL_INFO"))
                    sv_setiv(ST(0),AFS_XSTATSCOLL_CALL_INFO);
#ifndef NOAFS_XSTATSCOLL_CBSTATS
		else if (strEQ(name,"AFS_XSTATSCOLL_CBSTATS"))
                    sv_setiv(ST(0),AFS_XSTATSCOLL_CBSTATS);
#endif
		else if (strEQ(name,"AFS_XSTATSCOLL_FULL_PERF_INFO"))
                    sv_setiv(ST(0),AFS_XSTATSCOLL_FULL_PERF_INFO);
		else if (strEQ(name,"AFS_XSTATSCOLL_PERF_INFO"))
                    sv_setiv(ST(0),AFS_XSTATSCOLL_PERF_INFO);
		else if (strEQ(name,"AFS_XSTAT_VERSION"))
                    sv_setiv(ST(0),AFS_XSTAT_VERSION);
		else {
		     ST(0) = ST(1) = &PL_sv_undef;
		     return;
		}
		break;
		case '_':
		if (strEQ(name,"AF_INET")) sv_setiv(ST(0),AF_INET);
		else {
		     ST(0) = ST(1) = &PL_sv_undef;
		     return;



( run in 0.972 second using v1.01-cache-2.11-cpan-df04353d9ac )