/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* bos720 src/bos/usr/ccs/lib/libperfstat/simplediskstat.c 1.5.1.1 */ /* */ /* Licensed Materials - Property of IBM */ /* */ /* Restricted Materials of IBM */ /* */ /* COPYRIGHT International Business Machines Corp. 2008,2010 */ /* All Rights Reserved */ /* */ /* US Government Users Restricted Rights - Use, duplication or */ /* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ /* */ /* IBM_PROLOG_END_TAG */ static char sccsid[] = "@(#)64 1.5.1.1 src/bos/usr/ccs/lib/libperfstat/simplediskstat.c, libperfstat, bos720 4/21/10 08:25:18"; /* The sample program retrieves the metrics */ /* related to each and every individual disk in the LPAR */ #include #include #include #include #include #include #include /* Non zero WPAR ID indicates WPAR */ #define IS_WPAR(X) ((X)) /* Default values for interval and count */ #define INTERVAL_DEFAULT 1 #define COUNT_DEFAULT 1 /* To Check whether malloc is successful or not */ #define CHECK_FOR_MALLOC_NULL(X) { if ((X) == NULL) {\ perror ("malloc");\ exit(2);\ }\ } /* Stores the information related to Individual disks*/ static perfstat_disk_t *statp, *statq; /* Used to store the current corral id */ cid_t cid; static int ndisks; /* number of disks */ static int interval = INTERVAL_DEFAULT; static int count = COUNT_DEFAULT ; static int rc; /* 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; /* 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 *); /* *NAME: showusage * This function displays the usage syntax * */ static void showusage(char *cmd) { fprintf (stderr, "usage: %s [-i ] [-c ] [-n ]\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. */ static int do_initialization(void) { int rc; /* Get the total number of disks available */ if(collect_remote_node_stats) { strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN); nodeid.spec = NODENAME; ndisks = perfstat_disk_node(&nodeid, NULL,sizeof(perfstat_disk_t), 0); } else { ndisks = perfstat_disk(NULL, NULL,sizeof(perfstat_disk_t), 0); } if (ndisks == 0) { printf("no disk found\n"); exit(0); } if (ndisks < 0) { perror("perfstat_disk: "); exit(1); } /* Allocate sufficient memory */ statp = (perfstat_disk_t *)malloc(sizeof(perfstat_disk_t) * ndisks); CHECK_FOR_MALLOC_NULL(statp); statq = (perfstat_disk_t *)malloc(sizeof(perfstat_disk_t) * ndisks); CHECK_FOR_MALLOC_NULL(statq); /* Initialize the structures to zero */ memset(statq, 0, (sizeof(perfstat_disk_t) * ndisks)); memset(statp, 0, (sizeof(perfstat_disk_t) * ndisks)); return(0); } /* * NAME: do_cleanup * This function cleans up the data structues allocated. * */ static void do_cleanup(void) { if (statp) { free(statp); } if (statq) { free(statq); } } /* *NAME: collect_disk_metrics * This function collects the metrics for all available disks. * */ void collect_disk_metrics(void) { unsigned long long delta_read, delta_write,delta_xrate, delta_xfers; perfstat_id_t first; /*call do_initialisation and allocate memory for the data structures */ do_initialization(); /* ask to get all the structures available in one call */ /* return code is number of structures returned */ if(collect_remote_node_stats) { strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN); nodeid.spec = NODENAME; strcpy(nodeid.name, FIRST_DISK); rc = perfstat_disk_node(&nodeid, statq, sizeof(perfstat_disk_t), ndisks); } else { strcpy(first.name, FIRST_DISK); rc = perfstat_disk(&first, statq, sizeof(perfstat_disk_t), ndisks); } if (rc < ndisks) { perror("perfstat_disk:"); exit(-1); } while (count > 0) { sleep (interval); if(collect_remote_node_stats) { rc = perfstat_disk_node(&nodeid, statp, sizeof(perfstat_disk_t), ndisks); } else { rc = perfstat_disk(&first, statp, sizeof(perfstat_disk_t), ndisks); } if (rc < ndisks ) { perror("perfstat_disk:"); exit(-1); } /* print statistics for each of the disks */ for (int i = 0; i < rc; i++) { delta_write = statp[i].wserv - statq[i].wserv; delta_read = statp[i].rserv - statq[i].rserv; delta_xfers = statp[i].xfers - statq[i].xfers; delta_xrate = statp[i].xrate - statq[i].xrate; printf("%-10s %10llu %10llu %10llu %13llu %8llu %10llu %13llu %8llu \n", statp[i].name, statp[i].size, statp[i].free, statp[i].min_rserv, statp[i].max_rserv, delta_read / delta_xrate, statp[i].min_wserv, statp[i].max_wserv, delta_write / (delta_xfers - delta_xrate)); } memcpy(statq, statp, sizeof(perfstat_disk_t)*ndisks); count--; printf("\n"); } /* remove all data structures */ do_cleanup(); } /* *NAME: print_disk_header * This function gets the lpar info and prints the header * */ void print_disk_header() { /* To Store the LPAR level disk information */ perfstat_disk_total_t dinfo; /* gather LPAR level disk data */ perfstat_disk_total(NULL, &dinfo, sizeof(perfstat_disk_total_t), 1); /* Check how many perfstat_disk_t structures are available*/ ndisks = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0); if (ndisks <= 0){ perror("perfstat_disk:"); exit(1); } /* Print the count of DISKS in the LPAR */ printf("\nDisks = %d \n",dinfo.number); /* Print the total size of all disks */ printf("Size (in MB) = %llu \n",dinfo.size); /* Print the amount time disks are active */ printf("Active time = %llu\n",dinfo.time); /* Print the free portion of all disks */ printf("Free space(in MB) = %llu\n\n",dinfo.free); /* Name - name of the disk * Size - size of the disk * Free - free space on the disk * MinRST - minimum read service time * MaxRST - maximum read service time * AvgRST - average read service time * MinWST - minimum write service time * MaxWST - maximum write service time * AvgWST - average write service time */ printf("%-10s %10s %10s %10s %13s %8s %10s %13s %8s\n", "Name", "Size(MB)", "Free(MB)", "MinRST", "MaxRST", "AvgRST", "MinWST", "MaxWST", "AvgWST"); printf("%-10s %10s %10s %10s %13s %8s %10s %13s %8s\n", "----", "--------", "--------", "------", "------", "------","------","------","------"); } /* *NAME: main * */ int main(int argc, char* argv[]) { int i; /* get the current corral's cid */ 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); } } print_disk_header(); collect_disk_metrics(); if(collect_remote_node_stats) { /* Now disable cluster statistics by calling perfstat_config */ perfstat_config(PERFSTAT_DISABLE|PERFSTAT_CLUSTER_STATS, NULL); } return(0); }