143 lines
3.4 KiB
C
143 lines
3.4 KiB
C
/*
|
|
Repeatable prints disk statistics and sleeps for 10 seconds
|
|
Modified example from: https://www.ibm.com/docs/en/aix/7.3?topic=interfaces-perfstat-disk-interface
|
|
*/
|
|
|
|
#include <time.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <libperfstat.h>
|
|
|
|
const int true = 1;
|
|
const int false = 0;
|
|
|
|
|
|
int startsWith(const char *a, const char *b) {
|
|
if(strncmp(a, b, strlen(b)) == 0) return true;
|
|
return false;
|
|
}
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
|
|
|
|
|
int i, ret, tot, sleepSecs;
|
|
perfstat_disk_t *statp;
|
|
perfstat_id_t first;
|
|
time_t now;
|
|
|
|
if(argc == 2) {
|
|
char *a = argv[1];
|
|
sleepSecs = atoi(a);
|
|
} else {
|
|
sleepSecs = 10;
|
|
}
|
|
|
|
|
|
/* check how many perfstat_disk_t structures are available */
|
|
tot = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0);
|
|
|
|
/* check for error */
|
|
if (tot < 0) {
|
|
perror("perfstat_disk");
|
|
exit(-1);
|
|
}
|
|
if (tot == 0) {
|
|
printf("No disks found in the system\n");
|
|
exit(-1);
|
|
}
|
|
|
|
/* keep previous values to calculate difference */
|
|
long history[32][8] = { 0 };
|
|
|
|
/* allocate enough memory for all the structures */
|
|
statp = calloc(tot, sizeof(perfstat_disk_t));
|
|
|
|
/* set name to first interface */
|
|
strcpy(first.name, FIRST_DISK);
|
|
|
|
while (1)
|
|
{
|
|
|
|
/* ask to get all the structures available in one call */
|
|
/* return code is number of structures returned */
|
|
ret = perfstat_disk(&first, statp, sizeof(perfstat_disk_t), tot);
|
|
|
|
/* check for error */
|
|
if (ret <= 0) {
|
|
perror("perfstat_disk");
|
|
exit(-1);
|
|
}
|
|
|
|
|
|
// Obtain current time
|
|
// `time()` returns the current time of the system as a `time_t` value
|
|
time(&now);
|
|
|
|
/* print statistics for each of the disks */
|
|
for (i = 0; i < ret; i++) {
|
|
|
|
if(!startsWith(statp[i].name, "hdisk")) {
|
|
continue;
|
|
}
|
|
|
|
unsigned long bsize = statp[i].bsize; // Disk block size (in bytes).
|
|
unsigned long rblks = statp[i].rblks; // Number of blocks read from disk.
|
|
unsigned long wblks = statp[i].wblks; // Number of blocks written to disk.
|
|
|
|
unsigned long rbytes = 0;
|
|
if(rblks > 0) {
|
|
rbytes = rblks * bsize;
|
|
}
|
|
|
|
unsigned long wbytes = 0;
|
|
if (wblks > 0) {
|
|
wbytes = wblks * bsize;
|
|
}
|
|
|
|
|
|
unsigned long drblbks = 0;
|
|
if (history[i][0] > 0) {
|
|
drblbks = rblks - history[i][0];
|
|
}
|
|
|
|
unsigned long drbytes = 0;
|
|
if(history[i][0] > 0) {
|
|
drbytes = rbytes - (history[i][0] * bsize);
|
|
}
|
|
|
|
|
|
unsigned long dwblbks = 0;
|
|
if (history[i][1] > 0) {
|
|
dwblbks = wblks - history[i][1];
|
|
}
|
|
|
|
unsigned long dwbytes = 0;
|
|
if(history[i][1] > 0) {
|
|
dwbytes = wbytes - (history[i][1] * bsize);
|
|
}
|
|
|
|
|
|
printf("%s - %s => reads: [ blocks: %10u (%8u ), bytes: %10u (%8u ) ], writes: [ blocks: %10u (%8u ), bytes: %10u (%8u ) ]\n",
|
|
strtok(ctime(&now), "\n"),
|
|
statp[i].name,
|
|
rblks,
|
|
drblbks,
|
|
rbytes,
|
|
drbytes,
|
|
wblks,
|
|
dwblbks,
|
|
wbytes,
|
|
dwbytes);
|
|
|
|
history[i][0] = rblks;
|
|
history[i][1] = wblks;
|
|
}
|
|
|
|
sleep(sleepSecs);
|
|
}
|
|
}
|
|
|