xref: /original-bsd/usr.sbin/iostat/iostat.c (revision 6c57d260)
1 static	char *sccsid = "@(#)iostat.c	4.6 (Berkeley) 81/04/21";
2 /*
3  * iostat
4  */
5 #include <stdio.h>
6 #include <nlist.h>
7 #include <sys/types.h>
8 #include <sys/buf.h>
9 #include <sys/ubavar.h>
10 #include <sys/mbavar.h>
11 #include <sys/dk.h>
12 
13 struct nlist nl[] = {
14 	{ "_dk_busy" },
15 #define	X_DK_BUSY	0
16 	{ "_dk_time" },
17 #define	X_DK_TIME	1
18 	{ "_dk_xfer" },
19 #define	X_DK_XFER	2
20 	{ "_dk_wds" },
21 #define	X_DK_WDS	3
22 	{ "_tk_nin" },
23 #define	X_TK_NIN	4
24 	{ "_tk_nout" },
25 #define	X_TK_NOUT	5
26 	{ "_dk_seek" },
27 #define	X_DK_SEEK	6
28 	{ "_cp_time" },
29 #define	X_CP_TIME	7
30 	{ "_dk_mspw" },
31 #define	X_DK_MSPW	8
32 	{ "_mbdinit" },
33 #define X_MBDINIT	9
34 	{ "_ubdinit" },
35 #define X_UBDINIT	10
36 	{ 0 },
37 };
38 
39 char dr_name[DK_NDRIVE][10];
40 
41 struct
42 {
43 	int	dk_busy;
44 	long	cp_time[CPUSTATES];
45 	long	dk_time[DK_NDRIVE];
46 	long	dk_wds[DK_NDRIVE];
47 	long	dk_seek[DK_NDRIVE];
48 	long	dk_xfer[DK_NDRIVE];
49 	float	dk_mspw[DK_NDRIVE];
50 	long	tk_nin;
51 	long	tk_nout;
52 } s, s1;
53 
54 int	mf;
55 double	etime;
56 
57 main(argc, argv)
58 char *argv[];
59 {
60 	extern char *ctime();
61 	register  i;
62 	int iter;
63 	double f1, f2;
64 	long t;
65 	int tohdr = 1;
66 
67 	nlist("/vmunix", nl);
68 	if(nl[X_DK_BUSY].n_type == 0) {
69 		printf("dk_busy not found in /vmunix namelist\n");
70 		exit(1);
71 	}
72 	mf = open("/dev/kmem", 0);
73 	if(mf < 0) {
74 		printf("cannot open /dev/kmem\n");
75 		exit(1);
76 	}
77 	iter = 0;
78 	while (argc>1&&argv[1][0]=='-') {
79 		argc--;
80 		argv++;
81 	}
82 	lseek(mf, (long)nl[X_DK_MSPW].n_value, 0);
83 	read(mf, s.dk_mspw, sizeof s.dk_mspw);
84 	for (i = 0; i < DK_NDRIVE; i++)
85 		sprintf(dr_name[i], "dk%d", i);
86 	read_names();
87 	if(argc > 2)
88 		iter = atoi(argv[2]);
89 loop:
90 	if (--tohdr == 0) {
91 		printf("      tty");
92 		for (i = 0; i < DK_NDRIVE; i++)
93 			if (s.dk_mspw[i] != 0.0)
94 				printf("          %3.3s ", dr_name[i]);
95 		printf("         cpu\n");
96 		printf(" tin tout");
97 		for (i = 0; i < DK_NDRIVE; i++)
98 			if (s.dk_mspw[i] != 0.0)
99 				printf(" sps tps msps ");
100 		printf(" us ni sy id\n");
101 		tohdr = 19;
102 	}
103 	lseek(mf, (long)nl[X_DK_BUSY].n_value, 0);
104  	read(mf, &s.dk_busy, sizeof s.dk_busy);
105  	lseek(mf, (long)nl[X_DK_TIME].n_value, 0);
106  	read(mf, s.dk_time, sizeof s.dk_time);
107  	lseek(mf, (long)nl[X_DK_XFER].n_value, 0);
108  	read(mf, s.dk_xfer, sizeof s.dk_xfer);
109  	lseek(mf, (long)nl[X_DK_WDS].n_value, 0);
110  	read(mf, s.dk_wds, sizeof s.dk_wds);
111  	lseek(mf, (long)nl[X_TK_NIN].n_value, 0);
112  	read(mf, &s.tk_nin, sizeof s.tk_nin);
113  	lseek(mf, (long)nl[X_TK_NOUT].n_value, 0);
114  	read(mf, &s.tk_nout, sizeof s.tk_nout);
115 	lseek(mf, (long)nl[X_DK_SEEK].n_value, 0);
116 	read(mf, s.dk_seek, sizeof s.dk_seek);
117 	lseek(mf, (long)nl[X_CP_TIME].n_value, 0);
118 	read(mf, s.cp_time, sizeof s.cp_time);
119 	lseek(mf, (long)nl[X_DK_MSPW].n_value, 0);
120 	read(mf, s.dk_mspw, sizeof s.dk_mspw);
121 	for (i = 0; i < DK_NDRIVE; i++) {
122 #define X(fld)	t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
123 		X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);
124 	}
125 	t = s.tk_nin; s.tk_nin -= s1.tk_nin; s1.tk_nin = t;
126 	t = s.tk_nout; s.tk_nout -= s1.tk_nout; s1.tk_nout = t;
127 	etime = 0;
128 	for(i=0; i<CPUSTATES; i++) {
129 		X(cp_time);
130 		etime += s.cp_time[i];
131 	}
132 	if (etime == 0.0)
133 		etime = 1.0;
134 	etime /= 60.0;
135 	printf("%4.0f%5.0f", s.tk_nin/etime, s.tk_nout/etime);
136 	for (i=0; i<DK_NDRIVE; i++)
137 		if (s.dk_mspw[i] != 0.0)
138 			stats(i);
139 	for (i=0; i<CPUSTATES; i++)
140 		stat1(i);
141 	printf("\n");
142 contin:
143 	--iter;
144 	if(iter)
145 	if(argc > 1) {
146 		sleep(atoi(argv[1]));
147 		goto loop;
148 	}
149 }
150 
151 stats(dn)
152 {
153 	register i;
154 	double atime, words, xtime, itime;
155 
156 	if (s.dk_mspw[dn] == 0.0) {
157 		printf("%4.0f%4.0f%5.1f ", 0.0, 0.0, 0.0);
158 		return;
159 	}
160 	atime = s.dk_time[dn];
161 	atime /= 60.0;
162 	words = s.dk_wds[dn]*32.0;	/* number of words transferred */
163 	xtime = s.dk_mspw[dn]*words;	/* transfer time */
164 	itime = atime - xtime;		/* time not transferring */
165 /*
166 	printf("\ndn %d, words %8.2f, atime %6.2f, xtime %6.2f, itime %6.2f\n",
167 	    dn, words, atime, xtime, itime);
168 */
169 	if (xtime < 0)
170 		itime += xtime, xtime = 0;
171 	if (itime < 0)
172 		xtime += itime, itime = 0;
173 	printf("%4.0f", s.dk_seek[dn]/etime);
174 	printf("%4.0f", s.dk_xfer[dn]/etime);
175 	printf("%5.1f ",
176 	    s.dk_seek[dn] ? itime*1000./s.dk_seek[dn] : 0.0);
177 /*
178 	printf("%4.1f",
179 	    s.dk_xfer[dn] ? xtime*1000./s.dk_xfer[dn] : 0.0);
180 */
181 }
182 
183 stat1(o)
184 {
185 	register i;
186 	double time;
187 
188 	time = 0;
189 	for(i=0; i<CPUSTATES; i++)
190 		time += s.cp_time[i];
191 	if (time == 0.0)
192 		time = 1.0;
193 	printf("%3.0f", 100*s.cp_time[o]/time);
194 }
195 
196 /*
197  * Read the drive names out of kmem.
198  * ARGH ARGH ARGH ARGH !!!!!!!!!!!!
199  */
200 
201 #define steal(where, var) lseek(mf, where, 0); read(mf, &var, sizeof var);
202 read_names()
203 {
204 	struct mba_device mdev;
205 	register struct mba_device *mp;
206 	struct mba_driver mdrv;
207 	short two_char;
208 	char *cp = (char *) &two_char;
209 	struct uba_device udev, *up;
210 	struct uba_driver udrv;
211 
212 	mp = (struct mba_device *) nl[X_MBDINIT].n_value;
213 	up = (struct uba_device *) nl[X_UBDINIT].n_value;
214 	if (up == 0)
215 	{
216 		fprintf(stderr, "iostat: Disk init info not in namelist\n");
217 		exit(1);
218 	}
219 	if (mp)
220 	while(1)
221 	{
222 		steal(mp++, mdev);
223 		if (mdev.mi_driver == 0)
224 			break;
225 		if (mdev.mi_dk < 0 || mdev.mi_alive == 0)
226 			continue;
227 		steal(mdev.mi_driver, mdrv);
228 		steal(mdrv.md_dname, two_char);
229 		sprintf(dr_name[mdev.mi_dk], "%c%c%d", cp[0], cp[1], mdev.mi_unit);
230 	}
231 	while(1)
232 	{
233 		steal(up++, udev);
234 		if (udev.ui_driver == 0)
235 			break;
236 		if (udev.ui_dk < 0 || udev.ui_alive == 0)
237 			continue;
238 		steal(udev.ui_driver, udrv);
239 		steal(udrv.ud_dname, two_char);
240 		sprintf(dr_name[udev.ui_dk], "%c%c%d", cp[0], cp[1], udev.ui_unit);
241 	}
242 }
243