1:1 Userland threading stage 2.11/4:
[dragonfly.git] / sys / kern / kern_kinfo.c
1 /*-
2  * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Simon 'corecode' Schubert <corecode@fs.ei.tum.de>
6  * by Thomas E. Spanjaard <tgen@netphreax.net>
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  * 3. Neither the name of The DragonFly Project nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific, prior written permission.
21  * 
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
26  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  * 
35  * $DragonFly: src/sys/kern/kern_kinfo.c,v 1.5 2007/02/03 17:05:57 corecode Exp $
36  */
37
38 /*
39  * This is a source file used by both the kernel and libkvm.
40  */
41
42 #ifndef _KERNEL
43 #define _KERNEL_STRUCTURES
44 #endif
45
46 #include <sys/proc.h>
47 #include <vm/vm_map.h>
48 #include <sys/kinfo.h>
49 #include <sys/tty.h>
50 #include <sys/conf.h>
51 #include <sys/jail.h>
52 #include <sys/globaldata.h>
53 #ifdef _KERNEL
54 #include <sys/systm.h>
55 #else
56 #include <string.h>
57 #endif
58
59
60 /*
61  * Fill in a struct kinfo_proc.
62  */
63 void
64 fill_kinfo_proc(struct proc *p, struct kinfo_proc *kp)
65 {
66         struct session *sess = p->p_pgrp->pg_session;
67
68         bzero(kp, sizeof(*kp));
69
70         kp->kp_paddr = (uintptr_t)p;
71         kp->kp_fd = (uintptr_t)p->p_fd;
72
73         kp->kp_flags = p->p_flag;
74         kp->kp_stat = p->p_stat;
75         kp->kp_lock = p->p_lock;
76         kp->kp_acflag = p->p_acflag;
77         kp->kp_traceflag = p->p_traceflag;
78         kp->kp_siglist = p->p_siglist;
79         kp->kp_sigignore = p->p_sigignore;
80         kp->kp_sigcatch = p->p_sigcatch;
81         kp->kp_sigflag = p->p_procsig->ps_flag;
82         kp->kp_start = p->p_start;
83
84         strncpy(kp->kp_comm, p->p_comm, sizeof(kp->kp_comm) - 1);
85         kp->kp_comm[sizeof(kp->kp_comm) - 1] = 0;
86
87         kp->kp_uid = p->p_ucred->cr_uid;
88         kp->kp_ngroups = p->p_ucred->cr_ngroups;
89         bcopy(p->p_ucred->cr_groups, kp->kp_groups,
90               NGROUPS * sizeof(kp->kp_groups[0]));
91         kp->kp_ruid = p->p_ucred->cr_ruid;
92         kp->kp_svuid = p->p_ucred->cr_svuid;
93         kp->kp_rgid = p->p_ucred->cr_rgid;
94         kp->kp_svgid = p->p_ucred->cr_svgid;
95
96         kp->kp_pid = p->p_pid;
97         if (p->p_oppid != 0)
98                 kp->kp_ppid = p->p_oppid;
99         else
100                 kp->kp_ppid = p->p_pptr != NULL ? p->p_pptr->p_pid : -1;
101         kp->kp_pgid = p->p_pgrp->pg_id;
102         kp->kp_jobc = p->p_pgrp->pg_jobc;
103         kp->kp_sid = sess->s_sid;
104         bcopy(sess->s_login, kp->kp_login, MAXLOGNAME);
105         if (sess->s_ttyvp != NULL)
106                 kp->kp_auxflags |= KI_CTTY;
107         if (SESS_LEADER(p))
108                 kp->kp_auxflags |= KI_SLEADER;
109         if (((p->p_flag & P_CONTROLT) != 0) && (sess->s_ttyp != NULL)) {
110                 kp->kp_tdev = (sess->s_ttyp->t_dev != NOCDEV) ?
111                                         sess->s_ttyp->t_dev->si_udev :
112                                         NOUDEV;
113                 if (sess->s_ttyp->t_pgrp != NULL)
114                         kp->kp_tpgid = sess->s_ttyp->t_pgrp->pg_id;
115                 else
116                         kp->kp_tpgid = -1;
117                 if (sess->s_ttyp->t_session != NULL)
118                         kp->kp_tsid = sess->s_ttyp->t_session->s_sid;
119                 else
120                         kp->kp_tsid = -1;
121         } else {
122                 kp->kp_tdev = NOUDEV;
123         }
124         kp->kp_exitstat = p->p_xstat;
125         kp->kp_nthreads = p->p_nthreads;
126         kp->kp_nice = p->p_nice;
127         kp->kp_swtime = p->p_swtime;
128
129         kp->kp_vm_map_size = p->p_vmspace->vm_map.size;
130         kp->kp_vm_rssize = p->p_vmspace->vm_rssize;
131         kp->kp_vm_swrss = p->p_vmspace->vm_swrss;
132         kp->kp_vm_tsize = p->p_vmspace->vm_tsize;
133         kp->kp_vm_dsize = p->p_vmspace->vm_dsize;
134         kp->kp_vm_ssize = p->p_vmspace->vm_ssize;
135
136         if (jailed(p->p_ucred))
137                 kp->kp_jailid = p->p_ucred->cr_prison->pr_id;
138
139         kp->kp_ru = p->p_ru;
140         kp->kp_ru = p->p_cru;
141 }
142
143 /*
144  * Fill in a struct kinfo_lwp.
145  */
146 void
147 fill_kinfo_lwp(struct lwp *lwp, struct kinfo_lwp *kl)
148 {
149         bzero(kl, sizeof(*kl));
150
151         kl->kl_pid = lwp->lwp_proc->p_pid;
152         kl->kl_tid = lwp->lwp_tid;
153
154         kl->kl_flags = lwp->lwp_flag;
155 #ifdef notyet
156         kl->kl_stat = lwp->lwp_stat;
157 #endif
158         kl->kl_tdflags = lwp->lwp_thread->td_flags;
159 #ifdef SMP
160         kl->kl_mpcount = lwp->lwp_thread->td_mpcount;
161 #else
162         kl->kl_mpcount = 0;
163 #endif
164
165         kl->kl_prio = lwp->lwp_usdata.bsd4.priority;    /* XXX TGEN dangerous assumption */
166         kl->kl_tdprio = lwp->lwp_thread->td_pri;
167         kl->kl_rtprio = lwp->lwp_rtprio;
168
169         kl->kl_uticks = lwp->lwp_thread->td_uticks;
170         kl->kl_sticks = lwp->lwp_thread->td_sticks;
171         kl->kl_iticks = lwp->lwp_thread->td_iticks;
172         kl->kl_cpticks = lwp->lwp_cpticks;
173         kl->kl_pctcpu = lwp->lwp_pctcpu;
174         kl->kl_slptime = lwp->lwp_slptime;
175         kl->kl_origcpu = lwp->lwp_usdata.bsd4.origcpu;  /* XXX TGEN same */
176         kl->kl_estcpu = lwp->lwp_usdata.bsd4.estcpu;
177         kl->kl_cpuid = lwp->lwp_thread->td_gd->gd_cpuid;
178
179         kl->kl_ru = lwp->lwp_ru;
180
181         kl->kl_siglist = lwp->lwp_siglist;
182         kl->kl_sigmask = lwp->lwp_sigmask;
183
184         kl->kl_wchan = (uintptr_t)lwp->lwp_thread->td_wchan;
185         if (lwp->lwp_thread->td_wmesg) {
186                 strncpy(kl->kl_wmesg, lwp->lwp_thread->td_wmesg, WMESGLEN);
187                 kl->kl_wmesg[WMESGLEN] = 0;
188         }
189 }
190
191 /*
192  * Fill in a struct kinfo_proc for kernel threads (i.e. those without proc).
193  */
194 void
195 fill_kinfo_proc_kthread(struct thread *td, struct kinfo_proc *kp)
196 {
197         bzero(kp, sizeof(*kp));
198
199         /*
200          * Fill in fake proc information and semi-fake lwp info.
201          */
202         kp->kp_pid = -1;
203         kp->kp_tdev = NOUDEV;
204         strncpy(kp->kp_comm, td->td_comm, sizeof(kp->kp_comm) - 1);
205         kp->kp_comm[sizeof(kp->kp_comm) - 1] = 0;
206 #ifdef notyet
207         kp->kp_lwp.kl_flags = LWP_SYSTEM;
208 #else
209         kp->kp_flags = P_SYSTEM;
210 #endif
211         kp->kp_lwp.kl_pid = -1;
212         kp->kp_lwp.kl_tid = (uintptr_t)td;
213         kp->kp_lwp.kl_tdflags = td->td_flags;
214 #ifdef SMP
215         kp->kp_lwp.kl_mpcount = td->td_mpcount;
216 #else /* !SMP */
217         kp->kp_lwp.kl_mpcount = 0;
218 #endif /* SMP */
219
220         kp->kp_lwp.kl_tdprio = td->td_pri;
221         kp->kp_lwp.kl_rtprio.type = RTP_PRIO_THREAD;
222         kp->kp_lwp.kl_rtprio.prio = td->td_pri & TDPRI_MASK;
223
224         kp->kp_lwp.kl_uticks = td->td_uticks;
225         kp->kp_lwp.kl_sticks = td->td_sticks;
226         kp->kp_lwp.kl_iticks = td->td_iticks;
227         kp->kp_lwp.kl_cpuid = td->td_gd->gd_cpuid;
228
229         kp->kp_lwp.kl_wchan = (uintptr_t)td->td_wchan;
230         if (td->td_wchan) {
231 #ifdef notyet
232                 kp->kp_lwp.kl_stat = SSLEEP;
233 #else
234                 kp->kp_stat = SSLEEP;
235 #endif
236         } else {
237 #ifdef notyet
238                 kp->kp_lwp.kl_stat = SRUN;
239 #else
240                 kp->kp_stat = SRUN;
241 #endif
242         }
243         if (td->td_wmesg) {
244                 strncpy(kp->kp_lwp.kl_wmesg, td->td_wmesg, WMESGLEN);
245                 kp->kp_lwp.kl_wmesg[WMESGLEN] = 0;
246         }
247 }