perfstat_diskadapter Interface
The perfstat_diskadapter interface returns a set of structures of type perfstat_diskadapter_t, which is defined in the libperfstat.h file.
Selected fields from the perfstat_diskadapter_t structure include:
Several other disk adapter-related metrics (such as the number of blocks read from and
written to the adapter) are also returned. For a complete list, see the
perfstat_diskadapter_t section in the libperfstat.h header file.
Item | Descriptor |
---|---|
name | Adapter name (from ODM) |
description | Adapter description (from ODM) |
size | Total disk size connected to this adapter (in MB) |
free | Total free space on disks connected to this adapter (in MB) |
xfers | Total transfers to/from this adapter (in KB) |
The following program emulates the diskadapterstat behavior
and also shows an example of how the perfstat_diskadapter interface
is used:
The program displays an output that
is similar to the following example output:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libperfstat.h>
#include <errno.h>
#include <wpars/wparcfg.h>
/* Non zero WPAR ID indicates WPAR */
#define IS_WPAR(X) ((X))
/* To Check whether malloc is successful or not */
#define CHECK_FOR_MALLOC_NULL(X) { if ((X) == NULL) {\
perror ("malloc");\
exit(2);\
}\
}
/* Default values for interval and count */
#define INTERVAL_DEFAULT 1
#define COUNT_DEFAULT 1
/* Function prototypes */
static int do_initialization(void);
static void do_cleanup(void);
static void collect_disk_metrics(void);
static void print_disk_header(void);
static void showusage(char *);
/* variables and data structures declaration */
static perfstat_diskadapter_t *statp, *statq;
static int num_adapt;
static int interval = INTERVAL_DEFAULT;
static int count = COUNT_DEFAULT;
static int rc;
/* support for remote node statistics collection in a cluster environment */
static perfstat_id_node_t nodeid;
static char nodename[MAXHOSTNAMELEN] = "";
static int collect_remote_node_stats = 0;
cid_t cid; /* store the WPAR cid */
/*
* 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
* - exit with code 1.
*/
static int do_initialization(void)
{
if (collect_remote_node_stats){
strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN);
nodeid.spec = NODENAME;
/* Get the total number of disk adapters available in the current system */
num_adapt = perfstat_diskadapter_node(&nodeid, NULL, sizeof(perfstat_diskadapter_t), 0);
}
else{
/* Get the total number of disk adapters available in the current system */
num_adapt = perfstat_diskadapter(NULL, NULL, sizeof(perfstat_diskadapter_t), 0);
}
if (num_adapt == 0) {
printf("There are no disk adapters.\n");
exit(0);
}
if (num_adapt < 0) {
perror("perfstat_diskadapter: ");
exit(1);
}
/* Allocate sufficient memory for perfstat structures */
statp = (perfstat_diskadapter_t *)malloc(sizeof(perfstat_diskadapter_t) * num_adapt);
CHECK_FOR_MALLOC_NULL(statp);
statq = (perfstat_diskadapter_t *)malloc(sizeof(perfstat_diskadapter_t) * num_adapt);
CHECK_FOR_MALLOC_NULL(statq);
/* Make the structures as 0 */
memset(statq, 0, (sizeof(perfstat_diskadapter_t) * num_adapt));
memset(statp, 0, (sizeof(perfstat_diskadapter_t) * num_adapt));
return (0);
}
/*
*NAME: Showusage
* This function displays 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_cleanup
* This function frees the memory allocated for the perfstat structures.
*
*/
static void do_cleanup(void)
{
if (statp) {
free(statp);
}
if (statq) {
free(statq);
}
}
/*
* NAME: collect_diskadapter_metrics
* This function collects the raw values in to
* the specified structures and derive the metrics from the
* raw values
*
*/
void collect_diskadapter_metrics(void)
{
perfstat_id_t first;
unsigned long long delta_read, delta_write,delta_xfers, delta_xrate;
if(collect_remote_node_stats) {
strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN);
nodeid.spec = NODENAME;
strcpy(nodeid.name, FIRST_DISKADAPTER);
rc = perfstat_diskadapter_node(&nodeid ,statq, sizeof(perfstat_diskadapter_t),num_adapt);
}
else {
strcpy(first.name, FIRST_DISKADAPTER);
rc = perfstat_diskadapter(&first ,statq, sizeof(perfstat_diskadapter_t),num_adapt);
}
if (rc < num_adapt){
perror("perfstat_diskadapter: ");
exit(1);
}
/* Name - name of the diskadapter
* Disks- number of disks connected
* Size - total size of all the disks
* Free - free space on disk
* ARS - average read per second
* AWS - average write per second
*/
printf("\n%-8s %7s %8s %8s %8s %8s\n", " Name ", " Disks ", " Size ", " Free ", " ARS ", " AWS ");
printf("%-8s %7s %8s %8s %8s %8s\n", "======", "======", "======", "======", "=====", "=====");
while (count > 0) {
sleep(interval);
if(collect_remote_node_stats) {
rc = perfstat_diskadapter_node(&nodeid, statp, sizeof(perfstat_diskadapter_t), num_adapt);
}
else {
rc = perfstat_diskadapter(&first ,statp, sizeof(perfstat_diskadapter_t),num_adapt);
}
if (rc < num_adapt ) {
perror("perfstat_diskadapter:");
exit(-1);
}
/* print statistics for each of the diskadapter */
for (int i = 0; i < rc; i++) {
delta_write = statp[i].wblks - statq[i].wblks;
delta_read = statp[i].rblks - statq[i].rblks;
delta_xfers = statp[i].xfers - statq[i].xfers;
delta_xrate = statp[i].xrate - statq[i].xrate;
printf("%-8s %7d %8llu %8llu %8llu %8llu\n", statp[i].name, statp[i].number,
statp[i].size, statp[i].free, (u_longlong_t)(delta_read / (statp[i].xrate - statq[i].xrate)),
(u_longlong_t)(delta_write / (delta_xfers - delta_xrate)));
}
/* copy to the old data structures */
memcpy(statq, statp, sizeof(perfstat_diskadapter_t) * num_adapt);
count--;
printf("\n");
}
/* Free all the memory allocated for all the data structures */
do_cleanup();
}
/*
*NAME: main
*
*/
int main(int argc, char* argv[])
{
int i;
cid = corral_getcid();
/* Check Whether running Inside WPAR or on Global*/
if(IS_WPAR(cid)) {
printf("The metrics requested for WPAR cannot be retrieved.\n");
exit(1);
}
/* 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();
/* call the functions to collect the metrics and display them */
collect_diskadapter_metrics();
if(collect_remote_node_stats)
{ /* Now disable cluster statistics by calling perfstat_config */
perfstat_config(PERFSTAT_DISABLE|PERFSTAT_CLUSTER_STATS, NULL);
}
return (0);
}
Name Disks Size Free ARS AWS
====== ====== ====== ====== ===== =====
vscsi0 1 25568 19616 1 9