Date: Wed, 22 Mar 2000 20:16:25 +0000 (GMT) From: iedowse@maths.tcd.ie To: FreeBSD-gnats-submit@freebsd.org Subject: bin/17555: fstat(1) doesn't show memory-mapped files Message-ID: <200003222016.aa54468@bell.maths.tcd.ie>
next in thread | raw e-mail | index | archive | help
>Number: 17555 >Category: bin >Synopsis: fstat(1) doesn't show memory-mapped files >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Mar 22 12:20:01 PST 2000 >Closed-Date: >Last-Modified: >Originator: Ian Dowse >Release: FreeBSD 3.3-STABLE i386 >Organization: School of Mathematics Trinity College, Dublin >Environment: FreeBSD -current or -stable (patch included is for RELENG_4 or -current) >Description: fstat(1) is a useful tool for determining which processes hold references to a filesystem - I use it frequently to help resolve 'Device busy' errors when attempting to unmount a filesystem. However, files that are memory-mapped into a process's address space don't show up (unless the file descriptor is still open). The patch included below makes fstat include mmap()'d files in its listing of open files for each process. The word 'mmap' appears in the FD column to indicate that this is a mmap()'d file. Most of the logic in the new dommap() function below is taken from procfs_map.c. >How-To-Repeat: >Fix: --- fstat.1.orig Sun Oct 17 23:59:50 1999 +++ fstat.1 Wed Mar 22 19:56:21 2000 @@ -50,6 +50,7 @@ .Nm Fstat identifies open files. A file is considered open by a process if it was explicitly opened, +memory-mapped, is the working directory, root directory, active executable text, or kernel trace file for that process. If no options are specified, @@ -117,6 +118,7 @@ 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 --- fstat.c.orig Wed Mar 22 19:33:17 2000 +++ fstat.c Wed Mar 22 19:56:18 2000 @@ -74,6 +74,10 @@ #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 @@ #define CDIR -2 #define RDIR -3 #define TRACE -4 +#define MMAP -5 DEVS *devs; @@ -132,6 +137,7 @@ 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)); @@ -246,6 +252,7 @@ if (p->kp_proc.p_stat == SZOMB) continue; dofiles(p); + dommap(p); } exit(0); } @@ -267,6 +274,9 @@ case TRACE: \ printf(" tr"); \ break; \ + case MMAP: \ + printf(" mmap"); \ + break; \ default: \ printf(" %4d", i); \ break; \ @@ -356,6 +366,65 @@ dprintf(stderr, "unknown file type %d for file %d of pid %d\n", file.f_type, i, Pid); + } + } +} + +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; } } } >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200003222016.aa54468>