diff --git a/usr.bin/fstat/fstat.1 b/usr.bin/fstat/fstat.1 index c6c6dbc00e37..c07616b3bc2c 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 c60019843023..9bbe502a8961 100644 --- a/usr.bin/fstat/fstat.c +++ b/usr.bin/fstat/fstat.c @@ -74,6 +74,10 @@ static const char rcsid[] = #include +#include +#include +#include + #include #include #include @@ -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; \ @@ -360,6 +375,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; @@ -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); }