summaryrefslogtreecommitdiffstats
path: root/usr.bin/fstat
diff options
context:
space:
mode:
authorgreen <green@FreeBSD.org>2000-04-05 05:45:40 +0000
committergreen <green@FreeBSD.org>2000-04-05 05:45:40 +0000
commitaa7e4f0b1b108e1f4fbeef460453b098113b0ef3 (patch)
tree2136d4b5c441ee45fb91ff4a44fdc883f2aefbb5 /usr.bin/fstat
parent0acc8510070bc2e92a30e2050425cd513b5d2cf7 (diff)
downloadFreeBSD-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.16
-rw-r--r--usr.bin/fstat/fstat.c78
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);
}
OpenPOWER on IntegriCloud