version 1.55, 2001/06/24 16:05:33 |
version 1.56, 2001/06/24 20:30:52 |
|
|
#include "dkstats.h" |
#include "dkstats.h" |
|
|
#ifdef UVM |
#ifdef UVM |
|
#include <uvm/uvm_object.h> |
#include <uvm/uvm_extern.h> |
#include <uvm/uvm_extern.h> |
#endif |
#endif |
|
|
|
|
int reps; |
int reps; |
char errbuf[_POSIX2_LINE_MAX]; |
char errbuf[_POSIX2_LINE_MAX]; |
|
|
memf = nlistf = NULL; |
|
interval = reps = todo = 0; |
interval = reps = todo = 0; |
while ((c = getopt(argc, argv, "c:fiM:mN:stw:")) != -1) { |
while ((c = getopt(argc, argv, "c:fiM:mN:stw:")) != -1) { |
switch (c) { |
switch (c) { |
|
|
if (todo == 0) |
if (todo == 0) |
todo = VMSTAT; |
todo = VMSTAT; |
|
|
|
if (nlistf != NULL || memf != NULL) { |
|
setegid(getgid()); |
|
setgid(getgid()); |
|
} |
|
|
/* |
/* |
* Discard setgid privileges if not the running kernel so that bad |
* Discard setgid privileges if not the running kernel so that bad |
* guys can't print interesting stuff from kernel memory. |
* guys can't print interesting stuff from kernel memory. |
*/ |
*/ |
|
#if notyet |
if (nlistf != NULL || memf != NULL) { |
if (nlistf != NULL || memf != NULL) { |
setegid(getgid()); |
#endif |
setgid(getgid()); |
kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); |
} |
if (kd == 0) |
|
errx(1, "kvm_openfiles: %s", errbuf); |
|
|
kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); |
if ((c = kvm_nlist(kd, namelist)) != 0) { |
if (kd == 0) |
setgid(getgid()); |
errx(1, "kvm_openfiles: %s", errbuf); |
setegid(getegid()); |
|
|
if ((c = kvm_nlist(kd, namelist)) != 0) { |
if (c > 0) { |
|
(void)fprintf(stderr, |
setegid(getgid()); |
"%s: undefined symbols:", __progname); |
setgid(getgid()); |
for (c = 0; |
|
c < sizeof(namelist)/sizeof(namelist[0]); |
if (c > 0) { |
c++) |
(void)fprintf(stderr, |
if (namelist[c].n_type == 0) |
"%s: undefined symbols:", __progname); |
fprintf(stderr, " %s", |
for (c = 0; |
namelist[c].n_name); |
c < sizeof(namelist)/sizeof(namelist[0]); c++) |
(void)fputc('\n', stderr); |
if (namelist[c].n_type == 0) |
exit(1); |
fprintf(stderr, " %s", |
} else |
namelist[c].n_name); |
errx(1, "kvm_nlist: %s", kvm_geterr(kd)); |
(void)fputc('\n', stderr); |
} |
exit(1); |
#ifdef notyet |
} else |
|
errx(1, "kvm_nlist: %s", kvm_geterr(kd)); |
|
} |
} |
|
#endif notyet |
|
|
|
setegid(getegid()); |
|
setgid(getgid()); |
|
|
if (todo & VMSTAT) { |
if (todo & VMSTAT) { |
struct winsize winsize; |
struct winsize winsize; |
|
|
|
|
|
|
} |
} |
|
|
setegid(getgid()); |
|
setgid(getgid()); |
|
|
|
#define BACKWARD_COMPATIBILITY |
#define BACKWARD_COMPATIBILITY |
#ifdef BACKWARD_COMPATIBILITY |
#ifdef BACKWARD_COMPATIBILITY |
if (*argv) { |
if (*argv) { |
|
|
size_t size; |
size_t size; |
|
|
if (boottime.tv_sec == 0) { |
if (boottime.tv_sec == 0) { |
if (nlist == NULL && memf == NULL) { |
if (nlistf == NULL && memf == NULL) { |
kread(X_BOOTTIME, &boottime, sizeof(boottime)); |
|
} else { |
|
size = sizeof(boottime); |
size = sizeof(boottime); |
mib[0] = CTL_KERN; |
mib[0] = CTL_KERN; |
mib[1] = KERN_BOOTTIME; |
mib[1] = KERN_BOOTTIME; |
if (sysctl(mib, 2, &boottime, &size, NULL, 0) < 0) { |
if (sysctl(mib, 2, &boottime, &size, NULL, 0) < 0) { |
printf("Can't get kerninfo: %s\n", |
warn("could not get kern.boottime"); |
strerror(errno)); |
|
bzero(&boottime, sizeof(boottime)); |
bzero(&boottime, sizeof(boottime)); |
} |
} |
|
} else { |
|
kread(X_BOOTTIME, &boottime, sizeof(boottime)); |
} |
} |
} |
} |
(void)time(&now); |
(void)time(&now); |
|
|
mib[1] = KERN_CLOCKRATE; |
mib[1] = KERN_CLOCKRATE; |
size = sizeof(clkinfo); |
size = sizeof(clkinfo); |
if (sysctl(mib, 2, &clkinfo, &size, NULL, 0) < 0) { |
if (sysctl(mib, 2, &clkinfo, &size, NULL, 0) < 0) { |
printf("Can't get kerninfo: %s\n", strerror(errno)); |
warn("could not read kern.clockrate"); |
return; |
return; |
} |
} |
hz = clkinfo.stathz; |
hz = clkinfo.stathz; |
|
|
/* Read new disk statistics */ |
/* Read new disk statistics */ |
dkreadstats(); |
dkreadstats(); |
#ifdef UVM |
#ifdef UVM |
if (nlist == NULL && memf == NULL) { |
if (nlistf == NULL && memf == NULL) { |
kread(X_UVMEXP, &uvmexp, sizeof(uvmexp)); |
size = sizeof(struct uvmexp); |
} else { |
|
size = sizeof(uvmexp); |
|
mib[0] = CTL_VM; |
mib[0] = CTL_VM; |
mib[1] = VM_UVMEXP; |
mib[1] = VM_UVMEXP; |
if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) { |
if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) { |
printf("Can't get kerninfo: %s\n", |
warn("could not get vm.uvmexp"); |
strerror(errno)); |
bzero(&uvmexp, sizeof(struct uvmexp)); |
bzero(&uvmexp, sizeof(uvmexp)); |
|
} |
} |
|
} else { |
|
kread(X_UVMEXP, &uvmexp, sizeof(struct uvmexp)); |
} |
} |
#else |
#else |
kread(X_SUM, &sum, sizeof(sum)); |
kread(X_SUM, &sum, sizeof(sum)); |
|
|
mib[0] = CTL_VM; |
mib[0] = CTL_VM; |
mib[1] = VM_METER; |
mib[1] = VM_METER; |
if (sysctl(mib, 2, &total, &size, NULL, 0) < 0) { |
if (sysctl(mib, 2, &total, &size, NULL, 0) < 0) { |
printf("Can't get kerninfo: %s\n", strerror(errno)); |
warn("could not read vm.vmmeter"); |
bzero(&total, sizeof(total)); |
bzero(&total, sizeof(total)); |
} |
} |
(void)printf("%2u%2u%2u", |
(void)printf("%2u%2u%2u", |
|
|
int mib[2]; |
int mib[2]; |
size_t size; |
size_t size; |
|
|
|
/* XXX Why are these set to 0 ? This doesn't look right. */ |
pgintime = 0; |
pgintime = 0; |
rectime = 0; |
rectime = 0; |
|
|
#ifdef UVM |
#ifdef UVM |
if (nlist == NULL && memf == NULL) { |
if (nlistf == NULL && memf == NULL) { |
kread(X_UVMEXP, &uvmexp, sizeof(uvmexp)); |
size = sizeof(struct uvmexp); |
} else { |
|
size = sizeof(uvmexp); |
|
mib[0] = CTL_VM; |
mib[0] = CTL_VM; |
mib[1] = VM_UVMEXP; |
mib[1] = VM_UVMEXP; |
if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) { |
if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) { |
printf("Can't get kerninfo: %s\n", strerror(errno)); |
warn("could not read vm.uvmexp"); |
bzero(&uvmexp, sizeof(uvmexp)); |
bzero(&uvmexp, sizeof(struct uvmexp)); |
} |
} |
|
} else { |
|
kread(X_UVMEXP, &uvmexp, sizeof(struct uvmexp)); |
} |
} |
|
|
(void)printf("%u reactivates, %u total time (usec)\n", |
(void)printf("%u reactivates, %u total time (usec)\n", |
|
|
int mib[2], nselcoll; |
int mib[2], nselcoll; |
|
|
#ifdef UVM |
#ifdef UVM |
if (nlist == NULL && memf == NULL) { |
if (nlistf == NULL && memf == NULL) { |
kread(X_UVMEXP, &nchstats, sizeof(uvmexp)); |
size = sizeof(struct uvmexp); |
} else { |
|
size = sizeof(uvmexp); |
|
mib[0] = CTL_VM; |
mib[0] = CTL_VM; |
mib[1] = VM_UVMEXP; |
mib[1] = VM_UVMEXP; |
if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) { |
if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) { |
printf("Can't get kerninfo: %s\n", strerror(errno)); |
warn("could not read vm.uvmexp"); |
bzero(&uvmexp, sizeof(uvmexp)); |
bzero(&uvmexp, sizeof(struct uvmexp)); |
} |
} |
|
} else { |
|
kread(X_UVMEXP, &uvmexp, sizeof(struct uvmexp)); |
} |
} |
|
|
/* vm_page constants */ |
/* vm_page constants */ |
|
|
(void)printf("%11u bytes per page\n", sum.v_page_size); |
(void)printf("%11u bytes per page\n", sum.v_page_size); |
#endif |
#endif |
|
|
if (nlist == NULL && memf == NULL) { |
if (nlistf == NULL && memf == NULL) { |
kread(X_NCHSTATS, &nchstats, sizeof(nchstats)); |
|
} else { |
|
size = sizeof(nchstats); |
size = sizeof(nchstats); |
mib[0] = CTL_KERN; |
mib[0] = CTL_KERN; |
mib[1] = KERN_NCHSTATS; |
mib[1] = KERN_NCHSTATS; |
if (sysctl(mib, 2, &nchstats, &size, NULL, 0) < 0) { |
if (sysctl(mib, 2, &nchstats, &size, NULL, 0) < 0) { |
printf("Can't get kerninfo: %s\n", strerror(errno)); |
warn("could not read kern.nchstats"); |
bzero(&nchstats, sizeof(nchstats)); |
bzero(&nchstats, sizeof(nchstats)); |
} |
} |
|
} else { |
|
kread(X_NCHSTATS, &nchstats, sizeof(nchstats)); |
} |
} |
|
|
nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits + |
nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits + |
|
|
PCT(nchstats.ncs_falsehits, nchtotal), |
PCT(nchstats.ncs_falsehits, nchtotal), |
PCT(nchstats.ncs_long, nchtotal)); |
PCT(nchstats.ncs_long, nchtotal)); |
|
|
if (nlist == NULL && memf == NULL) { |
if (nlistf == NULL && memf == NULL) { |
kread(X_NSELCOLL, &nselcoll, sizeof(nselcoll)); |
|
} else { |
|
size = sizeof(nselcoll); |
size = sizeof(nselcoll); |
mib[0] = CTL_KERN; |
mib[0] = CTL_KERN; |
mib[1] = KERN_NSELCOLL; |
mib[1] = KERN_NSELCOLL; |
if (sysctl(mib, 2, &nselcoll, &size, NULL, 0) < 0) { |
if (sysctl(mib, 2, &nselcoll, &size, NULL, 0) < 0) { |
printf("Can't get kerninfo: %s\n", strerror(errno)); |
warn("could not read kern.nselcoll"); |
nselcoll = 0; |
nselcoll = 0; |
} |
} |
|
} else { |
|
kread(X_NSELCOLL, &nselcoll, sizeof(nselcoll)); |
} |
} |
(void)printf("%11d select collisions\n", nselcoll); |
(void)printf("%11d select collisions\n", nselcoll); |
} |
} |
|
|
size_t size; |
size_t size; |
int mib[2]; |
int mib[2]; |
|
|
if (nlist == NULL && memf == NULL) { |
if (nlistf == NULL && memf == NULL) { |
kread(X_FORKSTAT, &fks, sizeof(struct forkstat)); |
|
} else { |
|
size = sizeof(struct forkstat); |
size = sizeof(struct forkstat); |
mib[0] = CTL_KERN; |
mib[0] = CTL_KERN; |
mib[1] = KERN_FORKSTAT; |
mib[1] = KERN_FORKSTAT; |
if (sysctl(mib, 2, &fks, &size, NULL, 0) < 0) { |
if (sysctl(mib, 2, &fks, &size, NULL, 0) < 0) { |
printf("Can't get kerninfo: %s\n", strerror(errno)); |
warn("could not read kern.forkstat"); |
bzero(&fks, sizeof(struct forkstat)); |
bzero(&fks, sizeof(struct forkstat)); |
} |
} |
|
} else { |
|
kread(X_FORKSTAT, &fks, sizeof(struct forkstat)); |
} |
} |
|
|
(void)printf("%d forks, %d pages, average %.2f\n", |
(void)printf("%d forks, %d pages, average %.2f\n", |
|
|
/* To get struct intrhand */ |
/* To get struct intrhand */ |
#define _KERNEL |
#define _KERNEL |
#include <machine/psl.h> |
#include <machine/psl.h> |
|
#include <machine/cpu.h> |
#undef _KERNEL |
#undef _KERNEL |
void |
void |
dointr() |
dointr() |
{ |
{ |
struct intrhand *intrhand[16], *ihp, ih; |
struct intrhand *intrhand[16], *ihp, ih; |
u_long inttotal; |
u_long inttotal = 0; |
time_t uptime; |
time_t uptime; |
u_long intrstray[16]; |
u_long intrstray[16]; |
char iname[17], fname[31]; |
char iname[17], fname[31]; |
int i; |
int i, mib[2], l, incflag; |
|
size_t size; |
|
char *intrnames, *intrcount, *intrn, *intrc, *buf1, *buf2; |
|
|
iname[16] = '\0'; |
iname[16] = '\0'; |
uptime = getuptime(); |
uptime = getuptime(); |
kread(X_INTRHAND, intrhand, sizeof(intrhand)); |
|
kread(X_INTRSTRAY, intrstray, sizeof(intrstray)); |
|
|
|
(void)printf("interrupt total rate\n"); |
(void)printf("interrupt total rate\n"); |
inttotal = 0; |
|
for (i = 0; i < 16; i++) { |
#if 0 /* XXX Something else is needed here....get on with it Theo! */ |
ihp = intrhand[i]; |
if (nlistf == NULL && memf == NULL) { |
while (ihp) { |
mib[0] = CTL_MACHDEP; |
if (kvm_read(kd, (u_long)ihp, &ih, sizeof(ih)) != sizeof(ih)) |
mib[1] = CPU_INTRNAMES; |
errx(1, "vmstat: ih: %s", kvm_geterr(kd)); |
size = 0; |
if (kvm_read(kd, (u_long)ih.ih_what, iname, 16) != 16) |
if (sysctl(mib, 2, NULL, &size, NULL, 0) < 0) |
errx(1, "vmstat: ih_what: %s", kvm_geterr(kd)); |
err(1, "could not get machdep.intrnames"); |
snprintf(fname, sizeof fname, "irq%d/%s", i, iname); |
intrnames = calloc(size, sizeof(char)); |
printf("%-16.16s %10lu %8lu\n", fname, ih.ih_count, |
if (intrnames == NULL) |
ih.ih_count / uptime); |
err(1, |
inttotal += ih.ih_count; |
"could not allocate memory for interrupt names"); |
ihp = ih.ih_next; |
if (sysctl(mib, 2, intrnames, &size, NULL, 0) < 0) |
|
err(1, "could not get machdep.intrnames"); |
|
|
|
mib[1] = CPU_INTRCOUNT; |
|
size = 0; |
|
if (sysctl(mib, 2, NULL, &size, NULL, 0) < 0) |
|
err(1, "could not get machdep.intrcount"); |
|
intrcount = calloc(size, sizeof(char)); |
|
if (intrcount == NULL) |
|
err(1, |
|
"could not allocate memory for interrupt count"); |
|
if (sysctl(mib, 2, intrcount, &size, NULL, 0) < 0) |
|
err(1, "could not get machdep.intrcount"); |
|
|
|
mib[1] = CPU_INTRSTRAY; |
|
size = sizeof(intrstray); |
|
if (sysctl(mib, 2, intrstray, &size, NULL, 0) < 0) { |
|
warn("could not get machdep.intrstray"); |
|
bzero(intrstray, sizeof(intrstray)); |
} |
} |
|
|
|
buf1 = intrnames; |
|
buf2 = intrcount; |
|
i = 0; |
|
while ((intrn = strsep(&buf1, ",/")) != NULL) { |
|
/* Find what the next delimiter is */ |
|
for (l = 0; buf2[l] != '\0'; l++) { |
|
if (buf2[l] == '/') { |
|
/* Don't increase the irq count */ |
|
incflag = 0; |
|
break; |
|
} else if (buf2[l] == ',') { |
|
incflag = 1; |
|
break; |
|
} |
|
} |
|
|
|
if ((intrc = strsep(&buf2, ",/")) == NULL) |
|
errx(1, "unexpected failure matching interrupts with usage counters"); |
|
|
|
/* Unused interrupt ? If so, skip this entry */ |
|
if (intrn[0] == '\0') { |
|
if (incflag) |
|
i++; |
|
continue; |
|
} |
|
|
|
snprintf(fname, sizeof fname, "irq%d/%s", i, intrn); |
|
printf("%-16.16s %10lu %8lu\n", fname, |
|
strtoul(intrc, NULL, 10), |
|
strtoul(intrc, NULL, 10) / uptime); |
|
inttotal += strtoul(intrc, NULL, 10); |
|
|
|
if (incflag) |
|
i++; |
|
} |
|
|
|
free(intrnames); |
|
free(intrcount); |
|
} else |
|
#endif /* 0 */ |
|
{ |
|
kread(X_INTRHAND, intrhand, sizeof(intrhand)); |
|
kread(X_INTRSTRAY, intrstray, sizeof(intrstray)); |
|
|
|
for (i = 0; i < 16; i++) { |
|
ihp = intrhand[i]; |
|
while (ihp) { |
|
if (kvm_read(kd, (u_long)ihp, &ih, |
|
sizeof(ih)) != sizeof(ih)) |
|
errx(1, "vmstat: ih: %s", |
|
kvm_geterr(kd)); |
|
if (kvm_read(kd, (u_long)ih.ih_what, iname, |
|
16) != 16) |
|
errx(1, "vmstat: ih_what: %s", |
|
kvm_geterr(kd)); |
|
snprintf(fname, sizeof fname, "irq%d/%s", i, |
|
iname); |
|
printf("%-16.16s %10lu %8lu\n", fname, |
|
ih.ih_count, ih.ih_count / uptime); |
|
inttotal += ih.ih_count; |
|
ihp = ih.ih_next; |
|
} |
|
} |
} |
} |
|
|
for (i = 0; i < 16; i++) |
for (i = 0; i < 16; i++) |
if (intrstray[i]) { |
if (intrstray[i]) { |
printf("Stray irq %-2d %10lu %8lu\n", |
printf("Stray irq %-2d %10lu %8lu\n", |
|
|
mib[2] = KERN_MALLOC_BUCKETS; |
mib[2] = KERN_MALLOC_BUCKETS; |
siz = sizeof(buf); |
siz = sizeof(buf); |
if (sysctl(mib, 3, buf, &siz, NULL, 0) < 0) { |
if (sysctl(mib, 3, buf, &siz, NULL, 0) < 0) { |
printf("Could not acquire information on kernel memory bucket sizes.\n"); |
warnx("could not read kern.malloc.buckets"); |
return; |
return; |
} |
} |
|
|
|
|
|
|
if (sysctl(mib, 4, &buckets[MINBUCKET + i], &siz, |
if (sysctl(mib, 4, &buckets[MINBUCKET + i], &siz, |
NULL, 0) < 0) { |
NULL, 0) < 0) { |
printf("Failed to read statistics for bucket %d.\n", |
warn("could not read kern.malloc.bucket.%d", mib[3]); |
mib[3]); |
|
return; |
return; |
} |
} |
i++; |
i++; |
|
|
|
|
while (addr != 0) { |
while (addr != 0) { |
char name[32]; |
char name[32]; |
|
|
if (kvm_read(kd, addr, (void *)pp, sizeof *pp) != sizeof *pp) { |
if (kvm_read(kd, addr, (void *)pp, sizeof *pp) != sizeof *pp) { |
(void)fprintf(stderr, |
(void)fprintf(stderr, |
"vmstat: pool chain trashed: %s\n", |
"vmstat: pool chain trashed: %s\n", |
|
|
kvm_geterr(kd)); |
kvm_geterr(kd)); |
exit(1); |
exit(1); |
} |
} |
|
|
name[31] = '\0'; |
name[31] = '\0'; |
|
|
print_pool(pp, name); |
print_pool(pp, name); |
|
|
inuse += (pp->pr_nget - pp->pr_nput) * pp->pr_size; |
inuse += (pp->pr_nget - pp->pr_nput) * pp->pr_size; |
total += pp->pr_npages * pp->pr_pagesz; |
total += pp->pr_npages * pp->pr_pagesz; |
|
|
addr = (long)TAILQ_NEXT(pp, pr_poollist); |
addr = (long)TAILQ_NEXT(pp, pr_poollist); |
} |
} |
|
|
|
|
"[-N system] [-w wait] [disks]\n", __progname); |
"[-N system] [-w wait] [disks]\n", __progname); |
exit(1); |
exit(1); |
} |
} |
|
|