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