Teach vmstat -m and vmstat -z to use libmemstat(3). Certain

statistics from -z are now a bit different due to changes in the
way statistics are now measured.  Reproduce with some amount of
accuracy the slightly obscure layouts adopted by the two kernel
sysctls.  In the future, we might want to normalize them.

GC dosysctl(), which is now no longer used.

MFC after:	1 week
This commit is contained in:
Robert Watson 2005-07-25 22:35:10 +00:00
parent 67685686ad
commit 8e73022dda
2 changed files with 96 additions and 23 deletions

View File

@ -3,7 +3,7 @@
PROG= vmstat PROG= vmstat
MAN= vmstat.8 MAN= vmstat.8
DPADD= ${LIBDEVSTAT} ${LIBKVM} DPADD= ${LIBDEVSTAT} ${LIBKVM} ${LIBMEMSTAT}
LDADD= -ldevstat -lkvm LDADD= -ldevstat -lkvm -lmemstat
.include <bsd.prog.mk> .include <bsd.prog.mk>

View File

@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <errno.h> #include <errno.h>
#include <kvm.h> #include <kvm.h>
#include <limits.h> #include <limits.h>
#include <memstat.h>
#include <nlist.h> #include <nlist.h>
#include <paths.h> #include <paths.h>
#include <stdio.h> #include <stdio.h>
@ -153,7 +154,6 @@ static void doforkst(void);
static void domem(void); static void domem(void);
static void dointr(void); static void dointr(void);
static void dosum(void); static void dosum(void);
static void dosysctl(const char *);
static void dovmstat(unsigned int, int); static void dovmstat(unsigned int, int);
static void dozmem(void); static void dozmem(void);
static void kread(int, void *, size_t); static void kread(int, void *, size_t);
@ -897,6 +897,97 @@ dointr(void)
(long long)inttotal, (long long)(inttotal / uptime)); (long long)inttotal, (long long)(inttotal / uptime));
} }
/*
* Query libmemstat(3) for information on malloc(9).
*/
static void
domemstat_malloc(void)
{
struct memory_type_list *mtlp;
struct memory_type *mtp;
int first, i;
mtlp = memstat_mtl_alloc();
if (mtlp == NULL) {
warn("memstat_mtl_alloc");
return;
}
if (memstat_sysctl_malloc(mtlp, 0) < 0) {
warnx("memstat_sysctl_malloc: %s",
memstat_strerror(memstat_mtl_geterror(mtlp)));
return;
}
printf("\n");
printf("%13s %5s %6s %7s %8s Size(s)\n", "Type", "InUse", "MemUse",
"HighUse", "Requests");
for (mtp = memstat_mtl_first(mtlp); mtp != NULL;
mtp = memstat_mtl_next(mtp)) {
if (memstat_get_numallocs(mtp) == 0 &&
memstat_get_count(mtp) == 0)
continue;
printf("%13s %5lld %5lldK %7s %8lld ",
memstat_get_name(mtp), memstat_get_count(mtp),
((int64_t)memstat_get_bytes(mtp) + 1023) / 1024, "-",
memstat_get_numallocs(mtp));
first = 1;
for (i = 0; i < 32; i++) {
if (memstat_get_sizemask(mtp) & (1 << i)) {
if (!first)
printf(",");
printf("%d", 1 << (i + 4));
first = 0;
}
}
printf("\n");
}
memstat_mtl_free(mtlp);
}
/*
* Query libmemstat(3) for information on uma(9).
*/
static void
domemstat_zone(void)
{
struct memory_type_list *mtlp;
struct memory_type *mtp;
char name[MEMTYPE_MAXNAME + 1];
mtlp = memstat_mtl_alloc();
if (mtlp == NULL) {
warn("memstat_mtl_alloc");
return;
}
if (memstat_sysctl_uma(mtlp, 0) < 0) {
warnx("memstat_sysctl_uma: %s",
memstat_strerror(memstat_mtl_geterror(mtlp)));
return;
}
printf("\n");
printf("%-15s %-8s %-9s %-7s %-5s %-8s\n\n", "ITEM", "SIZE", "LIMIT",
"USED", "FREE", "REQUESTS");
for (mtp = memstat_mtl_first(mtlp); mtp != NULL;
mtp = memstat_mtl_next(mtp)) {
strlcpy(name, memstat_get_name(mtp), MEMTYPE_MAXNAME);
strcat(name, ":");
printf("%-15s %4llu, %8llu, %7llu, %6llu, %8llu\n", name,
memstat_get_size(mtp), memstat_get_countlimit(mtp),
memstat_get_count(mtp), memstat_get_free(mtp),
memstat_get_numallocs(mtp));
}
memstat_mtl_free(mtlp);
printf("\n");
}
/* /*
* domem() replicates the kernel implementation of kern.malloc by inspecting * domem() replicates the kernel implementation of kern.malloc by inspecting
* kernel data structures, which is appropriate for use on a core dump. * kernel data structures, which is appropriate for use on a core dump.
@ -915,7 +1006,7 @@ domem(void)
int i; int i;
if (kd == NULL) { if (kd == NULL) {
dosysctl("kern.malloc"); domemstat_malloc();
return; return;
} }
kread(X_KMEMSTATS, &type.ks_next, sizeof(type.ks_next)); kread(X_KMEMSTATS, &type.ks_next, sizeof(type.ks_next));
@ -991,25 +1082,7 @@ dozmem(void)
{ {
if (kd != NULL) if (kd != NULL)
errx(1, "not implemented"); errx(1, "not implemented");
dosysctl("vm.zone"); domemstat_zone();
}
static void
dosysctl(const char *name)
{
char *buf;
size_t bufsize;
for (buf = NULL, bufsize = 1024; ; bufsize *= 2) {
if ((buf = realloc(buf, bufsize)) == NULL)
err(1, "realloc()");
bufsize--; /* Leave space for the kern.malloc fixup. */
if (mysysctl(name, buf, &bufsize, NULL, 0) == 0)
break;
}
buf[bufsize] = '\0'; /* Fix up kern.malloc not returning a string. */
(void)printf("%s", buf);
free(buf);
} }
/* /*