V7M/src/cmd/iostat.c

Compare this file to the similar file:
Show the results in this format:

/*
 * 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));
}