Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140559185
D35068.id105439.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D35068.id105439.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D35068: proc: Add new process hold facility.
Attached
Detach File
Event Timeline
Log In to Comment