Fix a minor bug in lwkt_init_thread() (the thread was being added to the
[dragonfly.git] / sys / kern / kern_proc.c
index 9c353a8..06923d2 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
  * $FreeBSD: src/sys/kern/kern_proc.c,v 1.63.2.9 2003/05/08 07:47:16 kbyanc Exp $
- * $DragonFly: src/sys/kern/kern_proc.c,v 1.2 2003/06/17 04:28:41 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_proc.c,v 1.10 2003/07/25 05:26:50 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -57,8 +57,11 @@ static MALLOC_DEFINE(M_PROC, "proc", "Proc structures");
 MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures");
 
 static int ps_showallprocs = 1;
+static int ps_showallthreads = 1;
 SYSCTL_INT(_kern, OID_AUTO, ps_showallprocs, CTLFLAG_RW,
     &ps_showallprocs, 0, "");
+SYSCTL_INT(_kern, OID_AUTO, ps_showallthreads, CTLFLAG_RW,
+    &ps_showallthreads, 0, "");
 
 static void pgdelete   __P((struct pgrp *));
 
@@ -74,6 +77,7 @@ u_long pgrphash;
 struct proclist allproc;
 struct proclist zombproc;
 vm_zone_t proc_zone;
+vm_zone_t thread_zone;
 
 /*
  * Initialize global process hashing structures.
@@ -87,6 +91,7 @@ procinit()
        pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
        pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
        proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5);
+       thread_zone = zinit("THREAD", sizeof (struct thread), 0, 0, 5);
        uihashinit();
 }
 
@@ -347,23 +352,51 @@ DB_SHOW_COMMAND(pgrpdump, pgrpdump)
 }
 #endif /* DDB */
 
+/*
+ * Fill in an eproc structure for the specified thread.
+ */
+void
+fill_eproc_td(thread_t td, struct eproc *ep, struct proc *xp)
+{
+       bzero(ep, sizeof(*ep));
+
+       ep->e_uticks = td->td_uticks;
+       ep->e_sticks = td->td_sticks;
+       ep->e_iticks = td->td_iticks;
+       ep->e_tdev = NOUDEV;
+       ep->e_cpuid = td->td_gd->gd_cpuid;
+       if (td->td_wmesg) {
+               strncpy(ep->e_wmesg, td->td_wmesg, WMESGLEN);
+               ep->e_wmesg[WMESGLEN] = 0;
+       }
+
+       /*
+        * Fake up portions of the proc structure copied out by the sysctl
+        * to return useful information.  Note that using td_pri directly
+        * is messy because it includes critial section data so we fake
+        * up an rtprio.prio for threads.
+        */
+       if (xp) {
+               *xp = *initproc;
+               xp->p_rtprio.type = RTP_PRIO_THREAD;
+               xp->p_rtprio.prio = td->td_pri & TDPRI_MASK;
+               xp->p_pid = -1;
+       }
+}
+
 /*
  * Fill in an eproc structure for the specified process.
  */
 void
-fill_eproc(p, ep)
-       register struct proc *p;
-       register struct eproc *ep;
+fill_eproc(struct proc *p, struct eproc *ep)
 {
-       register struct tty *tp;
+       struct tty *tp;
 
-       bzero(ep, sizeof(*ep));
+       fill_eproc_td(p->p_thread, ep, NULL);
 
        ep->e_paddr = p;
-       if (p->p_cred) {
-               ep->e_pcred = *p->p_cred;
-               if (p->p_ucred)
-                       ep->e_ucred = *p->p_ucred;
+       if (p->p_ucred) {
+               ep->e_ucred = *p->p_ucred;
        }
        if (p->p_procsig) {
                ep->e_procsig = *p->p_procsig;
@@ -396,11 +429,8 @@ fill_eproc(p, ep)
                ep->e_tdev = dev2udev(tp->t_dev);
                ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
                ep->e_tsess = tp->t_session;
-       } else
+       } else {
                ep->e_tdev = NOUDEV;
-       if (p->p_wmesg) {
-               strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN);
-               ep->e_wmesg[WMESGLEN] = 0;
        }
 }
 
@@ -415,25 +445,38 @@ zpfind(pid_t pid)
        return (NULL);
 }
 
-
 static int
-sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb)
+sysctl_out_proc(struct proc *p, struct thread *td, struct sysctl_req *req, int doingzomb)
 {
        struct eproc eproc;
+       struct proc xproc;
        int error;
+#if 0
        pid_t pid = p->p_pid;
-
-       fill_eproc(p, &eproc);
-       error = SYSCTL_OUT(req,(caddr_t)p, sizeof(struct proc));
+#endif
+
+       if (p) {
+               td = p->p_thread;
+               fill_eproc(p, &eproc);
+               xproc = *p;
+       } else if (td) {
+               fill_eproc_td(td, &eproc, &xproc);
+       }
+       error = SYSCTL_OUT(req,(caddr_t)&xproc, sizeof(struct proc));
        if (error)
                return (error);
        error = SYSCTL_OUT(req,(caddr_t)&eproc, sizeof(eproc));
        if (error)
                return (error);
+       error = SYSCTL_OUT(req,(caddr_t)td, sizeof(struct thread));
+       if (error)
+               return (error);
+#if 0
        if (!doingzomb && pid && (pfind(pid) != p))
                return EAGAIN;
        if (doingzomb && zpfind(pid) != p)
                return EAGAIN;
+#endif
        return (0);
 }
 
@@ -443,8 +486,10 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
        int *name = (int*) arg1;
        u_int namelen = arg2;
        struct proc *p;
+       struct thread *td;
        int doingzomb;
        int error = 0;
+       struct ucred *cr1 = curproc->p_ucred;
 
        if (oidp->oid_number == KERN_PROC_PID) {
                if (namelen != 1) 
@@ -452,9 +497,9 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
                p = pfind((pid_t)name[0]);
                if (!p)
                        return (0);
-               if (!PRISON_CHECK(curproc, p))
+               if (!PRISON_CHECK(cr1, p->p_ucred))
                        return (0);
-               error = sysctl_out_proc(p, req, 0);
+               error = sysctl_out_proc(p, NULL, req, 0);
                return (error);
        }
        if (oidp->oid_number == KERN_PROC_ALL && !namelen)
@@ -479,7 +524,7 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
                        /*
                         * Show a user only their processes.
                         */
-                       if ((!ps_showallprocs) && p_trespass(curproc, p))
+                       if ((!ps_showallprocs) && p_trespass(cr1, p->p_ucred))
                                continue;
                        /*
                         * Skip embryonic processes.
@@ -491,7 +536,6 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
                         * do by session.
                         */
                        switch (oidp->oid_number) {
-
                        case KERN_PROC_PGRP:
                                /* could do this by traversing pgrp */
                                if (p->p_pgrp == NULL || 
@@ -516,15 +560,36 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
 
                        case KERN_PROC_RUID:
                                if (p->p_ucred == NULL || 
-                                   p->p_cred->p_ruid != (uid_t)name[0])
+                                   p->p_ucred->cr_ruid != (uid_t)name[0])
                                        continue;
                                break;
                        }
 
-                       if (!PRISON_CHECK(curproc, p))
+                       if (!PRISON_CHECK(cr1, p->p_ucred))
                                continue;
-
-                       error = sysctl_out_proc(p, req, doingzomb);
+                       PHOLD(p);
+                       error = sysctl_out_proc(p, NULL, req, doingzomb);
+                       PRELE(p);
+                       if (error)
+                               return (error);
+               }
+       }
+       if (ps_showallthreads) {
+               TAILQ_FOREACH(td, &mycpu->gd_tdallq, td_allq) {
+                       if (td->td_proc)
+                               continue;
+                       switch (oidp->oid_number) {
+                       case KERN_PROC_PGRP:
+                       case KERN_PROC_TTY:
+                       case KERN_PROC_UID:
+                       case KERN_PROC_RUID:
+                               continue;
+                       default:
+                               break;
+                       }
+                       lwkt_hold(td);
+                       error = sysctl_out_proc(NULL, td, req, doingzomb);
+                       lwkt_rele(td);
                        if (error)
                                return (error);
                }
@@ -546,6 +611,7 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS)
        struct proc *p;
        struct pargs *pa;
        int error = 0;
+       struct ucred *cr1 = curproc->p_ucred;
 
        if (namelen != 1) 
                return (EINVAL);
@@ -554,7 +620,7 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS)
        if (!p)
                return (0);
 
-       if ((!ps_argsopen) && p_trespass(curproc, p))
+       if ((!ps_argsopen) && p_trespass(cr1, p->p_ucred))
                return (0);
 
        if (req->newptr && curproc != p)