diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2014-01-20 21:19:29 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2014-01-20 21:19:29 +0000 |
commit | ee0ecd963da884228886664033fd7694a2eb8316 (patch) | |
tree | 52a9fc57aabaf3a0c1918697e14b24bc5f30528e /lib/libkvm | |
parent | d97b363c4b36ac6fd5d7bd23bce2badd8549c7ee (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.c | 80 | ||||
-rw-r--r-- | lib/libkvm/kvm_proc2.c | 178 |
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; |