V7M/src/cmd/iostat.c
/*
* Unix/v7m 2.1 iostat command - iostat.c
*
* Fred Canter 9/19/81
*
*/
int bflg;
int dflg;
int tflg;
int iflg;
int aflg;
int sflg;
int dsflag;
struct
{
char name[8];
int type;
unsigned value;
} nl[] = {
"_cp_time", 0, 0,
"_io_info", 0, 0,
"_dk_iop", 0, 0,
"_dk_nd", 0, 0,
"_tk_nin", 0, 0,
"_tk_nout", 0, 0,
"\0\0\0\0\0\0\0\0", 0, 0
};
/*
* WARNING !,
* DK_NC is defined here and in /sys/h/systm.h,
* if one is changed the other must also be changed.
*/
#define DK_NC 6 /* number of possible disk controllers */
long cp_t[5];
long cp_t1[5];
struct ios
{
char dk_tr; /* drive xfer rate */
char dk_busy; /* drive activity flag */
long dk_numb; /* drive xfer count */
long dk_wds; /* drive words xfer'd (32 word clicks) */
long dk_time; /* drive active time tally */
} dk_ios[DK_NC*8], dk_ios1[DK_NC*8];
struct ios *dk_iop[DK_NC]; /* iostat structure pointers */
char dk_nd[DK_NC]; /* number of drives per controller */
char *dt[] =
{
"hp",
"hm",
"hk",
"ml",
"rp",
"rl",
0
};
char dname[10]; /* drive select name */
char ds[7]; /* drive select numbers */
/*
* Number of tty char's in/out.
*/
long tin, tin1;
long tout, tout1;
/* usec per word for the various disks */
double xf[] = {
0.0, /* dummy - no dirve available */
2.48, /* RM02 and RP04/5/6 */
1.65, /* RM03 */
4.3, /* RK06/7 */
1.0, /* ML11 - 2.0 mb */
2.0, /* ML11 - 1.0 mb */
4.0, /* ML11 - 0.5 mb */
8.0, /* ML11 - 0.25 mb */
7.5, /* RP03 */
3.9, /* RL01/2 */
};
struct iostat {
int nbuf;
long nread;
long nreada;
long ncache;
long nwrite;
long bufcount[100];
} io_info, io_delta;
double etime;
int mf;
main(argc, argv)
char *argv[];
{
struct ios *iop;
extern char *ctime();
register i, j;
int iter, lc;
double f1, f2;
long t;
nlist("/unix", nl);
for(i=0; i<4; i++)
if(nl[i].type == -1) {
printf("%s not found in /unix namelist\n", nl[i].name);
exit(1);
}
mf = open("/dev/kmem", 0);
if(mf < 0) {
printf("cannot open /dev/kmem\n");
exit(1);
}
iter = 0;
while (argc>1&&argv[1][0]=='-') {
if (argv[1][1]=='d')
dflg++;
else if (argv[1][1]=='s')
sflg++;
else if (argv[1][1]=='a')
aflg++;
else if (argv[1][1]=='t')
tflg++;
else if (argv[1][1]=='i')
iflg++;
else if (argv[1][1]=='b')
bflg++;
argc--;
argv++;
}
/*
* Scan the argument list for drive select
* specifications, up to six are allowed.
*/
if(argc <2)
goto dsend;
j = 0;
dsloop:
if((argv[1] [0] >= '0') && (argv[1] [0] <= '9'))
goto dsend;
dsflag++;
dname[0] = argv[1] [0];
dname[1] = argv[1] [1];
dname[2] = 0;
for(i=0; i<DK_NC; i++)
if(equal(&dname, dt[i]))
break;
if(i < DK_NC) {
ds[j] = (i * 8) + (argv[1] [2] - '0');
if(++j >= 6)
goto dsend;
}
argc--;
argv++;
goto dsloop;
dsend:
if(argc > 2)
iter = atoi(argv[2]);
/*
* Locate and read in the pointers to the
* iostat structures for each controller and
* the number of drives on each controller.
*/
lseek(mf, (long)nl[2].value, 0);
read(mf, (char *)&dk_iop, sizeof(dk_iop));
lseek(mf, (long)nl[3].value, 0);
read(mf, (char *)&dk_nd, sizeof(dk_nd));
loop:
lseek(mf, (long)nl[0].value, 0);
read(mf, (char *)&cp_t, sizeof(cp_t));
for(i=0; i<5; i++) {
t = cp_t[i];
cp_t[i] -= cp_t1[i];
cp_t1[i] = t;
}
lseek(mf, (long)nl[4].value, 0);
read(mf, (char *)&tin, sizeof(tin));
lseek(mf, (long)nl[5].value, 0);
read(mf, (char *)&tout, sizeof(tout));
t = tin;
tin -= tin1;
tin1 = t;
t = tout;
tout -= tout1;
tout1 = t;
for(i=0; i<DK_NC; i++) {
if(dk_iop[i] == 0)
continue;
iop = &dk_ios[0];
iop += (i*8);
lseek(mf, (long)dk_iop[i], 0);
read(mf, (char *)iop, (sizeof(struct ios)*dk_nd[i]));
}
for(i=0; i<(DK_NC * 8); i++) {
if(dsflag) {
for(j=0; j<6; j++)
if( i == ds[j])
dk_ios[i].dk_busy++;
} else
dk_ios[i].dk_busy++;
}
for(i=0; i<(DK_NC * 8); i++) {
t = dk_ios[i].dk_numb;
dk_ios[i].dk_numb -= dk_ios1[i].dk_numb;
dk_ios1[i].dk_numb = t;
t = dk_ios[i].dk_wds;
dk_ios[i].dk_wds -= dk_ios1[i].dk_wds;
dk_ios1[i].dk_wds = t;
t = dk_ios[i].dk_time;
dk_ios[i].dk_time -= dk_ios1[i].dk_time;
dk_ios1[i].dk_time = t;
}
if(lc == 0) {
if (!(sflg|iflg|bflg)) {
if (dflg) {
long tm;
time(&tm);
printf("\n%s", ctime(&tm));
}
printf("\n");
if(tflg)
printf(" TTY");
if (bflg==0) {
for(i=0; i<(DK_NC * 8); i++)
if(dk_ios[i].dk_tr && dk_ios[i].dk_busy)
printf(" %s%o ", dt[i/8], i&7);
printf(" PERCENT\n");
}
if(tflg)
printf(" tin tout");
if(bflg==0) {
for(i=0; i<(DK_NC * 8); i++)
if(dk_ios[i].dk_tr && dk_ios[i].dk_busy)
printf(" tpm msps mspt");
printf(" user nice systm idle\n");
}
}
}
if(++lc == 10)
lc = 0;
t = 0;
for(i=0; i<4; i++)
t += cp_t[i];
etime = t;
if(etime == 0.)
etime = 1.;
if (bflg) {
biostats();
goto contin;
}
if (sflg) {
stats2(etime);
goto contin;
}
if (iflg) {
stats3(etime);
goto contin;
}
etime /= 60.;
if(tflg) {
f1 = tin;
f2 = tout;
printf("%6.1f", f1/etime);
printf("%6.1f", f2/etime);
}
for(i=0; i<(DK_NC * 8); i++)
if(dk_ios[i].dk_tr && dk_ios[i].dk_busy)
stats(i);
for(i=0; i<4; i++)
stat1(i);
printf("\n");
if (aflg)
printf("%.2f minutes total\n", etime/60);
contin:
--iter;
if(iter)
if(argc > 1) {
sleep(atoi(argv[1]));
goto loop;
}
}
stats(dn)
{
register i;
double f1, f2, f3;
double f4, f5, f6;
long t;
t = dk_ios[i].dk_time;
f1 = t;
f1 = f1/60.;
f2 = dk_ios[i].dk_numb;
if(f2 == 0.) {
printf("%6.0f%6.1f%6.1f", 0.0, 0.0, 0.0);
return;
}
f3 = dk_ios[i].dk_wds;
f3 = f3*32.;
f4 = xf[dk_ios[i].dk_tr];
f4 = f4*1.0e-6;
f5 = f1 - f4*f3;
f6 = f1 - f5;
printf("%6.0f", f2*60./etime);
f1 = (f5*1000.)/f2;
if(f1 < 0.)
f1 = 0.0;
printf("%6.1f", f1);
printf("%6.1f", f6*1000./f2);
}
stat1(o)
{
register i;
long t;
double f1, f2;
t = 0;
for(i=0; i<4; i++)
t += cp_t[i];
f1 = t;
if(f1 == 0.)
f1 = 1.;
f2 = cp_t[o];
printf("%6.2f", f2*100./f1);
}
stats2(t)
double t;
{
register i, j, k;
if (dflg) {
long tm;
time(&tm);
printf("\n\n%s", ctime(&tm));
}
printf("\ndisk\tdrive\tus/word\t%%time\txfer's\t words\n");
for (i=0; i<DK_NC; i++) {
for (j=0; j<8; j++) {
k = (i*8) + j;
if(dk_ios[k].dk_tr == 0)
continue;
printf("\n%s\t%d\t", dt[i], j);
printf("%4.2f\t", xf[dk_ios[k].dk_tr]);
printf("%5.2f\t", dk_ios[i*8+j].dk_time/(t/100));
printf("%D\t ", dk_ios[k].dk_numb);
printf("%D", (dk_ios[k].dk_wds)*32);
}
}
printf("\n");
if (aflg)
printf("\n%.2f minutes total\n", etime/3600);
}
stats3(t)
double t;
{
register i, j;
double sum;
if (dflg) {
long tm;
time(&tm);
printf("\n\n%s", ctime(&tm));
}
printf("\n %%time state\n");
t /= 100;
sum = cp_t[3];
printf("%6.2f idle\n", sum/t);
sum = cp_t[0];
printf("%6.2f user\n", sum/t);
sum = cp_t[1];
printf("%6.2f nice\n", sum/t);
sum = cp_t[2];
printf("%6.2f system\n", sum/t);
sum = cp_t[4];
printf("%6.2f IO wait\n", sum/t);
sum = 0;
for (i=0; i<(DK_NC * 8); i++)
if(dk_ios[i].dk_tr)
sum += dk_ios[i].dk_time;
printf("%6.2f IO active\n", sum/t);
for(i=0; i<DK_NC; i++) {
sum = 0;
for(j=0; j<8; j++)
sum += dk_ios[(i*8)+j].dk_time;
if(sum)
printf("%6.2f %s active\n", sum/t, dt[i]);
}
if (aflg)
printf("\n%.2f minutes total\n", etime/3600);
}
biostats()
{
register i;
if (dflg) {
long tm;
time(&tm);
printf("\n%s", ctime(&tm));
}
lseek(mf,(long)nl[1].value, 0);
read(mf, (char *)&io_info, sizeof(io_info));
printf("\nnbuf\tnread\tnreada\tncache\tnwrite\n");
printf("%d\t%D\t%D\t%D\t%D\n",
io_info.nbuf,
io_info.nread-io_delta.nread, io_info.nreada-io_delta.nreada,
io_info.ncache-io_delta.ncache, io_info.nwrite-io_delta.nwrite);
printf("\nI/O operations per buffer (0->NBUF)\n");
for(i=0; i<io_info.nbuf; ) {
printf("%D\t",(long)io_info.bufcount[i]-io_delta.bufcount[i]);
i++;
if (i % 10 == 0)
printf("\n");
}
io_delta = io_info;
printf("\n");
if (aflg)
printf("\n%.2f minutes total\n", etime/3600);
}
equal(a, b)
char *a, *b;
{
return(!strcmp(a, b));
}