perfstat_netadapter Interface
The perfstat_netadpater interface returns a set of structures of type perfstat_netadapter_t, which is defined in the libperfstat.h file.
Note: The perfstat_netadpater interface returns only
the network Ethernet adapter statistics similar to the entstat command.
The following program shows an example of how the perfstat_netadapter interface
is used:
/* The sample program displays the metrics *
* related to every Individual *
* network adapter in the LPAR*/
#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;
/* store the data structures */
static perfstat_netadapter_t *statp ,*statq;
/* 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;
/*
* 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 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_netadapter_t structures are available */
if(collect_remote_node_stats) {
strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN);
nodeid.spec = NODENAME;
tot = perfstat_netadapter_node(&nodeid, NULL, sizeof(perfstat_netadapter_t), 0);
}
else
{
tot = perfstat_netadapter(NULL, NULL, sizeof(perfstat_netadapter_t), 0);
}
if (tot == 0)
{
printf("There is no net adapter\n");
exit(0);
}
if (tot < 0)
{
perror("perfstat_netadapter: ");
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;
strcpy(nodeid.name , FIRST_NETINTERFACE);
ret = perfstat_netadapter_node(&nodeid, statq, sizeof(perfstat_netadapter_t), tot);
}
else {
strcpy(first.name , FIRST_NETINTERFACE);
ret = perfstat_netadapter( &first, statq, sizeof(perfstat_netadapter_t), tot);
}
if (ret < 0){
free(statp);
free(statq);
perror("perfstat_netadapter: ");
exit(1);
}
while (count)
{
sleep (interval);
if(collect_remote_node_stats)
{
ret = perfstat_netadapter_node(&nodeid, statp, sizeof(perfstat_netadapter_t), tot);
}
else {
ret = perfstat_netadapter(&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(" Number 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(" ==================================================================\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 iterations */
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;
}
The program produces the output similar to the following:
Adapter name: ent0
======================== Transmit Statistics=====================
Transmit Packets: 0
Transmit Bytes: 0
Transfer Interrupts : 0
Transmit Errors : 0
Packets Dropped at the time of Data Transmission : 0
Transmit Queue Size: 0
Transmit Queue Length :0
Transmit Queue Overflow : 0
Broadcast Packets Transmitted: 0
Multicast packets Transmitted: 0
Lost Carrier Sense signal count : 0
Count of DMA Under-runs for Transmission: 0
Number of unsuccessful transmissions : 0
Maximum Collision Errors at Transmission: 0
Late Collision Errors at Transmission : 0
Number of packets deferred for Transmission : 0
Time Out Errors for Transmission : 0
Count of Single Collision error at Transmission: 0
Count of Multiple Collision error at Transmission : 0
========================== Receive Statistics ====================
Receive Packets :48
Receive Bytes :2962
Receive Interrupts : 44
Input errors on interface :0
Number of Packets Dropped : 0
Count of Bad Packets Received : 0
Number of MultiCast Packets Received : 0
Number of Broadcast Packets Received : 47
Count of Packets Received with CRC errors: 0
DMA over-runs : 0
Alignment Errors : 0
No Resource Errors : 0
Collision Errors: 0
Number of Short Packets Received: 0
Number of Too Long Packets Received : 0
Number of Received Packets discarded by Adapter: 0