diff options
author | green <green@FreeBSD.org> | 2000-04-05 05:45:40 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 2000-04-05 05:45:40 +0000 |
commit | aa7e4f0b1b108e1f4fbeef460453b098113b0ef3 (patch) | |
tree | 2136d4b5c441ee45fb91ff4a44fdc883f2aefbb5 /usr.bin/fstat | |
parent | 0acc8510070bc2e92a30e2050425cd513b5d2cf7 (diff) | |
download | FreeBSD-src-aa7e4f0b1b108e1f4fbeef460453b098113b0ef3.zip FreeBSD-src-aa7e4f0b1b108e1f4fbeef460453b098113b0ef3.tar.gz |
Add a new options: -m enables searching for memory-mapped files.
It is not default because it's an expensive option by nature, making the
search take 2-3 times as long.
PR: 17555
Submitted by: Ian Dowse <iedowse@maths.tcd.ie>
Diffstat (limited to 'usr.bin/fstat')
-rw-r--r-- | usr.bin/fstat/fstat.1 | 6 | ||||
-rw-r--r-- | usr.bin/fstat/fstat.c | 78 |
2 files changed, 81 insertions, 3 deletions
diff --git a/usr.bin/fstat/fstat.1 b/usr.bin/fstat/fstat.1 index c6c6dbc..c07616b 100644 --- a/usr.bin/fstat/fstat.1 +++ b/usr.bin/fstat/fstat.1 @@ -40,7 +40,7 @@ .Nd file status .Sh SYNOPSIS .Nm fstat -.Op Fl fnv +.Op Fl fmnv .Op Fl M Ar core .Op Fl N Ar system .Op Fl p Ar pid @@ -74,6 +74,9 @@ instead of the default .It Fl N Extract the name list from the specified system instead of the default .Pa /kernel . +.It Fl m +Include memory-mapped files in the listing; normally these are excluded +due to the extra processing required. .It Fl n Numerical format. Print the device number (maj,min) of the filesystem the file resides in rather than the mount point name; for special @@ -117,6 +120,7 @@ text - executable text inode wd - current working directory root - root inode tr - kernel trace file +mmap - memory-mapped file .Ed .Pp If the file number is followed by an asterisk (``*''), the file is diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c index c600198..9bbe502 100644 --- a/usr.bin/fstat/fstat.c +++ b/usr.bin/fstat/fstat.c @@ -74,6 +74,10 @@ static const char rcsid[] = #include <nfs/nfsnode.h> +#include <vm/vm.h> +#include <vm/vm_map.h> +#include <vm/vm_object.h> + #include <net/route.h> #include <netinet/in.h> #include <netinet/in_systm.h> @@ -100,6 +104,7 @@ static const char rcsid[] = #define CDIR -2 #define RDIR -3 #define TRACE -4 +#define MMAP -5 DEVS *devs; @@ -115,6 +120,7 @@ int fsflg, /* show files on same filesystem as file(s) argument */ int checkfile; /* true if restricting to particular files or filesystems */ int nflg; /* (numerical) display f.s. and rdev as dev_t */ int vflg; /* display errors in locating kernel data objects etc... */ +int mflg; /* include memory-mapped files */ struct file **ofiles; /* buffer of pointers to file structures */ @@ -132,6 +138,7 @@ int maxfiles; kvm_t *kd; void dofiles __P((struct kinfo_proc *kp)); +void dommap __P((struct kinfo_proc *kp)); void vtrans __P((struct vnode *vp, int i, int flag)); int ufs_filestat __P((struct vnode *vp, struct filestat *fsp)); int nfs_filestat __P((struct vnode *vp, struct filestat *fsp)); @@ -158,7 +165,7 @@ main(argc, argv) arg = 0; what = KERN_PROC_ALL; nlistf = memf = NULL; - while ((ch = getopt(argc, argv, "fnp:u:vN:M:")) != -1) + while ((ch = getopt(argc, argv, "fmnp:u:vN:M:")) != -1) switch((char)ch) { case 'f': fsflg = 1; @@ -169,6 +176,9 @@ main(argc, argv) case 'N': nlistf = optarg; break; + case 'm': + mflg = 1; + break; case 'n': nflg = 1; break; @@ -246,6 +256,8 @@ main(argc, argv) if (p->kp_proc.p_stat == SZOMB) continue; dofiles(p); + if (mflg) + dommap(p); } exit(0); } @@ -267,6 +279,9 @@ int Pid; case TRACE: \ printf(" tr"); \ break; \ + case MMAP: \ + printf(" mmap"); \ + break; \ default: \ printf(" %4d", i); \ break; \ @@ -361,6 +376,65 @@ dofiles(kp) } void +dommap(kp) + struct kinfo_proc *kp; +{ + struct proc *p = &kp->kp_proc; + struct vmspace vmspace; + vm_map_t map; + struct vm_map_entry entry; + vm_map_entry_t entryp; + struct vm_object object; + vm_object_t objp; + int prot, fflags; + + if (!KVM_READ(p->p_vmspace, &vmspace, sizeof(vmspace))) { + dprintf(stderr, "can't read vmspace at %p for pid %d\n", + (void *)p->p_vmspace, Pid); + return; + } + + map = &vmspace.vm_map; + + for (entryp = map->header.next; entryp != &p->p_vmspace->vm_map.header; + entryp = entry.next) { + if (!KVM_READ(entryp, &entry, sizeof(entry))) { + dprintf(stderr, + "can't read vm_map_entry at %p for pid %d\n", + (void *)entryp, Pid); + return; + } + + if (entry.eflags & MAP_ENTRY_IS_SUB_MAP) + continue; + + if ((objp = entry.object.vm_object) == NULL) + continue; + + for (; objp; objp = object.backing_object) { + if (!KVM_READ(objp, &object, sizeof(object))) { + dprintf(stderr, + "can't read vm_object at %p for pid %d\n", + (void *)objp, Pid); + return; + } + } + + prot = entry.protection; + fflags = (prot & VM_PROT_READ ? FREAD : 0) | + (prot & VM_PROT_WRITE ? FWRITE : 0); + + switch (object.type) { + case OBJT_VNODE: + vtrans((struct vnode *)object.handle, MMAP, fflags); + break; + default: + break; + } + } +} + +void vtrans(vp, i, flag) struct vnode *vp; int i; @@ -794,6 +868,6 @@ void usage() { (void)fprintf(stderr, - "usage: fstat [-fnv] [-p pid] [-u user] [-N system] [-M core] [file ...]\n"); + "usage: fstat [-fmnv] [-p pid] [-u user] [-N system] [-M core] [file ...]\n"); exit(1); } |