- Separate hashstat namelist into separate hashnl[], and don't barf if
some of the symbols can't be found - Only kvm_nlist() hashnl[] and histnl[] once - Add a description to struct kernel_hash, and print with -L - Sort entries in khashes[] - Don't exit on unknown hashes; just display a warning and move on
This commit is contained in:
parent
3dfc0ff3ab
commit
31c1ed8952
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: vmstat.c,v 1.89 2001/11/26 10:38:59 lukem Exp $ */
|
/* $NetBSD: vmstat.c,v 1.90 2001/11/26 14:06:31 lukem Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1998, 2000, 2001 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998, 2000, 2001 The NetBSD Foundation, Inc.
|
||||||
@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1991, 1993\n\
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95";
|
static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: vmstat.c,v 1.89 2001/11/26 10:38:59 lukem Exp $");
|
__RCSID("$NetBSD: vmstat.c,v 1.90 2001/11/26 14:06:31 lukem Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@ -137,6 +137,9 @@ __RCSID("$NetBSD: vmstat.c,v 1.89 2001/11/26 10:38:59 lukem Exp $");
|
|||||||
|
|
||||||
#include "dkstats.h"
|
#include "dkstats.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General namelist
|
||||||
|
*/
|
||||||
struct nlist namelist[] =
|
struct nlist namelist[] =
|
||||||
{
|
{
|
||||||
#define X_BOOTTIME 0
|
#define X_BOOTTIME 0
|
||||||
@ -165,51 +168,71 @@ struct nlist namelist[] =
|
|||||||
{ "_pool_head" },
|
{ "_pool_head" },
|
||||||
#define X_UVMEXP 12
|
#define X_UVMEXP 12
|
||||||
{ "_uvmexp" },
|
{ "_uvmexp" },
|
||||||
#define X_NFSNODE 13
|
#define X_END 13
|
||||||
{ "_nfsnodehash" },
|
|
||||||
#define X_NFSNODETBL 14
|
|
||||||
{ "_nfsnodehashtbl" },
|
|
||||||
#define X_IHASH 15
|
|
||||||
{ "_ihash" },
|
|
||||||
#define X_IHASHTBL 16
|
|
||||||
{ "_ihashtbl" },
|
|
||||||
#define X_BUFHASH 17
|
|
||||||
{ "_bufhash" },
|
|
||||||
#define X_BUFHASHTBL 18
|
|
||||||
{ "_bufhashtbl" },
|
|
||||||
#define X_PIDHASH 19
|
|
||||||
{ "_pidhash" },
|
|
||||||
#define X_PIDHASHTBL 20
|
|
||||||
{ "_pidhashtbl" },
|
|
||||||
#define X_PGRPHASH 21
|
|
||||||
{ "_pgrphash" },
|
|
||||||
#define X_PGRPHASHTBL 22
|
|
||||||
{ "_pgrphashtbl" },
|
|
||||||
#define X_UIHASH 23
|
|
||||||
{ "_uihash" },
|
|
||||||
#define X_UIHASHTBL 24
|
|
||||||
{ "_uihashtbl" },
|
|
||||||
#define X_IFADDRHASH 25
|
|
||||||
{ "_in_ifaddrhash" },
|
|
||||||
#define X_IFADDRHASHTBL 26
|
|
||||||
{ "_in_ifaddrhashtbl" },
|
|
||||||
#define X_NCHASH 27
|
|
||||||
{ "_nchash" },
|
|
||||||
#define X_NCHASHTBL 28
|
|
||||||
{ "_nchashtbl" },
|
|
||||||
#define X_NCVHASH 29
|
|
||||||
{ "_ncvhash" },
|
|
||||||
#define X_NCVHASHTBL 30
|
|
||||||
{ "_ncvhashtbl" },
|
|
||||||
|
|
||||||
#define X_END 31
|
|
||||||
#if defined(pc532)
|
#if defined(pc532)
|
||||||
#define X_IVT (X_END)
|
#define X_IVT (X_END)
|
||||||
{ "_ivt" },
|
{ "_ivt" },
|
||||||
#endif
|
#endif
|
||||||
{ "" },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Namelist for hash statistics
|
||||||
|
*/
|
||||||
|
struct nlist hashnl[] =
|
||||||
|
{
|
||||||
|
#define X_NFSNODE 0
|
||||||
|
{ "_nfsnodehash" },
|
||||||
|
#define X_NFSNODETBL 1
|
||||||
|
{ "_nfsnodehashtbl" },
|
||||||
|
#define X_IHASH 2
|
||||||
|
{ "_ihash" },
|
||||||
|
#define X_IHASHTBL 3
|
||||||
|
{ "_ihashtbl" },
|
||||||
|
#define X_BUFHASH 4
|
||||||
|
{ "_bufhash" },
|
||||||
|
#define X_BUFHASHTBL 5
|
||||||
|
{ "_bufhashtbl" },
|
||||||
|
#define X_PIDHASH 6
|
||||||
|
{ "_pidhash" },
|
||||||
|
#define X_PIDHASHTBL 7
|
||||||
|
{ "_pidhashtbl" },
|
||||||
|
#define X_PGRPHASH 8
|
||||||
|
{ "_pgrphash" },
|
||||||
|
#define X_PGRPHASHTBL 9
|
||||||
|
{ "_pgrphashtbl" },
|
||||||
|
#define X_UIHASH 10
|
||||||
|
{ "_uihash" },
|
||||||
|
#define X_UIHASHTBL 11
|
||||||
|
{ "_uihashtbl" },
|
||||||
|
#define X_IFADDRHASH 12
|
||||||
|
{ "_in_ifaddrhash" },
|
||||||
|
#define X_IFADDRHASHTBL 13
|
||||||
|
{ "_in_ifaddrhashtbl" },
|
||||||
|
#define X_NCHASH 14
|
||||||
|
{ "_nchash" },
|
||||||
|
#define X_NCHASHTBL 15
|
||||||
|
{ "_nchashtbl" },
|
||||||
|
#define X_NCVHASH 16
|
||||||
|
{ "_ncvhash" },
|
||||||
|
#define X_NCVHASHTBL 17
|
||||||
|
{ "_ncvhashtbl" },
|
||||||
|
#define X_HASHNL_SIZE 18 /* must be last */
|
||||||
|
{ NULL },
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Namelist for UVM histories
|
||||||
|
*/
|
||||||
|
struct nlist histnl[] =
|
||||||
|
{
|
||||||
|
{ "_uvm_histories" },
|
||||||
|
#define X_UVM_HISTORIES 0
|
||||||
|
{ NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct uvmexp uvmexp, ouvmexp;
|
struct uvmexp uvmexp, ouvmexp;
|
||||||
int ndrives;
|
int ndrives;
|
||||||
@ -357,19 +380,19 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((c = kvm_nlist(kd, namelist)) != 0) {
|
if ((c = kvm_nlist(kd, namelist)) != 0) {
|
||||||
if (c > 0) {
|
if (c == -1)
|
||||||
(void)fprintf(stderr,
|
errx(1, "kvm_nlist: %s %s", "namelist", kvm_geterr(kd));
|
||||||
"vmstat: undefined symbols:");
|
(void)fprintf(stderr, "vmstat: undefined symbols:");
|
||||||
for (c = 0;
|
for (c = 0; c < sizeof(namelist) / sizeof(namelist[0]); c++)
|
||||||
c < sizeof(namelist) / sizeof(namelist[0]); c++)
|
if (namelist[c].n_type == 0)
|
||||||
if (namelist[c].n_type == 0)
|
fprintf(stderr, " %s", namelist[c].n_name);
|
||||||
fprintf(stderr, " %s",
|
(void)fputc('\n', stderr);
|
||||||
namelist[c].n_name);
|
|
||||||
(void)fputc('\n', stderr);
|
|
||||||
} else
|
|
||||||
warnx("kvm_nlist: %s", kvm_geterr(kd));
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if ((c = kvm_nlist(kd, hashnl)) == -1 || c == X_HASHNL_SIZE)
|
||||||
|
errx(1, "kvm_nlist: %s %s", "hashnl", kvm_geterr(kd));
|
||||||
|
if (kvm_nlist(kd, histnl) == -1)
|
||||||
|
errx(1, "kvm_nlist: %s %s", "histnl", kvm_geterr(kd));
|
||||||
|
|
||||||
if (todo & VMSTAT) {
|
if (todo & VMSTAT) {
|
||||||
struct winsize winsize;
|
struct winsize winsize;
|
||||||
@ -1129,6 +1152,7 @@ dopool(void)
|
|||||||
inuse, total, (double)(100 * inuse) / total);
|
inuse, total, (double)(100 * inuse) / total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum hashtype { /* from <sys/systm.h> */
|
enum hashtype { /* from <sys/systm.h> */
|
||||||
HASH_LIST,
|
HASH_LIST,
|
||||||
HASH_TAILQ
|
HASH_TAILQ
|
||||||
@ -1141,41 +1165,51 @@ struct uidinfo { /* XXX: no kernel header file */
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct kernel_hash {
|
struct kernel_hash {
|
||||||
int hashsize;
|
const char * description; /* description */
|
||||||
int hashtbl;
|
int hashsize; /* nlist index for hash size */
|
||||||
enum hashtype type;
|
int hashtbl; /* nlist index for hash table */
|
||||||
size_t offset;
|
enum hashtype type; /* type of hash table */
|
||||||
|
size_t offset; /* offset of {LIST,TAILQ}_NEXT */
|
||||||
} khashes[] =
|
} khashes[] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
X_NFSNODE, X_NFSNODETBL,
|
"buffer hash",
|
||||||
HASH_LIST, offsetof(struct nfsnode, n_hash)
|
|
||||||
} , {
|
|
||||||
X_IHASH, X_IHASHTBL,
|
|
||||||
HASH_LIST, offsetof(struct inode, i_hash)
|
|
||||||
} , {
|
|
||||||
X_BUFHASH, X_BUFHASHTBL,
|
X_BUFHASH, X_BUFHASHTBL,
|
||||||
HASH_LIST, offsetof(struct buf, b_hash)
|
HASH_LIST, offsetof(struct buf, b_hash)
|
||||||
} , {
|
}, {
|
||||||
X_PIDHASH, X_PIDHASHTBL,
|
"inode cache (ihash)",
|
||||||
HASH_LIST, offsetof(struct proc, p_hash)
|
X_IHASH, X_IHASHTBL,
|
||||||
} , {
|
HASH_LIST, offsetof(struct inode, i_hash)
|
||||||
X_PGRPHASH, X_PGRPHASHTBL,
|
}, {
|
||||||
HASH_LIST, offsetof(struct pgrp, pg_hash),
|
"ipv4 address -> interface hash",
|
||||||
} , {
|
|
||||||
X_UIHASH, X_UIHASHTBL,
|
|
||||||
HASH_LIST, offsetof(struct uidinfo, ui_hash),
|
|
||||||
} , {
|
|
||||||
X_IFADDRHASH, X_IFADDRHASHTBL,
|
X_IFADDRHASH, X_IFADDRHASHTBL,
|
||||||
HASH_LIST, offsetof(struct in_ifaddr, ia_hash),
|
HASH_LIST, offsetof(struct in_ifaddr, ia_hash),
|
||||||
} , {
|
}, {
|
||||||
|
"name cache hash",
|
||||||
X_NCHASH, X_NCHASHTBL,
|
X_NCHASH, X_NCHASHTBL,
|
||||||
HASH_LIST, offsetof(struct namecache, nc_hash),
|
HASH_LIST, offsetof(struct namecache, nc_hash),
|
||||||
} , {
|
}, {
|
||||||
|
"name cache directory hash",
|
||||||
X_NCVHASH, X_NCVHASHTBL,
|
X_NCVHASH, X_NCVHASHTBL,
|
||||||
HASH_LIST, offsetof(struct namecache, nc_vhash),
|
HASH_LIST, offsetof(struct namecache, nc_vhash),
|
||||||
} , {
|
}, {
|
||||||
-1, -1, 0, 0
|
"nfs client node cache",
|
||||||
|
X_NFSNODE, X_NFSNODETBL,
|
||||||
|
HASH_LIST, offsetof(struct nfsnode, n_hash)
|
||||||
|
}, {
|
||||||
|
"process group (pgrp) hash",
|
||||||
|
X_PGRPHASH, X_PGRPHASHTBL,
|
||||||
|
HASH_LIST, offsetof(struct pgrp, pg_hash),
|
||||||
|
}, {
|
||||||
|
"process id (pid) hash",
|
||||||
|
X_PIDHASH, X_PIDHASHTBL,
|
||||||
|
HASH_LIST, offsetof(struct proc, p_hash)
|
||||||
|
}, {
|
||||||
|
"user info (uid -> used processes) hash",
|
||||||
|
X_UIHASH, X_UIHASHTBL,
|
||||||
|
HASH_LIST, offsetof(struct uidinfo, ui_hash),
|
||||||
|
}, {
|
||||||
|
NULL, -1, -1, 0, 0,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1194,25 +1228,30 @@ dohashstat(int verbose, int todo, const char *hashname)
|
|||||||
hashbufsize = 0;
|
hashbufsize = 0;
|
||||||
|
|
||||||
if (todo & HASHLIST) {
|
if (todo & HASHLIST) {
|
||||||
const char *prefix = "";
|
printf("Supported hashes:\n");
|
||||||
|
for (curhash = khashes; curhash->description; curhash++) {
|
||||||
printf("Supported hashes:\n\t");
|
if (hashnl[curhash->hashsize].n_value == 0 ||
|
||||||
for (curhash = khashes; curhash->hashsize != -1; curhash++) {
|
hashnl[curhash->hashtbl].n_value == 0)
|
||||||
printf("%s%s",
|
continue;
|
||||||
prefix, namelist[curhash->hashsize].n_name + 1);
|
printf("\t%-16s%s\n",
|
||||||
prefix = ", ";
|
hashnl[curhash->hashsize].n_name + 1,
|
||||||
|
curhash->description);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hashname != NULL) {
|
if (hashname != NULL) {
|
||||||
for (curhash = khashes; curhash->hashsize != -1; curhash++) {
|
for (curhash = khashes; curhash->description; curhash++) {
|
||||||
if (strcmp(namelist[curhash->hashsize].n_name + 1,
|
if (strcmp(hashnl[curhash->hashsize].n_name + 1,
|
||||||
hashname) == 0)
|
hashname) == 0 &&
|
||||||
|
hashnl[curhash->hashsize].n_value != 0 &&
|
||||||
|
hashnl[curhash->hashtbl].n_value != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (curhash->hashsize == -1)
|
if (curhash->description == NULL) {
|
||||||
errx(1, "%s: no such hash", hashname);
|
warnx("%s: no such hash", hashname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(
|
printf(
|
||||||
@ -1222,28 +1261,35 @@ dohashstat(int verbose, int todo, const char *hashname)
|
|||||||
"hash table", "buckets", "buckets", "%", "items", "chain",
|
"hash table", "buckets", "buckets", "%", "items", "chain",
|
||||||
"chain");
|
"chain");
|
||||||
|
|
||||||
for (curhash = khashes; curhash->hashsize != -1; curhash++) {
|
for (curhash = khashes; curhash->description; curhash++) {
|
||||||
|
if (hashnl[curhash->hashsize].n_value == 0 ||
|
||||||
|
hashnl[curhash->hashtbl].n_value == 0)
|
||||||
|
continue;
|
||||||
if (hashname != NULL &&
|
if (hashname != NULL &&
|
||||||
strcmp(namelist[curhash->hashsize].n_name + 1, hashname))
|
strcmp(hashnl[curhash->hashsize].n_name + 1, hashname))
|
||||||
continue;
|
continue;
|
||||||
elemsize = curhash->type == HASH_LIST ?
|
elemsize = curhash->type == HASH_LIST ?
|
||||||
sizeof(*hashtbl_list) : sizeof(*hashtbl_tailq);
|
sizeof(*hashtbl_list) : sizeof(*hashtbl_tailq);
|
||||||
kread(curhash->hashsize, &hashsize, sizeof(hashsize));
|
deref_kptr((void *)hashnl[curhash->hashsize].n_value,
|
||||||
|
&hashsize, sizeof(hashsize),
|
||||||
|
hashnl[curhash->hashsize].n_name);
|
||||||
hashsize++;
|
hashsize++;
|
||||||
kread(curhash->hashtbl, &hashaddr, sizeof(hashaddr));
|
deref_kptr((void *)hashnl[curhash->hashtbl].n_value,
|
||||||
|
&hashaddr, sizeof(hashaddr),
|
||||||
|
hashnl[curhash->hashtbl].n_name);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf("%s %lu, %s %p, offset %ld, elemsize %d\n",
|
printf("%s %lu, %s %p, offset %ld, elemsize %d\n",
|
||||||
namelist[curhash->hashsize].n_name + 1, hashsize,
|
hashnl[curhash->hashsize].n_name + 1, hashsize,
|
||||||
namelist[curhash->hashtbl].n_name + 1, hashaddr,
|
hashnl[curhash->hashtbl].n_name + 1, hashaddr,
|
||||||
(long)curhash->offset, elemsize);
|
(long)curhash->offset, elemsize);
|
||||||
thissize = hashsize * elemsize;
|
thissize = hashsize * elemsize;
|
||||||
if (thissize > hashbufsize) {
|
if (thissize > hashbufsize) {
|
||||||
hashbufsize = thissize;
|
hashbufsize = thissize;
|
||||||
if ((hashbuf = realloc(hashbuf, hashbufsize)) == NULL)
|
if ((hashbuf = realloc(hashbuf, hashbufsize)) == NULL)
|
||||||
errx(1, "malloc %d", hashbufsize);
|
errx(1, "malloc hashbuf %d", hashbufsize);
|
||||||
}
|
}
|
||||||
deref_kptr(hashaddr, hashbuf, thissize,
|
deref_kptr(hashaddr, hashbuf, thissize,
|
||||||
namelist[curhash->hashtbl].n_name);
|
hashnl[curhash->hashtbl].n_name);
|
||||||
used = 0;
|
used = 0;
|
||||||
items = maxchain = 0;
|
items = maxchain = 0;
|
||||||
if (curhash->type == HASH_LIST)
|
if (curhash->type == HASH_LIST)
|
||||||
@ -1282,14 +1328,14 @@ dohashstat(int verbose, int todo, const char *hashname)
|
|||||||
maxchain = chain;
|
maxchain = chain;
|
||||||
}
|
}
|
||||||
printf("%-16s %8ld %8d %8.2f %8d %8d %8d\n",
|
printf("%-16s %8ld %8d %8.2f %8d %8d %8d\n",
|
||||||
namelist[curhash->hashsize].n_name + 1,
|
hashnl[curhash->hashsize].n_name + 1,
|
||||||
hashsize, used, used * 100.0 / hashsize,
|
hashsize, used, used * 100.0 / hashsize,
|
||||||
items, used ? items / used : 0, maxchain);
|
items, used ? items / used : 0, maxchain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* kread reads something from the kernel, given its nlist index.
|
* kread reads something from the kernel, given its nlist index in namelist[].
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
kread(int nlx, void *addr, size_t size)
|
kread(int nlx, void *addr, size_t size)
|
||||||
@ -1319,14 +1365,6 @@ deref_kptr(const void *kptr, void *ptr, size_t len, const char *msg)
|
|||||||
errx(1, "kptr %lx: %s: %s", (u_long)kptr, msg, kvm_geterr(kd));
|
errx(1, "kptr %lx: %s: %s", (u_long)kptr, msg, kvm_geterr(kd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct nlist histnl[] =
|
|
||||||
{
|
|
||||||
{ "_uvm_histories" },
|
|
||||||
#define X_UVM_HISTORIES 0
|
|
||||||
{ NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Traverse the UVM history buffers, performing the requested action.
|
* Traverse the UVM history buffers, performing the requested action.
|
||||||
*
|
*
|
||||||
@ -1340,7 +1378,7 @@ hist_traverse(int todo, const char *histname)
|
|||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
size_t namelen = 0;
|
size_t namelen = 0;
|
||||||
|
|
||||||
if (kvm_nlist(kd, histnl) != 0) {
|
if (histnl[0].n_value == 0) {
|
||||||
warnx("UVM history is not compiled into the kernel.");
|
warnx("UVM history is not compiled into the kernel.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user