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