📄 vmstat.c
字号:
/* * Copyright (c) 1980, 1986, 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1980, 1986, 1991, 1993\n\ The Regents of the University of California. All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)vmstat.c 8.1 (Berkeley) 6/6/93";#endif /* not lint */#include <sys/param.h>#include <sys/time.h>#include <sys/proc.h>#include <sys/user.h>#include <sys/dkstat.h>#include <sys/buf.h>#include <sys/namei.h>#include <sys/malloc.h>#include <sys/signal.h>#include <sys/fcntl.h>#include <sys/ioctl.h>#include <sys/sysctl.h>#include <vm/vm.h>#include <time.h>#include <nlist.h>#include <kvm.h>#include <errno.h>#include <unistd.h>#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include <paths.h>#include <limits.h>#define NEWVM /* XXX till old has been updated or purged */struct nlist namelist[] = {#define X_CPTIME 0 { "_cp_time" },#define X_DK_NDRIVE 1 { "_dk_ndrive" },#define X_SUM 2 { "_cnt" },#define X_BOOTTIME 3 { "_boottime" },#define X_DKXFER 4 { "_dk_xfer" },#define X_HZ 5 { "_hz" },#define X_STATHZ 6 { "_stathz" },#define X_NCHSTATS 7 { "_nchstats" },#define X_INTRNAMES 8 { "_intrnames" },#define X_EINTRNAMES 9 { "_eintrnames" },#define X_INTRCNT 10 { "_intrcnt" },#define X_EINTRCNT 11 { "_eintrcnt" },#define X_KMEMSTAT 12 { "_kmemstats" },#define X_KMEMBUCKETS 13 { "_bucket" },#ifdef notdef#define X_DEFICIT 14 { "_deficit" },#define X_FORKSTAT 15 { "_forkstat" },#define X_REC 16 { "_rectime" },#define X_PGIN 17 { "_pgintime" },#define X_XSTATS 18 { "_xstats" },#define X_END 18#else#define X_END 14#endif#if defined(hp300) || defined(luna68k)#define X_HPDINIT (X_END) { "_hp_dinit" },#endif#ifdef mips#define X_SCSI_DINIT (X_END) { "_scsi_dinit" },#endif#ifdef tahoe#define X_VBDINIT (X_END) { "_vbdinit" },#define X_CKEYSTATS (X_END+1) { "_ckeystats" },#define X_DKEYSTATS (X_END+2) { "_dkeystats" },#endif#ifdef vax#define X_MBDINIT (X_END) { "_mbdinit" },#define X_UBDINIT (X_END+1) { "_ubdinit" },#endif { "" },};struct _disk { long time[CPUSTATES]; long *xfer;} cur, last;struct vmmeter sum, osum;char **dr_name;int *dr_select, dk_ndrive, ndrives;int winlines = 20;kvm_t *kd;#define FORKSTAT 0x01#define INTRSTAT 0x02#define MEMSTAT 0x04#define SUMSTAT 0x08#define TIMESTAT 0x10#define VMSTAT 0x20#include "names.c" /* disk names -- machine dependent */void cpustats(), dkstats(), dointr(), domem(), dosum();void dovmstat(), kread(), usage();#ifdef notdefvoid dotimes(), doforkst();#endifmain(argc, argv) register int argc; register char **argv;{ extern int optind; extern char *optarg; register int c, todo; u_int interval; int reps; char *memf, *nlistf; char errbuf[_POSIX2_LINE_MAX]; memf = nlistf = NULL; interval = reps = todo = 0; while ((c = getopt(argc, argv, "c:fiM:mN:stw:")) != EOF) { switch (c) { case 'c': reps = atoi(optarg); break;#ifndef notdef case 'f': todo |= FORKSTAT; break;#endif case 'i': todo |= INTRSTAT; break; case 'M': memf = optarg; break; case 'm': todo |= MEMSTAT; break; case 'N': nlistf = optarg; break; case 's': todo |= SUMSTAT; break;#ifndef notdef case 't': todo |= TIMESTAT; break;#endif case 'w': interval = atoi(optarg); break; case '?': default: usage(); } } argc -= optind; argv += optind; if (todo == 0) todo = VMSTAT; /* * Discard setgid privileges if not the running kernel so that bad * guys can't print interesting stuff from kernel memory. */ if (nlistf != NULL || memf != NULL) setgid(getgid()); kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); if (kd == 0) { (void)fprintf(stderr, "vmstat: kvm_openfiles: %s\n", errbuf); exit(1); } if ((c = kvm_nlist(kd, namelist)) != 0) { if (c > 0) { (void)fprintf(stderr, "vmstat: undefined symbols:"); for (c = 0; c < sizeof(namelist)/sizeof(namelist[0]); c++) if (namelist[c].n_type == 0) fprintf(stderr, " %s", namelist[c].n_name); (void)fputc('\n', stderr); } else (void)fprintf(stderr, "vmstat: kvm_nlist: %s\n", kvm_geterr(kd)); exit(1); } if (todo & VMSTAT) { char **getdrivedata(); struct winsize winsize; argv = getdrivedata(argv); winsize.ws_row = 0; (void) ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&winsize); if (winsize.ws_row > 0) winlines = winsize.ws_row; }#define BACKWARD_COMPATIBILITY#ifdef BACKWARD_COMPATIBILITY if (*argv) { interval = atoi(*argv); if (*++argv) reps = atoi(*argv); }#endif if (interval) { if (!reps) reps = -1; } else if (reps) interval = 1;#ifdef notdef if (todo & FORKSTAT) doforkst();#endif if (todo & MEMSTAT) domem(); if (todo & SUMSTAT) dosum();#ifdef notdef if (todo & TIMESTAT) dotimes();#endif if (todo & INTRSTAT) dointr(); if (todo & VMSTAT) dovmstat(interval, reps); exit(0);}char **getdrivedata(argv) char **argv;{ register int i; register char **cp; char buf[30]; kread(X_DK_NDRIVE, &dk_ndrive, sizeof(dk_ndrive)); if (dk_ndrive <= 0) { (void)fprintf(stderr, "vmstat: dk_ndrive %d\n", dk_ndrive); exit(1); } dr_select = calloc((size_t)dk_ndrive, sizeof(int)); dr_name = calloc((size_t)dk_ndrive, sizeof(char *)); for (i = 0; i < dk_ndrive; i++) dr_name[i] = NULL; cur.xfer = calloc((size_t)dk_ndrive, sizeof(long)); last.xfer = calloc((size_t)dk_ndrive, sizeof(long)); if (!read_names()) exit (1); for (i = 0; i < dk_ndrive; i++) if (dr_name[i] == NULL) { (void)sprintf(buf, "??%d", i); dr_name[i] = strdup(buf); } /* * Choose drives to be displayed. Priority goes to (in order) drives * supplied as arguments, default drives. If everything isn't filled * in and there are drives not taken care of, display the first few * that fit. */#define BACKWARD_COMPATIBILITY for (ndrives = 0; *argv; ++argv) {#ifdef BACKWARD_COMPATIBILITY if (isdigit(**argv)) break;#endif for (i = 0; i < dk_ndrive; i++) { if (strcmp(dr_name[i], *argv)) continue; dr_select[i] = 1; ++ndrives; break; } } for (i = 0; i < dk_ndrive && ndrives < 4; i++) { if (dr_select[i]) continue; for (cp = defdrives; *cp; cp++) if (strcmp(dr_name[i], *cp) == 0) { dr_select[i] = 1; ++ndrives; break; } } for (i = 0; i < dk_ndrive && ndrives < 4; i++) { if (dr_select[i]) continue; dr_select[i] = 1; ++ndrives; } return(argv);}longgetuptime(){ static time_t now, boottime; time_t uptime; if (boottime == 0) kread(X_BOOTTIME, &boottime, sizeof(boottime)); (void)time(&now); uptime = now - boottime; if (uptime <= 0 || uptime > 60*60*24*365*10) { (void)fprintf(stderr, "vmstat: time makes no sense; namelist must be wrong.\n"); exit(1); } return(uptime);}int hz, hdrcnt;voiddovmstat(interval, reps) u_int interval; int reps;{ struct vmtotal total; time_t uptime, halfuptime; void needhdr(); int mib[2], size; uptime = getuptime(); halfuptime = uptime / 2; (void)signal(SIGCONT, needhdr); if (namelist[X_STATHZ].n_type != 0 && namelist[X_STATHZ].n_value != 0) kread(X_STATHZ, &hz, sizeof(hz)); if (!hz) kread(X_HZ, &hz, sizeof(hz)); for (hdrcnt = 1;;) { if (!--hdrcnt) printhdr(); kread(X_CPTIME, cur.time, sizeof(cur.time)); kread(X_DKXFER, cur.xfer, sizeof(*cur.xfer) * dk_ndrive); kread(X_SUM, &sum, sizeof(sum)); size = sizeof(total); mib[0] = CTL_VM; mib[1] = VM_METER; if (sysctl(mib, 2, &total, &size, NULL, 0) < 0) { printf("Can't get kerninfo: %s\n", strerror(errno)); bzero(&total, sizeof(total)); } (void)printf("%2d%2d%2d", total.t_rq - 1, total.t_dw + total.t_pw, total.t_sw);#define pgtok(a) ((a) * sum.v_page_size >> 10)#define rate(x) (((x) + halfuptime) / uptime) /* round */ (void)printf("%6ld%6ld ", pgtok(total.t_avm), pgtok(total.t_free));#ifdef NEWVM (void)printf("%4lu ", rate(sum.v_faults - osum.v_faults)); (void)printf("%3lu ", rate(sum.v_reactivated - osum.v_reactivated)); (void)printf("%3lu ", rate(sum.v_pageins - osum.v_pageins)); (void)printf("%3lu %3lu ", rate(sum.v_pageouts - osum.v_pageouts), 0);#else (void)printf("%3lu %2lu ", rate(sum.v_pgrec - (sum.v_xsfrec+sum.v_xifrec) - (osum.v_pgrec - (osum.v_xsfrec+osum.v_xifrec))), rate(sum.v_xsfrec + sum.v_xifrec - osum.v_xsfrec - osum.v_xifrec));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -