summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2014-01-20 21:19:29 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2014-01-20 21:19:29 +0000
commitee0ecd963da884228886664033fd7694a2eb8316 (patch)
tree52a9fc57aabaf3a0c1918697e14b24bc5f30528e
parentd97b363c4b36ac6fd5d7bd23bce2badd8549c7ee (diff)
Threads can't be zombies, only processes, so change zombproc to zombprocess,
make it a list of processes, and change P_NOZOMBIE and P_STOPPED from thread flags to process flags. Add allprocess list for the code that just wants to see processes. ok tedu@
-rw-r--r--lib/libkvm/kvm_file2.c80
-rw-r--r--lib/libkvm/kvm_proc2.c178
-rw-r--r--sys/arch/sh/sh/db_interface.c11
-rw-r--r--sys/arch/sh/sh/pmap.c16
-rw-r--r--sys/compat/linux/linux_sched.c10
-rw-r--r--sys/kern/init_main.c13
-rw-r--r--sys/kern/kern_exit.c181
-rw-r--r--sys/kern/kern_fork.c22
-rw-r--r--sys/kern/kern_ktrace.c18
-rw-r--r--sys/kern/kern_proc.c79
-rw-r--r--sys/kern/kern_resource.c23
-rw-r--r--sys/kern/kern_sig.c27
-rw-r--r--sys/kern/kern_sysctl.c99
-rw-r--r--sys/miscfs/procfs/procfs_vnops.c31
-rw-r--r--sys/sys/proc.h25
15 files changed, 434 insertions, 379 deletions
diff --git a/lib/libkvm/kvm_file2.c b/lib/libkvm/kvm_file2.c
index b970247380e..bd18d4b1a0b 100644
--- a/lib/libkvm/kvm_file2.c
+++ b/lib/libkvm/kvm_file2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm_file2.c,v 1.32 2014/01/20 04:27:32 guenther Exp $ */
+/* $OpenBSD: kvm_file2.c,v 1.33 2014/01/20 21:19:28 guenther Exp $ */
/*
* Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -124,7 +124,7 @@ static int fill_file(kvm_t *, struct kinfo_file *, struct file *, u_long,
struct vnode *, struct proc *, int, pid_t);
static int filestat(kvm_t *, struct kinfo_file *, struct vnode *);
-LIST_HEAD(proclist, proc);
+LIST_HEAD(processlist, process);
struct kinfo_file *
kvm_getfiles(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
@@ -268,9 +268,9 @@ kvm_deadfile_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
struct filelist filehead;
struct filedesc0 filed0;
#define filed filed0.fd_fd
- struct proclist allproc;
- struct proc *p, proc, proc2;
- struct process process;
+ struct processlist allprocess;
+ struct proc proc, proc2;
+ struct process *pr, process;
struct pcred pcred;
struct ucred ucred;
char *filebuf = NULL;
@@ -279,7 +279,7 @@ kvm_deadfile_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
nl[0].n_name = "_filehead";
nl[1].n_name = "_nfiles";
- nl[2].n_name = "_allproc";
+ nl[2].n_name = "_allprocess";
nl[3].n_name = 0;
if (kvm_nlist(kd, nl) != 0) {
@@ -297,8 +297,8 @@ kvm_deadfile_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
_kvm_err(kd, kd->program, "can't read nfiles");
return (NULL);
}
- if (KREAD(kd, nl[2].n_value, &allproc)) {
- _kvm_err(kd, kd->program, "can't read allproc");
+ if (KREAD(kd, nl[2].n_value, &allprocess)) {
+ _kvm_err(kd, kd->program, "can't read allprocess");
return (NULL);
}
/* this may be more room than we need but counting is expensive */
@@ -308,52 +308,32 @@ kvm_deadfile_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
if (kd->filebase == NULL)
return (NULL);
- for (p = LIST_FIRST(&allproc);
- p != NULL;
- p = LIST_NEXT(&proc, p_list)) {
- if (KREAD(kd, (u_long)p, &proc)) {
- _kvm_err(kd, kd->program, "can't read proc at %lx",
- (u_long)p);
+ for (pr = LIST_FIRST(&allprocess);
+ pr != NULL;
+ pr = LIST_NEXT(&process, ps_list)) {
+ if (KREAD(kd, (u_long)pr, &process)) {
+ _kvm_err(kd, kd->program, "can't read process at %lx",
+ (u_long)pr);
goto cleanup;
}
- /* skip system, embryonic and undead processes */
- if ((proc.p_flag & P_SYSTEM) || (proc.p_flag & P_THREAD) ||
- proc.p_stat == SIDL || proc.p_stat == SZOMB)
+ if (process.ps_mainproc == NULL)
continue;
- if (op == KERN_FILE_BYPID) {
- if (arg > 0 && proc.p_pid != (pid_t)arg) {
- /* not the pid we are looking for */
- continue;
- }
- } else /* if (op == KERN_FILE_BYUID) */ {
- if (arg >= 0 && proc.p_ucred->cr_uid != (uid_t)arg) {
- /* not the uid we are looking for */
- continue;
- }
+ if (KREAD(kd, (u_long)process.ps_mainproc, &proc)) {
+ _kvm_err(kd, kd->program, "can't read proc at %lx",
+ (u_long)process.ps_mainproc);
+ goto cleanup;
}
- if (proc.p_fd == NULL || proc.p_p == NULL)
+ /* skip system, exiting, embryonic and undead processes */
+ if (proc.p_flag & P_SYSTEM || process.ps_flags & PS_EXITING ||
+ proc.p_stat == SIDL || proc.p_stat == SZOMB)
continue;
- if (KREAD(kd, (u_long)proc.p_p, &process)) {
- _kvm_err(kd, kd->program, "can't read process at %lx",
- (u_long)proc.p_p);
- goto cleanup;
- }
- if (process.ps_flags & PS_EXITING)
- continue;
- proc.p_p = &process;
- if ((proc.p_flag & P_THREAD) == 0)
- pid = proc.p_pid;
- else {
- if (KREAD(kd, (u_long)process.ps_mainproc, &proc2)) {
- _kvm_err(kd, kd->program,
- "can't read proc at %lx",
- (u_long)process.ps_mainproc);
- goto cleanup;
- }
- pid = proc2.p_pid;
+ if (op == KERN_FILE_BYPID && arg > 0 &&
+ proc.p_pid != (pid_t)arg) {
+ /* not the pid we are looking for */
+ continue;
}
if (KREAD(kd, (u_long)process.ps_cred, &pcred)) {
@@ -366,9 +346,17 @@ kvm_deadfile_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
(u_long)pcred.pc_ucred);
goto cleanup;
}
+ process.ps_mainproc = &proc;
+ proc.p_p = &process;
process.ps_cred = &pcred;
pcred.pc_ucred = &ucred;
+ if (op == KERN_FILE_BYUID && arg >= 0 &&
+ proc.p_ucred->cr_uid != (uid_t)arg) {
+ /* not the uid we are looking for */
+ continue;
+ }
+
if (KREAD(kd, (u_long)proc.p_fd, &filed0)) {
_kvm_err(kd, kd->program, "can't read filedesc at %lx",
(u_long)proc.p_fd);
diff --git a/lib/libkvm/kvm_proc2.c b/lib/libkvm/kvm_proc2.c
index 4a9604e5dc6..b3c3feb0600 100644
--- a/lib/libkvm/kvm_proc2.c
+++ b/lib/libkvm/kvm_proc2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm_proc2.c,v 1.17 2013/11/12 14:49:41 guenther Exp $ */
+/* $OpenBSD: kvm_proc2.c,v 1.18 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: kvm_proc.c,v 1.30 1999/03/24 05:50:50 mrg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -103,14 +103,14 @@
* at most maxcnt procs.
*/
static int
-kvm_proclist(kvm_t *kd, int op, int arg, struct proc *p,
+kvm_proclist(kvm_t *kd, int op, int arg, struct process *pr,
char *bp, int maxcnt, size_t esize)
{
struct kinfo_proc kp;
struct session sess;
struct pcred pcred;
struct ucred ucred;
- struct proc proc, proc2;
+ struct proc proc, proc2, *p;
struct process process, process2;
struct pgrp pgrp;
struct tty tty;
@@ -124,33 +124,30 @@ kvm_proclist(kvm_t *kd, int op, int arg, struct proc *p,
dothreads = op & KERN_PROC_SHOW_THREADS;
op &= ~KERN_PROC_SHOW_THREADS;
- for (; cnt < maxcnt && p != NULL; p = LIST_NEXT(&proc, p_list)) {
- if (KREAD(kd, (u_long)p, &proc)) {
- _kvm_err(kd, kd->program, "can't read proc at %lx",
- (u_long)p);
+ /*
+ * Modelled on sysctl_doproc() in sys/kern/kern_sysctl.c
+ */
+ for (; cnt < maxcnt && pr != NULL; pr = LIST_NEXT(&process, ps_list)) {
+ if (KREAD(kd, (u_long)pr, &process)) {
+ _kvm_err(kd, kd->program, "can't read process at %lx",
+ (u_long)pr);
return (-1);
}
- if (KREAD(kd, (u_long)proc.p_p, &process)) {
- _kvm_err(kd, kd->program, "can't read process at %lx",
- (u_long)proc.p_p);
+ if (process.ps_pgrp == NULL)
+ continue;
+ if (KREAD(kd, (u_long)process.ps_mainproc, &proc)) {
+ _kvm_err(kd, kd->program, "can't read proc at %lx",
+ (u_long)process.ps_mainproc);
return (-1);
}
+ if (proc.p_stat == SIDL)
+ continue;
if (KREAD(kd, (u_long)process.ps_cred, &pcred)) {
_kvm_err(kd, kd->program, "can't read pcred at %lx",
(u_long)process.ps_cred);
return (-1);
}
- if ((proc.p_flag & P_THREAD) == 0)
- process_pid = proc.p_pid;
- else {
- if (KREAD(kd, (u_long)process.ps_mainproc, &proc2)) {
- _kvm_err(kd, kd->program,
- "can't read proc at %lx",
- (u_long)process.ps_mainproc);
- return (-1);
- }
- process_pid = proc2.p_pid;
- }
+ process_pid = proc.p_pid;
if (KREAD(kd, (u_long)pcred.pc_ucred, &ucred)) {
_kvm_err(kd, kd->program, "can't read ucred at %lx",
(u_long)pcred.pc_ucred);
@@ -277,24 +274,80 @@ kvm_proclist(kvm_t *kd, int op, int arg, struct proc *p,
}
/* set up stuff that might not always be there */
- vmp = &vm;
- if (proc.p_stat == SIDL ||
- P_ZOMBIE(&proc) ||
- KREAD(kd, (u_long)proc.p_vmspace, &vm))
- vmp = NULL;
-
limp = &limits;
if (!process.ps_limit ||
KREAD(kd, (u_long)process.ps_limit, &limits))
limp = NULL;
+ vmp = NULL;
+
+ if (proc.p_stat != SIDL && !P_ZOMBIE(&proc) &&
+ !KREAD(kd, (u_long)proc.p_vmspace, &vm))
+ vmp = &vm;
+
#define do_copy_str(_d, _s, _l) kvm_read(kd, (u_long)(_s), (_d), (_l)-1)
- if ((proc.p_flag & P_THREAD) == 0) {
+ FILL_KPROC(&kp, do_copy_str, &proc, &process, &pcred,
+ &ucred, &pgrp, p, proc.p_p, &sess, vmp, limp, sap,
+ 0, 1);
+
+ /* stuff that's too painful to generalize */
+ kp.p_pid = process_pid;
+ kp.p_ppid = parent_pid;
+ kp.p_sid = leader_pid;
+ if ((process.ps_flags & PS_CONTROLT) && sess.s_ttyp != NULL) {
+ kp.p_tdev = tty.t_dev;
+ if (tty.t_pgrp != NULL &&
+ tty.t_pgrp != process.ps_pgrp &&
+ KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) {
+ _kvm_err(kd, kd->program,
+ "can't read tpgrp at %lx",
+ (u_long)tty.t_pgrp);
+ return (-1);
+ }
+ kp.p_tpgid = tty.t_pgrp ? pgrp.pg_id : -1;
+ kp.p_tsess = PTRTOINT64(tty.t_session);
+ } else {
+ kp.p_tpgid = -1;
+ kp.p_tdev = NODEV;
+ }
+
+ /* update %cpu for all threads */
+ if (!dothreads) {
+ for (p = TAILQ_FIRST(&process.ps_threads); p != NULL;
+ p = TAILQ_NEXT(&proc, p_thr_link)) {
+ if (KREAD(kd, (u_long)p, &proc)) {
+ _kvm_err(kd, kd->program,
+ "can't read proc at %lx",
+ (u_long)p);
+ return (-1);
+ }
+ if (p == process.ps_mainproc)
+ continue;
+ kp.p_pctcpu += proc.p_pctcpu;
+ }
+ }
+
+ memcpy(bp, &kp, esize);
+ bp += esize;
+ ++cnt;
+
+ /* Skip per-thread entries if not required by op */
+ if (!dothreads)
+ continue;
+
+ for (p = TAILQ_FIRST(&process.ps_threads); p != NULL;
+ p = TAILQ_NEXT(&proc, p_thr_link)) {
+ if (KREAD(kd, (u_long)p, &proc)) {
+ _kvm_err(kd, kd->program,
+ "can't read proc at %lx",
+ (u_long)p);
+ return (-1);
+ }
FILL_KPROC(&kp, do_copy_str, &proc, &process, &pcred,
&ucred, &pgrp, p, proc.p_p, &sess, vmp, limp, sap,
- 0, 1);
+ 1, 1);
- /* stuff that's too painful to generalize */
+ /* see above */
kp.p_pid = process_pid;
kp.p_ppid = parent_pid;
kp.p_sid = leader_pid;
@@ -315,37 +368,6 @@ kvm_proclist(kvm_t *kd, int op, int arg, struct proc *p,
kp.p_tpgid = -1;
kp.p_tdev = NODEV;
}
-
- memcpy(bp, &kp, esize);
- bp += esize;
- ++cnt;
- }
-
- if (!dothreads)
- continue;
-
- FILL_KPROC(&kp, do_copy_str, &proc, &process, &pcred, &ucred,
- &pgrp, p, proc.p_p, &sess, vmp, limp, sap, 1, 1);
-
- /* stuff that's too painful to generalize into the macros */
- kp.p_pid = process_pid;
- kp.p_ppid = parent_pid;
- kp.p_sid = leader_pid;
- if ((process.ps_flags & PS_CONTROLT) && sess.s_ttyp != NULL) {
- kp.p_tdev = tty.t_dev;
- if (tty.t_pgrp != NULL &&
- tty.t_pgrp != process.ps_pgrp &&
- KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) {
- _kvm_err(kd, kd->program,
- "can't read tpgrp at %lx",
- (u_long)tty.t_pgrp);
- return (-1);
- }
- kp.p_tpgid = tty.t_pgrp ? pgrp.pg_id : -1;
- kp.p_tsess = PTRTOINT64(tty.t_session);
- } else {
- kp.p_tpgid = -1;
- kp.p_tdev = NODEV;
}
memcpy(bp, &kp, esize);
@@ -399,9 +421,9 @@ kvm_getprocs(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
}
nthreads = size / esize;
} else {
- struct nlist nl[4];
- int i, maxthread;
- struct proc *p;
+ struct nlist nl[5];
+ int i, maxthread, maxprocess;
+ struct process *pr;
char *bp;
if (esize > sizeof(struct kinfo_proc)) {
@@ -412,9 +434,10 @@ kvm_getprocs(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
memset(nl, 0, sizeof(nl));
nl[0].n_name = "_nthreads";
- nl[1].n_name = "_allproc";
- nl[2].n_name = "_zombproc";
- nl[3].n_name = NULL;
+ nl[1].n_name = "_nprocesses";
+ nl[2].n_name = "_allprocess";
+ nl[3].n_name = "_zombprocess";
+ nl[4].n_name = NULL;
if (kvm_nlist(kd, nl) != 0) {
for (i = 0; nl[i].n_type != 0; ++i)
@@ -427,27 +450,32 @@ kvm_getprocs(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
_kvm_err(kd, kd->program, "can't read nthreads");
return (NULL);
}
+ if (KREAD(kd, nl[1].n_value, &maxprocess)) {
+ _kvm_err(kd, kd->program, "can't read nprocesses");
+ return (NULL);
+ }
+ maxthread += maxprocess;
kd->procbase = _kvm_malloc(kd, maxthread * esize);
if (kd->procbase == 0)
return (NULL);
bp = (char *)kd->procbase;
- /* allproc */
- if (KREAD(kd, nl[1].n_value, &p)) {
- _kvm_err(kd, kd->program, "cannot read allproc");
+ /* allprocess */
+ if (KREAD(kd, nl[2].n_value, &pr)) {
+ _kvm_err(kd, kd->program, "cannot read allprocess");
return (NULL);
}
- nthreads = kvm_proclist(kd, op, arg, p, bp, maxthread, esize);
+ nthreads = kvm_proclist(kd, op, arg, pr, bp, maxthread, esize);
if (nthreads < 0)
return (NULL);
- /* zombproc */
- if (KREAD(kd, nl[2].n_value, &p)) {
- _kvm_err(kd, kd->program, "cannot read zombproc");
+ /* zombprocess */
+ if (KREAD(kd, nl[3].n_value, &pr)) {
+ _kvm_err(kd, kd->program, "cannot read zombprocess");
return (NULL);
}
- i = kvm_proclist(kd, op, arg, p, bp + (esize * nthreads),
+ i = kvm_proclist(kd, op, arg, pr, bp + (esize * nthreads),
maxthread - nthreads, esize);
if (i > 0)
nthreads += i;
diff --git a/sys/arch/sh/sh/db_interface.c b/sys/arch/sh/sh/db_interface.c
index b74e46673ea..5b69acf7068 100644
--- a/sys/arch/sh/sh/db_interface.c
+++ b/sys/arch/sh/sh/db_interface.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_interface.c,v 1.3 2010/04/21 03:03:26 deraadt Exp $ */
+/* $OpenBSD: db_interface.c,v 1.4 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: db_interface.c,v 1.37 2006/09/06 00:11:49 uwe Exp $ */
/*-
@@ -368,10 +368,15 @@ char *
__db_procname_by_asid(int asid)
{
static char notfound[] = "---";
+ struct process *pr;
struct proc *p;
- LIST_FOREACH(p, &allproc, p_list) {
- if (p->p_vmspace->vm_map.pmap->pm_asid == asid)
+ LIST_FOREACH(pr, &allprocess, ps_list) {
+ /* find a thread that still has the process vmspace attached */
+ TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link)
+ if (p->p_vmspace != NULL)
+ break;
+ if (p != NULL && p->p_vmspace->vm_map.pmap->pm_asid == asid)
return (p->p_comm);
}
diff --git a/sys/arch/sh/sh/pmap.c b/sys/arch/sh/sh/pmap.c
index a79035a7874..085df11e5fc 100644
--- a/sys/arch/sh/sh/pmap.c
+++ b/sys/arch/sh/sh/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.20 2013/03/02 22:44:47 guenther Exp $ */
+/* $OpenBSD: pmap.c,v 1.21 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: pmap.c,v 1.55 2006/08/07 23:19:36 tsutsui Exp $ */
/*-
@@ -1066,6 +1066,7 @@ __pmap_pte_load(pmap_t pmap, vaddr_t va, int flags)
int
__pmap_asid_alloc()
{
+ struct process *pr;
struct proc *p;
int i, j, k, n, map, asid;
@@ -1085,7 +1086,18 @@ __pmap_asid_alloc()
}
/* Steal ASID */
- LIST_FOREACH(p, &allproc, p_list) {
+ /*
+ * XXX this always steals the ASID of the *newest* proc with one,
+ * so it's far from LRU but rather almost pessimal once you have
+ * too many processes.
+ */
+ LIST_FOREACH(pr, &allprocess, ps_list) {
+ /* find a thread that still has the process vmspace attached */
+ TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link)
+ if (p->p_vmspace != NULL)
+ break;
+ if (p == NULL)
+ continue;
if ((asid = p->p_vmspace->vm_map.pmap->pm_asid) > 0) {
pmap_t pmap = p->p_vmspace->vm_map.pmap;
pmap->pm_asid = -1;
diff --git a/sys/compat/linux/linux_sched.c b/sys/compat/linux/linux_sched.c
index 599dc9ffc7a..04fb2fec1b8 100644
--- a/sys/compat/linux/linux_sched.c
+++ b/sys/compat/linux/linux_sched.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_sched.c,v 1.14 2012/05/25 04:39:40 guenther Exp $ */
+/* $OpenBSD: linux_sched.c,v 1.15 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: linux_sched.c,v 1.6 2000/05/28 05:49:05 thorpej Exp $ */
/*-
@@ -110,13 +110,7 @@ linux_sys_clone(struct proc *p, void *v, register_t *retval)
LINUX_CLONE_VFORK
if ((cflags & (REQUIRED | BANNED)) != REQUIRED)
return (EINVAL);
- /*
- * Linux says that CLONE_THREAD means no signal
- * will be sent on exit (even if a non-standard
- * signal is requested via CLONE_CSIGNAL), so pass
- * FORK_NOZOMBIE too.
- */
- flags |= FORK_THREAD | FORK_NOZOMBIE;
+ flags |= FORK_THREAD;
} else {
/*
* These are only supported with CLONE_THREAD. Arguably,
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 14dff21a4d4..7e35cf205d2 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.202 2014/01/19 23:52:54 deraadt Exp $ */
+/* $OpenBSD: init_main.c,v 1.203 2014/01/20 21:19:27 guenther Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -266,6 +266,7 @@ main(void *framep)
TAILQ_INSERT_TAIL(&process0.ps_threads, p, p_thr_link);
process0.ps_refcnt = 1;
p->p_p = pr = &process0;
+ LIST_INSERT_HEAD(&allprocess, pr, ps_list);
/* Set the default routing table/domain. */
process0.ps_rtableid = 0;
@@ -492,10 +493,12 @@ main(void *framep)
* munched in mi_switch() after the time got set.
*/
nanotime(&boottime);
- LIST_FOREACH(p, &allproc, p_list) {
- p->p_p->ps_start = boottime;
- nanouptime(&p->p_cpu->ci_schedstate.spc_runtime);
- timespecclear(&p->p_rtime);
+ LIST_FOREACH(pr, &allprocess, ps_list) {
+ pr->ps_start = boottime;
+ TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
+ nanouptime(&p->p_cpu->ci_schedstate.spc_runtime);
+ timespecclear(&p->p_rtime);
+ }
}
uvm_swap_init();
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 40366f27390..eabd41c4dd6 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exit.c,v 1.130 2014/01/20 03:23:42 guenther Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.131 2014/01/20 21:19:27 guenther Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
@@ -235,6 +235,14 @@ exit1(struct proc *p, int rv, int flags)
if (pr->ps_tracevp)
ktrcleartrace(pr);
#endif
+
+ /*
+ * If parent has the SAS_NOCLDWAIT flag set, we're not
+ * going to become a zombie.
+ */
+ if (pr->ps_pptr->ps_mainproc->p_sigacts->ps_flags &
+ SAS_NOCLDWAIT)
+ atomic_setbits_int(&pr->ps_flags, PS_NOZOMBIE);
}
#if NSYSTRACE > 0
@@ -249,12 +257,13 @@ exit1(struct proc *p, int rv, int flags)
(*p->p_emul->e_proc_exit)(p);
/*
- * Remove proc from pidhash chain so looking it up won't
- * work. Move it from allproc to zombproc, but do not yet
- * wake up the reaper. We will put the proc on the
- * deadproc list later (using the p_hash member), and
- * wake up the reaper when we do.
- */
+ * Remove proc from pidhash chain and allproc so looking
+ * it up won't work. We will put the proc on the
+ * deadproc list later (using the p_hash member), and
+ * wake up the reaper when we do. If this is the last
+ * thread of a process that isn't PS_NOZOMBIE, we'll put
+ * the process on the zombprocess list below.
+ */
/*
* NOTE: WE ARE NO LONGER ALLOWED TO SLEEP!
*/
@@ -262,12 +271,24 @@ exit1(struct proc *p, int rv, int flags)
LIST_REMOVE(p, p_hash);
LIST_REMOVE(p, p_list);
- LIST_INSERT_HEAD(&zombproc, p, p_list);
- /*
- * Give orphaned children to init(8).
- */
if ((p->p_flag & P_THREAD) == 0) {
+ LIST_REMOVE(pr, ps_list);
+
+ if ((pr->ps_flags & PS_NOZOMBIE) == 0)
+ LIST_INSERT_HEAD(&zombprocess, pr, ps_list);
+ else {
+ /*
+ * Not going to be a zombie, so it's now off all
+ * the lists scanned by ispidtaken(), so block
+ * fast reuse of the pid now.
+ */
+ freepid(p->p_pid);
+ }
+
+ /*
+ * Give orphaned children to init(8).
+ */
qr = LIST_FIRST(&pr->ps_children);
if (qr) /* only need this if any child is S_ZOMB */
wakeup(initproc->p_p);
@@ -295,7 +316,6 @@ exit1(struct proc *p, int rv, int flags)
}
}
-
/* add thread's accumulated rusage into the process's total */
ruadd(rup, &p->p_ru);
@@ -316,21 +336,14 @@ exit1(struct proc *p, int rv, int flags)
knote_processexit(pr);
/*
- * Notify parent that we're gone. If we have P_NOZOMBIE
- * or parent has the SAS_NOCLDWAIT flag set, notify process 1
- * instead (and hope it will handle this situation).
+ * Notify parent that we're gone. If we're not going to
+ * become a zombie, reparent to process 1 (init) so that
+ * we can wake our original parent to possibly unblock
+ * wait4() to return ECHILD.
*/
- if ((p->p_flag & P_NOZOMBIE) ||
- (pr->ps_pptr->ps_mainproc->p_sigacts->ps_flags &
- SAS_NOCLDWAIT)) {
+ if (pr->ps_flags & PS_NOZOMBIE) {
struct process *ppr = pr->ps_pptr;
proc_reparent(pr, initproc->p_p);
-
- /*
- * Notify parent, so in case he was wait(2)ing or
- * executing waitpid(2) with our pid, he will
- * continue.
- */
wakeup(ppr);
}
}
@@ -340,6 +353,14 @@ exit1(struct proc *p, int rv, int flags)
*/
sigactsfree(p);
+ /* just a thread? detach it from its process */
+ if (p->p_flag & P_THREAD) {
+ /* scheduler_wait_hook(pr->ps_mainproc, p); XXX */
+ --pr->ps_refcnt;
+ KASSERT(pr->ps_refcnt > 0);
+ p->p_p = NULL;
+ }
+
/*
* Other substructures are freed from reaper and wait().
*/
@@ -363,8 +384,7 @@ exit1(struct proc *p, int rv, int flags)
* Locking of this proclist is special; it's accessed in a
* critical section of process exit, and thus locking it can't
* modify interrupt state. We use a simple spin lock for this
- * proclist. Processes on this proclist are also on zombproc;
- * we use the p_hash member to linkup to deadproc.
+ * proclist. We use the p_hash member to linkup to deadproc.
*/
struct mutex deadproc_mutex = MUTEX_INITIALIZER(IPL_NONE);
struct proclist deadproc = LIST_HEAD_INITIALIZER(deadproc);
@@ -390,6 +410,13 @@ exit2(struct proc *p)
wakeup(&deadproc);
}
+void
+proc_free(struct proc *p)
+{
+ pool_put(&proc_pool, p);
+ nthreads--;
+}
+
/*
* Process reaper. This is run by a kernel thread to free the resources
* of a dead process. Once the resources are free, the process becomes
@@ -422,17 +449,25 @@ reaper(void)
*/
uvm_exit(p);
- /* Process is now a true zombie. */
- if ((p->p_flag & P_NOZOMBIE) == 0) {
- p->p_stat = SZOMB;
-
- if (P_EXITSIG(p) != 0)
- prsignal(p->p_p->ps_pptr, P_EXITSIG(p));
- /* Wake up the parent so it can get exit status. */
- wakeup(p->p_p->ps_pptr);
+ if (p->p_flag & P_THREAD) {
+ /* Just a thread */
+ proc_free(p);
} else {
- /* Noone will wait for us. Just zap the process now */
- proc_zap(p);
+ struct process *pr = p->p_p;
+
+ if ((pr->ps_flags & PS_NOZOMBIE) == 0) {
+ /* Process is now a true zombie. */
+ p->p_stat = SZOMB;
+
+ if (P_EXITSIG(p) != 0)
+ prsignal(pr->ps_pptr, P_EXITSIG(p));
+
+ /* Wake up the parent so it can get exit status. */
+ wakeup(pr->ps_pptr);
+ } else {
+ /* No one will wait for us. Just zap the process now */
+ process_zap(pr);
+ }
}
KERNEL_UNLOCK();
@@ -481,7 +516,7 @@ loop:
nfound = 0;
LIST_FOREACH(pr, &q->p_p->ps_children, ps_sibling) {
p = pr->ps_mainproc;
- if ((p->p_flag & P_NOZOMBIE) ||
+ if ((pr->ps_flags & PS_NOZOMBIE) ||
(pid != WAIT_ANY &&
p->p_pid != pid &&
pr->ps_pgid != -pid))
@@ -489,7 +524,7 @@ loop:
/*
* Wait for processes with p_exitsig != SIGCHLD processes only
- * if WALTSIG is set; wait for processes with pexitsig ==
+ * if WALTSIG is set; wait for processes with p_exitsig ==
* SIGCHLD only if WALTSIG is clear.
*/
if ((options & WALTSIG) ?
@@ -561,8 +596,7 @@ proc_finish_wait(struct proc *waiter, struct proc *p)
* we need to give it back to the old parent.
*/
pr = p->p_p;
- if ((p->p_flag & P_THREAD) == 0 && pr->ps_oppid &&
- (tr = prfind(pr->ps_oppid))) {
+ if (pr->ps_oppid && (tr = prfind(pr->ps_oppid))) {
atomic_clearbits_int(&pr->ps_flags, PS_TRACED);
pr->ps_oppid = 0;
proc_reparent(pr, tr);
@@ -574,7 +608,9 @@ proc_finish_wait(struct proc *waiter, struct proc *p)
p->p_xstat = 0;
rup = &waiter->p_p->ps_cru;
ruadd(rup, pr->ps_ru);
- proc_zap(p);
+ LIST_REMOVE(pr, ps_list); /* off zombprocess */
+ freepid(p->p_pid);
+ process_zap(pr);
}
}
@@ -597,52 +633,41 @@ proc_reparent(struct process *child, struct process *parent)
}
void
-proc_zap(struct proc *p)
+process_zap(struct process *pr)
{
- struct process *pr = p->p_p;
struct vnode *otvp;
+ struct proc *p = pr->ps_mainproc;
/*
* Finally finished with old proc entry.
* Unlink it from its process group and free it.
*/
- if ((p->p_flag & P_THREAD) == 0)
- leavepgrp(pr);
- LIST_REMOVE(p, p_list); /* off zombproc */
- if ((p->p_flag & P_THREAD) == 0) {
- LIST_REMOVE(pr, ps_sibling);
-
- /*
- * Decrement the count of procs running with this uid.
- */
- (void)chgproccnt(p->p_cred->p_ruid, -1);
-
- /*
- * Release reference to text vnode
- */
- otvp = pr->ps_textvp;
- pr->ps_textvp = NULL;
- if (otvp)
- vrele(otvp);
- }
+ leavepgrp(pr);
+ LIST_REMOVE(pr, ps_sibling);
/*
- * Remove us from our process list, possibly killing the process
- * in the process (pun intended).
+ * Decrement the count of procs running with this uid.
*/
- if (--pr->ps_refcnt == 0) {
- if (pr->ps_ptstat != NULL)
- free(pr->ps_ptstat, M_SUBPROC);
- pool_put(&rusage_pool, pr->ps_ru);
- KASSERT(TAILQ_EMPTY(&pr->ps_threads));
- limfree(pr->ps_limit);
- crfree(pr->ps_cred->pc_ucred);
- pool_put(&pcred_pool, pr->ps_cred);
- pool_put(&process_pool, pr);
- nprocesses--;
- }
+ (void)chgproccnt(pr->ps_cred->p_ruid, -1);
- freepid(p->p_pid);
- pool_put(&proc_pool, p);
- nthreads--;
+ /*
+ * Release reference to text vnode
+ */
+ otvp = pr->ps_textvp;
+ pr->ps_textvp = NULL;
+ if (otvp)
+ vrele(otvp);
+
+ KASSERT(pr->ps_refcnt == 1);
+ if (pr->ps_ptstat != NULL)
+ free(pr->ps_ptstat, M_SUBPROC);
+ pool_put(&rusage_pool, pr->ps_ru);
+ KASSERT(TAILQ_EMPTY(&pr->ps_threads));
+ limfree(pr->ps_limit);
+ crfree(pr->ps_cred->pc_ucred);
+ pool_put(&pcred_pool, pr->ps_cred);
+ pool_put(&process_pool, pr);
+ nprocesses--;
+
+ proc_free(p);
}
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 5a426374126..9188a7d50a3 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.155 2014/01/20 03:23:42 guenther Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.156 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -134,7 +134,7 @@ sys___tfork(struct proc *p, void *v, register_t *retval)
#endif
flags = FORK_TFORK | FORK_THREAD | FORK_SIGHAND | FORK_SHAREVM
- | FORK_NOZOMBIE | FORK_SHAREFILES;
+ | FORK_SHAREFILES;
return (fork1(p, 0, flags, param.tf_stack, param.tf_tid,
tfork_child_return, param.tf_tcb, retval, NULL));
@@ -195,6 +195,9 @@ process_new(struct proc *p, struct process *parent)
atomic_setbits_int(&pr->ps_flags, PS_CONTROLT);
p->p_p = pr;
+
+ /* it's sufficiently inited to be globally visible */
+ LIST_INSERT_HEAD(&allprocess, pr, ps_list);
}
/* print the 'table full' message once per 10 seconds */
@@ -220,8 +223,7 @@ fork1(struct proc *curp, int exitsig, int flags, void *stack, pid_t *tidptr,
/* sanity check some flag combinations */
if (flags & FORK_THREAD) {
- if ((flags & (FORK_SIGHAND | FORK_NOZOMBIE)) !=
- (FORK_SIGHAND | FORK_NOZOMBIE))
+ if ((flags & FORK_SIGHAND) == 0)
return (EINVAL);
}
if (flags & FORK_SIGHAND && (flags & FORK_SHAREVM) == 0)
@@ -330,6 +332,8 @@ fork1(struct proc *curp, int exitsig, int flags, void *stack, pid_t *tidptr,
startprofclock(pr);
if ((flags & FORK_PTRACE) && (curpr->ps_flags & PS_TRACED))
atomic_setbits_int(&pr->ps_flags, PS_TRACED);
+ if (flags & FORK_NOZOMBIE)
+ atomic_setbits_int(&pr->ps_flags, PS_NOZOMBIE);
}
if (flags & FORK_SHAREFILES)
@@ -341,8 +345,6 @@ fork1(struct proc *curp, int exitsig, int flags, void *stack, pid_t *tidptr,
atomic_setbits_int(&pr->ps_flags, PS_PPWAIT);
atomic_setbits_int(&curpr->ps_flags, PS_ISPWAIT);
}
- if (flags & FORK_NOZOMBIE)
- atomic_setbits_int(&p->p_flag, P_NOZOMBIE);
#ifdef KTRACE
/*
@@ -538,7 +540,7 @@ int
ispidtaken(pid_t pid)
{
uint32_t i;
- struct proc *p;
+ struct process *pr;
for (i = 0; i < nitems(oldpids); i++)
if (pid == oldpids[i])
@@ -548,9 +550,9 @@ ispidtaken(pid_t pid)
return (1);
if (pgfind(pid) != NULL)
return (1);
- LIST_FOREACH(p, &zombproc, p_list) {
- if (p->p_pid == pid ||
- (p->p_p->ps_pgrp && p->p_p->ps_pgrp->pg_id == pid))
+ LIST_FOREACH(pr, &zombprocess, ps_list) {
+ if (pr->ps_pid == pid ||
+ (pr->ps_pgrp && pr->ps_pgrp->pg_id == pid))
return (1);
}
return (0);
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 50e29d13398..da050c9e7fd 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_ktrace.c,v 1.61 2013/09/14 02:28:01 guenther Exp $ */
+/* $OpenBSD: kern_ktrace.c,v 1.62 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: kern_ktrace.c,v 1.23 1996/02/09 18:59:36 christos Exp $ */
/*
@@ -403,7 +403,6 @@ sys_ktrace(struct proc *curp, void *v, register_t *retval)
syscallarg(pid_t) pid;
} */ *uap = v;
struct vnode *vp = NULL;
- struct proc *p = NULL;
struct process *pr = NULL;
struct ucred *cred = NULL;
struct pgrp *pg;
@@ -437,10 +436,10 @@ sys_ktrace(struct proc *curp, void *v, register_t *retval)
* Clear all uses of the tracefile
*/
if (ops == KTROP_CLEARFILE) {
- LIST_FOREACH(p, &allproc, p_list) {
- if (p->p_p->ps_tracevp == vp) {
- if (ktrcanset(curp, p->p_p))
- ktrcleartrace(p->p_p);
+ LIST_FOREACH(pr, &allprocess, ps_list) {
+ if (pr->ps_tracevp == vp) {
+ if (ktrcanset(curp, pr))
+ ktrcleartrace(pr);
else
error = EPERM;
}
@@ -587,6 +586,7 @@ ktrwriteraw(struct proc *p, struct vnode *vp, struct ucred *cred,
{
struct uio auio;
struct iovec aiov[2];
+ struct process *pr;
int error;
auio.uio_iov = &aiov[0];
@@ -615,9 +615,9 @@ ktrwriteraw(struct proc *p, struct vnode *vp, struct ucred *cred,
*/
log(LOG_NOTICE, "ktrace write failed, errno %d, tracing stopped\n",
error);
- LIST_FOREACH(p, &allproc, p_list)
- if (p->p_p->ps_tracevp == vp && p->p_p->ps_tracecred == cred)
- ktrcleartrace(p->p_p);
+ LIST_FOREACH(pr, &allprocess, ps_list)
+ if (pr->ps_tracevp == vp && pr->ps_tracecred == cred)
+ ktrcleartrace(pr);
vput(vp);
return (error);
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 4d028a557c6..a22597aa23e 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_proc.c,v 1.54 2013/10/02 21:17:32 sf Exp $ */
+/* $OpenBSD: kern_proc.c,v 1.55 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */
/*
@@ -60,8 +60,9 @@ struct pidhashhead *pidhashtbl;
u_long pidhash;
struct pgrphashhead *pgrphashtbl;
u_long pgrphash;
+struct processlist allprocess;
+struct processlist zombprocess;
struct proclist allproc;
-struct proclist zombproc;
struct pool proc_pool;
struct pool process_pool;
@@ -82,8 +83,9 @@ void pgrpdump(void);
void
procinit(void)
{
+ LIST_INIT(&allprocess);
+ LIST_INIT(&zombprocess);
LIST_INIT(&allproc);
- LIST_INIT(&zombproc);
pidhashtbl = hashinit(maxthread / 4, M_PROC, M_NOWAIT, &pidhash);
@@ -437,7 +439,7 @@ db_show_all_procs(db_expr_t addr, int haddr, db_expr_t count, char *modif)
return;
}
- p = LIST_FIRST(&allproc);
+ pr = LIST_FIRST(&allprocess);
switch (*mode) {
@@ -455,45 +457,46 @@ db_show_all_procs(db_expr_t addr, int haddr, db_expr_t count, char *modif)
break;
}
- while (p != 0) {
- pr = p->p_p;
+ while (pr != NULL) {
ppr = pr->ps_pptr;
- if (p->p_stat) {
-
- db_printf("%c%5d ", p == curproc ? '*' : ' ',
- p->p_pid);
-
- switch (*mode) {
-
- case 'a':
- db_printf("%-10.10s %18p %18p %18p\n",
- p->p_comm, p, p->p_addr, p->p_vmspace);
- break;
-
- case 'n':
- db_printf("%5d %5d %5d %d %#10x "
- "%-12.12s %-16s\n",
- ppr ? ppr->ps_pid : -1,
- pr->ps_pgrp ? pr->ps_pgrp->pg_id : -1,
- pr->ps_cred->p_ruid, p->p_stat,
- p->p_flag | p->p_p->ps_flags,
- (p->p_wchan && p->p_wmesg) ?
- p->p_wmesg : "", p->p_comm);
- break;
-
- case 'w':
- db_printf("%-16s %-8s %18p %s\n", p->p_comm,
- p->p_emul->e_name, p->p_wchan,
- (p->p_wchan && p->p_wmesg) ?
- p->p_wmesg : "");
- break;
+ TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
+ if (p->p_stat) {
+ db_printf("%c%5d ", p == curproc ? '*' : ' ',
+ p->p_pid);
+
+ switch (*mode) {
+
+ case 'a':
+ db_printf("%-10.10s %18p %18p %18p\n",
+ p->p_comm, p, p->p_addr, p->p_vmspace);
+ break;
+
+ case 'n':
+ db_printf("%5d %5d %5d %d %#10x "
+ "%-12.12s %-16s\n",
+ ppr ? ppr->ps_pid : -1,
+ pr->ps_pgrp ? pr->ps_pgrp->pg_id : -1,
+ pr->ps_cred->p_ruid, p->p_stat,
+ p->p_flag | pr->ps_flags,
+ (p->p_wchan && p->p_wmesg) ?
+ p->p_wmesg : "", p->p_comm);
+ break;
+
+ case 'w':
+ db_printf("%-16s %-8s %18p %s\n", p->p_comm,
+ p->p_emul->e_name, p->p_wchan,
+ (p->p_wchan && p->p_wmesg) ?
+ p->p_wmesg : "");
+ break;
+
+ }
}
}
- p = LIST_NEXT(p, p_list);
- if (p == 0 && doingzomb == 0) {
+ pr = LIST_NEXT(pr, ps_list);
+ if (pr == NULL && doingzomb == 0) {
doingzomb = 1;
- p = LIST_FIRST(&zombproc);
+ pr = LIST_FIRST(&zombprocess);
}
}
}
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 4ba85ea9da5..6a6100da684 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_resource.c,v 1.46 2013/10/25 04:42:48 guenther Exp $ */
+/* $OpenBSD: kern_resource.c,v 1.47 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: kern_resource.c,v 1.38 1996/10/23 07:19:38 matthias Exp $ */
/*-
@@ -73,7 +73,6 @@ sys_getpriority(struct proc *curp, void *v, register_t *retval)
syscallarg(id_t) who;
} */ *uap = v;
struct process *pr;
- struct proc *p;
int low = NZERO + PRIO_MAX + 1;
switch (SCARG(uap, which)) {
@@ -105,11 +104,10 @@ sys_getpriority(struct proc *curp, void *v, register_t *retval)
case PRIO_USER:
if (SCARG(uap, who) == 0)
SCARG(uap, who) = curp->p_ucred->cr_uid;
- LIST_FOREACH(p, &allproc, p_list)
- if ((p->p_flag & P_THREAD) == 0 &&
- p->p_ucred->cr_uid == SCARG(uap, who) &&
- p->p_p->ps_nice < low)
- low = p->p_p->ps_nice;
+ LIST_FOREACH(pr, &allprocess, ps_list)
+ if (pr->ps_cred->pc_ucred->cr_uid == SCARG(uap, who) &&
+ pr->ps_nice < low)
+ low = pr->ps_nice;
break;
default:
@@ -160,18 +158,15 @@ sys_setpriority(struct proc *curp, void *v, register_t *retval)
break;
}
- case PRIO_USER: {
- struct proc *p;
+ case PRIO_USER:
if (SCARG(uap, who) == 0)
SCARG(uap, who) = curp->p_ucred->cr_uid;
- LIST_FOREACH(p, &allproc, p_list)
- if ((p->p_flag & P_THREAD) == 0 &&
- p->p_ucred->cr_uid == SCARG(uap, who)) {
- error = donice(curp, p->p_p, SCARG(uap, prio));
+ LIST_FOREACH(pr, &allprocess, ps_list)
+ if (pr->ps_cred->pc_ucred->cr_uid == SCARG(uap, who)) {
+ error = donice(curp, pr, SCARG(uap, prio));
found++;
}
break;
- }
default:
return (EINVAL);
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index dd8fbfcc83e..a1b210e3f3e 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sig.c,v 1.155 2013/10/08 03:50:07 guenther Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.156 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@@ -616,8 +616,9 @@ killpg1(struct proc *cp, int signum, int pgid, int all)
/*
* broadcast
*/
- LIST_FOREACH(p, &allproc, p_list) {
- if (p->p_pid <= 1 || p->p_flag & (P_SYSTEM|P_THREAD) ||
+ LIST_FOREACH(pr, &allprocess, ps_list) {
+ p = pr->ps_mainproc;
+ if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
p == cp || !cansignal(cp, pc, p, signum))
continue;
nfound++;
@@ -1222,6 +1223,7 @@ keep:
void
proc_stop(struct proc *p, int sw)
{
+ struct process *pr = p->p_p;
extern void *softclock_si;
#ifdef MULTIPROCESSOR
@@ -1229,8 +1231,9 @@ proc_stop(struct proc *p, int sw)
#endif
p->p_stat = SSTOP;
- atomic_clearbits_int(&p->p_p->ps_flags, PS_WAITED);
- atomic_setbits_int(&p->p_flag, P_STOPPED|P_SUSPSIG);
+ atomic_clearbits_int(&pr->ps_flags, PS_WAITED);
+ atomic_setbits_int(&pr->ps_flags, PS_STOPPED);
+ atomic_setbits_int(&p->p_flag, P_SUSPSIG);
if (!timeout_pending(&proc_stop_to)) {
timeout_add(&proc_stop_to, 0);
/*
@@ -1251,17 +1254,17 @@ proc_stop(struct proc *p, int sw)
void
proc_stop_sweep(void *v)
{
- struct proc *p;
+ struct process *pr;
- LIST_FOREACH(p, &allproc, p_list) {
- if ((p->p_flag & P_STOPPED) == 0)
+ LIST_FOREACH(pr, &allprocess, ps_list) {
+ if ((pr->ps_flags & PS_STOPPED) == 0)
continue;
- atomic_clearbits_int(&p->p_flag, P_STOPPED);
+ atomic_clearbits_int(&pr->ps_flags, PS_STOPPED);
- if ((p->p_p->ps_pptr->ps_mainproc->p_sigacts->ps_flags &
+ if ((pr->ps_pptr->ps_mainproc->p_sigacts->ps_flags &
SAS_NOCLDSTOP) == 0)
- prsignal(p->p_p->ps_pptr, SIGCHLD);
- wakeup(p->p_p->ps_pptr);
+ prsignal(pr->ps_pptr, SIGCHLD);
+ wakeup(pr->ps_pptr);
}
}
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 41ef093684b..2e36b845fee 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.242 2014/01/20 03:23:42 guenther Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.243 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -1188,6 +1188,7 @@ sysctl_file(int *name, u_int namelen, char *where, size_t *sizep,
struct filedesc *fdp;
struct file *fp;
struct proc *pp;
+ struct process *pr;
size_t buflen, elem_size, elem_count, outsize;
char *dp = where;
int arg, i, error = 0, needed = 0;
@@ -1245,13 +1246,13 @@ sysctl_file(int *name, u_int namelen, char *where, size_t *sizep,
error = EINVAL;
break;
}
- LIST_FOREACH(pp, &allproc, p_list) {
+ LIST_FOREACH(pr, &allprocess, ps_list) {
/*
* skip system, exiting, embryonic and undead
- * processes, as well as threads
+ * processes
*/
- if ((pp->p_flag & P_SYSTEM) || (pp->p_flag & P_THREAD)
- || (pp->p_p->ps_flags & PS_EXITING)
+ pp = pr->ps_mainproc;
+ if ((pp->p_flag & P_SYSTEM) || (pr->ps_flags & PS_EXITING)
|| pp->p_stat == SIDL || pp->p_stat == SZOMB)
continue;
if (arg > 0 && pp->p_pid != (pid_t)arg) {
@@ -1259,14 +1260,14 @@ sysctl_file(int *name, u_int namelen, char *where, size_t *sizep,
continue;
}
fdp = pp->p_fd;
- if (pp->p_p->ps_textvp)
- FILLIT(NULL, NULL, KERN_FILE_TEXT, pp->p_p->ps_textvp, pp);
+ if (pr->ps_textvp)
+ FILLIT(NULL, NULL, KERN_FILE_TEXT, pr->ps_textvp, pp);
if (fdp->fd_cdir)
FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pp);
if (fdp->fd_rdir)
FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pp);
- if (pp->p_p->ps_tracevp)
- FILLIT(NULL, NULL, KERN_FILE_TRACE, pp->p_p->ps_tracevp, pp);
+ if (pr->ps_tracevp)
+ FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pp);
for (i = 0; i < fdp->fd_nfiles; i++) {
if ((fp = fdp->fd_ofiles[i]) == NULL)
continue;
@@ -1277,13 +1278,13 @@ sysctl_file(int *name, u_int namelen, char *where, size_t *sizep,
}
break;
case KERN_FILE_BYUID:
- LIST_FOREACH(pp, &allproc, p_list) {
+ LIST_FOREACH(pr, &allprocess, ps_list) {
+ pp = pr->ps_mainproc;
/*
* skip system, exiting, embryonic and undead
- * processes, as well as threads
+ * processes
*/
- if ((pp->p_flag & P_SYSTEM) || (pp->p_flag & P_THREAD)
- || (pp->p_p->ps_flags & PS_EXITING)
+ if ((pp->p_flag & P_SYSTEM) || (pr->ps_flags & PS_EXITING)
|| pp->p_stat == SIDL || pp->p_stat == SZOMB)
continue;
if (arg >= 0 && pp->p_ucred->cr_uid != (uid_t)arg) {
@@ -1295,8 +1296,8 @@ sysctl_file(int *name, u_int namelen, char *where, size_t *sizep,
FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pp);
if (fdp->fd_rdir)
FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pp);
- if (pp->p_p->ps_tracevp)
- FILLIT(NULL, NULL, KERN_FILE_TRACE, pp->p_p->ps_tracevp, pp);
+ if (pr->ps_tracevp)
+ FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pp);
for (i = 0; i < fdp->fd_nfiles; i++) {
if ((fp = fdp->fd_ofiles[i]) == NULL)
continue;
@@ -1360,21 +1361,22 @@ sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep)
if (where != NULL)
kproc = malloc(sizeof(*kproc), M_TEMP, M_WAITOK);
- p = LIST_FIRST(&allproc);
+ pr = LIST_FIRST(&allprocess);
doingzomb = 0;
again:
- for (; p != 0; p = LIST_NEXT(p, p_list)) {
+ for (; pr != NULL; pr = LIST_NEXT(pr, ps_list)) {
+ /* XXX skip processes in the middle of being zapped */
+ if (pr->ps_pgrp == NULL)
+ continue;
+
+ p = pr->ps_mainproc;
+
/*
* Skip embryonic processes.
*/
if (p->p_stat == SIDL)
continue;
- /* XXX skip processes in the middle of being zapped */
- pr = p->p_p;
- if (pr->ps_pgrp == NULL)
- continue;
-
/*
* TODO - make more efficient (see notes below).
*/
@@ -1429,33 +1431,17 @@ again:
goto err;
}
- if ((p->p_flag & P_THREAD) == 0) {
- if (buflen >= elem_size && elem_count > 0) {
- fill_kproc(p, kproc, 0, show_pointers);
- /* Update %cpu for all threads */
- if (!dothreads) {
- TAILQ_FOREACH(pp, &pr->ps_threads,
- p_thr_link) {
- if (pp == p)
- continue;
- kproc->p_pctcpu += pp->p_pctcpu;
- }
+ if (buflen >= elem_size && elem_count > 0) {
+ fill_kproc(p, kproc, 0, show_pointers);
+ /* Update %cpu for all threads */
+ if (!dothreads) {
+ TAILQ_FOREACH(pp, &pr->ps_threads,
+ p_thr_link) {
+ if (pp == p)
+ continue;
+ kproc->p_pctcpu += pp->p_pctcpu;
}
- error = copyout(kproc, dp, elem_size);
- if (error)
- goto err;
- dp += elem_size;
- buflen -= elem_size;
- elem_count--;
}
- needed += elem_size;
- }
- /* Skip the second entry if not required by op */
- if (!dothreads)
- continue;
-
- if (buflen >= elem_size && elem_count > 0) {
- fill_kproc(p, kproc, 1, show_pointers);
error = copyout(kproc, dp, elem_size);
if (error)
goto err;
@@ -1464,9 +1450,26 @@ again:
elem_count--;
}
needed += elem_size;
+
+ /* Skip per-thread entries if not required by op */
+ if (!dothreads)
+ continue;
+
+ TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
+ if (buflen >= elem_size && elem_count > 0) {
+ fill_kproc(p, kproc, 1, show_pointers);
+ error = copyout(kproc, dp, elem_size);
+ if (error)
+ goto err;
+ dp += elem_size;
+ buflen -= elem_size;
+ elem_count--;
+ }
+ needed += elem_size;
+ }
}
if (doingzomb == 0) {
- p = LIST_FIRST(&zombproc);
+ pr = LIST_FIRST(&zombprocess);
doingzomb++;
goto again;
}
diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c
index 7b60dcbf196..92de9db8bd3 100644
--- a/sys/miscfs/procfs/procfs_vnops.c
+++ b/sys/miscfs/procfs/procfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: procfs_vnops.c,v 1.57 2014/01/20 03:23:42 guenther Exp $ */
+/* $OpenBSD: procfs_vnops.c,v 1.58 2014/01/20 21:19:28 guenther Exp $ */
/* $NetBSD: procfs_vnops.c,v 1.40 1996/03/16 23:52:55 christos Exp $ */
/*
@@ -845,9 +845,9 @@ procfs_readdir(void *v)
/*
* this is for the root of the procfs filesystem
* what is needed is a special entry for "curproc"
- * followed by an entry for each process on allproc
+ * followed by an entry for each process on allprocess
#ifdef PROCFS_ZOMBIE
- * and zombproc.
+ * and zombprocess.
#endif
*/
@@ -856,16 +856,14 @@ procfs_readdir(void *v)
int doingzomb = 0;
#endif
int pcnt = i;
- volatile struct proc *p = LIST_FIRST(&allproc);
+ volatile struct process *pr = LIST_FIRST(&allprocess);
if (pcnt > 3)
pcnt = 3;
#ifdef PROCFS_ZOMBIE
again:
#endif
- while (p && (p->p_flag & P_THREAD))
- p = LIST_NEXT(p, p_list);
- for (; p && uio->uio_resid >= UIO_MX; i++, pcnt++) {
+ for (; pr && uio->uio_resid >= UIO_MX; i++, pcnt++) {
switch (i) {
case 0: /* `.' */
case 1: /* `..' */
@@ -913,21 +911,12 @@ procfs_readdir(void *v)
/* fall through */
default:
- while (pcnt < i) {
+ while (pcnt < i)
pcnt++;
- do {
- p = LIST_NEXT(p, p_list);
- } while (p && (p->p_flag & P_THREAD));
- if (!p)
- goto done;
- }
- d.d_fileno = PROCFS_FILENO(p->p_pid, Pproc);
+ d.d_fileno = PROCFS_FILENO(pr->ps_pid, Pproc);
d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),
- "%ld", (long)p->p_pid);
+ "%ld", (long)pr->ps_pid);
d.d_type = DT_REG;
- do {
- p = LIST_NEXT(p, p_list);
- } while (p && (p->p_flag & P_THREAD));
break;
}
@@ -937,9 +926,9 @@ procfs_readdir(void *v)
done:
#ifdef PROCFS_ZOMBIE
- if (p == 0 && doingzomb == 0) {
+ if (pr == NULL && doingzomb == 0) {
doingzomb = 1;
- p = LIST_FIRST(&zombproc);
+ pr = LIST_FIRST(&zombprocess);
goto again;
}
#endif
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index b1525f20cd9..5e842066c79 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.173 2014/01/20 03:23:42 guenther Exp $ */
+/* $OpenBSD: proc.h,v 1.174 2014/01/20 21:19:27 guenther Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -156,6 +156,7 @@ struct process {
struct proc *ps_mainproc;
struct pcred *ps_cred; /* Process owner's identity. */
+ LIST_ENTRY(process) ps_list; /* List of all processes. */
TAILQ_HEAD(,proc) ps_threads; /* Threads in this process. */
LIST_ENTRY(process) ps_pglist; /* List of processes in pgrp. */
@@ -238,16 +239,19 @@ struct process {
#define PS_COREDUMP 0x00000800 /* Busy coredumping */
#define PS_SINGLEEXIT 0x00001000 /* Other threads must die. */
#define PS_SINGLEUNWIND 0x00002000 /* Other threads must unwind. */
+#define PS_NOZOMBIE 0x00004000 /* Pid 1 waits for me instead of dad */
+#define PS_STOPPED 0x00008000 /* Just stopped, need sig to parent. */
#define PS_BITS \
("\20\01CONTROLT\02EXEC\03INEXEC\04EXITING\05SUGID" \
"\06SUGIDEXEC\07PPWAIT\010ISPWAIT\011PROFIL\012TRACED" \
- "\013WAITED\014COREDUMP\015SINGLEEXIT\016SINGLEUNWIND")
+ "\013WAITED\014COREDUMP\015SINGLEEXIT\016SINGLEUNWIND" \
+ "\017NOZOMBIE\018STOPPED")
struct proc {
TAILQ_ENTRY(proc) p_runq;
- LIST_ENTRY(proc) p_list; /* List of all processes. */
+ LIST_ENTRY(proc) p_list; /* List of all threads. */
struct process *p_p; /* The process of this thread. */
TAILQ_ENTRY(proc) p_thr_link;/* Threads in a process linkage. */
@@ -370,21 +374,19 @@ struct proc {
#define P_WEXIT 0x002000 /* Working on exiting. */
#define P_OWEUPC 0x008000 /* Owe proc an addupc() at next ast. */
#define P_SUSPSINGLE 0x080000 /* Need to stop for single threading. */
-#define P_NOZOMBIE 0x100000 /* Pid 1 waits for me instead of dad */
#define P_SYSTRACE 0x400000 /* Process system call tracing active*/
#define P_CONTINUED 0x800000 /* Proc has continued from a stopped state. */
#define P_THREAD 0x4000000 /* Only a thread, not a real process */
#define P_SUSPSIG 0x8000000 /* Stopped from signal. */
#define P_SOFTDEP 0x10000000 /* Stuck processing softdep worklist */
-#define P_STOPPED 0x20000000 /* Just stopped, need sig to parent. */
#define P_CPUPEG 0x40000000 /* Do not move to another cpu. */
#define P_BITS \
("\20\01INKTR\02PROFPEND\03ALRMPEND\04SIGSUSPEND\07SELECT" \
"\010SINTR\012SYSTEM" \
"\013TIMEOUT\016WEXIT\020OWEUPC\024SUSPSINGLE" \
- "\025NOZOMBIE\027SYSTRACE\030CONTINUED\033THREAD" \
- "\034SUSPSIG\035SOFTDEP\036STOPPED\037CPUPEG")
+ "\027SYSTRACE\030CONTINUED\033THREAD" \
+ "\034SUSPSIG\035SOFTDEP\037CPUPEG")
/* Macro to compute the exit signal to be delivered. */
#define P_EXITSIG(p) \
@@ -467,8 +469,10 @@ extern int nthreads, maxthread; /* Cur and max number of threads. */
extern int randompid; /* fork() should create random pid's */
LIST_HEAD(proclist, proc);
-extern struct proclist allproc; /* List of all processes. */
-extern struct proclist zombproc; /* List of zombie processes. */
+LIST_HEAD(processlist, process);
+extern struct processlist allprocess; /* List of all processes. */
+extern struct processlist zombprocess; /* List of zombie processes. */
+extern struct proclist allproc; /* List of all threads. */
extern struct proc *initproc; /* Process slot for init. */
extern struct proc *reaperproc; /* Process slot for reaper. */
@@ -527,7 +531,8 @@ void child_return(void *);
int proc_cansugid(struct proc *);
void proc_finish_wait(struct proc *, struct proc *);
-void proc_zap(struct proc *);
+void process_zap(struct process *);
+void proc_free(struct proc *);
struct sleep_state {
int sls_s;