Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/miscfs/procfs For -o linux mounts, add some code to emul...



details:   https://anonhg.NetBSD.org/src/rev/fb25f5c2eb20
branches:  trunk
changeset: 507706:fb25f5c2eb20
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Thu Mar 29 22:41:52 2001 +0000

description:
For -o linux mounts, add some code to emulate /proc/#/maps.
Needs NAMECACHE_ENTER_REVERSE to include filenames.

diffstat:

 sys/miscfs/procfs/procfs.h       |    7 +-
 sys/miscfs/procfs/procfs_map.c   |  141 ++++++++++++++++++++++++++++++++------
 sys/miscfs/procfs/procfs_subr.c  |    8 +-
 sys/miscfs/procfs/procfs_vnops.c |   13 +++-
 4 files changed, 140 insertions(+), 29 deletions(-)

diffs (298 lines):

diff -r 48bb82298008 -r fb25f5c2eb20 sys/miscfs/procfs/procfs.h
--- a/sys/miscfs/procfs/procfs.h        Thu Mar 29 22:40:06 2001 +0000
+++ b/sys/miscfs/procfs/procfs.h        Thu Mar 29 22:41:52 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: procfs.h,v 1.33 2001/01/25 12:44:56 jdolecek Exp $     */
+/*     $NetBSD: procfs.h,v 1.34 2001/03/29 22:41:52 fvdl Exp $ */
 
 /*
  * Copyright (c) 1993 Jan-Simon Pendry
@@ -58,7 +58,8 @@
        Pmap,           /* memory map */
        Pcmdline,       /* process command line args */
        Pmeminfo,       /* system memory info (if -o linux) */
-       Pcpuinfo        /* CPU info (if -o linux) */
+       Pcpuinfo,       /* CPU info (if -o linux) */
+       Pmaps,          /* memory map, Linux style (if -o linux) */
 } pfstype;
 
 /*
@@ -139,7 +140,7 @@
 int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *,
     struct uio *));
 int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *,
-    struct uio *));
+    struct uio *, int));
 int procfs_docmdline __P((struct proc *, struct proc *, struct pfsnode *,
     struct uio *));
 int procfs_domeminfo __P((struct proc *, struct proc *, struct pfsnode *,
diff -r 48bb82298008 -r fb25f5c2eb20 sys/miscfs/procfs/procfs_map.c
--- a/sys/miscfs/procfs/procfs_map.c    Thu Mar 29 22:40:06 2001 +0000
+++ b/sys/miscfs/procfs/procfs_map.c    Thu Mar 29 22:41:52 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: procfs_map.c,v 1.10 2001/01/17 00:09:08 fvdl Exp $     */
+/*     $NetBSD: procfs_map.c,v 1.11 2001/03/29 22:41:52 fvdl Exp $     */
 
 /*
  * Copyright (c) 1993 Jan-Simon Pendry
@@ -45,6 +45,8 @@
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <sys/vnode.h>
+#include <sys/malloc.h>
+#include <sys/namei.h>
 #include <miscfs/procfs/procfs.h>
 
 #include <sys/lock.h>
@@ -53,6 +55,12 @@
 
 #define MEBUFFERSIZE 256
 
+extern int getcwd_common __P((struct vnode *, struct vnode *,
+                             char **, char *, int, int, struct proc *));
+
+static int procfs_vnode_to_path(struct vnode *vp, char *path, int len,
+                               struct proc *curp, struct proc *p);
+
 /*
  * The map entries can *almost* be read with programs like cat.  However,
  * large maps need special programs to read.  It is not easy to implement
@@ -64,17 +72,19 @@
  * can try a bigger buffer.
  */
 int
-procfs_domap(curp, p, pfs, uio)
-       struct proc *curp;
-       struct proc *p;
-       struct pfsnode *pfs;
-       struct uio *uio;
+procfs_domap(struct proc *curp, struct proc *p, struct pfsnode *pfs,
+            struct uio *uio, int linuxmode)
 {
        int len;
-       int error;
+       int error, buf_full;
        vm_map_t map = &p->p_vmspace->vm_map;
        vm_map_entry_t entry;
        char mebuffer[MEBUFFERSIZE];
+       char *path;
+       struct vnode *vp;
+       struct vattr va;
+       dev_t dev;
+       long fileid;
 
        if (uio->uio_rw != UIO_READ)
                return (EOPNOTSUPP);
@@ -83,6 +93,7 @@
                return (0);
        
        error = 0;
+       buf_full = 0;
        if (map != &curproc->p_vmspace->vm_map)
                vm_map_lock_read(map);
        for (entry = map->header.next;
@@ -92,18 +103,57 @@
                if (UVM_ET_ISSUBMAP(entry))
                        continue;
 
-               snprintf(mebuffer, sizeof(mebuffer),
-                   "0x%lx 0x%lx %c%c%c %c%c%c %s %s %d %d %d\n",
-                   entry->start, entry->end,
-                   (entry->protection & VM_PROT_READ) ? 'r' : '-',
-                   (entry->protection & VM_PROT_WRITE) ? 'w' : '-',
-                   (entry->protection & VM_PROT_EXECUTE) ? 'x' : '-',
-                   (entry->max_protection & VM_PROT_READ) ? 'r' : '-',
-                   (entry->max_protection & VM_PROT_WRITE) ? 'w' : '-',
-                   (entry->max_protection & VM_PROT_EXECUTE) ? 'x' : '-',
-                   (entry->etype & UVM_ET_COPYONWRITE) ? "COW" : "NCOW",
-                   (entry->etype & UVM_ET_NEEDSCOPY) ? "NC" : "NNC",
-                   entry->inheritance, entry->wired_count, entry->advice);
+               if (linuxmode != 0) {
+                       path = (char *)malloc(MAXPATHLEN * 4, M_TEMP, M_WAITOK);
+                       if (path == NULL) {
+                               error = ENOMEM;
+                               break;
+                       }
+                       *path = 0;
+
+                       dev = (dev_t)0;
+                       fileid = 0;
+                       if (UVM_ET_ISOBJ(entry) &&
+                           UVM_OBJ_IS_VNODE(entry->object.uvm_obj)) {
+                               vp = (struct vnode *)entry->object.uvm_obj;
+                               error = VOP_GETATTR(vp, &va, curp->p_ucred,
+                                   curp);
+                               if (error == 0 && vp != pfs->pfs_vnode) {
+                                       fileid = va.va_fileid;
+                                       dev = va.va_fsid;
+                                       error = procfs_vnode_to_path(vp, path,  
+                                           MAXPATHLEN * 4, curp, p);
+                               }
+                       }
+                       snprintf(mebuffer, sizeof(mebuffer),
+                           "%0*lx-%0*lx %c%c%c%c %0*lx %02x:%02x %ld     %s\n",
+                           sizeof (void *) * 2, (unsigned long)entry->start,
+                           sizeof (void *) * 2, (unsigned long)entry->end,
+                           (entry->protection & VM_PROT_READ) ? 'r' : '-',
+                           (entry->protection & VM_PROT_WRITE) ? 'w' : '-',
+                           (entry->protection & VM_PROT_EXECUTE) ? 'x' : '-',
+                           (entry->etype & UVM_ET_COPYONWRITE) ? 'p' : 's',
+                           sizeof (void *) * 2,
+                           (unsigned long)entry->offset,
+                           major(dev), minor(dev), fileid, path);
+                       free(path, M_TEMP);
+               } else {
+                       snprintf(mebuffer, sizeof(mebuffer),
+                           "0x%lx 0x%lx %c%c%c %c%c%c %s %s %d %d %d\n",
+                           entry->start, entry->end,
+                           (entry->protection & VM_PROT_READ) ? 'r' : '-',
+                           (entry->protection & VM_PROT_WRITE) ? 'w' : '-',
+                           (entry->protection & VM_PROT_EXECUTE) ? 'x' : '-',
+                           (entry->max_protection & VM_PROT_READ) ? 'r' : '-',
+                           (entry->max_protection & VM_PROT_WRITE) ? 'w' : '-',
+                           (entry->max_protection & VM_PROT_EXECUTE) ?
+                               'x' : '-',
+                           (entry->etype & UVM_ET_COPYONWRITE) ?
+                               "COW" : "NCOW",
+                           (entry->etype & UVM_ET_NEEDSCOPY) ? "NC" : "NNC",
+                           entry->inheritance, entry->wired_count,
+                           entry->advice);
+               }
 
                len = strlen(mebuffer);
                if (len > uio->uio_resid) {
@@ -120,9 +170,56 @@
 }
 
 int
-procfs_validmap(p, mp)
-       struct proc *p;
-       struct mount *mp;
+procfs_validmap(struct proc *p, struct mount *mp)
 {
        return ((p->p_flag & P_SYSTEM) == 0);
 }
+
+/*
+ * Try to find a pathname for a vnode. Since there is no mapping
+ * vnode -> parent directory, this needs the NAMECACHE_ENTER_REVERSE
+ * option to work (to make cache_revlookup succeed).
+ */
+static int procfs_vnode_to_path(struct vnode *vp, char *path, int len,
+                               struct proc *curp, struct proc *p)
+{
+       int error, lenused, elen;
+       char *bp, *bend;
+       struct vnode *dvp;
+
+       bp = bend = &path[len];
+       *(--bp) = '\0';
+
+       error = vget(vp, LK_EXCLUSIVE | LK_RETRY);
+       if (error != 0)
+               return error;
+       error = cache_revlookup(vp, &dvp, &bp, path);
+       vput(vp);
+       if (error != 0)
+               return (error == -1 ? ENOENT : error);
+
+       error = vget(dvp, 0);
+       if (error != 0)
+               return error;
+       *(--bp) = '/';
+       /* XXX GETCWD_CHECK_ACCESS == 0x0001 */
+       error = getcwd_common(dvp, NULL, &bp, path, len / 2, 1, curp);
+
+       /*
+        * Strip off emulation path for emulated processes looking at
+        * the maps file of a process of the same emulation. (Won't
+        * work if /emul/xxx is a symlink..)
+        */
+       if (curp->p_emul == p->p_emul && curp->p_emul->e_path != NULL) {
+               elen = strlen(curp->p_emul->e_path);
+               if (!strncmp(bp, curp->p_emul->e_path, elen))
+                       bp = &bp[elen];
+       }
+
+       lenused = bend - bp;
+
+       memcpy(path, bp, lenused);
+       path[lenused] = 0;
+
+       return 0;
+}
diff -r 48bb82298008 -r fb25f5c2eb20 sys/miscfs/procfs/procfs_subr.c
--- a/sys/miscfs/procfs/procfs_subr.c   Thu Mar 29 22:40:06 2001 +0000
+++ b/sys/miscfs/procfs/procfs_subr.c   Thu Mar 29 22:41:52 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: procfs_subr.c,v 1.36 2001/01/18 20:28:21 jdolecek Exp $        */
+/*     $NetBSD: procfs_subr.c,v 1.37 2001/03/29 22:41:52 fvdl Exp $    */
 
 /*
  * Copyright (c) 1994 Christopher G. Demetriou.  All rights reserved.
@@ -156,6 +156,7 @@
                break;
 
        case Pmap:      /* /proc/N/map = -r--r--r-- */
+       case Pmaps:     /* /proc/N/maps = -r--r--r-- */
        case Pstatus:   /* /proc/N/status = -r--r--r-- */
        case Pcmdline:  /* /proc/N/cmdline = -r--r--r-- */
        case Pmeminfo:  /* /proc/meminfo = -r--r--r-- */
@@ -238,7 +239,10 @@
                return (procfs_dostatus(curp, p, pfs, uio));
 
        case Pmap:
-               return (procfs_domap(curp, p, pfs, uio));
+               return (procfs_domap(curp, p, pfs, uio, 0));
+
+       case Pmaps:
+               return (procfs_domap(curp, p, pfs, uio, 1));
 
        case Pmem:
                return (procfs_domem(curp, p, pfs, uio));
diff -r 48bb82298008 -r fb25f5c2eb20 sys/miscfs/procfs/procfs_vnops.c
--- a/sys/miscfs/procfs/procfs_vnops.c  Thu Mar 29 22:40:06 2001 +0000
+++ b/sys/miscfs/procfs/procfs_vnops.c  Thu Mar 29 22:41:52 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: procfs_vnops.c,v 1.78 2001/02/21 21:39:58 jdolecek Exp $       */
+/*     $NetBSD: procfs_vnops.c,v 1.79 2001/03/29 22:41:53 fvdl Exp $   */
 
 /*
  * Copyright (c) 1993 Jan-Simon Pendry
@@ -97,6 +97,7 @@
        { DT_REG, N("note"),    Pnote,          NULL },
        { DT_REG, N("notepg"),  Pnotepg,        NULL },
        { DT_REG, N("map"),     Pmap,           procfs_validmap },
+       { DT_REG, N("maps"),    Pmaps,          procfs_validmap },
        { DT_REG, N("cmdline"), Pcmdline,       NULL },
        { DT_REG, N("exe"),     Pfile,          procfs_validfile_linux },
 #undef N
@@ -552,6 +553,7 @@
        case Pnote:
        case Pnotepg:
        case Pmap:
+       case Pmaps:
        case Pcmdline:
                vap->va_nlink = 1;
                vap->va_uid = procp->p_ucred->cr_uid;
@@ -639,12 +641,19 @@
        case Pstatus:
        case Pnote:
        case Pnotepg:
-       case Pmap:
        case Pcmdline:
        case Pmeminfo:
        case Pcpuinfo:
                vap->va_bytes = vap->va_size = 0;
                break;
+       case Pmap:
+       case Pmaps:
+               /*
+                * Advise a larger blocksize for the map files, so that
+                * they may be read in one pass.
+                */
+               vap->va_blocksize = 2 *PAGE_SIZE;
+               break;
 
        default:
                panic("procfs_getattr");



Home | Main Index | Thread Index | Old Index