/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* bos720 src/bos/usr/ccs/lib/libperfstat/simplewparstat.c 1.6 */ /* */ /* Licensed Materials - Property of IBM */ /* */ /* Restricted Materials of IBM */ /* */ /* COPYRIGHT International Business Machines Corp. 2007,2009 */ /* 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[] = "@(#)29 1.6 src/bos/usr/ccs/lib/libperfstat/simplewparstat.c, libperfstat, bos720 4/17/09 01:56:10"; /* NOTE : This example assumes that the sample program will be run in DLPAR without * donation capability. For DLPAR donation capability and SPLPAR CPU usage * calculation, please refer /usr/samples/libperfstat/simplelparstat.c and make * changes in the display_lpar_wpar_stats() function for calculating * delta wait and idle physical processor tics */ #include #include #include #include #include #include #include /* state of wpar */ #define ACTIVE 1 #define INACTIVE 0 /* 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)) /* Non zero WPAR ID indicates WPAR */ #define IS_WPAR(X) ((X)) /* For WPAR, use NULL else use the actual WPAR ID (for global) */ #define WPAR_ID ((cid)?NULL:&wparid) /* Convert 4K pages to MB */ #define AS_MB(X) ((X) * 4096/1024/1024) #define COUNT_DEFAULT 1 #define INTERVAL_DEFAULT 1 /* store LPAR level stats */ perfstat_cpu_total_t cinfo; perfstat_memory_total_t minfo; perfstat_partition_total_t pinfo; perfstat_id_wpar_t wparid; /* stores wpar id for perfstat library */ /* store per WPAR stats */ perfstat_wpar_total_t *winfo; perfstat_cpu_total_wpar_t *cinfo_wpar; perfstat_memory_total_wpar_t *minfo_wpar; corrallist_t *wpar_list; /* store wpar information for each WPAR */ cid_t cid; /* store current WPAR ID */ unsigned long long last_user, last_sys, last_idle, last_wait, last_timebase; unsigned long long *last_wpar_user, *last_wpar_sys; int *status; int interval = INTERVAL_DEFAULT, count = COUNT_DEFAULT; char wpar[MAXCORRALNAMELEN+1]; /* Store total number of WPARs in the LPAR.If * the program is executed from an LPAR it * holds 1 (when started from a WPAR) */ int total_wpars = 0; /* *Name: showusage * displays the usage * */ void showusage() { if(!cid) printf("Usage:simplewparstat [-@ { ALL | WPARNAME }] [interval] [count]\n "); else printf("Usage:simplewparstat [interval] [count]\n"); exit(1); } /* *Name: get_WPAR_list * get all the wpars and allocate memory for them * */ void get_WPAR_list(void) { int i, rc; /* Check whether we are running inside WPAR */ cid = corral_getcid(); /* Get the WPAR id */ if (IS_WPAR(cid)) { /* Check if the process is running inside WPAR */ /* While running inside the WPAR, set number of WPARs as 1*/ total_wpars = 1; } else { /* Running in LPAR .i.e. global system */ /* Get the number of WPARs in the System */ total_wpars = perfstat_wpar_total( NULL, NULL, sizeof(perfstat_wpar_total_t), 0); if (total_wpars < 0) { perror("perfstat_wpar_total:"); exit(1); } } /* If WPARs exists in the system, get WPAR details */ if (total_wpars > 0) { wpar_list = (corrallist_t*) malloc(total_wpars * sizeof(corrallist_t)); CHECK_FOR_MALLOC_NULL(wpar_list); if (IS_GLOBAL(cid)) { /* For global system, get list of WPARs */ rc = getcorrallist(wpar_list, &total_wpars); if (rc != 0) { perror ("getcorrallist():"); exit (1); } } else { /* sample is running inside a WPAR */ /* set cid to the current id and print name as local */ wpar_list[0].cid = cid; strcpy(wpar_list[0].cname, "Local\0"); } } } /* *Name: allocate * allocates memory for all data structures * */ void allocate(void){ status = (int *) malloc (total_wpars * sizeof (int)); CHECK_FOR_MALLOC_NULL(status); last_wpar_user = (unsigned long long *) malloc(total_wpars * sizeof (unsigned long long)); CHECK_FOR_MALLOC_NULL(last_wpar_user); last_wpar_sys = (unsigned long long *) malloc(total_wpars * sizeof (unsigned long long)); CHECK_FOR_MALLOC_NULL(last_wpar_sys); winfo = (perfstat_wpar_total_t *) malloc(total_wpars * sizeof(perfstat_wpar_total_t)); CHECK_FOR_MALLOC_NULL(winfo); cinfo_wpar = (perfstat_cpu_total_wpar_t *) malloc(total_wpars * sizeof(perfstat_cpu_total_wpar_t)); CHECK_FOR_MALLOC_NULL(cinfo_wpar); minfo_wpar = (perfstat_memory_total_wpar_t *) malloc(total_wpars * sizeof(perfstat_memory_total_wpar_t)); CHECK_FOR_MALLOC_NULL(minfo_wpar); } /* *Name: getwpardata * get all wpar data and find if they are active * */ void getwpardata(void){ int i; /* Obtain WPAR Data */ wparid.spec = WPARID; for (i=0; i < total_wpars; i++) { status[i]=ACTIVE; wparid.u.wpar_id = wpar_list[i].cid; if (perfstat_wpar_total (WPAR_ID, &winfo[i], sizeof(perfstat_wpar_total_t), 1) <= 0){ status[i]= INACTIVE; continue; } wparid.u.wpar_id = wpar_list[i].cid; if (perfstat_cpu_total_wpar (WPAR_ID, &cinfo_wpar[i], sizeof(perfstat_cpu_total_wpar_t), 1) <= 0){ status[i]= INACTIVE; continue; } if (perfstat_memory_total_wpar (WPAR_ID, &minfo_wpar[i], sizeof(perfstat_memory_total_wpar_t), 1) <= 0) status[i] = INACTIVE; } } /* *Name: save_last_values * this function is used to store the values * */ void save_last_values (void) { int i; last_user = cinfo.puser; last_sys = cinfo.psys; last_idle = cinfo.pidle; last_wait = cinfo.pwait; last_timebase = pinfo.timebase_last; for (i=0; i < total_wpars; i++) { if (status[i] == INACTIVE){ last_wpar_user[i] = 0; last_wpar_sys[i] = 0; continue; } last_wpar_user[i] = cinfo_wpar[i].puser; last_wpar_sys[i] = cinfo_wpar[i].psys; } } /* *Name: display_configuration * display /par/wpar configuration * */ void display_configuration (void) { unsigned long long memlimit; double cpulimit; int i; /* gather LPAR level data */ if (perfstat_partition_total(NULL, &pinfo, sizeof(perfstat_partition_total_t), 1) <= 0) { perror("perfstat_partition_total\n"); exit(1); } if (perfstat_cpu_total(NULL, &cinfo, sizeof(perfstat_cpu_total_t), 1) <= 0) { perror("perfstat_cpu_total\n"); exit(1); } if (perfstat_memory_total(NULL, &minfo, sizeof(perfstat_memory_total_t), 1) <= 0) { perror("perfstat_memory_total\n"); exit(-1); } /* print WPAR general processor information */ printf("\nWPARs Configuration:\n"); for (i=0; i < total_wpars; i++) { if (status[i] == INACTIVE) continue; /* perfstat_wpar_total_t.mem_limit and perfstat_wpar_total_t.cpu_limit are stored as 100s of * a percentage (ex: 60% will stored as 60 * 100. So dividing them by 100 */ /* memory limit of a WPAR as 4k pages */ memlimit = (minfo_wpar[i].real_total * (winfo[i].mem_limit/10000.0)); /* CPU limit of a WPAR as entitled capacity */ cpulimit = ((double)pinfo.entitled_proc_capacity/100.0) * ((double)winfo[i].cpu_limit/10000.0); /* print WPAR configuration */ printf("%s Configuration: ",winfo[i].name); /* WPAR Name */ printf("memlimit = %lluMB, ", AS_MB(memlimit)); /* WPAR Mem limit as MB */ printf("cpulimit = %#5.2f\n",cpulimit); /* WPAR CPU limit */ } } /* *Name: display_lpar_wpar_stats * collect the data and display them * */ void display_lpar_wpar_stats (void) { unsigned long long delta_total, delta_user, delta_sys, delta_idle, delta_wait, delta_timebase; unsigned long long memlimit; double cpulimit; int i; /* retrive partition level statistics */ if (perfstat_partition_total(NULL, &pinfo, sizeof(perfstat_partition_total_t), 1) <= 0) { perror("perfstat_partition_total\n"); exit(-1); } if (perfstat_cpu_total(NULL, &cinfo, sizeof(perfstat_cpu_total_t), 1) <= 0) { perror("perfstat_cpu_total\n"); exit(-1); } if (perfstat_memory_total(NULL, &minfo, sizeof(perfstat_memory_total_t), 1) <= 0) { perror("perfstat_memory_total\n"); exit(-1); } /* retrieve WPAR level statistics */ for (i=0; i < total_wpars; i++) { if (wparid.spec != WPARNAME) wparid.u.wpar_id = wpar_list[i].cid; if (perfstat_memory_total_wpar (WPAR_ID, &minfo_wpar[i], sizeof(perfstat_memory_total_wpar_t), 1) <= 0){ status[i] = INACTIVE; continue; } else status[i] = ACTIVE; if (wparid.spec == WPARNAME) strcpy(wparid.u.wparname,wpar); if (perfstat_cpu_total_wpar (WPAR_ID, &cinfo_wpar[i], sizeof(perfstat_cpu_total_wpar_t), 1) <= 0) status[i] = INACTIVE; else status[i] = ACTIVE; if (wparid.spec == WPARNAME) strcpy(wparid.u.wparname,wpar); } /* calculate physical processor tics during the last interval in user, system, idle and wait mode */ delta_user = cinfo.puser - last_user; delta_sys = cinfo.psys - last_sys; delta_idle = cinfo.pidle - last_idle; delta_wait = cinfo.pwait - last_wait; /* calculate delta time in terms of physical processor tics */ delta_timebase = pinfo.timebase_last - last_timebase; /* calculate total physcial processor tics during the last interval */ delta_total = delta_user + delta_sys + delta_idle + delta_wait; printf ("%-18s ", "System\0"); /* WPAR name as System for global */ printf ("%9llu ", minfo.real_inuse); /* Memory in use as 4K pages */ printf ("%9llu ", minfo.real_free); /* Memory free as 4k Pages */ printf ("%#5.1f ", (((double)minfo.real_inuse/(double)minfo.real_total)*100.0)); /* mem consumed */ printf ("%#4.1f ", ((double)(delta_user)/(double)delta_total)*100.0); /* percentage of time spent in user mode */ printf ("%#4.1f ", ((double)(delta_sys)/(double)delta_total)*100.0); /* percentage of time spent in system mode */ printf ("%#5.1f ", ((double)(delta_user + delta_sys)/(double)delta_timebase)*100.0); /* physical busy */ printf ("%#5.1f\n", ((double)(delta_total)/(double)(delta_timebase * ((double)pinfo.entitled_proc_capacity/100.0)))*100.0); /* physical consumed */ for (i=0; i < total_wpars; i++) { if (status[i] == INACTIVE) continue; /* memory limit of a WPAR as MB */ memlimit = (minfo_wpar[i].real_total * (winfo[i].mem_limit/10000.0)); /* CPU limit of a WPAR as entitled capacity */ cpulimit = ((double)pinfo.entitled_proc_capacity/100.0) * ((double)winfo[i].cpu_limit/10000.0); /* calculate physcial processor tics during the last interval in user and system */ delta_user = cinfo_wpar[i].puser - last_wpar_user[i]; delta_sys = cinfo_wpar[i].psys - last_wpar_sys[i]; delta_total= delta_user + delta_sys; printf ("%-18s ", winfo[i].name); /* WPAR name */ printf ("%9llu ", minfo_wpar[i].real_inuse); /* Memory in use as 4K pages */ printf ("%9llu ", memlimit - minfo_wpar[i].real_inuse); /* Memory free as 4k Pages */ printf ("%#5.1f ", (((double)minfo_wpar[i].real_inuse/(double)memlimit)*100.0)); /* mem consumed */ /* if delta_total is 0, it means the wpar is idle, so make both usr and sys as 0 */ if (delta_total == 0){ printf ("%#4.1f ", 0.0 ); /* percentage of time spent in user mode */ printf ("%#4.1f ", 0.0 ); /* percentage of time spent in system mode */ } else{ printf ("%#4.1f ", ((double)(delta_user)/(double)delta_total)*100.0); /* percentage of time spent in user mode */ printf ("%#4.1f ", ((double)(delta_sys)/(double)delta_total)*100.0); /* percentage of time spent in system mode */ } printf ("%#5.1f ", ((double)(delta_user + delta_sys)/(double)delta_timebase)*100.0); /* physical busy */ printf ("%#5.1f\n", ((double)(delta_user + delta_sys)/(double)(delta_timebase * cpulimit))*100.0); /* physical consumed */ } } /* *Name: main * */ int main(int argc, char *argv[]) { int c, atflag = 0; strcpy(wpar, NULL); /* Get the cid of the process */ cid = corral_getcid(); /* process all the options and get the interval and count */ while((c = getopt(argc, argv, "@:"))!= EOF){ if (c == '@'){ if (IS_WPAR(cid)) showusage(); atflag = 1; strcpy(wpar, optarg); } } argc -= optind; argv += optind; if (argc > 2) showusage(); /* if interval or count is less than or equal to zero show the usage and exit */ if(argc){ if ((interval = atoi(argv[0])) <= 0) showusage(); argc--; } if (argc){ if ((count = atoi(argv[1])) <= 0) showusage(); } /* if the argument passed with -@ is not ALL set the totalwpar to 1 */ if (atflag && strcmp(wpar,"ALL")){ total_wpars = 1; allocate(); wparid.spec = WPARNAME; strcpy(wparid.u.wparname,wpar); if (perfstat_wpar_total (WPAR_ID, winfo, sizeof(perfstat_wpar_total_t), 1) <= 0){ perror("perfstat_wpar_total :"); exit(1); } strcpy(wparid.u.wparname,wpar); if (perfstat_cpu_total_wpar (WPAR_ID, cinfo_wpar, sizeof(perfstat_cpu_total_wpar_t), 1) <= 0){ perror("perfstat_cpu_total_wpar :"); exit(1); } if (perfstat_memory_total_wpar (WPAR_ID, minfo_wpar, sizeof(perfstat_memory_total_wpar_t), 1) <= 0){ perror("perfstat_memory_total_wpar :"); exit(1); } status[0] = ACTIVE; strcpy(wparid.u.wparname,wpar); display_configuration(); } else{ get_WPAR_list(); allocate(); getwpardata(); display_configuration (); } /* Print headers */ printf("\n%-18s %-30s %-30s\n", "WPAR\0", "Memory Utilization\0", "CPU Utilization\0"); printf(" InUse Free %%Cons Usr Sys %%Phyb %%Cons"); printf("\n"); save_last_values(); while (count) { sleep (interval); display_lpar_wpar_stats(); printf ("\n"); count--; save_last_values(); } }