perfstat_bridgedadapters Interface

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

The following program shows an example of how the perfstat_bridgedadapters interface is used:
/* The sample program display the metrics *
 * related to each and every Individual   * 
 * physical and virtual/trunk adapters which are under SEA in the VIOS  */
#include<stdio.h>
#include<stdlib.h>
#include<libperfstat.h>
#include<net/if_types.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;
int returncode;
/* 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;

/* store the data structures */

static perfstat_netadapter_t *statp ,*statq;

/*
 * 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>]/n; ", cmd);
    exit(1);
}
/*
/*
 * NAME: do_initialization
 *       This function initializes the data structues.
 *       It also collects initial set of values.
 *
 * RETURNS:
 * On successful completion:
 *   - returns 0.
 * In case of error
 *    - exits with code 1.
 */

int do_initialization(void)
{
    perfstat_id_t first;

    /* check how many perfstat_netadapter_t structures are available */
    if(collect_remote_node_stats) {
        strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN);
        /* SEA Adapter Name must be filled */
        strcpy(nodeid.name , FIRST_SEA); 
        /*nodeid.spec = NODENAME; */
        tot = perfstat_bridgedadapters_node(&nodeid, NULL, sizeof(perfstat_netadapter_t), 0);
     } else
 {
         /* SEA Adapter Name must be filled */
         strcpy(first.name , FIRST_SEA);
            tot = perfstat_bridgedadapters(&first, NULL, sizeof(perfstat_netadapter_t), 0);
     }
     if (tot == 0)
 {
         printf("There is no SEA Chilren\n");
         exit(0);
     }if (tot < 0) {
        if (collect_remote_node_stats)
                perror("perfstat_bridgedadapters_node: ");
        else
                perror("perfstat_bridgedadapters: ");

          exit(1);
      }
      /* allocate enough memory for all the structures */
      statp = (perfstat_netadapter_t *)malloc(tot * sizeof(perfstat_netadapter_t));
      CHECK_FOR_MALLOC_NULL(statp);
      statq = (perfstat_netadapter_t *)malloc(tot * sizeof(perfstat_netadapter_t));
      CHECK_FOR_MALLOC_NULL(statq);
      return(0);
 }
/*
 *Name: display_metrics
 *       collect the metrics and display them
 *
 */
void display_metrics()
{
    perfstat_id_t first;
    int ret, i;
    
    if(collect_remote_node_stats) {
        strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN);
        nodeid.spec = NODENAME;

        /* Valid SEA Adapter Name Must be passed */
        strcpy(nodeid.name , FIRST_SEA);
        ret = perfstat_bridgedadapters_node(&nodeid, statq, sizeof(perfstat_netadapter_t), tot);
     } else
 {
         /* Valid SEA Adapter Name Must be passed */
         strcpy(first.name , FIRST_SEA);
         ret = perfstat_bridgedadapters( &first, statq, sizeof(perfstat_netadapter_t), tot);
     }
    if (ret < 0) {
          free(statp);
          free(statq);
          if (collect_remote_node_stats)
               perror("perfstat_bridgedadapters_node: ");
          else
                perror("perfstat_bridgedadapters: ");
          exit(1);
     }
      while (count)
     {
         sleep (interval);
         if(collect_remote_node_stats)
 {
            ret = perfstat_bridgedadapters_node(&nodeid, statp, sizeof(perfstat_netadapter_t), tot);
         } else
 {
            ret = perfstat_bridgedadapters( &first, statp, sizeof(perfstat_netadapter_t), tot);
         }
        /* print statistics for each of the interfaces */
         for (i = 0; i < ret; i++)
 {
             printf(" Adapter name: %s \n",  statp[i].name);
             printf(" ======================== Transmit Statistics ============================\n");
             printf(" Transmit Packets: %lld \n", statp[i].tx_packets - statq[i].tx_packets);
             printf(" Transmit Bytes: %lld \n",  statp[i].tx_bytes - statq[i].tx_bytes);
             printf(" Transfer Interrupts : %lld \n",  statp[i].tx_interrupts - statq[i].tx_interrupts);
            printf(" Transmit Errors : %lld \n",  statp[i].tx_errors - statq[i].tx_errors);
            printf(" Packets Dropped at the time of Data Transmission : %lld \n",  statp[i].tx_packets_dropped - statq[i].tx_packets_dropped);
            printf(" Transmit Queue Size: %lld \n",  statp[i].tx_queue_size - statq[i].tx_queue_size);
            printf(" Transmit Queue Length :%lld \n", statp[i].tx_queue_len - statq[i].tx_queue_len);
            printf(" Transmit Queue Overflow : %lld \n", statp[i].tx_queue_overflow - statq[i].tx_queue_overflow);
            printf(" Broadcast Packets Transmitted: %lld \n", statp[i].tx_broadcast_packets - statq[i].tx_broadcast_packets);
            printf(" Multicast packets Transmitted: %lld \n", statp[i].tx_multicast_packets - statq[i].tx_multicast_packets);
            printf(" Lost Carrier Sense signal count : %lld \n",statp[i].tx_carrier_sense - statq[i].tx_carrier_sense);
            printf(" Count of DMA Under-runs for Transmission: %lld \n",statp[i].tx_DMA_underrun - statq[i].tx_DMA_underrun);
            printf(" Number of unsuccessful transmissions : %lld \n",statp[i].tx_lost_CTS_errors - statq[i].tx_lost_CTS_errors);
            printf(" Maximum Collision Errors at Transmission: %lld \n",statp[i].tx_max_collision_errors - statq[i].tx_max_collision_errors);
            printf(" Late Collision Errors at Transmission : %lld \n",statp[i].tx_late_collision_errors - statq[i].tx_late_collision_errors);
            printf(" Number of packets deferred for Transmission : %lld \n",statp[i].tx_deferred - statq[i].tx_deferred);
            printf(" Time Out Errors for Transmission : %lld \n",statp[i].tx_timeout_errors - statq[i].tx_timeout_errors);
            printf(" Count of Single Collision error at Transmission: %lld \n",statp[i].tx_single_collision_count - statq[i].tx_single_collision_count);
            printf(" Count of Multiple Collision error at Transmission : %lld \n",statp[i].tx_multiple_collision_count - statq[i].tx_multiple_collision_count);


            printf(" ========================== Receive Statistics ==============================\n");
            printf(" Receive Packets :%lld \n",statp[i].rx_packets - statq[i].rx_packets);
            printf(" Receive Bytes :%lld \n", statp[i].rx_bytes - statq[i].rx_bytes);
            printf(" Receive Interrupts : %lld \n", statp[i].rx_interrupts - statq[i].rx_interrupts);
            printf(" Input errors on interface :%lld \n", statp[i].rx_errors - statq[i].rx_errors);
            printf(" Nunber of Packets Dropped : %lld \n", statp[i].rx_packets_dropped - statq[i].rx_packets_dropped);
            printf(" Count of Bad Packets Received : %lld \n", statp[i].rx_bad_packets - statq[i].rx_bad_packets);
            printf(" Number of MultiCast Packets Received : %lld \n", statp[i].rx_multicast_packets - statq[i].rx_multicast_packets);
            printf(" Number of Broadcast Packets Received : %lld \n",statp[i].rx_broadcast_packets - statq[i].rx_broadcast_packets);
            printf(" Count of Packets Received with CRC errors: %lld \n",statp[i].rx_CRC_errors - statq[i].rx_CRC_errors);
            printf(" DMA over-runs : %lld \n", statp[i].rx_DMA_overrun - statq[i].rx_DMA_overrun);
            printf(" Alignment Errors : %lld \n", statp[i].rx_alignment_errors - statq[i].rx_alignment_errors);
            printf(" No Resource Errors : %lld \n", statp[i].rx_noresource_errors - statq[i].rx_noresource_errors);
            printf(" Collision Errors: %lld \n",  statp[i].rx_collision_errors - statq[i].rx_collision_errors);
            printf(" Number of Short Packets Received: %lld \n",statp[i].rx_packet_tooshort_errors - statq[i].rx_packet_tooshort_errors);
            printf(" Number of Too Long Packets Received : %lld \n", statp[i].rx_packet_toolong_errors - statq[i].rx_packet_toolong_errors);
            printf(" Number of Received Packets discarded by Adapter: %lld \n", statp[i].rx_packets_discardedbyadapter - 
                     statq[i].rx_packets_discardedbyadapter);
            printf(" Adapter Type :%d \n",statp[i].adapter_type);
            printf(" =============================================================================\n");

        }

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

/*
 *Name: main
 *
 */

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

    /* Process the arguments */
    while ((i = getopt(argc, argv, "i:c:n:")) != 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;
           default:
                   /* Invalid arguments. Print the usage and terminate */
                   showusage(argv[0]);
        }
    }

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