File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / usr.bin / iostat.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:25:28 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v121, HEAD
Power 6/32 Unix version 1.21

/*
 * iostat
 */
#include <curses.h>
#include <signal.h>
#include <stdio.h>
#include <nlist.h>
#include <sys/types.h>
#include <sys/buf.h>
#include <sys/dk.h>
#include <vba/vbavar.h>
#include <setjmp.h>
#include <vba/vddc.h>

struct nlist nli[] = {
	{ "_dk_busy" },
#define	X_DK_BUSY	0
	{ "_dk_time" },
#define	X_DK_TIME	1
	{ "_dk_xfer" },
#define	X_DK_XFER	2
	{ "_dk_wds" },
#define	X_DK_WDS	3
	{ "_tk_nin" },
#define	X_TK_NIN	4
	{ "_tk_nout" },
#define	X_TK_NOUT	5
	{ "_dk_seek" },
#define	X_DK_SEEK	6
	{ "_cp_time" },
#define	X_CP_TIME	7
	{ "_dk_mspw" },
#define	X_DK_MSPW	8
	{ "_hz" },
#define	X_HZ		9
	{ "_vbdinit" },
#define X_VBDINIT	10
	{ "_vdst" },
#define X_VDST		11
	{ "_nvddrv" },
#define X_NVDDRV	12
	{ 0 },
};
#define	PART	16	/* 16 drives displayed in one mounted set */
#define	MAX_PART	((int)((DK_NDRIVE+(PART-1))/PART))

char dr_name[DK_NDRIVE][10];
int  dr_win[DK_NDRIVE];

fs_tab *vdinfo,*vdinfo_save;
long	name;

struct
{
	int	dk_busy;
	long 	cp_time[CPUSTATES];
	long	dk_time[DK_NDRIVE];
	long	dk_wds[DK_NDRIVE];
	long	dk_seek[DK_NDRIVE];
	long	dk_xfer[DK_NDRIVE];
	float	dk_mspw[DK_NDRIVE];
	long	tk_nin;
	long	tk_nout;
} s, s1;

#define	CPUSTE	4
#define	NCOLS	80
#define	NLINES	24
#define	MAXRPT 	4
#define	UNIX	"/vmunix"

struct
{
	float	tin;
	float	tout;
	float	syste[CPUSTE];
	float	bps[DK_NDRIVE];
	float	tps[DK_NDRIVE];
	float	mspt[DK_NDRIVE];
} rec[MAXRPT];

int	mf;
int	hz;
int	nodktyp;
int 	count,repcnt, iter;

double	etime;
extern char *malloc();
int	wno;
jmp_buf	jb;
int timer();
int	max_win, recurflg;

main(argc, argv)
int	argc;
char *argv[];
{
	extern char *ctime();
	register  i;
	int iter;
	int	j, totrep;
	double f1, f2;
	long t;
	int	beg_i, end_i,head[MAX_PART],hd;
	int tohdr = 1;
	int die();
	int dietty();
	int ptoutput();
	int shiftarray();
	int	TERM;
	/* addition variables for windowing implementation  */
	WINDOW *win[MAX_PART], *window, *newwin(); 
	register	w;
	int	w_sv;
	int	deft=0;
	int	brkflg;
	int	wsleep, wrnd;
	int	sleeptime;
	char	ch;
	
	TERM = isatty(1);
	nlist(UNIX, nli);
	if(nli[X_DK_BUSY].n_value == 0) {
		printf("dk_busy not found in %s namelist\n",UNIX);
		exit(1);
	}
	mf = open("/dev/kmem", 0);
	if(mf < 0) {
		printf("cannot open /dev/kmem\n");
		exit(1);
	}
	lseek(mf, (long)nli[X_DK_MSPW].n_value, 0);
	read(mf, s.dk_mspw, sizeof s.dk_mspw);
	for (i = 0; i < DK_NDRIVE; i++){
		sprintf (dr_name[i],"?%x",i);
		dr_win[i] = -1;
	}
	lseek(mf, (long)nli[X_NVDDRV].n_value, 0);
	read(mf, &nodktyp, sizeof nodktyp);
	vdinfo = (fs_tab *)malloc(nodktyp*sizeof(fs_tab));
	lseek(mf, (long)nli[X_VDST].n_value, 0);
	read(mf, (char *)vdinfo, nodktyp*sizeof(fs_tab));
 	vdinfo_save = vdinfo;
 	for (i = 0; i < nodktyp; vdinfo++, i++) {
 		name = (long)vdinfo->type_name;
 		vdinfo->type_name = malloc(3);
 		lseek(mf, (long)name, 0);
 		read(mf, vdinfo->type_name, 3);
 	}
 	vdinfo = vdinfo_save;
	read_names();  
 	max_win=wno+1;
	argc--, argv++;
	while (argc>0 && argv[0][0]=='-') {
		char *cp= *argv++;
		argc--;
		while (*++cp) switch (*cp){

 		case '0':
 		case '1':
 		case '2':
 		case '3':
 		case '4':
 		case '5':
 		case '6':
 		case '7':
 		case '8':
 		case '9':
 			if (TERM) deft=(*cp)-'0';
			if(deft >= max_win) deft=0;
 			break;
 
 		case 'A':
 		case 'B':
 		case 'C':
 		case 'D':
 		case 'E':
 		case 'F':
 			if (TERM) deft=(*cp) -'A' +10;
			if(deft > max_win) deft=0;
 			break;

		case 'r':
			if(TERM && max_win > 0 )
					recurflg++;
			break;
		
		default:
			fprintf(stderr,"usage:iostat");
			if(max_win > 0 )
			    if(max_win <10)
				fprintf(stderr,"[-[0-%x][r]",max_win); 
			    else if (max_win >=10 && max_win < 16)
				fprintf(stderr,"[-[0-9A%x][r]",max_win);
			    else;
			fprintf(stderr," [interval] [count] \n");
			exit(1);
		}

	}

	totrep = 1;
	if(argc > 1)
		totrep = atoi(argv[2]);
	if (argc ==1)
		totrep = -1;
	iter = 0;
	if ((totrep < 0) || (totrep > MAXRPT))
		repcnt = MAXRPT;
	else
		repcnt = totrep;
	if (TERM){
		initscr();
		signal(SIGINT,dietty);
		signal(SIGBUS,dietty);
		signal(SIGALRM, timer);
		nonl();
		crmode();
		noecho();
		leaveok(stdscr, TRUE);
		scrollok(stdscr,FALSE);
		for(w=0; w < max_win; w++){
			win[w]=newwin(NLINES,NCOLS,0,0);
		}
	}
	else
		signal(SIGINT,die);
loop:
	for (w=0; w < max_win; w++)
		head[w] = 4;
	end_i = 0;
	hd=0;
	lseek(mf, (long)nli[X_DK_BUSY].n_value, 0);
 	read(mf, &s.dk_busy, sizeof s.dk_busy);
 	lseek(mf, (long)nli[X_DK_TIME].n_value, 0);
 	read(mf, s.dk_time, sizeof s.dk_time);
 	lseek(mf, (long)nli[X_DK_XFER].n_value, 0);
 	read(mf, s.dk_xfer, sizeof s.dk_xfer);
 	lseek(mf, (long)nli[X_DK_WDS].n_value, 0);
 	read(mf, s.dk_wds, sizeof s.dk_wds);
 	lseek(mf, (long)nli[X_TK_NIN].n_value, 0);
 	read(mf, &s.tk_nin, sizeof s.tk_nin);
 	lseek(mf, (long)nli[X_TK_NOUT].n_value, 0);
 	read(mf, &s.tk_nout, sizeof s.tk_nout);
	lseek(mf, (long)nli[X_DK_SEEK].n_value, 0);
	read(mf, s.dk_seek, sizeof s.dk_seek);
	lseek(mf, (long)nli[X_CP_TIME].n_value, 0);
	read(mf, s.cp_time, sizeof s.cp_time);
	lseek(mf, (long)nli[X_DK_MSPW].n_value, 0);
	read(mf, s.dk_mspw, sizeof s.dk_mspw);
	lseek(mf, (long)nli[X_HZ].n_value, 0);
	read(mf, &hz, sizeof hz);
	for (i = 0; i < DK_NDRIVE; i++) {
#define X(fld)	t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
		X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);
	}
	t = s.tk_nin; s.tk_nin -= s1.tk_nin; s1.tk_nin = t;
	t = s.tk_nout; s.tk_nout -= s1.tk_nout; s1.tk_nout = t;
	etime = 0;
	for(i=0; i<CPUSTATES; i++) {
#define X(fld)	t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
		X(cp_time);
		etime += s.cp_time[i];
	}
	if (etime == 0.0)
		etime = 1.0;
	etime /= (float) hz;
	rec[iter].tin = s.tk_nin/etime;
	rec[iter].tout = s.tk_nout/etime;
	for (i=0; i<DK_NDRIVE; i++){
		if(dr_name[i][0] != '?'){
			stats(i,iter);
		}
	}
	for (i=0; i<CPUSTATES; i++){
		stat1(i,iter);
		}
	count++;
prt_loop:
	beg_i = hd;
	if (TERM) {
		for (i = hd; i < DK_NDRIVE; i++){ 
			if (dr_name[i][0] != '?'){
				w = dr_win[i];
				if (head[w] == 4){
					wmove(win[w],0,0);
					wprintw(win[w]," tty  tin tout     cpu    us ni sy id     "); 
				}
				wprintw(win[w],"          %3.3s ",dr_name[i]); 
				head[w]++;
				w_sv=w;
				brkflg++;
				for(j=i+1; j < DK_NDRIVE; j++){
					if(dr_win[j] == w_sv){
						brkflg=0;
						break;
					}
				}
				if ((head[w] % 5 == 0) || (brkflg!=0 )){
					if(head[w_sv] !=5 )
						wprintw(win[w_sv],"\n");
					break;
				}
			}
		}
		if (i == DK_NDRIVE)
			i--;
		end_i = i;
		for (i = beg_i; i <= end_i; i++)
			if(dr_name[i][0] != '?'){
				wprintw(win[dr_win[i]]," bps tps  mspt");
			}
		wprintw (win[w_sv],"\n");
		for(i = 0; i < (iter+1); i++){
			if (head[w_sv] == 5){
			  	wprintw(win[w_sv],"     %4.0f%5.0f           ",rec[i].tin,rec[i].tout);
				for (j = 0; j < CPUSTE; j++)
					wprintw(win[w_sv],"%3.0f",rec[i].syste[j]);
			   	wprintw(win[w_sv],"                   ");
			}	
			for (j = beg_i; j <= end_i; j++)
				if (dr_name[j][0] != '?')
			      		wprintw(win[dr_win[j]],"%4.0f%4.0f %5.1f",
				  	 rec[i].bps[j], rec[i].tps[j],
					 rec[i].mspt[j]);
			wprintw (win[w_sv],"\n");
		}
		for(i=(iter+1); i<repcnt; i++)
			wprintw(win[w_sv],"\n");
		if (end_i < (DK_NDRIVE-1) ){
			hd = end_i+1;
			goto prt_loop;
		}
		for(w=0; w < max_win; w++){
			if(max_win >1){
				wmove(win[w],NLINES-1,0);
				wprintw(win[w],"More mounted disk set display: type [0-%x] to select or [r] to rotate", (max_win-1));
			}
			wmove(win[w],0,0);
		}
		window = win[deft];
		touchwin(window);
		wrefresh(window);
	}
	else
	     if ((count >= MAXRPT) &&( (count % MAXRPT ) == 0))
			ptoutput(iter+1);

	if (totrep > 0 )
		totrep--;
	iter++;

	if (count >=  MAXRPT ){
		for(i=0; i < (MAXRPT -1); i++){
			shiftarray(i,1);
		}
		iter = MAXRPT-1;
	}
	if (totrep != 0 ){
		if(argc > 0) {
 			sleeptime=atoi(argv[0]);
 			if (TERM){
			   w_sv=deft;
 			   if (recurflg){
			     wrnd=(max_win-deft);
 			     wsleep=(int)(sleeptime/(wrnd+1));
 			     if (wsleep < 1 ) recurflg = 0;
			     else{
 				   for(w=0; w< wrnd; w++){
 					w_sv=wtimed_ch(window,wsleep);
 					window=win[w+deft];
 					touchwin(window);
 					wrefresh(window);
 				   }
			    }
 			    w_sv=wtimed_ch(window,sleeptime-(wrnd*wsleep));
 			   }
 			   else {
 				w_sv=wtimed_ch(window,sleeptime);
 				}
			   if(w_sv >= 0 && w_sv < max_win) deft=w_sv;
			   if(recurflg && deft == max_win-1) recurflg=0;
 			   }
			   else
 				sleep(sleeptime); 	
 		goto loop;
		}
	}
	if(TERM)
		dietty();
	else
		die();
}

stats(dn,cnt)
	int dn, cnt;
{
	register i;
	double atime, words, xtime, itime;
	atime = s.dk_time[dn];
	atime /= (float) hz;
	words = s.dk_wds[dn]*32.0;	/* number of words transferred */
	xtime = s.dk_mspw[dn]*words;	/* transfer time */
	itime = atime - xtime;		/* time not transferring */
	if (xtime < 0)
		itime += xtime, xtime = 0;
	if (itime < 0)
		xtime += itime, itime = 0;
	rec[cnt].bps[dn] = words/512.0/etime;
	rec[cnt].tps[dn] = s.dk_xfer[dn]/etime; 
	rec[cnt].mspt[dn] = s.dk_seek[dn] ? (itime*1000./s.dk_seek[dn])+8.0 : 0.0;
}

stat1(o,ict)
	int	o,ict;
{
	register i;
	float time;

	time = 0;
	for(i=0; i<CPUSTATES; i++)
		time += s.cp_time[i];
	if (time == 0.0)
		time = 1.0;
	rec[ict].syste[o] = (100.0*s.cp_time[o])/time;
}

#define steal(where, var) lseek(mf, where, 0); read(mf, &var, sizeof var);

read_names()
{
	struct vba_device udev, *up;
	struct vba_driver udrv;
	int	unit, i;
 	int	wcnt;
 	wno=0;
 	wcnt=0;

	up = (struct vba_device *) nli[X_VBDINIT].n_value;
	if (up == 0)
	{
		fprintf(stderr, "iostat: Disk init info not in namelist\n");
		exit(1);
	}
	vdinfo_save = vdinfo;
	for (;;) {
		steal(up++, udev);
		 if (udev.ui_driver == 0)
			break;
		if (udev.ui_dk <= 0 || udev.ui_alive == 0)
			continue;
		unit = (udev.ui_ctlr * 4) + udev.ui_slave;
		if(udev.ui_type >= nodktyp){
			fprintf(stderr,"iostat : disk type in unit %d not supported \n",unit);
			exit(1);
		}
 		if (wcnt >=PART){
 			wcnt=0;
 			wno++;
 		}
 		if(wno > MAX_PART){
 			fprintf(stderr, "iostat : maximum mounted disk set of display exceeded \n");
 			exit(1);
 		}
		vdinfo = vdinfo_save;
		for(i=0; i < udev.ui_type; i++)
			vdinfo++;
		dr_name[unit][0] = vdinfo->type_name[0];
/*		dr_name[unit][1] = vdinfo->type_name[1];	*/
 		dr_win[unit]=wno;
 		wcnt++;
	}
}
die()
{
	int	i,j,k;
	iter--;
	signal(SIGINT,SIG_IGN);
	i = count % MAXRPT;
	if (count >= MAXRPT){
		k = MAXRPT - i;
		for (j=0; j <i; j++)
			shiftarray(0,k);
	}
	ptoutput(i);
	exit(0);
}
dietty()
{
	signal(SIGINT, SIG_IGN);
	mvcur(0,NCOLS-1, NLINES-1,0);
	endwin();
	exit(0);
}
ptoutput(reptot)
	int reptot;
{
register	i,j;
int	doneflg,head,end_i,beg_i;
	head = 4;
	beg_i = 0;
	doneflg=0;
	printf(" tty  tin tout     cpu    us ni sy id     "); 
	while (!doneflg){
	  for (i = beg_i; i < DK_NDRIVE; i++){ 
		if (dr_name[i][0] != '?'){
			printf("          %3.3s ",dr_name[i]); 
			head++;
			if ((head % 5 )== 0)
				break;
		}
	  }
	  if (head !=5 )
			printf ("\n");
	  if (i == DK_NDRIVE){
		i--;
		doneflg++;
		}
	  end_i = i;
	  for (i = beg_i; i <= end_i; i++)
		if(dr_name[i][0] != '?')
			printf(" bps tps  mspt");
	  printf ("\n");
	  for(i = 0; i < reptot; i++){
		if (head == 5){
		        printf("     %4.0f%5.0f           ",
			       rec[i].tin,rec[i].tout);
			for (j = 0; j < CPUSTE; j++)
				printf("%3.0f",rec[i].syste[j]);
			printf("                   ");
		}
		for (j = beg_i; j <= end_i; j++)
			if (dr_name[j][0] != '?'){
			      printf("%4.0f%4.0f %5.1f", rec[i].bps[j],
			      rec[i].tps[j],rec[i].mspt[j]);
			}
		printf ("\n");
	  }
	  for(i=reptot; i<repcnt; i++)
			printf("\n");
	beg_i = end_i;
	}
}
shiftarray(srtary,offset)
	int	srtary; /* starting array to be shifted	*/
	int	offset;	/* offset to be skip in shifting array  */ 
{
register	j;
	rec[srtary].tin = rec[srtary+offset].tin;
	rec[srtary].tout = rec[srtary+offset].tout;
	for(j=0; j < CPUSTATES; j++)
		rec[srtary].syste[j] = rec[srtary+offset].syste[j];
	for(j=0; j< DK_NDRIVE; j++){
		rec[srtary].bps[j] =rec[srtary+offset].bps[j];
		rec[srtary].tps[j] =rec[srtary+offset].tps[j];
		rec[srtary].mspt[j] =rec[srtary+offset].mspt[j];
	}
}
timer()
{
	signal(SIGALRM, timer);
	longjmp(jb,1);
}

int wtimed_ch(win, seconds)
WINDOW	*win;
int	seconds;
{
	int ch = '\0';
	int	w;
	int	deft = -1;

	if(setjmp(jb) == 0)
	{
		do{
			alarm(seconds);
			ch = wgetch(win);
			if(ch == 'r') {
				deft= -2;
				recurflg++;
			}
			w=ch-'0';
			if (w < max_win && w >=0) {
				recurflg=0;
				deft=w;
			}
 		        w=ch -'A' +10;
 		        if (w < max_win && w >10){
				recurflg=0;
				deft=w;
			}
 			else ; 
			seconds = alarm(0);
 				    
		} while (ch != 'r'|| deft <0 );
	}
	return(deft);
}

terminate()	/* SIGINT handler */
{
	endwin();
	exit(0);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.