summaryrefslogtreecommitdiff
path: root/lib/libkvm
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 /lib/libkvm
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@
Diffstat (limited to 'lib/libkvm')
-rw-r--r--lib/libkvm/kvm_file2.c80
-rw-r--r--lib/libkvm/kvm_proc2.c178
2 files changed, 137 insertions, 121 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;