perfstat_fcstat Interface

The perfstat_fcstat interface returns a set of structures of type perfstat_fcstat_t, which is defined in the libperfstat.h file.

The following program is an example of how the perfstat_fcstat interface is used:
/* The sample program displays the metrics *
 * related to every Individual   * 
 * Fiber Channel adapter in the LPAR      */
#include <stdio.h>
#include <stdlib.h>
#include <libperfstat.h>

/* define default interval and count values */
#define INTERVAL_DEFAULT 1
#define COUNT_DEFAULT    1

/* Check value returned by malloc for NULL */

#define CHECK_FOR_MALLOC_NULL(X) {  if ((X) == NULL) {\
                                       perror ("malloc");\
                                       exit(2);\
                                     }\
                  }

int count = COUNT_DEFAULT, interval = INTERVAL_DEFAULT, tot=0;
int returncode=0;

/* store the data structures */

static perfstat_fcstat_t *statp=NULL ,*statq=NULL;

/* support for remote node statistics collection in a cluster environment */
perfstat_id_node_t nodeid;
static char nodename[MAXHOSTNAMELEN] = "";
static int collect_remote_node_stats = 0;

unsigned long long wwpn_id=0;
int fc_flag=0, wwpn_flag=0;
char fcadapter_name[MAXHOSTNAMELEN];
/*
 * NAME: showusage
 *       to display the usage
 *
 */
void showusage(char *cmd)
{
    fprintf (stderr, "usage: %s [-i <interval in seconds> ] [-c <number of iterations> ] [-n <node name in the cluster> ] [-a FC adapter name] [-w worldwide port name]] \n", cmd);
    exit(1);
}
/*
* NAME: do_initialization
 *       This function initializes the data structures.
 *       It also collects the initial set of values.
 *
 * RETURNS:
 * On successful completion:
 *   - returns 0.
 * In case of error
 *    - exits with code 1.
 */

int do_initialization(void)
{
    /* check how many perfstat_fcstat_t structures are available */
    if(collect_remote_node_stats) {
        strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN);
        nodeid.spec = NODENAME;
        tot = perfstat_fcstat_node(&nodeid, NULL, sizeof(perfstat_fcstat_t), 0)
;
     } 
else if(fc_flag == 1 && wwpn_flag == 1)
 {
         tot = perfstat_fcstat_wwpn(NULL, NULL, sizeof(perfstat_fcstat_t), 0);
         if(tot >= 1)
 {
            tot = 1;
         }
 else
 {
            printf("There is no FC adapter \n");
            exit(-1);
         }
     }
 else
 {
         tot = perfstat_fcstat(NULL, NULL, sizeof(perfstat_fcstat_t), 0);
     }
    if (tot <= 0) {
        printf("There is no FC adapter\n");
        exit(0);
    }

    /* allocate enough memory for all the structures */

    statp = (perfstat_fcstat_t *)malloc(tot * sizeof(perfstat_fcstat_t));
    CHECK_FOR_MALLOC_NULL(statp);

    statq = (perfstat_fcstat_t *)malloc(tot * sizeof(perfstat_fcstat_t));
    CHECK_FOR_MALLOC_NULL(statq);
    return(0);
}

/*
 *Name: display_metrics
 *       collect the metrics and display them
 *
 */
void display_metrics()
{
    perfstat_id_t first;
    perfstat_wwpn_id_t wwpn;
    int ret=0, i=0;

    if(collect_remote_node_stats) {
        strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN);
        nodeid.spec = NODENAME;

        strcpy(nodeid.name , FIRST_NETINTERFACE);
        ret = perfstat_fcstat_node(&nodeid, statq, sizeof(perfstat_fcstat_t), tot);
    } else if((fc_flag == 1) && (wwpn_flag == 1)) {
        strcpy(wwpn.name , fcadapter_name);
        wwpn.initiator_wwpn_name = wwpn_id;
        ret = perfstat_fcstat_wwpn( &wwpn, statq, sizeof(perfstat_fcstat_t), tot);
     }
 else
 { 
        strcpy(first.name , FIRST_NETINTERFACE);
        ret = perfstat_fcstat( &first, statq, sizeof(perfstat_fcstat_t), tot);
     }
      if (ret < 0)
 {
         free(statp);
         free(statq);
         perror("perfstat_fcstat: ");
         exit(1);
     }
      while (count)
     {
         sleep (interval);
if(collect_remote_node_stats) {
           ret = perfstat_fcstat_node(&nodeid, statp, sizeof(perfstat_fcstat_t), tot);
         }
 if((fc_flag == 1) && (wwpn_flag == 1))
 {
            strcpy(wwpn.name , fcadapter_name);
            wwpn.initiator_wwpn_name = wwpn_id;
            ret = perfstat_fcstat_wwpn(&wwpn, statp, sizeof(perfstat_fcstat_t), tot);
         }
  else
 {
            ret = perfstat_fcstat(&first, statp, sizeof(perfstat_fcstat_t), tot);
         }
/* print statistics for the Fiber channel */
        for (i = 0; i < ret; i++) {
            printf(" FC Adapter name: %s \n",  statp[i].name);
            printf(" ======================== Traffic Statistics ============================\n");
            printf(" Number of Input Requests: %lld \n", 
            statp[i].InputRequests - statq[i].InputRequests);
            printf(" Number of Output Requests: %lld \n",
            statp[i].OutputRequests - statq[i].OutputRequests);
            printf(" Number of Input Bytes : %lld \n",
            statp[i].InputBytes - statq[i].InputBytes);
            printf(" Number of Output Bytes : %lld \n",
            statp[i].OutputBytes - statq[i].OutputBytes);
            printf(" ======================== Transfer Statistics ============================\n");
            printf(" Adapter's Effective Maximum  Transfer Value  : %lld \n",
            statp[i].EffMaxTransfer - statq[i].EffMaxTransfer);
            printf(" ======================== Driver Statistics ============================\n");            
            printf(" Count of DMA failures: %lld \n",
            statp[i].NoDMAResourceCnt - statq[i].NoDMAResourceCnt);
            printf(" No command resource available :%lld \n",
            statp[i].NoCmdResourceCnt - statq[i].NoCmdResourceCnt);
            printf(" Link Indicator : %d \n", statp[i].AttentionType);
            printf(" ======================== CHBA Statistics ============================\n");                        
            printf(" Seconds since last reset of the statistics on the adapter: %lld \n",
            statp[i].SecondsSinceLastReset - statq[i].SecondsSinceLastReset);
            printf(" Number of frames transmitted: %lld \n",
            statp[i].TxFrames - statq[i].TxFrames);
            printf(" Fiber Channel Kbytes transmitted : %lld \n",
            statp[i].TxWords - statq[i].TxWords);
            printf(" Number of Frames Received.: %lld \n",
            statp[i].RxFrames - statq[i].RxFrames);
            printf(" Fiber Channel Kbytes Received : %lld \n",
            statp[i].RxWords - statq[i].RxWords);
            printf(" Loop Initialization Protocol(LIP) Count: %lld \n",
            statp[i].LIPCount - statq[i].LIPCount);
            printf(" NOS(Not_Operational) Count : %lld \n",
            statp[i].NOSCount - statq[i].NOSCount);
            printf(" Number of frames received with the CRC Error : %lld \n",
            statp[i].ErrorFrames - statq[i].ErrorFrames);
            printf(" Number of lost frames : %lld \n",
            statp[i].DumpedFrames - statq[i].DumpedFrames);
            printf(" Count of Link failures: %lld \n",
            statp[i].LinkFailureCount - statq[i].LinkFailureCount);
            printf(" Count of loss of sync : %lld \n",
            statp[i].LossofSyncCount - statq[i].LossofSyncCount);
            printf(" Count of loss of Signal:%lld \n",
            statp[i].LossofSignal - statq[i].LossofSignal);
            printf(" Number of times a primitive sequence was in error :%lld \n", 
            statp[i].PrimitiveSeqProtocolErrCount - statq[i].PrimitiveSeqProtocolErrCount);
            printf(" Count of Invalid Transmission words received : %lld \n", 
            statp[i].InvalidTxWordCount - statq[i].InvalidTxWordCount);
            printf(" Count of CRC Errors in a Received Frame :%lld \n", 
            statp[i].InvalidCRCCount - statq[i].InvalidCRCCount);
            printf(" SCSI Id of the adapter : %lld \n", 
            statp[i].PortFcId);
            printf(" Speed of Adapter in GBIT : %lld \n", 
            statp[i].PortSpeed);
            printf(" Connection Type: %s \n", 
            statp[i].PortType);
            printf(" worldwide port name : %lld \n",
            statp[i].PortWWN);
            printf(" Supported Port Speed in GBIT: %lld \n",
            statp[i].PortSupportedSpeed);
            
            printf(" ================================== End ===============================\n");

        }
        memcpy(statq, statp, (tot * sizeof(perfstat_fcstat_t)));
        count--;
    }
}

/*
 *Name: main
 *
 */

int main(int argc, char *argv[])
{
    int i=0, rc=0;
    /* get the interval and count values */

    /* Process the arguments */
    while ((i = getopt(argc, argv, "i:c:n:a:w")) != EOF)
    {
        switch(i)
        {
           case 'i':               /* Interval */
                    interval = atoi(optarg);
                    if( interval <= 0 )
                        interval = INTERVAL_DEFAULT;
                    break;
           case 'c':               /* Number of interations */
                    count = atoi(optarg);
                    if( count <= 0 )
                        count = COUNT_DEFAULT;
                    break;
           case 'n':               /* Node name in a cluster environment */
                    strncpy(nodename, optarg, MAXHOSTNAMELEN);
                    nodename[MAXHOSTNAMELEN-1] = '\0';
                    collect_remote_node_stats = 1;
                    break;
           case 'a':    /* Fiber Channel Adapter Name */ 
                    strncpy(fcadapter_name, optarg, MAXHOSTNAMELEN);
                    fcadapter_name[MAXHOSTNAMELEN-1] = '\0';
                    fc_flag = 1;
                    break; 
           case 'w':    /* Worldwide port name(WWPN) */
                    wwpn_id = (unsigned long long) (atoll(optarg));
                    wwpn_flag = 1;
                    break;           
           default:
                   /* Invalid arguments. Print the usage and terminate */
                   showusage(argv[0]);
        }
    }

    if((fc_flag == 1))
    {
        if(fcadapter_name == NULL )
        {
            fprintf(stderr, "FC adapter Name  should not be NULL");
            exit(-1);
        }
    }

    if(wwpn_flag == 1)
    {
        if(wwpn_id < 0 )
        {
            fprintf(stderr, "WWPN id should not be negavite ");
            exit(-1);
        }        
    }

    if(collect_remote_node_stats)
    {   /* perfstat_config needs to be called to enable cluster statistics collection */
        rc = perfstat_config(PERFSTAT_ENABLE|PERFSTAT_CLUSTER_STATS, NULL);
        if (rc == -1)
        {
            perror("cluster statistics collection is not available");
exit(-1);
        }
    }

    do_initialization();
    display_metrics();

    if(collect_remote_node_stats)
    {   /* Now disable cluster statistics by calling perfstat_config */
        perfstat_config(PERFSTAT_DISABLE|PERFSTAT_CLUSTER_STATS, NULL);
    }
    free(statp);
    free(statq);
    return 0;
}