Page MenuHomeFreeBSD

D35068.id105439.diff
No OneTemporary

D35068.id105439.diff

Index: sys/compat/linprocfs/linprocfs.c
===================================================================
--- sys/compat/linprocfs/linprocfs.c
+++ sys/compat/linprocfs/linprocfs.c
@@ -2033,7 +2033,8 @@
NULL, NULL, NULL, PFS_RD);
/* /proc/<pid>/... */
- dir = pfs_create_dir(root, "pid", NULL, NULL, NULL, PFS_PROCDEP);
+ dir = pfs_create_dir(root, "pid", NULL, NULL, NULL,
+ PFS_PROCDEP | PFS_ZOMBIE);
pfs_create_file(dir, "cmdline", &linprocfs_doproccmdline,
NULL, NULL, NULL, PFS_RD);
pfs_create_link(dir, "cwd", &linprocfs_doproccwd,
@@ -2057,7 +2058,7 @@
pfs_create_file(dir, "statm", &linprocfs_doprocstatm,
NULL, NULL, NULL, PFS_RD);
pfs_create_file(dir, "status", &linprocfs_doprocstatus,
- NULL, NULL, NULL, PFS_RD);
+ NULL, NULL, NULL, PFS_RD | PFS_ZOMBIE);
pfs_create_link(dir, "fd", &linprocfs_dofdescfs,
NULL, NULL, NULL, 0);
pfs_create_file(dir, "auxv", &linprocfs_doauxv,
Index: sys/fs/pseudofs/pseudofs.h
===================================================================
--- sys/fs/pseudofs/pseudofs.h
+++ sys/fs/pseudofs/pseudofs.h
@@ -79,6 +79,7 @@
#define PFS_PROCDEP 0x0010 /* process-dependent */
#define PFS_NOWAIT 0x0020 /* allow malloc to fail */
#define PFS_AUTODRAIN 0x0040 /* sbuf_print can sleep to drain */
+#define PFS_ZOMBIE 0x0080 /* zombie visibility */
/*
* Data structures
Index: sys/fs/pseudofs/pseudofs_internal.h
===================================================================
--- sys/fs/pseudofs/pseudofs_internal.h
+++ sys/fs/pseudofs/pseudofs_internal.h
@@ -94,6 +94,45 @@
return (err)
#endif
+#define PFS_VISIBILITY(x) (x->pn_flags & PFS_ZOMBIE)
+
+#define PFS_PROC_ASSERT_HELD(pn, p) \
+ do { \
+ if (PFS_VISIBILITY(pn)) \
+ KASSERT((p)->p_lockreap > 0, \
+ ("process %p not held", p)); \
+ else \
+ PROC_ASSERT_HELD(p); \
+ } while (0)
+#define _PFS_PHOLD(pn, p) \
+ do { \
+ if (PFS_VISIBILITY(pn)) { \
+ PROC_LOCK_ASSERT((p), MA_OWNED); \
+ (p)->p_lockreap++; \
+ } else \
+ _PHOLD(p); \
+ } while (0)
+#define _PFS_PRELE(pn, p) \
+ do { \
+ if (PFS_VISIBILITY(pn)) { \
+ PROC_LOCK_ASSERT((p), MA_OWNED); \
+ PFS_PROC_ASSERT_HELD(pn, p); \
+ (--(p)->p_lockreap); \
+ if ((p)->p_lockreap == 0) \
+ wakeup(&(p)->p_lockreap); \
+ } else \
+ _PRELE(p); \
+ } while (0)
+#define PFS_PRELE(pn, p) \
+ do { \
+ if (PFS_VISIBILITY(pn)) { \
+ PROC_LOCK(p); \
+ _PFS_PRELE(pn, p); \
+ PROC_UNLOCK(p); \
+ } else \
+ PRELE(p); \
+ } while (0)
+
/*
* Inline helpers for locking
*/
@@ -133,7 +172,7 @@
KASSERT(pn->pn_fill != NULL, ("%s(): no callback", __func__));
if (p != NULL) {
PROC_LOCK_ASSERT(p, MA_NOTOWNED);
- PROC_ASSERT_HELD(p);
+ PFS_PROC_ASSERT_HELD(pn, p);
}
pfs_assert_not_owned(pn);
return ((pn->pn_fill)(PFS_FILL_ARGNAMES));
Index: sys/fs/pseudofs/pseudofs_vnops.c
===================================================================
--- sys/fs/pseudofs/pseudofs_vnops.c
+++ sys/fs/pseudofs/pseudofs_vnops.c
@@ -84,6 +84,13 @@
return (pn->pn_fileno);
}
+static struct proc *
+pfs_pfind(pid_t pid, struct pfs_node *pn)
+{
+
+ return (PFS_VISIBILITY(pn) ? pfind_any(pid) : pfind(pid));
+}
+
/*
* Returns non-zero if given file is visible to given thread.
*/
@@ -97,7 +104,9 @@
PROC_LOCK_ASSERT(proc, MA_OWNED);
- visible = ((proc->p_flag & P_WEXIT) == 0);
+ visible = PFS_VISIBILITY(pn);
+ if (!visible)
+ visible = ((proc->p_flag & P_WEXIT) == 0);
if (visible)
visible = (p_cansee(td, proc) == 0);
if (visible && pn->pn_vis != NULL)
@@ -120,7 +129,7 @@
*p = NULL;
if (pid == NO_PID)
PFS_RETURN (1);
- proc = pfind(pid);
+ proc = pfs_pfind(pid, pn);
if (proc == NULL)
PFS_RETURN (0);
if (pfs_visible_proc(td, pn, proc)) {
@@ -135,18 +144,14 @@
}
static int
-pfs_lookup_proc(pid_t pid, struct proc **p)
+pfs_lookup_proc(struct pfs_node *pn, pid_t pid, struct proc **p)
{
struct proc *proc;
- proc = pfind(pid);
+ proc = pfs_pfind(pid, pn);
if (proc == NULL)
return (0);
- if ((proc->p_flag & P_WEXIT) != 0) {
- PROC_UNLOCK(proc);
- return (0);
- }
- _PHOLD(proc);
+ _PFS_PHOLD(pn, proc);
PROC_UNLOCK(proc);
*p = proc;
return (1);
@@ -197,7 +202,7 @@
PFS_RETURN (0);
if (pvd->pvd_pid != NO_PID) {
- proc = pfind(pvd->pvd_pid);
+ proc = pfs_pfind(pvd->pvd_pid, pn);
} else {
proc = NULL;
}
@@ -703,7 +708,7 @@
if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc))
PFS_RETURN (EIO);
if (proc != NULL) {
- _PHOLD(proc);
+ _PFS_PHOLD(pn, proc);
PROC_UNLOCK(proc);
}
@@ -781,7 +786,7 @@
vn_lock(vn, locked | LK_RETRY);
vdrop(vn);
if (proc != NULL)
- PRELE(proc);
+ PFS_PRELE(pn, proc);
PFS_RETURN (error);
}
@@ -881,7 +886,7 @@
PFS_RETURN (0);
proc = NULL;
- if (pid != NO_PID && !pfs_lookup_proc(pid, &proc))
+ if (pid != NO_PID && !pfs_lookup_proc(pd, pid, &proc))
PFS_RETURN (ENOENT);
sx_slock(&allproc_lock);
@@ -895,7 +900,7 @@
/* check if the directory is visible to the caller */
if (!pfs_visible_proc(curthread, pd, proc)) {
- _PRELE(proc);
+ _PFS_PRELE(pd, proc);
PROC_UNLOCK(proc);
sx_sunlock(&allproc_lock);
pfs_unlock(pd);
@@ -908,7 +913,7 @@
if (pfs_iterate(curthread, proc, pd, &pn, &p) == -1) {
/* nothing left... */
if (proc != NULL) {
- _PRELE(proc);
+ _PFS_PRELE(pd, proc);
PROC_UNLOCK(proc);
}
pfs_unlock(pd);
@@ -962,7 +967,7 @@
resid -= PFS_DELEN;
}
if (proc != NULL) {
- _PRELE(proc);
+ _PFS_PRELE(pd, proc);
PROC_UNLOCK(proc);
}
pfs_unlock(pd);
@@ -1004,13 +1009,9 @@
PFS_RETURN (EIO);
if (pvd->pvd_pid != NO_PID) {
- if ((proc = pfind(pvd->pvd_pid)) == NULL)
+ if ((proc = pfs_pfind(pvd->pvd_pid, pn)) == NULL)
PFS_RETURN (EIO);
- if (proc->p_flag & P_WEXIT) {
- PROC_UNLOCK(proc);
- PFS_RETURN (EIO);
- }
- _PHOLD(proc);
+ _PFS_PHOLD(pn, proc);
PROC_UNLOCK(proc);
}
vhold(vn);
@@ -1023,7 +1024,7 @@
error = pn_fill(curthread, proc, pn, &sb, NULL);
if (proc != NULL)
- PRELE(proc);
+ PFS_PRELE(pn, proc);
vn_lock(vn, locked | LK_RETRY);
vdrop(vn);
@@ -1112,29 +1113,26 @@
if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc))
PFS_RETURN (EIO);
if (proc != NULL) {
- _PHOLD(proc);
+ _PFS_PHOLD(pn, proc);
PROC_UNLOCK(proc);
}
if (pn->pn_flags & PFS_RAWWR) {
error = pn_fill(curthread, proc, pn, NULL, uio);
- if (proc != NULL)
- PRELE(proc);
- PFS_RETURN (error);
+ goto out;
}
sbuf_uionew(&sb, uio, &error);
- if (error) {
- if (proc != NULL)
- PRELE(proc);
- PFS_RETURN (error);
- }
+ if (error)
+ goto out;
error = pn_fill(curthread, proc, pn, &sb, uio);
sbuf_delete(&sb);
+
+out:
if (proc != NULL)
- PRELE(proc);
+ PFS_PRELE(pn, proc);
PFS_RETURN (error);
}
Index: sys/kern/kern_exit.c
===================================================================
--- sys/kern/kern_exit.c
+++ sys/kern/kern_exit.c
@@ -976,6 +976,15 @@
procdesc_reap(p);
sx_xunlock(&proctree_lock);
+ /*
+ * Wait for any processes that have a hold on our vmspace to
+ * release their reference.
+ */
+ PROC_LOCK(p);
+ while (p->p_lockreap > 0)
+ msleep(&p->p_lockreap, &p->p_mtx, PWAIT, "reaphold", 0);
+ PROC_UNLOCK(p);
+
proc_id_clear(PROC_ID_PID, p->p_pid);
PROC_LOCK(p);
Index: sys/kern/kern_thread.c
===================================================================
--- sys/kern/kern_thread.c
+++ sys/kern/kern_thread.c
@@ -117,11 +117,11 @@
"struct proc KBI p_flag");
_Static_assert(offsetof(struct proc, p_pid) == 0x78,
"struct proc KBI p_pid");
-_Static_assert(offsetof(struct proc, p_filemon) == 0x270,
+_Static_assert(offsetof(struct proc, p_filemon) == 0x274,
"struct proc KBI p_filemon");
-_Static_assert(offsetof(struct proc, p_comm) == 0x284,
+_Static_assert(offsetof(struct proc, p_comm) == 0x288,
"struct proc KBI p_comm");
-_Static_assert(offsetof(struct proc, p_emuldata) == 0x310,
+_Static_assert(offsetof(struct proc, p_emuldata) == 0x314,
"struct proc KBI p_emuldata");
#endif
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -675,6 +675,7 @@
struct vnode *p_textdvp; /* (b) Dir containing textvp. */
char *p_binname; /* (b) Binary hardlink name. */
u_int p_lock; /* (c) Proclock (prevent swap) count. */
+ uint32_t p_lockreap; /* (c) Proclock (prevent reap) count. */
struct sigiolst p_sigiolst; /* (c) List of sigio sources. */
int p_sigparent; /* (c) Signal to parent on exit. */
int p_sig; /* (n) For core dump/debugger XXX. */

File Metadata

Mime Type
text/plain
Expires
Fri, Dec 26, 6:33 AM (16 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27277291
Default Alt Text
D35068.id105439.diff (8 KB)

Event Timeline