diff options
author | 2016-05-26 17:23:49 +0000 | |
---|---|---|
committer | 2016-05-26 17:23:49 +0000 | |
commit | 2f639c72a402bd8954af94b40ba1b94e5b7c9084 (patch) | |
tree | f12fe5583b168275ef8b765345c550aa1ba4fa73 | |
parent | for textrels (sthen ran into one...): (diff) | |
download | wireguard-openbsd-2f639c72a402bd8954af94b40ba1b94e5b7c9084.tar.xz wireguard-openbsd-2f639c72a402bd8954af94b40ba1b94e5b7c9084.zip |
Re-introduce vnode-to-filename mapping
The name cache walking code got adapted to the new name cache layout.
Along with the previous commit, procmap is now able to map a vnode
to a filename as long as it is in the name cache.
"nice stuff" deraadt@
-rw-r--r-- | usr.sbin/procmap/procmap.1 | 6 | ||||
-rw-r--r-- | usr.sbin/procmap/procmap.c | 74 |
2 files changed, 74 insertions, 6 deletions
diff --git a/usr.sbin/procmap/procmap.1 b/usr.sbin/procmap/procmap.1 index 34fca120310..850fb50be0a 100644 --- a/usr.sbin/procmap/procmap.1 +++ b/usr.sbin/procmap/procmap.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: procmap.1,v 1.20 2015/03/13 19:58:41 jmc Exp $ +.\" $OpenBSD: procmap.1,v 1.21 2016/05/26 17:23:49 stefan Exp $ .\" $NetBSD: pmap.1,v 1.6 2003/01/19 21:25:43 atatat Exp $ .\" .\" Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: March 13 2015 $ +.Dd $Mdocdate: May 26 2016 $ .Dt PROCMAP 1 .Os .Sh NAME @@ -90,6 +90,8 @@ dump the process's vm_map structure dump the vm_map.header structure .It Cm 8 dump each vm_map_entry in its entirety +.It Cm 16 +dump the namei cache as it is traversed .El .It Fl d Dumps the vm_map and vm_map_entry structures in a style similar to diff --git a/usr.sbin/procmap/procmap.c b/usr.sbin/procmap/procmap.c index a1a1f729c89..1007b853ceb 100644 --- a/usr.sbin/procmap/procmap.c +++ b/usr.sbin/procmap/procmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: procmap.c,v 1.61 2016/05/25 15:45:53 stefan Exp $ */ +/* $OpenBSD: procmap.c,v 1.62 2016/05/26 17:23:50 stefan Exp $ */ /* $NetBSD: pmap.c,v 1.1 2002/09/01 20:32:44 atatat Exp $ */ /* @@ -38,6 +38,7 @@ #include <sys/vnode.h> #include <sys/mount.h> #include <sys/uio.h> +#include <sys/namei.h> #include <sys/sysctl.h> /* XXX until uvm gets cleaned up */ @@ -79,6 +80,7 @@ typedef int boolean_t; #define PRINT_VM_MAP 0x00000002 #define PRINT_VM_MAP_HEADER 0x00000004 #define PRINT_VM_MAP_ENTRY 0x00000008 +#define DUMP_NAMEI_CACHE 0x00000010 struct cache_entry { LIST_ENTRY(cache_entry) ce_next; @@ -89,8 +91,10 @@ struct cache_entry { }; LIST_HEAD(cache_head, cache_entry) lcache; +TAILQ_HEAD(namecache_head, namecache) nclruhead; +int namecache_loaded; void *uvm_vnodeops, *uvm_deviceops, *aobj_pager; -u_long kernel_map_addr; +u_long kernel_map_addr, nclruhead_addr; int debug, verbose; int print_all, print_map, print_maps, print_solaris, print_ddb, print_amap; int rwx = PROT_READ | PROT_WRITE | PROT_EXEC; @@ -165,6 +169,8 @@ struct nlist nl[] = { #define NL_AOBJ_PAGER 3 { "_kernel_map" }, #define NL_KERNEL_MAP 4 + { "_nclruhead" }, +#define NL_NCLRUHEAD 5 { NULL } }; @@ -178,6 +184,8 @@ size_t dump_vm_map_entry(kvm_t *, struct kbit *, struct vm_map_entry *, char *findname(kvm_t *, struct kbit *, struct vm_map_entry *, struct kbit *, struct kbit *, struct kbit *); int search_cache(kvm_t *, struct kbit *, char **, char *, size_t); +void load_name_cache(kvm_t *); +void cache_enter(struct namecache *); static void __dead usage(void); static pid_t strtopid(const char *); void print_sum(struct sum *, struct sum *); @@ -219,7 +227,7 @@ main(int argc, char *argv[]) print_ddb = 1; break; case 'D': - debug = strtonum(optarg, 0, 0xf, &errstr); + debug = strtonum(optarg, 0, 0x1f, &errstr); if (errstr) errx(1, "invalid debug mask"); break; @@ -524,6 +532,8 @@ load_symbols(kvm_t *kd) uvm_deviceops = (void*)nl[NL_UVM_DEVICEOPS].n_value; aobj_pager = (void*)nl[NL_AOBJ_PAGER].n_value; + nclruhead_addr = nl[NL_NCLRUHEAD].n_value; + _KDEREF(kd, nl[NL_MAXSSIZ].n_value, &maxssiz, sizeof(maxssiz)); _KDEREF(kd, nl[NL_KERNEL_MAP].n_value, &kernel_map_addr, @@ -889,6 +899,9 @@ search_cache(kvm_t *kd, struct kbit *vp, char **name, char *buf, size_t blen) char *o, *e; u_long cid; + if (!namecache_loaded) + load_name_cache(kd); + P(&svp) = P(vp); S(&svp) = sizeof(struct vnode); cid = D(vp, vnode)->v_id; @@ -900,8 +913,11 @@ search_cache(kvm_t *kd, struct kbit *vp, char **name, char *buf, size_t blen) if (ce->ce_vp == P(&svp) && ce->ce_cid == cid) break; if (ce && ce->ce_vp == P(&svp) && ce->ce_cid == cid) { - if (o != e) + if (o != e) { + if (o <= buf) + break; *(--o) = '/'; + } if (o - ce->ce_nlen <= buf) break; o -= ce->ce_nlen; @@ -921,6 +937,56 @@ search_cache(kvm_t *kd, struct kbit *vp, char **name, char *buf, size_t blen) return (D(&svp, vnode)->v_flag & VROOT); } +void +load_name_cache(kvm_t *kd) +{ + struct namecache n, *tmp; + struct namecache_head nchead; + + LIST_INIT(&lcache); + _KDEREF(kd, nclruhead_addr, &nchead, sizeof(nchead)); + tmp = TAILQ_FIRST(&nchead); + while (tmp != NULL) { + _KDEREF(kd, (u_long)tmp, &n, sizeof(n)); + + if (n.nc_nlen > 0) { + if (n.nc_nlen > 2 || + n.nc_name[0] != '.' || + (n.nc_nlen != 1 && n.nc_name[1] != '.')) + cache_enter(&n); + } + tmp = TAILQ_NEXT(&n, nc_lru); + } + + namecache_loaded = 1; +} + +void +cache_enter(struct namecache *ncp) +{ + struct cache_entry *ce; + + if (debug & DUMP_NAMEI_CACHE) + printf("ncp->nc_vp %10p, ncp->nc_dvp %10p, ncp->nc_nlen " + "%3d [%.*s] (nc_dvpid=%lu, nc_vpid=%lu)\n", + ncp->nc_vp, ncp->nc_dvp, + ncp->nc_nlen, ncp->nc_nlen, ncp->nc_name, + ncp->nc_dvpid, ncp->nc_vpid); + + ce = malloc(sizeof(struct cache_entry)); + if (ce == NULL) + err(1, "cache_enter"); + + ce->ce_vp = ncp->nc_vp; + ce->ce_pvp = ncp->nc_dvp; + ce->ce_cid = ncp->nc_vpid; + ce->ce_pcid = ncp->nc_dvpid; + ce->ce_nlen = (unsigned)ncp->nc_nlen; + strlcpy(ce->ce_name, ncp->nc_name, sizeof(ce->ce_name)); + + LIST_INSERT_HEAD(&lcache, ce, ce_next); +} + static void __dead usage(void) { |