summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstefan <stefan@openbsd.org>2016-05-26 17:23:49 +0000
committerstefan <stefan@openbsd.org>2016-05-26 17:23:49 +0000
commit2f639c72a402bd8954af94b40ba1b94e5b7c9084 (patch)
treef12fe5583b168275ef8b765345c550aa1ba4fa73
parentfor textrels (sthen ran into one...): (diff)
downloadwireguard-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.16
-rw-r--r--usr.sbin/procmap/procmap.c74
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)
{