Make vmstat -m work with -M/-N again. Note that making vmstat -z work

is much harder, and -m is grossly using unexported interfaces (that is,
the array of malloc zones/sizes does not have an exported type).
This commit is contained in:
Brian Feldman 2004-06-30 01:34:26 +00:00
parent cfb81ac317
commit 22ab6be3d4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=131300

View File

@ -99,18 +99,22 @@ static struct nlist namelist[] = {
{ "_intrcnt" },
#define X_EINTRCNT 9
{ "_eintrcnt" },
#define X_KMEMSTATS 10
{ "_kmemstatistics" },
#define X_KMEMZONES 11
{ "_kmemzones" },
#ifdef notyet
#define X_DEFICIT 10
#define X_DEFICIT XXX
{ "_deficit" },
#define X_REC 11
#define X_REC XXX
{ "_rectime" },
#define X_PGIN 12
#define X_PGIN XXX
{ "_pgintime" },
#define X_XSTATS 13
#define X_XSTATS XXX
{ "_xstats" },
#define X_END 14
#define X_END XXX
#else
#define X_END 10
#define X_END 12
#endif
{ "" },
};
@ -153,6 +157,8 @@ static void dosysctl(const char *);
static void dovmstat(unsigned int, int);
static void dozmem(void);
static void kread(int, void *, size_t);
static void kreado(int, void *, size_t, size_t);
static char *kgetstr(const char *);
static void needhdr(int);
static void printhdr(void);
static void usage(void);
@ -894,9 +900,59 @@ dointr(void)
static void
domem(void)
{
if (kd != NULL)
errx(1, "not implemented");
dosysctl("kern.malloc");
struct malloc_type type;
if (kd == NULL) {
dosysctl("kern.malloc");
return;
}
kread(X_KMEMSTATS, &type.ks_next, sizeof(type.ks_next));
(void)printf("\n Type InUse MemUse HighUse Requests"
" Size(s)\n");
do {
/* XXX this should be exported in sys/malloc.h */
struct {
int kz_size;
char *kz_name;
/* uma_zone_t */ void *kz_zone;
} kz;
size_t kmemzonenum;
char *str;
int first;
if (kvm_read(kd, (u_long)type.ks_next, &type, sizeof(type)) !=
sizeof(type))
errx(1, "%s: %p: %s", __func__, type.ks_next,
kvm_geterr(kd));
if (type.ks_calls == 0)
continue;
str = kgetstr(type.ks_shortdesc);
(void)printf("%13s%6lu%6luK%7luK%9llu",
str,
type.ks_inuse,
(type.ks_memuse + 1023) / 1024,
(type.ks_maxused + 1023) / 1024,
(long long unsigned)type.ks_calls);
free(str);
for (kmemzonenum = 0, first = 1; ; kmemzonenum++) {
kreado(X_KMEMZONES, &kz, sizeof(kz),
kmemzonenum * sizeof(kz));
if (kz.kz_name == NULL) {
(void)printf("\n");
break;
}
if (!(type.ks_size & (1 << kmemzonenum)))
continue;
if (first)
(void)printf(" ");
else
(void)printf(",");
first = 0;
str = kgetstr(kz.kz_name);
(void)printf("%s", str);
free(str);
}
} while (type.ks_next != NULL);
}
static void
@ -929,7 +985,7 @@ dosysctl(const char *name)
* kread reads something from the kernel, given its nlist index.
*/
static void
kread(int nlx, void *addr, size_t size)
kreado(int nlx, void *addr, size_t size, size_t offset)
{
const char *sym;
@ -939,7 +995,8 @@ kread(int nlx, void *addr, size_t size)
++sym;
errx(1, "symbol %s not defined", sym);
}
if ((size_t)kvm_read(kd, namelist[nlx].n_value, addr, size) != size) {
if ((size_t)kvm_read(kd, namelist[nlx].n_value + offset, addr,
size) != size) {
sym = namelist[nlx].n_name;
if (*sym == '_')
++sym;
@ -947,6 +1004,31 @@ kread(int nlx, void *addr, size_t size)
}
}
static void
kread(int nlx, void *addr, size_t size)
{
kreado(nlx, addr, size, 0);
}
static char *
kgetstr(const char *strp)
{
int n = 0, size = 1;
char *ret = NULL;
do {
if (size == n + 1) {
ret = realloc(ret, size);
if (ret == NULL)
err(1, "%s: realloc", __func__);
size *= 2;
}
if (kvm_read(kd, (u_long)strp + n, &ret[n], 1) != 1)
errx(1, "%s: %s", __func__, kvm_geterr(kd));
} while (ret[n++] != '\0');
return (ret);
}
static void
usage(void)
{