/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* bos720 src/bos/usr/ccs/lib/libperfstat/simplelvmstat.c 1.4.1.3 */ /* */ /* Licensed Materials - Property of IBM */ /* */ /* Restricted Materials of IBM */ /* */ /* COPYRIGHT International Business Machines Corp. 2008,2011 */ /* 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[] = "@(#)96 1.4.1.3 src/bos/usr/ccs/lib/libperfstat/simplelvmstat.c, libperfstat, bos720 7/15/11 02:56:20"; /* Sample program to display all the logical volumes and */ /* volume groups */ #include #include #include #include #include #include #include /* Check value returned by malloc for NULL */ #define CHECK_FOR_MALLOC_NULL(X) { if ((X) == NULL) {\ perror ("malloc");\ exit(2);\ }\ } /* WPAR ID for global will always be zero */ #define IS_GLOBAL(X) (!(X)) /* Define the default interval and count values */ #define INTERVAL_DEFAULT 1 #define COUNT_DEFAULT 1 /* declare structures for storing logical volume and volume group info */ perfstat_logicalvolume_t *lvinfo_new, *lvinfo_old; perfstat_volumegroup_t *vginfo_new, *vginfo_old; perfstat_id_t first; int lv_total, vg_total; int interval = INTERVAL_DEFAULT, count = COUNT_DEFAULT; /* support for remote node statistics collection in a cluster environment */ perfstat_id_node_t nodeid; char nodename[MAXHOSTNAMELEN]; int collect_remote_node_stats = 0; /* *Name: showusage * function to display the correct usage * */ void showusage(char *cmd) { fprintf (stderr, "usage: %s [-i ] [-c ] [-n ]\n", cmd); exit(1); } /* *Name: do_initialisation * get the total counts of logical volume and volume group and allocate memory * */ void do_initialisation() { strcpy(first.name, NULL); if (collect_remote_node_stats){ strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN); nodeid.spec = NODENAME; /*Get the total logical volumes and check for error */ lv_total = perfstat_logicalvolume_node(&nodeid, NULL, sizeof(perfstat_logicalvolume_t), 0); /*Get the total volume groups and check for errors */ vg_total = perfstat_volumegroup_node(&nodeid, NULL, sizeof(perfstat_volumegroup_t), 0); } else{ /*Get the total logical volumes and check for error */ lv_total = perfstat_logicalvolume(NULL, NULL, sizeof(perfstat_logicalvolume_t), 0); /*Get the total volume groups and check for errors */ vg_total = perfstat_volumegroup(NULL, NULL, sizeof(perfstat_volumegroup_t), 0); } if (lv_total <= 0){ perror("perfstat_logicalvolume"); exit(1); } if (vg_total <= 0){ perror("perfstat_volumegroup"); exit(1); } /*Allocate memory to hold old and new structures */ lvinfo_new = (perfstat_logicalvolume_t *)malloc (sizeof(perfstat_logicalvolume_t) * lv_total); CHECK_FOR_MALLOC_NULL(lvinfo_new); lvinfo_old = (perfstat_logicalvolume_t *)malloc (sizeof(perfstat_logicalvolume_t) * lv_total); CHECK_FOR_MALLOC_NULL(lvinfo_old); vginfo_new = (perfstat_volumegroup_t *)malloc (sizeof(perfstat_volumegroup_t) * vg_total); CHECK_FOR_MALLOC_NULL(vginfo_new); vginfo_old = (perfstat_volumegroup_t *)malloc (sizeof(perfstat_volumegroup_t) * vg_total); CHECK_FOR_MALLOC_NULL(vginfo_old); } /* *Name: do_cleanup * frees all the memory allocated for data structures * */ void do_cleanup(){ if (lvinfo_new) free(lvinfo_new); if (lvinfo_old) free(lvinfo_old); if (vginfo_new) free(vginfo_new); if (vginfo_old) free(vginfo_old); } /* *Name: display_lvm * collects all logical volumes and volume groups and displays them * */ void display_lvm() { int i = 0, rc = 0; if (collect_remote_node_stats){ strncpy(nodeid.u.nodename, nodename, MAXHOSTNAMELEN); nodeid.spec = NODENAME; /* Get the perfstat_logicalvolume data, rc has the number of structures returned*/ rc = perfstat_logicalvolume_node(&nodeid, lvinfo_old, sizeof(perfstat_logicalvolume_t), lv_total); if (rc <= 0){ perror("perfstat_logicalvolume_node"); exit(1); } /*Get the perfstat_volumegroup data */ rc = perfstat_volumegroup_node(&nodeid, vginfo_old, sizeof(perfstat_volumegroup_t), vg_total); if (rc <= 0){ perror("perfstat_volumegroup_node"); exit(1); } } else{ /* Get the perfstat_logicalvolume data, rc has the number of structures returned*/ rc = perfstat_logicalvolume(&first, lvinfo_old, sizeof(perfstat_logicalvolume_t), lv_total); if (rc <= 0){ perror("perfstat_logicalvolume"); exit(1); } /*Get the perfstat_volumegroup data */ rc = perfstat_volumegroup(&first, vginfo_old, sizeof(perfstat_volumegroup_t), vg_total); if (rc <= 0){ perror("perfstat_volumegroup"); exit(1); } } while(count){ sleep(interval); if (collect_remote_node_stats){ rc = perfstat_logicalvolume_node(&nodeid, lvinfo_new, sizeof(perfstat_logicalvolume_t), lv_total); } else{ rc = perfstat_logicalvolume(&first, lvinfo_new, sizeof(perfstat_logicalvolume_t), lv_total); } if (rc <= 0){ perror("perfstat_logicalvolume"); exit(1); } /* * LV - logical volume name * VG - Volume group name * size - size of the logical volume * iocount - number of read and write */ printf("\n%10s %10s %10s %10s\n", " LV ", " VG " , " size ", " iocnt "); printf("%10s %10s %10s %10s\n", "===", "===", "======", "======"); for (i = 0; i < rc; i++){ printf("%10s %10s %10llu %10llu\n", lvinfo_new[i].name, lvinfo_new[i].vgname, lvinfo_new[i].ppsize, (lvinfo_new[i].iocnt - lvinfo_old[i].iocnt)); } if (collect_remote_node_stats){ rc = perfstat_volumegroup_node(&nodeid, vginfo_new, sizeof(perfstat_volumegroup_t), vg_total); } else{ rc = perfstat_volumegroup(&first, vginfo_new, sizeof(perfstat_volumegroup_t), vg_total); } if (rc <= 0){ perror("perfstat_volumegroup"); exit(1); } /* * VG - volume group name * Disks - number of disks * lvcount- number of logivalvolume * iocount- number of read and write requests */ printf("\n%10s %10s %10s %10s\n", " VG ", " Disks ", " lvcount ", " iocount "); printf("%10s %10s %10s %10s\n", "====", "======", "=======", "======="); for (i = 0; i < rc; i++){ printf("%10s %10llu %10llu %10llu\n", vginfo_new[i].name, vginfo_new[i].total_disks, vginfo_new[i].total_logical_volumes, (vginfo_new[i].iocnt - vginfo_old[i].iocnt)); } count--; memcpy(lvinfo_old, lvinfo_new, (sizeof(perfstat_logicalvolume_t) * lv_total)); memcpy(vginfo_old, vginfo_new, (sizeof(perfstat_volumegroup_t) * vg_total)); } do_cleanup(); } /* *Name: main * */ int main(int argc, char *argv[]) { int i, cid, rc; cid = corral_getcid(); /*Display the usage message and exit if called inside WPAR */ if (!IS_GLOBAL(cid)){ showusage(argv[0]); } /* 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]); } } /* perfstat_config needs to be called to enabled LV and VG collection */ perfstat_config(PERFSTAT_ENABLE|PERFSTAT_LV, NULL); 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_initialisation(); display_lvm(); if(collect_remote_node_stats) { /* Now disable cluster statistics by calling perfstat_config */ perfstat_config(PERFSTAT_DISABLE|PERFSTAT_CLUSTER_STATS, NULL); } perfstat_config(PERFSTAT_DISABLE|PERFSTAT_LV, NULL); }