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.8 2007/02/18 16:17:09 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 = vmspace_resident_count(p->p_vmspace); 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 kl->kl_stat = lwp->lwp_stat; 156 kl->kl_lock = lwp->lwp_lock; 157 kl->kl_tdflags = lwp->lwp_thread->td_flags; 158 #ifdef SMP 159 kl->kl_mpcount = lwp->lwp_thread->td_mpcount; 160 #else 161 kl->kl_mpcount = 0; 162 #endif 163 164 kl->kl_prio = lwp->lwp_usdata.bsd4.priority; /* XXX TGEN dangerous assumption */ 165 kl->kl_tdprio = lwp->lwp_thread->td_pri; 166 kl->kl_rtprio = lwp->lwp_rtprio; 167 168 kl->kl_uticks = lwp->lwp_thread->td_uticks; 169 kl->kl_sticks = lwp->lwp_thread->td_sticks; 170 kl->kl_iticks = lwp->lwp_thread->td_iticks; 171 kl->kl_cpticks = lwp->lwp_cpticks; 172 kl->kl_pctcpu = lwp->lwp_pctcpu; 173 kl->kl_slptime = lwp->lwp_slptime; 174 kl->kl_origcpu = lwp->lwp_usdata.bsd4.origcpu; /* XXX TGEN same */ 175 kl->kl_estcpu = lwp->lwp_usdata.bsd4.estcpu; 176 kl->kl_cpuid = lwp->lwp_thread->td_gd->gd_cpuid; 177 178 kl->kl_ru = lwp->lwp_ru; 179 180 kl->kl_siglist = lwp->lwp_siglist; 181 kl->kl_sigmask = lwp->lwp_sigmask; 182 183 kl->kl_wchan = (uintptr_t)lwp->lwp_thread->td_wchan; 184 if (lwp->lwp_thread->td_wmesg) { 185 strncpy(kl->kl_wmesg, lwp->lwp_thread->td_wmesg, WMESGLEN); 186 kl->kl_wmesg[WMESGLEN] = 0; 187 } 188 } 189 190 /* 191 * Fill in a struct kinfo_proc for kernel threads (i.e. those without proc). 192 */ 193 void 194 fill_kinfo_proc_kthread(struct thread *td, struct kinfo_proc *kp) 195 { 196 bzero(kp, sizeof(*kp)); 197 198 /* 199 * Fill in fake proc information and semi-fake lwp info. 200 */ 201 kp->kp_pid = -1; 202 kp->kp_tdev = NOUDEV; 203 strncpy(kp->kp_comm, td->td_comm, sizeof(kp->kp_comm) - 1); 204 kp->kp_comm[sizeof(kp->kp_comm) - 1] = 0; 205 kp->kp_flags = P_SYSTEM; 206 kp->kp_stat = SACTIVE; 207 208 kp->kp_lwp.kl_pid = -1; 209 kp->kp_lwp.kl_tid = (uintptr_t)td; 210 kp->kp_lwp.kl_tdflags = td->td_flags; 211 #ifdef SMP 212 kp->kp_lwp.kl_mpcount = td->td_mpcount; 213 #else /* !SMP */ 214 kp->kp_lwp.kl_mpcount = 0; 215 #endif /* SMP */ 216 217 kp->kp_lwp.kl_tdprio = td->td_pri; 218 kp->kp_lwp.kl_rtprio.type = RTP_PRIO_THREAD; 219 kp->kp_lwp.kl_rtprio.prio = td->td_pri & TDPRI_MASK; 220 221 kp->kp_lwp.kl_uticks = td->td_uticks; 222 kp->kp_lwp.kl_sticks = td->td_sticks; 223 kp->kp_lwp.kl_iticks = td->td_iticks; 224 kp->kp_lwp.kl_cpuid = td->td_gd->gd_cpuid; 225 226 kp->kp_lwp.kl_wchan = (uintptr_t)td->td_wchan; 227 if (td->td_wchan) 228 kp->kp_lwp.kl_stat = LSSLEEP; 229 else 230 kp->kp_lwp.kl_stat = LSRUN; 231 if (td->td_wmesg) { 232 strncpy(kp->kp_lwp.kl_wmesg, td->td_wmesg, WMESGLEN); 233 kp->kp_lwp.kl_wmesg[WMESGLEN] = 0; 234 } 235 } 236