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;
}