|
|
1.1 root 1: /*
2: * Copyright (c) 1980 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)vmstat.c 5.21 (Berkeley) 6/6/90";
28: #endif /* not lint */
29:
30: #include <sys/param.h>
31: #include <sys/file.h>
32: #include <sys/vm.h>
33: #include <sys/dkstat.h>
34: #include <sys/buf.h>
35: #include <sys/namei.h>
36: #include <sys/text.h>
37: #include <sys/malloc.h>
38: #include <stdio.h>
39: #include <ctype.h>
40: #include <nlist.h>
41: #include <paths.h>
42:
43: struct nlist nl[] = {
44: #define X_CPTIME 0
45: { "_cp_time" },
46: #define X_RATE 1
47: { "_rate" },
48: #define X_TOTAL 2
49: { "_total" },
50: #define X_DEFICIT 3
51: { "_deficit" },
52: #define X_FORKSTAT 4
53: { "_forkstat" },
54: #define X_SUM 5
55: { "_sum" },
56: #define X_FIRSTFREE 6
57: { "_firstfree" },
58: #define X_MAXFREE 7
59: { "_maxfree" },
60: #define X_BOOTTIME 8
61: { "_boottime" },
62: #define X_DKXFER 9
63: { "_dk_xfer" },
64: #define X_REC 10
65: { "_rectime" },
66: #define X_PGIN 11
67: { "_pgintime" },
68: #define X_HZ 12
69: { "_hz" },
70: #define X_PHZ 13
71: { "_phz" },
72: #define X_NCHSTATS 14
73: { "_nchstats" },
74: #define X_INTRNAMES 15
75: { "_intrnames" },
76: #define X_EINTRNAMES 16
77: { "_eintrnames" },
78: #define X_INTRCNT 17
79: { "_intrcnt" },
80: #define X_EINTRCNT 18
81: { "_eintrcnt" },
82: #define X_DK_NDRIVE 19
83: { "_dk_ndrive" },
84: #define X_XSTATS 20
85: { "_xstats" },
86: #define X_KMEMSTAT 21
87: { "_kmemstats" },
88: #define X_KMEMBUCKETS 22
89: { "_bucket" },
90: #define X_END 22
91: #ifdef vax
92: #define X_MBDINIT (X_END+1)
93: { "_mbdinit" },
94: #define X_UBDINIT (X_END+2)
95: { "_ubdinit" },
96: #endif
97: #ifdef tahoe
98: #define X_VBDINIT (X_END+1)
99: { "_vbdinit" },
100: #define X_CKEYSTATS (X_END+2)
101: { "_ckeystats" },
102: #define X_DKEYSTATS (X_END+3)
103: { "_dkeystats" },
104: #endif
105: #ifdef hp300
106: #define X_HPDINIT (X_END+1)
107: { "_hp_dinit" },
108: #endif
109: { "" },
110: };
111:
112: char **dr_name;
113: int *dr_select;
114: int dk_ndrive;
115: int ndrives = 0;
116: #ifdef vax
117: char *defdrives[] = { "hp0", "hp1", "hp2", 0 };
118: #else
119: #ifdef hp300
120: char *defdrives[] = { "rd0", "rd1", "rd2", 0 };
121: #else
122: char *defdrives[] = { 0 };
123: #endif
124: #endif
125: double stat1();
126: int firstfree, maxfree;
127: int hz;
128: int phz;
129: int HZ;
130:
131: struct {
132: int busy;
133: long time[CPUSTATES];
134: long *xfer;
135: struct vmmeter Rate;
136: struct vmtotal Total;
137: struct vmmeter Sum;
138: struct forkstat Forkstat;
139: unsigned rectime;
140: unsigned pgintime;
141: } s, s1, z;
142: #define rate s.Rate
143: #define total s.Total
144: #define sum s.Sum
145: #define forkstat s.Forkstat
146:
147: struct vmmeter osum;
148: int deficit;
149: double etime;
150: int mf;
151: time_t now, boottime;
152: int printhdr();
153: int lines = 1;
154:
155: #define INTS(x) ((x) - (hz + phz))
156:
157: main(argc, argv)
158: int argc;
159: char **argv;
160: {
161: extern char *ctime();
162: register i;
163: int iter, nintv, iflag = 0;
164: long t;
165: char *arg, **cp, buf[BUFSIZ];
166:
167: nlist(_PATH_UNIX, nl);
168: if(nl[0].n_type == 0) {
169: fprintf(stderr, "vmstat: no %s namelist\n", _PATH_UNIX);
170: exit(1);
171: }
172: mf = open(_PATH_KMEM, 0);
173: if(mf < 0) {
174: fprintf(stderr, "vmstat: cannot open %s\n", _PATH_KMEM);
175: exit(1);
176: }
177: iter = 0;
178: argc--, argv++;
179: while (argc>0 && argv[0][0]=='-') {
180: char *cp = *argv++;
181: argc--;
182: while (*++cp) switch (*cp) {
183:
184: case 't':
185: dotimes();
186: exit(0);
187:
188: case 'z':
189: close(mf);
190: mf = open(_PATH_KMEM, 2);
191: lseek(mf, (long)nl[X_SUM].n_value, L_SET);
192: write(mf, &z.Sum, sizeof z.Sum);
193: exit(0);
194:
195: case 'f':
196: doforkst();
197: exit(0);
198:
199: case 'm':
200: domem();
201: exit(0);
202:
203: case 's':
204: dosum();
205: exit(0);
206:
207: case 'i':
208: iflag++;
209: break;
210:
211: default:
212: fprintf(stderr,
213: "usage: vmstat [ -fsim ] [ interval ] [ count]\n");
214: exit(1);
215: }
216: }
217: lseek(mf, (long)nl[X_FIRSTFREE].n_value, L_SET);
218: read(mf, &firstfree, sizeof firstfree);
219: lseek(mf, (long)nl[X_MAXFREE].n_value, L_SET);
220: read(mf, &maxfree, sizeof maxfree);
221: lseek(mf, (long)nl[X_BOOTTIME].n_value, L_SET);
222: read(mf, &boottime, sizeof boottime);
223: lseek(mf, (long)nl[X_HZ].n_value, L_SET);
224: read(mf, &hz, sizeof hz);
225: if (nl[X_PHZ].n_value != 0) {
226: lseek(mf, (long)nl[X_PHZ].n_value, L_SET);
227: read(mf, &phz, sizeof phz);
228: }
229: HZ = phz ? phz : hz;
230: if (nl[X_DK_NDRIVE].n_value == 0) {
231: fprintf(stderr, "dk_ndrive undefined in system\n");
232: exit(1);
233: }
234: lseek(mf, nl[X_DK_NDRIVE].n_value, L_SET);
235: read(mf, &dk_ndrive, sizeof (dk_ndrive));
236: if (dk_ndrive <= 0) {
237: fprintf(stderr, "dk_ndrive %d\n", dk_ndrive);
238: exit(1);
239: }
240: dr_select = (int *)calloc(dk_ndrive, sizeof (int));
241: dr_name = (char **)calloc(dk_ndrive, sizeof (char *));
242: #define allocate(e, t) \
243: s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
244: s1./**/e = (t *)calloc(dk_ndrive, sizeof (t));
245: allocate(xfer, long);
246: for (arg = buf, i = 0; i < dk_ndrive; i++) {
247: dr_name[i] = arg;
248: sprintf(dr_name[i], "dk%d", i);
249: arg += strlen(dr_name[i]) + 1;
250: }
251: read_names();
252: time(&now);
253: nintv = now - boottime;
254: if (nintv <= 0 || nintv > 60*60*24*365*10) {
255: fprintf(stderr,
256: "Time makes no sense... namelist must be wrong.\n");
257: exit(1);
258: }
259: if (iflag) {
260: dointr(nintv);
261: exit(0);
262: }
263: /*
264: * Choose drives to be displayed. Priority
265: * goes to (in order) drives supplied as arguments,
266: * default drives. If everything isn't filled
267: * in and there are drives not taken care of,
268: * display the first few that fit.
269: */
270: ndrives = 0;
271: while (argc > 0 && !isdigit(argv[0][0])) {
272: for (i = 0; i < dk_ndrive; i++) {
273: if (strcmp(dr_name[i], argv[0]))
274: continue;
275: dr_select[i] = 1;
276: ndrives++;
277: }
278: argc--, argv++;
279: }
280: for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
281: if (dr_select[i])
282: continue;
283: for (cp = defdrives; *cp; cp++)
284: if (strcmp(dr_name[i], *cp) == 0) {
285: dr_select[i] = 1;
286: ndrives++;
287: break;
288: }
289: }
290: for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
291: if (dr_select[i])
292: continue;
293: dr_select[i] = 1;
294: ndrives++;
295: }
296: if (argc > 1)
297: iter = atoi(argv[1]);
298: signal(SIGCONT, printhdr);
299: loop:
300: if (--lines == 0)
301: printhdr();
302: lseek(mf, (long)nl[X_CPTIME].n_value, L_SET);
303: read(mf, s.time, sizeof s.time);
304: lseek(mf, (long)nl[X_DKXFER].n_value, L_SET);
305: read(mf, s.xfer, dk_ndrive * sizeof (long));
306: if (nintv != 1)
307: lseek(mf, (long)nl[X_SUM].n_value, L_SET);
308: else
309: lseek(mf, (long)nl[X_RATE].n_value, L_SET);
310: read(mf, &rate, sizeof rate);
311: lseek(mf, (long)nl[X_TOTAL].n_value, L_SET);
312: read(mf, &total, sizeof total);
313: osum = sum;
314: lseek(mf, (long)nl[X_SUM].n_value, L_SET);
315: read(mf, &sum, sizeof sum);
316: lseek(mf, (long)nl[X_DEFICIT].n_value, L_SET);
317: read(mf, &deficit, sizeof deficit);
318: etime = 0;
319: for (i=0; i < dk_ndrive; i++) {
320: t = s.xfer[i];
321: s.xfer[i] -= s1.xfer[i];
322: s1.xfer[i] = t;
323: }
324: for (i=0; i < CPUSTATES; i++) {
325: t = s.time[i];
326: s.time[i] -= s1.time[i];
327: s1.time[i] = t;
328: etime += s.time[i];
329: }
330: if(etime == 0.)
331: etime = 1.;
332: printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw);
333: #define pgtok(a) ((a)*NBPG/1024)
334: printf("%6d%6d", pgtok(total.t_avm), pgtok(total.t_free));
335: printf("%4d%3d", (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv,
336: (rate.v_xsfrec+rate.v_xifrec)/nintv);
337: printf("%4d", pgtok(rate.v_pgpgin)/nintv);
338: printf("%4d%4d%4d%4d", pgtok(rate.v_pgpgout)/nintv,
339: pgtok(rate.v_dfree)/nintv, pgtok(deficit), rate.v_scan/nintv);
340: etime /= (float)HZ;
341: for (i = 0; i < dk_ndrive; i++)
342: if (dr_select[i])
343: stats(i);
344: printf("%4d%4d%4d", INTS(rate.v_intr/nintv), rate.v_syscall/nintv,
345: rate.v_swtch/nintv);
346: for(i=0; i<CPUSTATES; i++) {
347: float f = stat1(i);
348: if (i == 0) { /* US+NI */
349: i++;
350: f += stat1(i);
351: }
352: printf("%3.0f", f);
353: }
354: printf("\n");
355: fflush(stdout);
356: nintv = 1;
357: if (--iter &&argc > 0) {
358: sleep(atoi(argv[0]));
359: goto loop;
360: }
361: }
362:
363: printhdr()
364: {
365: register int i, j;
366:
367: printf(" procs memory page ");
368: i = (ndrives * 3 - 6) / 2;
369: if (i < 0)
370: i = 0;
371: for (j = 0; j < i; j++)
372: putchar(' ');
373: printf("faults");
374: i = ndrives * 3 - 6 - i;
375: for (j = 0; j < i; j++)
376: putchar(' ');
377: printf(" cpu\n");
378: printf(" r b w avm fre re at pi po fr de sr ");
379: for (i = 0; i < dk_ndrive; i++)
380: if (dr_select[i])
381: printf("%c%c ", dr_name[i][0], dr_name[i][2]);
382: printf(" in sy cs us sy id\n");
383: lines = 19;
384: }
385:
386: dotimes()
387: {
388:
389: lseek(mf, (long)nl[X_REC].n_value, L_SET);
390: read(mf, &s.rectime, sizeof s.rectime);
391: lseek(mf, (long)nl[X_PGIN].n_value, L_SET);
392: read(mf, &s.pgintime, sizeof s.pgintime);
393: lseek(mf, (long)nl[X_SUM].n_value, L_SET);
394: read(mf, &sum, sizeof sum);
395: printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime);
396: printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec);
397: printf("\n");
398: printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10);
399: printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0));
400: }
401:
402: #if defined(tahoe)
403: #include <tahoe/cpu.h>
404: #endif
405:
406: dosum()
407: {
408: struct nchstats nchstats;
409: struct xstats xstats;
410: long nchtotal;
411: #if defined(tahoe)
412: struct keystats keystats;
413: #endif
414:
415: lseek(mf, (long)nl[X_SUM].n_value, L_SET);
416: read(mf, &sum, sizeof sum);
417: printf("%9d swap ins\n", sum.v_swpin);
418: printf("%9d swap outs\n", sum.v_swpout);
419: printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE);
420: printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE);
421: printf("%9d total address trans. faults taken\n", sum.v_faults);
422: printf("%9d page ins\n", sum.v_pgin);
423: printf("%9d page outs\n", sum.v_pgout);
424: printf("%9d pages paged in\n", sum.v_pgpgin);
425: printf("%9d pages paged out\n", sum.v_pgpgout);
426: printf("%9d sequential process pages freed\n", sum.v_seqfree);
427: printf("%9d total reclaims (%d%% fast)\n", sum.v_pgrec,
428: pct(sum.v_fastpgrec, sum.v_pgrec));
429: printf("%9d reclaims from free list\n", sum.v_pgfrec);
430: printf("%9d intransit blocking page faults\n", sum.v_intrans);
431: printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE);
432: printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE);
433: printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE);
434: printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE);
435: printf("%9d swap text pages found in free list\n", sum.v_xsfrec);
436: printf("%9d inode text pages found in free list\n", sum.v_xifrec);
437: printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE);
438: printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE);
439: printf("%9d pages examined by the clock daemon\n", sum.v_scan);
440: printf("%9d revolutions of the clock hand\n", sum.v_rev);
441: printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE);
442: printf("%9d cpu context switches\n", sum.v_swtch);
443: printf("%9d device interrupts\n", sum.v_intr);
444: printf("%9d software interrupts\n", sum.v_soft);
445: #ifdef vax
446: printf("%9d pseudo-dma dz interrupts\n", sum.v_pdma);
447: #endif
448: printf("%9d traps\n", sum.v_trap);
449: printf("%9d system calls\n", sum.v_syscall);
450: lseek(mf, (long)nl[X_NCHSTATS].n_value, 0);
451: read(mf, &nchstats, sizeof nchstats);
452: nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits +
453: nchstats.ncs_badhits + nchstats.ncs_falsehits +
454: nchstats.ncs_miss + nchstats.ncs_long;
455: printf("%9d total name lookups\n", nchtotal);
456: printf("%9s cache hits (%d%% pos + %d%% neg) system %d%% per-process\n",
457: "", pct(nchstats.ncs_goodhits, nchtotal),
458: pct(nchstats.ncs_neghits, nchtotal),
459: pct(nchstats.ncs_pass2, nchtotal));
460: printf("%9s deletions %d%%, falsehits %d%%, toolong %d%%\n", "",
461: pct(nchstats.ncs_badhits, nchtotal),
462: pct(nchstats.ncs_falsehits, nchtotal),
463: pct(nchstats.ncs_long, nchtotal));
464: lseek(mf, (long)nl[X_XSTATS].n_value, 0);
465: read(mf, &xstats, sizeof xstats);
466: printf("%9d total calls to xalloc (cache hits %d%%)\n",
467: xstats.alloc, pct(xstats.alloc_cachehit, xstats.alloc));
468: printf("%9s sticky %d flushed %d unused %d\n", "",
469: xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused);
470: printf("%9d total calls to xfree", xstats.free);
471: printf(" (sticky %d cached %d swapped %d)\n",
472: xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap);
473: #if defined(tahoe)
474: lseek(mf, (long)nl[X_CKEYSTATS].n_value, 0);
475: read(mf, &keystats, sizeof keystats);
476: printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
477: keystats.ks_allocs, "code cache keys allocated",
478: pct(keystats.ks_allocfree, keystats.ks_allocs),
479: pct(keystats.ks_norefs, keystats.ks_allocs),
480: pct(keystats.ks_taken, keystats.ks_allocs),
481: pct(keystats.ks_shared, keystats.ks_allocs));
482: lseek(mf, (long)nl[X_DKEYSTATS].n_value, 0);
483: read(mf, &keystats, sizeof keystats);
484: printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
485: keystats.ks_allocs, "data cache keys allocated",
486: pct(keystats.ks_allocfree, keystats.ks_allocs),
487: pct(keystats.ks_norefs, keystats.ks_allocs),
488: pct(keystats.ks_taken, keystats.ks_allocs),
489: pct(keystats.ks_shared, keystats.ks_allocs));
490: #endif
491: }
492:
493: doforkst()
494: {
495:
496: lseek(mf, (long)nl[X_FORKSTAT].n_value, L_SET);
497: read(mf, &forkstat, sizeof forkstat);
498: printf("%d forks, %d pages, average=%.2f\n",
499: forkstat.cntfork, forkstat.sizfork,
500: (float) forkstat.sizfork / forkstat.cntfork);
501: printf("%d vforks, %d pages, average=%.2f\n",
502: forkstat.cntvfork, forkstat.sizvfork,
503: (float)forkstat.sizvfork / forkstat.cntvfork);
504: }
505:
506: stats(dn)
507: {
508:
509: if (dn >= dk_ndrive) {
510: printf(" 0");
511: return;
512: }
513: printf("%3.0f", s.xfer[dn]/etime);
514: }
515:
516: double
517: stat1(row)
518: {
519: double t;
520: register i;
521:
522: t = 0;
523: for(i=0; i<CPUSTATES; i++)
524: t += s.time[i];
525: if(t == 0.)
526: t = 1.;
527: return(s.time[row]*100./t);
528: }
529:
530: pct(top, bot)
531: {
532:
533: if (bot == 0)
534: return (0);
535: return ((top * 100) / bot);
536: }
537:
538: dointr(nintv)
539: {
540: int nintr, inttotal;
541: long *intrcnt;
542: char *intrname, *malloc();
543:
544: nintr = (nl[X_EINTRCNT].n_value - nl[X_INTRCNT].n_value) / sizeof(long);
545: intrcnt = (long *) malloc(nl[X_EINTRCNT].n_value -
546: nl[X_INTRCNT].n_value);
547: intrname = malloc(nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value);
548: if (intrcnt == NULL || intrname == NULL) {
549: fprintf(stderr, "vmstat: out of memory\n");
550: exit(9);
551: }
552: lseek(mf, (long)nl[X_INTRCNT].n_value, L_SET);
553: read(mf, intrcnt, nintr * sizeof (long));
554: lseek(mf, (long)nl[X_INTRNAMES].n_value, L_SET);
555: read(mf, intrname, nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value);
556: printf("interrupt total rate\n");
557: inttotal = 0;
558: while (nintr--) {
559: if (*intrcnt)
560: printf("%-12s %8ld %8ld\n", intrname,
561: *intrcnt, *intrcnt / nintv);
562: intrname += strlen(intrname) + 1;
563: inttotal += *intrcnt++;
564: }
565: printf("Total %8ld %8ld\n", inttotal, inttotal / nintv);
566: }
567:
568: /*
569: * These names must be kept in sync with
570: * the types defined in <sys/malloc.h>.
571: */
572: char *kmemnames[] = {
573: "free", /* 0 M_FREE */
574: "mbuf", /* 1 M_MBUF */
575: "devbuf", /* 2 M_DEVBUF */
576: "socket", /* 3 M_SOCKET */
577: "pcb", /* 4 M_PCB */
578: "routetbl", /* 5 M_RTABLE */
579: "hosttbl", /* 6 M_HTABLE */
580: "fragtbl", /* 7 M_FTABLE */
581: "zombie", /* 8 M_ZOMBIE */
582: "ifaddr", /* 9 M_IFADDR */
583: "soopts", /* 10 M_SOOPTS */
584: "soname", /* 11 M_SONAME */
585: "namei", /* 12 M_NAMEI */
586: "gprof", /* 13 M_GPROF */
587: "ioctlops", /* 14 M_IOCTLOPS */
588: "superblk", /* 15 M_SUPERBLK */
589: "cred", /* 16 M_CRED */
590: "pgrp", /* 17 M_PGRP */
591: "session", /* 18 M_SESSION */
592: "iov", /* 19 M_IOV */
593: "mount", /* 20 M_MOUNT */
594: "fhandle", /* 21 M_FHANDLE */
595: "NFS req", /* 22 M_NFSREQ */
596: "NFS mount", /* 23 M_NFSMNT */
597: "vnodes", /* 24 M_VNODE */
598: "namecache", /* 25 M_CACHE */
599: "UFS quota", /* 26 M_DQUOT */
600: "UFS mount", /* 27 M_UFSMNT */
601: "mapmem", /* 28 M_MAPMEM */
602: "shm", /* 29 M_SHM */
603: 0, 0, 0, 0,
604: 0, 0, 0, 0, 0,
605: 0, 0, 0, 0, 0,
606: 0, 0, 0, 0, 0,
607: "temp", /* 49 M_TEMP */
608: };
609:
610: domem()
611: {
612: struct kmemstats kmemstats[M_LAST];
613: struct kmembuckets buckets[MINBUCKET + 16];
614: register struct kmembuckets *kp;
615: register struct kmemstats *ks;
616: int i;
617:
618: lseek(mf, (long)nl[X_KMEMBUCKETS].n_value, L_SET);
619: read(mf, buckets, sizeof buckets);
620: printf("Memory statistics by bucket size\n");
621: printf(" Size In Use Free Requests HighWater Couldfree\n");
622: for (i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16; i++, kp++) {
623: if (kp->kb_calls == 0)
624: continue;
625: printf("%8d%9d%7d%11d%8d%11d\n", 1 << i,
626: kp->kb_total - kp->kb_totalfree,
627: kp->kb_totalfree, kp->kb_calls,
628: kp->kb_highwat, kp->kb_couldfree);
629:
630: }
631: lseek(mf, (long)nl[X_KMEMSTAT].n_value, L_SET);
632: read(mf, kmemstats, sizeof kmemstats);
633: printf("Memory statistics by type\n");
634: printf(" Type In Use MemUse HighUse Limit Requests %s\n",
635: "TypeLimit KernLimit");
636: for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) {
637: if (ks->ks_calls == 0)
638: continue;
639: printf("%10s%7d%8dK%9dK%6dK%9d%7d%10d\n",
640: kmemnames[i] ? kmemnames[i] : "undefined",
641: ks->ks_inuse, (ks->ks_memuse + 1023) / 1024,
642: (ks->ks_maxused + 1023) / 1024,
643: (ks->ks_limit + 1023) / 1024, ks->ks_calls,
644: ks->ks_limblocks, ks->ks_mapblocks);
645: }
646: }
647:
648: #define steal(where, var) \
649: lseek(mf, where, L_SET); read(mf, &var, sizeof var);
650: /*
651: * Read the drive names out of kmem.
652: */
653: #ifdef vax
654: #include <vaxuba/ubavar.h>
655: #include <vaxmba/mbavar.h>
656:
657: read_names()
658: {
659: struct mba_device mdev;
660: register struct mba_device *mp;
661: struct mba_driver mdrv;
662: short two_char;
663: char *cp = (char *) &two_char;
664: struct uba_device udev, *up;
665: struct uba_driver udrv;
666:
667: mp = (struct mba_device *) nl[X_MBDINIT].n_value;
668: up = (struct uba_device *) nl[X_UBDINIT].n_value;
669: if (up == 0) {
670: fprintf(stderr, "vmstat: Disk init info not in namelist\n");
671: exit(1);
672: }
673: if (mp) for (;;) {
674: steal(mp++, mdev);
675: if (mdev.mi_driver == 0)
676: break;
677: if (mdev.mi_dk < 0 || mdev.mi_alive == 0)
678: continue;
679: steal(mdev.mi_driver, mdrv);
680: steal(mdrv.md_dname, two_char);
681: sprintf(dr_name[mdev.mi_dk], "%c%c%d",
682: cp[0], cp[1], mdev.mi_unit);
683: }
684: for (;;) {
685: steal(up++, udev);
686: if (udev.ui_driver == 0)
687: break;
688: if (udev.ui_dk < 0 || udev.ui_alive == 0)
689: continue;
690: steal(udev.ui_driver, udrv);
691: steal(udrv.ud_dname, two_char);
692: sprintf(dr_name[udev.ui_dk], "%c%c%d",
693: cp[0], cp[1], udev.ui_unit);
694: }
695: }
696: #endif
697:
698: #ifdef tahoe
699: #include <tahoevba/vbavar.h>
700:
701: /*
702: * Read the drive names out of kmem.
703: */
704: read_names()
705: {
706: struct vba_device udev, *up;
707: struct vba_driver udrv;
708: short two_char;
709: char *cp = (char *)&two_char;
710:
711: up = (struct vba_device *) nl[X_VBDINIT].n_value;
712: if (up == 0) {
713: fprintf(stderr, "vmstat: Disk init info not in namelist\n");
714: exit(1);
715: }
716: for (;;) {
717: steal(up++, udev);
718: if (udev.ui_driver == 0)
719: break;
720: if (udev.ui_dk < 0 || udev.ui_alive == 0)
721: continue;
722: steal(udev.ui_driver, udrv);
723: steal(udrv.ud_dname, two_char);
724: sprintf(dr_name[udev.ui_dk], "%c%c%d",
725: cp[0], cp[1], udev.ui_unit);
726: }
727: }
728: #endif
729:
730: #ifdef hp300
731: #include <hpdev/device.h>
732:
733: #define validdisk(cp) ((cp)[1] == 'd' && ((cp)[0] == 'r' || (cp)[0] == 's'))
734:
735: read_names()
736: {
737: struct hp_device hdev;
738: register struct hp_device *hp;
739: struct driver hdrv;
740: short two_char;
741: char *cp = (char *) &two_char;
742: register char *dp;
743:
744: hp = (struct hp_device *) nl[X_HPDINIT].n_value;
745: if (hp == 0) {
746: fprintf(stderr, "vmstat: Disk init info not in namelist\n");
747: exit(1);
748: }
749: for (;;) {
750: steal(hp++, hdev);
751: if (hdev.hp_driver == 0)
752: break;
753: steal(hdev.hp_driver, hdrv);
754: steal(hdrv.d_name, two_char);
755: /*
756: * hp_dk is meaningless if the device isn't a disk
757: * (d_name not valid) or the disk was not found when
758: * booting (hp_alive == 0).
759: */
760: if (!validdisk(cp) || hdev.hp_alive == 0)
761: continue;
762: dp = dr_name[hdev.hp_dk];
763: sprintf(dp, "%c%c%d", cp[0], cp[1], hdev.hp_unit);
764: }
765: }
766: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.