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