1/* 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
| 1/* 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
|
34 * $FreeBSD: head/sys/kern/kern_proc.c 91066 2002-02-22 13:32:01Z phk $
| 34 * $FreeBSD: head/sys/kern/kern_proc.c 91140 2002-02-23 11:12:57Z tanimura $
|
35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/kernel.h> 40#include <sys/lock.h> 41#include <sys/malloc.h> 42#include <sys/mutex.h> 43#include <sys/proc.h> 44#include <sys/sysproto.h> 45#include <sys/sysctl.h> 46#include <sys/filedesc.h> 47#include <sys/tty.h> 48#include <sys/signalvar.h> 49#include <sys/sx.h> 50#include <sys/user.h> 51#include <sys/jail.h> 52 53#include <vm/vm.h> 54#include <vm/pmap.h> 55#include <vm/vm_map.h> 56#include <vm/vm_zone.h> 57
| 35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/kernel.h> 40#include <sys/lock.h> 41#include <sys/malloc.h> 42#include <sys/mutex.h> 43#include <sys/proc.h> 44#include <sys/sysproto.h> 45#include <sys/sysctl.h> 46#include <sys/filedesc.h> 47#include <sys/tty.h> 48#include <sys/signalvar.h> 49#include <sys/sx.h> 50#include <sys/user.h> 51#include <sys/jail.h> 52 53#include <vm/vm.h> 54#include <vm/pmap.h> 55#include <vm/vm_map.h> 56#include <vm/vm_zone.h> 57
|
58static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header");
| 58MALLOC_DEFINE(M_PGRP, "pgrp", "process group header");
|
59MALLOC_DEFINE(M_SESSION, "session", "session header"); 60static MALLOC_DEFINE(M_PROC, "proc", "Proc structures"); 61MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures"); 62
| 59MALLOC_DEFINE(M_SESSION, "session", "session header"); 60static MALLOC_DEFINE(M_PROC, "proc", "Proc structures"); 61MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures"); 62
|
| 63static struct proc *dopfind __P((register pid_t)); 64 65static void doenterpgrp __P((struct proc *, struct pgrp *)); 66
|
63static void pgdelete __P((struct pgrp *)); 64
| 67static void pgdelete __P((struct pgrp *)); 68
|
65static void orphanpg __P((struct pgrp *pg));
| 69static void orphanpg __P((struct pgrp *pg));
|
66 67/* 68 * Other process lists 69 */ 70struct pidhashhead *pidhashtbl; 71u_long pidhash; 72struct pgrphashhead *pgrphashtbl; 73u_long pgrphash; 74struct proclist allproc; 75struct proclist zombproc; 76struct sx allproc_lock; 77struct sx proctree_lock;
| 70 71/* 72 * Other process lists 73 */ 74struct pidhashhead *pidhashtbl; 75u_long pidhash; 76struct pgrphashhead *pgrphashtbl; 77u_long pgrphash; 78struct proclist allproc; 79struct proclist zombproc; 80struct sx allproc_lock; 81struct sx proctree_lock;
|
| 82struct sx pgrpsess_lock;
|
78vm_zone_t proc_zone; 79vm_zone_t ithread_zone; 80 81/* 82 * Initialize global process hashing structures. 83 */ 84void 85procinit() 86{ 87 int i, j; 88 89 sx_init(&allproc_lock, "allproc"); 90 sx_init(&proctree_lock, "proctree");
| 83vm_zone_t proc_zone; 84vm_zone_t ithread_zone; 85 86/* 87 * Initialize global process hashing structures. 88 */ 89void 90procinit() 91{ 92 int i, j; 93 94 sx_init(&allproc_lock, "allproc"); 95 sx_init(&proctree_lock, "proctree");
|
| 96 sx_init(&pgrpsess_lock, "pgrpsess");
|
91 LIST_INIT(&allproc); 92 LIST_INIT(&zombproc); 93 pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash); 94 pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash); 95 proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5); 96 uihashinit(); 97 /* 98 * This should really be a compile time warning, but I do 99 * not know of any way to do that... 100 */ 101 if (sizeof(struct kinfo_proc) != KINFO_PROC_SIZE) { 102 printf("This message will repeat for the next 20 seconds\n"); 103 for (i = 0; i < 20; i++) { 104 printf("WARNING: size of kinfo_proc (%ld) should be %d!!!\n", 105 (long)sizeof(struct kinfo_proc), KINFO_PROC_SIZE); 106 printf("The kinfo_proc structure was changed "); 107 printf("incorrectly in <sys/user.h>\n"); 108 for (j = 0; j < 0x7ffffff; j++); 109 } 110 111 } 112} 113 114/* 115 * Note that we do not link to the proc's ucred here 116 * The thread is linked as if running but no KSE assigned 117 */ 118static void 119thread_link(struct thread *td, struct ksegrp *kg) 120{ 121 struct proc *p = kg->kg_proc; 122 123 td->td_proc = p; 124 td->td_ksegrp = kg; 125 td->td_last_kse = &p->p_kse; 126 127 TAILQ_INSERT_HEAD(&p->p_threads, td, td_plist); 128 TAILQ_INSERT_HEAD(&kg->kg_threads, td, td_kglist); 129 td->td_critnest = 0; 130 td->td_savecrit = 0; 131 td->td_kse = NULL; 132} 133 134/* 135 * KSE is linked onto the idle queue. 136 */ 137static void 138kse_link(struct kse *ke, struct ksegrp *kg) 139{ 140 struct proc *p = kg->kg_proc; 141 142 TAILQ_INSERT_HEAD(&kg->kg_kseq, ke, ke_kglist); 143 kg->kg_kses++; 144 TAILQ_INSERT_HEAD(&kg->kg_iq, ke, ke_kgrlist); 145 ke->ke_proc = p; 146 ke->ke_ksegrp = kg; 147 ke->ke_thread = NULL; 148 ke->ke_oncpu = NOCPU; 149} 150 151static void 152ksegrp_link(struct ksegrp *kg, struct proc *p) 153{ 154 155 TAILQ_INIT(&kg->kg_threads); 156 TAILQ_INIT(&kg->kg_runq); /* links with td_runq */ 157 TAILQ_INIT(&kg->kg_slpq); /* links with td_runq */ 158 TAILQ_INIT(&kg->kg_kseq); /* all kses in ksegrp */ 159 TAILQ_INIT(&kg->kg_iq); /* all kses in ksegrp */ 160 kg->kg_proc = p; 161/* the following counters are in the -zero- section and may not need clearing */ 162 kg->kg_runnable = 0; 163 kg->kg_kses = 0; 164 kg->kg_runq_kses = 0; /* XXXKSE change name */ 165/* link it in now that it's consitant */ 166 TAILQ_INSERT_HEAD(&p->p_ksegrps, kg, kg_ksegrp); 167} 168 169/* 170 * for a newly created process, 171 * link up a the structure and its initial threads etc. 172 */ 173void 174proc_linkup(struct proc *p, struct ksegrp *kg, 175 struct kse *ke, struct thread *td) 176{ 177 178 TAILQ_INIT(&p->p_ksegrps); /* all ksegrps in proc */ 179 TAILQ_INIT(&p->p_threads); /* all threads in proc */ 180 181 ksegrp_link(kg, p); 182 kse_link(ke, kg); 183 thread_link(td, kg); 184 /* link them together for 1:1 */ 185 td->td_kse = ke; 186 ke->ke_thread = td; 187} 188 189/* temporary version is ultra simple while we are in 1:1 mode */ 190struct thread * 191thread_get(struct proc *p) 192{ 193 struct thread *td = &p->p_xxthread; 194 195 return (td); 196} 197 198 199/********************* 200* STUB KSE syscalls 201*********************/ 202 203/* struct thread_wakeup_args { struct thread_mailbox *tmbx; }; */ 204int 205thread_wakeup(struct thread *td, struct thread_wakeup_args *uap) 206{ 207 208 return(ENOSYS); 209} 210 211int 212kse_exit(struct thread *td, struct kse_exit_args *uap) 213{ 214 215 return(ENOSYS); 216} 217 218int 219kse_yield(struct thread *td, struct kse_yield_args *uap) 220{ 221 222 return(ENOSYS); 223} 224 225int kse_wakeup(struct thread *td, struct kse_wakeup_args *uap) 226{ 227 228 return(ENOSYS); 229} 230 231 232int 233kse_new(struct thread *td, struct kse_new_args *uap) 234/* struct kse_new_args { 235 struct kse_mailbox *mbx; 236 int new_grp_flag; 237}; */ 238{ 239 240 return (ENOSYS); 241} 242 243/* 244 * Is p an inferior of the current process? 245 */ 246int 247inferior(p) 248 register struct proc *p; 249{ 250 251 sx_assert(&proctree_lock, SX_LOCKED); 252 for (; p != curproc; p = p->p_pptr) 253 if (p->p_pid == 0) 254 return (0); 255 return (1); 256} 257 258/* 259 * Locate a process by number 260 */ 261struct proc * 262pfind(pid) 263 register pid_t pid; 264{ 265 register struct proc *p; 266 267 sx_slock(&allproc_lock);
| 97 LIST_INIT(&allproc); 98 LIST_INIT(&zombproc); 99 pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash); 100 pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash); 101 proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5); 102 uihashinit(); 103 /* 104 * This should really be a compile time warning, but I do 105 * not know of any way to do that... 106 */ 107 if (sizeof(struct kinfo_proc) != KINFO_PROC_SIZE) { 108 printf("This message will repeat for the next 20 seconds\n"); 109 for (i = 0; i < 20; i++) { 110 printf("WARNING: size of kinfo_proc (%ld) should be %d!!!\n", 111 (long)sizeof(struct kinfo_proc), KINFO_PROC_SIZE); 112 printf("The kinfo_proc structure was changed "); 113 printf("incorrectly in <sys/user.h>\n"); 114 for (j = 0; j < 0x7ffffff; j++); 115 } 116 117 } 118} 119 120/* 121 * Note that we do not link to the proc's ucred here 122 * The thread is linked as if running but no KSE assigned 123 */ 124static void 125thread_link(struct thread *td, struct ksegrp *kg) 126{ 127 struct proc *p = kg->kg_proc; 128 129 td->td_proc = p; 130 td->td_ksegrp = kg; 131 td->td_last_kse = &p->p_kse; 132 133 TAILQ_INSERT_HEAD(&p->p_threads, td, td_plist); 134 TAILQ_INSERT_HEAD(&kg->kg_threads, td, td_kglist); 135 td->td_critnest = 0; 136 td->td_savecrit = 0; 137 td->td_kse = NULL; 138} 139 140/* 141 * KSE is linked onto the idle queue. 142 */ 143static void 144kse_link(struct kse *ke, struct ksegrp *kg) 145{ 146 struct proc *p = kg->kg_proc; 147 148 TAILQ_INSERT_HEAD(&kg->kg_kseq, ke, ke_kglist); 149 kg->kg_kses++; 150 TAILQ_INSERT_HEAD(&kg->kg_iq, ke, ke_kgrlist); 151 ke->ke_proc = p; 152 ke->ke_ksegrp = kg; 153 ke->ke_thread = NULL; 154 ke->ke_oncpu = NOCPU; 155} 156 157static void 158ksegrp_link(struct ksegrp *kg, struct proc *p) 159{ 160 161 TAILQ_INIT(&kg->kg_threads); 162 TAILQ_INIT(&kg->kg_runq); /* links with td_runq */ 163 TAILQ_INIT(&kg->kg_slpq); /* links with td_runq */ 164 TAILQ_INIT(&kg->kg_kseq); /* all kses in ksegrp */ 165 TAILQ_INIT(&kg->kg_iq); /* all kses in ksegrp */ 166 kg->kg_proc = p; 167/* the following counters are in the -zero- section and may not need clearing */ 168 kg->kg_runnable = 0; 169 kg->kg_kses = 0; 170 kg->kg_runq_kses = 0; /* XXXKSE change name */ 171/* link it in now that it's consitant */ 172 TAILQ_INSERT_HEAD(&p->p_ksegrps, kg, kg_ksegrp); 173} 174 175/* 176 * for a newly created process, 177 * link up a the structure and its initial threads etc. 178 */ 179void 180proc_linkup(struct proc *p, struct ksegrp *kg, 181 struct kse *ke, struct thread *td) 182{ 183 184 TAILQ_INIT(&p->p_ksegrps); /* all ksegrps in proc */ 185 TAILQ_INIT(&p->p_threads); /* all threads in proc */ 186 187 ksegrp_link(kg, p); 188 kse_link(ke, kg); 189 thread_link(td, kg); 190 /* link them together for 1:1 */ 191 td->td_kse = ke; 192 ke->ke_thread = td; 193} 194 195/* temporary version is ultra simple while we are in 1:1 mode */ 196struct thread * 197thread_get(struct proc *p) 198{ 199 struct thread *td = &p->p_xxthread; 200 201 return (td); 202} 203 204 205/********************* 206* STUB KSE syscalls 207*********************/ 208 209/* struct thread_wakeup_args { struct thread_mailbox *tmbx; }; */ 210int 211thread_wakeup(struct thread *td, struct thread_wakeup_args *uap) 212{ 213 214 return(ENOSYS); 215} 216 217int 218kse_exit(struct thread *td, struct kse_exit_args *uap) 219{ 220 221 return(ENOSYS); 222} 223 224int 225kse_yield(struct thread *td, struct kse_yield_args *uap) 226{ 227 228 return(ENOSYS); 229} 230 231int kse_wakeup(struct thread *td, struct kse_wakeup_args *uap) 232{ 233 234 return(ENOSYS); 235} 236 237 238int 239kse_new(struct thread *td, struct kse_new_args *uap) 240/* struct kse_new_args { 241 struct kse_mailbox *mbx; 242 int new_grp_flag; 243}; */ 244{ 245 246 return (ENOSYS); 247} 248 249/* 250 * Is p an inferior of the current process? 251 */ 252int 253inferior(p) 254 register struct proc *p; 255{ 256 257 sx_assert(&proctree_lock, SX_LOCKED); 258 for (; p != curproc; p = p->p_pptr) 259 if (p->p_pid == 0) 260 return (0); 261 return (1); 262} 263 264/* 265 * Locate a process by number 266 */ 267struct proc * 268pfind(pid) 269 register pid_t pid; 270{ 271 register struct proc *p; 272 273 sx_slock(&allproc_lock);
|
| 274 p = dopfind(pid); 275 sx_sunlock(&allproc_lock); 276 return (p); 277} 278 279static struct proc * 280dopfind(pid) 281 register pid_t pid; 282{ 283 register struct proc *p; 284 285 sx_assert(&allproc_lock, SX_LOCKED); 286
|
268 LIST_FOREACH(p, PIDHASH(pid), p_hash) 269 if (p->p_pid == pid) { 270 PROC_LOCK(p); 271 break; 272 }
| 287 LIST_FOREACH(p, PIDHASH(pid), p_hash) 288 if (p->p_pid == pid) { 289 PROC_LOCK(p); 290 break; 291 }
|
273 sx_sunlock(&allproc_lock);
| |
274 return (p); 275} 276 277/*
| 292 return (p); 293} 294 295/*
|
278 * Locate a process group by number
| 296 * Locate a process group by number. 297 * The caller must hold pgrpsess_lock.
|
279 */ 280struct pgrp * 281pgfind(pgid) 282 register pid_t pgid; 283{ 284 register struct pgrp *pgrp; 285
| 298 */ 299struct pgrp * 300pgfind(pgid) 301 register pid_t pgid; 302{ 303 register struct pgrp *pgrp; 304
|
286 LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash) 287 if (pgrp->pg_id == pgid)
| 305 PGRPSESS_LOCK_ASSERT(SX_LOCKED); 306 307 LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash) { 308 if (pgrp->pg_id == pgid) { 309 PGRP_LOCK(pgrp);
|
288 return (pgrp);
| 310 return (pgrp);
|
| 311 } 312 }
|
289 return (NULL); 290} 291 292/*
| 313 return (NULL); 314} 315 316/*
|
293 * Move p to a new or existing process group (and session)
| 317 * Create a new process group. 318 * pgid must be equal to the pid of p. 319 * Begin a new session if required.
|
294 */ 295int
| 320 */ 321int
|
296enterpgrp(p, pgid, mksess)
| 322enterpgrp(p, pgid, pgrp, sess)
|
297 register struct proc *p; 298 pid_t pgid;
| 323 register struct proc *p; 324 pid_t pgid;
|
299 int mksess;
| 325 struct pgrp *pgrp; 326 struct session *sess;
|
300{
| 327{
|
301 register struct pgrp *pgrp = pgfind(pgid); 302 struct pgrp *savegrp;
| 328 struct pgrp *pgrp2;
|
303
| 329
|
304 KASSERT(pgrp == NULL || !mksess, 305 ("enterpgrp: setsid into non-empty pgrp"));
| 330 PGRPSESS_LOCK_ASSERT(SX_XLOCKED); 331 332 KASSERT(pgrp != NULL, ("enterpgrp: pgrp == NULL")); 333 KASSERT(p->p_pid == pgid, 334 ("enterpgrp: new pgrp and pid != pgid")); 335 336 pgrp2 = pgfind(pgid); 337 338 KASSERT(pgrp2 == NULL, 339 ("enterpgrp: pgrp with pgid exists"));
|
306 KASSERT(!SESS_LEADER(p), 307 ("enterpgrp: session leader attempted setpgrp")); 308
| 340 KASSERT(!SESS_LEADER(p), 341 ("enterpgrp: session leader attempted setpgrp")); 342
|
309 if (pgrp == NULL) { 310 pid_t savepid = p->p_pid; 311 struct proc *np;
| 343 mtx_init(&pgrp->pg_mtx, "process group", MTX_DEF); 344 345 if (sess != NULL) {
|
312 /*
| 346 /*
|
313 * new process group
| 347 * new session
|
314 */
| 348 */
|
315 KASSERT(p->p_pid == pgid, 316 ("enterpgrp: new pgrp and pid != pgid")); 317 if ((np = pfind(savepid)) == NULL || np != p) { 318 if (np != NULL) 319 PROC_UNLOCK(np); 320 return (ESRCH); 321 } 322 PROC_UNLOCK(np); 323 MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 324 M_WAITOK); 325 if (mksess) { 326 register struct session *sess; 327 328 /* 329 * new session 330 */ 331 MALLOC(sess, struct session *, sizeof(struct session), 332 M_SESSION, M_WAITOK); 333 sess->s_leader = p; 334 sess->s_sid = p->p_pid; 335 sess->s_count = 1; 336 sess->s_ttyvp = NULL; 337 sess->s_ttyp = NULL; 338 bcopy(p->p_session->s_login, sess->s_login,
| 349 mtx_init(&sess->s_mtx, "session", MTX_DEF); 350 PROC_LOCK(p); 351 p->p_flag &= ~P_CONTROLT; 352 PROC_UNLOCK(p); 353 PGRP_LOCK(pgrp); 354 sess->s_leader = p; 355 sess->s_sid = p->p_pid; 356 sess->s_count = 1; 357 sess->s_ttyvp = NULL; 358 sess->s_ttyp = NULL; 359 bcopy(p->p_session->s_login, sess->s_login,
|
339 sizeof(sess->s_login));
| 360 sizeof(sess->s_login));
|
340 PROC_LOCK(p); 341 p->p_flag &= ~P_CONTROLT; 342 PROC_UNLOCK(p); 343 pgrp->pg_session = sess; 344 KASSERT(p == curproc, 345 ("enterpgrp: mksession and p != curproc")); 346 } else { 347 pgrp->pg_session = p->p_session; 348 pgrp->pg_session->s_count++; 349 } 350 pgrp->pg_id = pgid; 351 LIST_INIT(&pgrp->pg_members); 352 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash); 353 pgrp->pg_jobc = 0; 354 SLIST_INIT(&pgrp->pg_sigiolst); 355 } else if (pgrp == p->p_pgrp) 356 return (0);
| 361 pgrp->pg_session = sess; 362 KASSERT(p == curproc, 363 ("enterpgrp: mksession and p != curproc")); 364 } else { 365 pgrp->pg_session = p->p_session; 366 SESS_LOCK(pgrp->pg_session); 367 pgrp->pg_session->s_count++; 368 SESS_UNLOCK(pgrp->pg_session); 369 PGRP_LOCK(pgrp); 370 } 371 pgrp->pg_id = pgid; 372 LIST_INIT(&pgrp->pg_members);
|
357 358 /*
| 373 374 /*
|
| 375 * As we have an exclusive lock of pgrpsess_lock, 376 * this should not deadlock. 377 */ 378 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash); 379 pgrp->pg_jobc = 0; 380 SLIST_INIT(&pgrp->pg_sigiolst); 381 PGRP_UNLOCK(pgrp); 382 383 doenterpgrp(p, pgrp); 384 385 return (0); 386} 387 388/* 389 * Move p to an existing process group 390 */ 391int 392enterthispgrp(p, pgrp) 393 register struct proc *p; 394 struct pgrp *pgrp; 395{ 396 PGRPSESS_LOCK_ASSERT(SX_XLOCKED); 397 PROC_LOCK_ASSERT(p, MA_NOTOWNED); 398 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); 399 PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED); 400 SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED); 401 KASSERT(pgrp->pg_session == p->p_session, 402 ("%s: pgrp's session %p, p->p_session %p.\n", 403 __func__, 404 pgrp->pg_session, 405 p->p_session)); 406 KASSERT(pgrp != p->p_pgrp, 407 ("%s: p belongs to pgrp.", __func__)); 408 409 doenterpgrp(p, pgrp); 410 411 return (0); 412} 413 414/* 415 * Move p to a process group 416 */ 417static void 418doenterpgrp(p, pgrp) 419 struct proc *p; 420 struct pgrp *pgrp; 421{ 422 struct pgrp *savepgrp; 423 424 PGRPSESS_LOCK_ASSERT(SX_XLOCKED); 425 PROC_LOCK_ASSERT(p, MA_NOTOWNED); 426 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); 427 PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED); 428 SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED); 429 430 savepgrp = p->p_pgrp; 431 432 /*
|
359 * Adjust eligibility of affected pgrps to participate in job control. 360 * Increment eligibility counts before decrementing, otherwise we 361 * could reach 0 spuriously during the first call. 362 */ 363 fixjobc(p, pgrp, 1); 364 fixjobc(p, p->p_pgrp, 0); 365
| 433 * Adjust eligibility of affected pgrps to participate in job control. 434 * Increment eligibility counts before decrementing, otherwise we 435 * could reach 0 spuriously during the first call. 436 */ 437 fixjobc(p, pgrp, 1); 438 fixjobc(p, p->p_pgrp, 0); 439
|
| 440 PGRP_LOCK(pgrp); 441 PGRP_LOCK(savepgrp);
|
366 PROC_LOCK(p); 367 LIST_REMOVE(p, p_pglist);
| 442 PROC_LOCK(p); 443 LIST_REMOVE(p, p_pglist);
|
368 savegrp = p->p_pgrp;
| |
369 p->p_pgrp = pgrp;
| 444 p->p_pgrp = pgrp;
|
370 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
| |
371 PROC_UNLOCK(p);
| 445 PROC_UNLOCK(p);
|
372 if (LIST_EMPTY(&savegrp->pg_members)) 373 pgdelete(savegrp); 374 return (0);
| 446 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist); 447 PGRP_UNLOCK(savepgrp); 448 PGRP_UNLOCK(pgrp); 449 if (LIST_EMPTY(&savepgrp->pg_members)) 450 pgdelete(savepgrp);
|
375} 376 377/* 378 * remove process from process group 379 */ 380int 381leavepgrp(p) 382 register struct proc *p; 383{
| 451} 452 453/* 454 * remove process from process group 455 */ 456int 457leavepgrp(p) 458 register struct proc *p; 459{
|
384 struct pgrp *savegrp;
| 460 struct pgrp *savepgrp;
|
385
| 461
|
| 462 PGRPSESS_XLOCK(); 463 savepgrp = p->p_pgrp; 464 PGRP_LOCK(savepgrp);
|
386 PROC_LOCK(p); 387 LIST_REMOVE(p, p_pglist);
| 465 PROC_LOCK(p); 466 LIST_REMOVE(p, p_pglist);
|
388 savegrp = p->p_pgrp;
| |
389 p->p_pgrp = NULL; 390 PROC_UNLOCK(p);
| 467 p->p_pgrp = NULL; 468 PROC_UNLOCK(p);
|
391 if (LIST_EMPTY(&savegrp->pg_members)) 392 pgdelete(savegrp);
| 469 PGRP_UNLOCK(savepgrp); 470 if (LIST_EMPTY(&savepgrp->pg_members)) 471 pgdelete(savepgrp); 472 PGRPSESS_XUNLOCK();
|
393 return (0); 394} 395 396/* 397 * delete a process group 398 */ 399static void 400pgdelete(pgrp) 401 register struct pgrp *pgrp; 402{
| 473 return (0); 474} 475 476/* 477 * delete a process group 478 */ 479static void 480pgdelete(pgrp) 481 register struct pgrp *pgrp; 482{
|
| 483 struct session *savesess;
|
403
| 484
|
| 485 PGRPSESS_LOCK_ASSERT(SX_XLOCKED); 486 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); 487 SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED); 488 489 PGRP_LOCK(pgrp); 490
|
404 /* 405 * Reset any sigio structures pointing to us as a result of 406 * F_SETOWN with our pgid. 407 */ 408 funsetownlst(&pgrp->pg_sigiolst); 409 410 if (pgrp->pg_session->s_ttyp != NULL && 411 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 412 pgrp->pg_session->s_ttyp->t_pgrp = NULL; 413 LIST_REMOVE(pgrp, pg_hash);
| 491 /* 492 * Reset any sigio structures pointing to us as a result of 493 * F_SETOWN with our pgid. 494 */ 495 funsetownlst(&pgrp->pg_sigiolst); 496 497 if (pgrp->pg_session->s_ttyp != NULL && 498 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 499 pgrp->pg_session->s_ttyp->t_pgrp = NULL; 500 LIST_REMOVE(pgrp, pg_hash);
|
414 if (--pgrp->pg_session->s_count == 0)
| 501 savesess = pgrp->pg_session; 502 SESS_LOCK(savesess); 503 savesess->s_count--; 504 SESS_UNLOCK(savesess); 505 PGRP_UNLOCK(pgrp); 506 if (savesess->s_count == 0) { 507 mtx_destroy(&savesess->s_mtx);
|
415 FREE(pgrp->pg_session, M_SESSION);
| 508 FREE(pgrp->pg_session, M_SESSION);
|
| 509 } 510 mtx_destroy(&pgrp->pg_mtx);
|
416 FREE(pgrp, M_PGRP); 417} 418 419/* 420 * Adjust pgrp jobc counters when specified process changes process group. 421 * We count the number of processes in each process group that "qualify" 422 * the group for terminal job control (those with a parent in a different 423 * process group of the same session). If that count reaches zero, the 424 * process group becomes orphaned. Check both the specified process' 425 * process group and that of its children. 426 * entering == 0 => p is leaving specified group. 427 * entering == 1 => p is entering specified group. 428 */ 429void 430fixjobc(p, pgrp, entering) 431 register struct proc *p; 432 register struct pgrp *pgrp; 433 int entering; 434{ 435 register struct pgrp *hispgrp;
| 511 FREE(pgrp, M_PGRP); 512} 513 514/* 515 * Adjust pgrp jobc counters when specified process changes process group. 516 * We count the number of processes in each process group that "qualify" 517 * the group for terminal job control (those with a parent in a different 518 * process group of the same session). If that count reaches zero, the 519 * process group becomes orphaned. Check both the specified process' 520 * process group and that of its children. 521 * entering == 0 => p is leaving specified group. 522 * entering == 1 => p is entering specified group. 523 */ 524void 525fixjobc(p, pgrp, entering) 526 register struct proc *p; 527 register struct pgrp *pgrp; 528 int entering; 529{ 530 register struct pgrp *hispgrp;
|
436 register struct session *mysession = pgrp->pg_session;
| 531 register struct session *mysession;
|
437
| 532
|
| 533 PGRPSESS_LOCK_ASSERT(SX_LOCKED); 534 PROC_LOCK_ASSERT(p, MA_NOTOWNED); 535 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); 536 SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED); 537
|
438 /* 439 * Check p's parent to see whether p qualifies its own process 440 * group; if so, adjust count for p's process group. 441 */
| 538 /* 539 * Check p's parent to see whether p qualifies its own process 540 * group; if so, adjust count for p's process group. 541 */
|
| 542 mysession = pgrp->pg_session;
|
442 sx_slock(&proctree_lock); 443 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && 444 hispgrp->pg_session == mysession) {
| 543 sx_slock(&proctree_lock); 544 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && 545 hispgrp->pg_session == mysession) {
|
| 546 PGRP_LOCK(pgrp);
|
445 if (entering) 446 pgrp->pg_jobc++;
| 547 if (entering) 548 pgrp->pg_jobc++;
|
447 else if (--pgrp->pg_jobc == 0) 448 orphanpg(pgrp);
| 549 else { 550 --pgrp->pg_jobc; 551 if (pgrp->pg_jobc == 0) 552 orphanpg(pgrp); 553 } 554 PGRP_UNLOCK(pgrp);
|
449 } 450 451 /* 452 * Check this process' children to see whether they qualify 453 * their process groups; if so, adjust counts for children's 454 * process groups. 455 */
| 555 } 556 557 /* 558 * Check this process' children to see whether they qualify 559 * their process groups; if so, adjust counts for children's 560 * process groups. 561 */
|
456 LIST_FOREACH(p, &p->p_children, p_sibling)
| 562 LIST_FOREACH(p, &p->p_children, p_sibling) {
|
457 if ((hispgrp = p->p_pgrp) != pgrp && 458 hispgrp->pg_session == mysession && 459 p->p_stat != SZOMB) {
| 563 if ((hispgrp = p->p_pgrp) != pgrp && 564 hispgrp->pg_session == mysession && 565 p->p_stat != SZOMB) {
|
| 566 PGRP_LOCK(hispgrp);
|
460 if (entering) 461 hispgrp->pg_jobc++;
| 567 if (entering) 568 hispgrp->pg_jobc++;
|
462 else if (--hispgrp->pg_jobc == 0) 463 orphanpg(hispgrp);
| 569 else { 570 --hispgrp->pg_jobc; 571 if (hispgrp->pg_jobc == 0) 572 orphanpg(hispgrp); 573 } 574 PGRP_UNLOCK(hispgrp);
|
464 }
| 575 }
|
| 576 }
|
465 sx_sunlock(&proctree_lock); 466} 467 468/* 469 * A process group has become orphaned; 470 * if there are any stopped processes in the group, 471 * hang-up all process in that group. 472 */ 473static void 474orphanpg(pg) 475 struct pgrp *pg; 476{ 477 register struct proc *p; 478
| 577 sx_sunlock(&proctree_lock); 578} 579 580/* 581 * A process group has become orphaned; 582 * if there are any stopped processes in the group, 583 * hang-up all process in that group. 584 */ 585static void 586orphanpg(pg) 587 struct pgrp *pg; 588{ 589 register struct proc *p; 590
|
| 591 PGRP_LOCK_ASSERT(pg, MA_OWNED); 592
|
479 mtx_lock_spin(&sched_lock); 480 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 481 if (p->p_stat == SSTOP) { 482 mtx_unlock_spin(&sched_lock); 483 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 484 PROC_LOCK(p); 485 psignal(p, SIGHUP); 486 psignal(p, SIGCONT); 487 PROC_UNLOCK(p); 488 } 489 return; 490 } 491 } 492 mtx_unlock_spin(&sched_lock); 493} 494 495#include "opt_ddb.h" 496#ifdef DDB 497#include <ddb/ddb.h> 498 499DB_SHOW_COMMAND(pgrpdump, pgrpdump) 500{ 501 register struct pgrp *pgrp; 502 register struct proc *p; 503 register int i; 504 505 for (i = 0; i <= pgrphash; i++) { 506 if (!LIST_EMPTY(&pgrphashtbl[i])) { 507 printf("\tindx %d\n", i); 508 LIST_FOREACH(pgrp, &pgrphashtbl[i], pg_hash) { 509 printf( 510 "\tpgrp %p, pgid %ld, sess %p, sesscnt %d, mem %p\n", 511 (void *)pgrp, (long)pgrp->pg_id, 512 (void *)pgrp->pg_session, 513 pgrp->pg_session->s_count, 514 (void *)LIST_FIRST(&pgrp->pg_members)); 515 LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { 516 printf("\t\tpid %ld addr %p pgrp %p\n", 517 (long)p->p_pid, (void *)p, 518 (void *)p->p_pgrp); 519 } 520 } 521 } 522 } 523} 524#endif /* DDB */ 525 526/* 527 * Fill in an kinfo_proc structure for the specified process. 528 */ 529void 530fill_kinfo_proc(p, kp) 531 struct proc *p; 532 struct kinfo_proc *kp; 533{ 534 struct thread *td; 535 struct tty *tp; 536 struct session *sp; 537 struct timeval tv; 538 539 bzero(kp, sizeof(*kp)); 540 541 kp->ki_structsize = sizeof(*kp); 542 kp->ki_paddr = p; 543 PROC_LOCK(p); 544 kp->ki_addr =/* p->p_addr; */0; /* XXXKSE */ 545 kp->ki_args = p->p_args; 546 kp->ki_tracep = p->p_tracep; 547 kp->ki_textvp = p->p_textvp; 548 kp->ki_fd = p->p_fd; 549 kp->ki_vmspace = p->p_vmspace; 550 if (p->p_ucred) { 551 kp->ki_uid = p->p_ucred->cr_uid; 552 kp->ki_ruid = p->p_ucred->cr_ruid; 553 kp->ki_svuid = p->p_ucred->cr_svuid; 554 /* XXX bde doesn't like KI_NGROUPS */ 555 kp->ki_ngroups = min(p->p_ucred->cr_ngroups, KI_NGROUPS); 556 bcopy(p->p_ucred->cr_groups, kp->ki_groups, 557 kp->ki_ngroups * sizeof(gid_t)); 558 kp->ki_rgid = p->p_ucred->cr_rgid; 559 kp->ki_svgid = p->p_ucred->cr_svgid; 560 } 561 if (p->p_procsig) { 562 kp->ki_sigignore = p->p_procsig->ps_sigignore; 563 kp->ki_sigcatch = p->p_procsig->ps_sigcatch; 564 } 565 mtx_lock_spin(&sched_lock); 566 if (p->p_stat != SIDL && p->p_stat != SZOMB && p->p_vmspace != NULL) { 567 struct vmspace *vm = p->p_vmspace; 568 569 kp->ki_size = vm->vm_map.size; 570 kp->ki_rssize = vmspace_resident_count(vm); /*XXX*/ 571 if (p->p_sflag & PS_INMEM) 572 kp->ki_rssize += UAREA_PAGES; 573 FOREACH_THREAD_IN_PROC(p, td) /* XXXKSE: thread swapout check */ 574 kp->ki_rssize += KSTACK_PAGES; 575 kp->ki_swrss = vm->vm_swrss; 576 kp->ki_tsize = vm->vm_tsize; 577 kp->ki_dsize = vm->vm_dsize; 578 kp->ki_ssize = vm->vm_ssize; 579 } 580 if ((p->p_sflag & PS_INMEM) && p->p_stats) { 581 kp->ki_start = p->p_stats->p_start; 582 kp->ki_rusage = p->p_stats->p_ru; 583 kp->ki_childtime.tv_sec = p->p_stats->p_cru.ru_utime.tv_sec + 584 p->p_stats->p_cru.ru_stime.tv_sec; 585 kp->ki_childtime.tv_usec = p->p_stats->p_cru.ru_utime.tv_usec + 586 p->p_stats->p_cru.ru_stime.tv_usec; 587 } 588 td = FIRST_THREAD_IN_PROC(p); 589 if (td->td_wmesg != NULL) 590 strncpy(kp->ki_wmesg, td->td_wmesg, sizeof(kp->ki_wmesg) - 1); 591 if (p->p_stat == SMTX) { 592 kp->ki_kiflag |= KI_MTXBLOCK; 593 strncpy(kp->ki_mtxname, td->td_mtxname, 594 sizeof(kp->ki_mtxname) - 1); 595 } 596 kp->ki_stat = p->p_stat; 597 kp->ki_sflag = p->p_sflag; 598 kp->ki_swtime = p->p_swtime; 599 kp->ki_traceflag = p->p_traceflag; 600 kp->ki_pid = p->p_pid; 601 /* vvv XXXKSE */ 602 bintime2timeval(&p->p_runtime, &tv); 603 kp->ki_runtime = tv.tv_sec * (u_int64_t)1000000 + tv.tv_usec; 604 kp->ki_pctcpu = p->p_kse.ke_pctcpu; 605 kp->ki_estcpu = td->td_ksegrp->kg_estcpu; 606 kp->ki_slptime = td->td_ksegrp->kg_slptime; 607 kp->ki_wchan = td->td_wchan; 608 kp->ki_pri.pri_level = td->td_priority; 609 kp->ki_pri.pri_user = td->td_ksegrp->kg_user_pri; 610 kp->ki_pri.pri_class = td->td_ksegrp->kg_pri_class; 611 kp->ki_pri.pri_native = td->td_base_pri; 612 kp->ki_nice = td->td_ksegrp->kg_nice; 613 kp->ki_rqindex = p->p_kse.ke_rqindex; 614 kp->ki_oncpu = p->p_kse.ke_oncpu; 615 kp->ki_lastcpu = td->td_lastcpu; 616 kp->ki_tdflags = td->td_flags; 617 kp->ki_pcb = td->td_pcb; 618 kp->ki_kstack = (void *)td->td_kstack; 619 /* ^^^ XXXKSE */ 620 mtx_unlock_spin(&sched_lock); 621 sp = NULL;
| 593 mtx_lock_spin(&sched_lock); 594 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 595 if (p->p_stat == SSTOP) { 596 mtx_unlock_spin(&sched_lock); 597 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 598 PROC_LOCK(p); 599 psignal(p, SIGHUP); 600 psignal(p, SIGCONT); 601 PROC_UNLOCK(p); 602 } 603 return; 604 } 605 } 606 mtx_unlock_spin(&sched_lock); 607} 608 609#include "opt_ddb.h" 610#ifdef DDB 611#include <ddb/ddb.h> 612 613DB_SHOW_COMMAND(pgrpdump, pgrpdump) 614{ 615 register struct pgrp *pgrp; 616 register struct proc *p; 617 register int i; 618 619 for (i = 0; i <= pgrphash; i++) { 620 if (!LIST_EMPTY(&pgrphashtbl[i])) { 621 printf("\tindx %d\n", i); 622 LIST_FOREACH(pgrp, &pgrphashtbl[i], pg_hash) { 623 printf( 624 "\tpgrp %p, pgid %ld, sess %p, sesscnt %d, mem %p\n", 625 (void *)pgrp, (long)pgrp->pg_id, 626 (void *)pgrp->pg_session, 627 pgrp->pg_session->s_count, 628 (void *)LIST_FIRST(&pgrp->pg_members)); 629 LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { 630 printf("\t\tpid %ld addr %p pgrp %p\n", 631 (long)p->p_pid, (void *)p, 632 (void *)p->p_pgrp); 633 } 634 } 635 } 636 } 637} 638#endif /* DDB */ 639 640/* 641 * Fill in an kinfo_proc structure for the specified process. 642 */ 643void 644fill_kinfo_proc(p, kp) 645 struct proc *p; 646 struct kinfo_proc *kp; 647{ 648 struct thread *td; 649 struct tty *tp; 650 struct session *sp; 651 struct timeval tv; 652 653 bzero(kp, sizeof(*kp)); 654 655 kp->ki_structsize = sizeof(*kp); 656 kp->ki_paddr = p; 657 PROC_LOCK(p); 658 kp->ki_addr =/* p->p_addr; */0; /* XXXKSE */ 659 kp->ki_args = p->p_args; 660 kp->ki_tracep = p->p_tracep; 661 kp->ki_textvp = p->p_textvp; 662 kp->ki_fd = p->p_fd; 663 kp->ki_vmspace = p->p_vmspace; 664 if (p->p_ucred) { 665 kp->ki_uid = p->p_ucred->cr_uid; 666 kp->ki_ruid = p->p_ucred->cr_ruid; 667 kp->ki_svuid = p->p_ucred->cr_svuid; 668 /* XXX bde doesn't like KI_NGROUPS */ 669 kp->ki_ngroups = min(p->p_ucred->cr_ngroups, KI_NGROUPS); 670 bcopy(p->p_ucred->cr_groups, kp->ki_groups, 671 kp->ki_ngroups * sizeof(gid_t)); 672 kp->ki_rgid = p->p_ucred->cr_rgid; 673 kp->ki_svgid = p->p_ucred->cr_svgid; 674 } 675 if (p->p_procsig) { 676 kp->ki_sigignore = p->p_procsig->ps_sigignore; 677 kp->ki_sigcatch = p->p_procsig->ps_sigcatch; 678 } 679 mtx_lock_spin(&sched_lock); 680 if (p->p_stat != SIDL && p->p_stat != SZOMB && p->p_vmspace != NULL) { 681 struct vmspace *vm = p->p_vmspace; 682 683 kp->ki_size = vm->vm_map.size; 684 kp->ki_rssize = vmspace_resident_count(vm); /*XXX*/ 685 if (p->p_sflag & PS_INMEM) 686 kp->ki_rssize += UAREA_PAGES; 687 FOREACH_THREAD_IN_PROC(p, td) /* XXXKSE: thread swapout check */ 688 kp->ki_rssize += KSTACK_PAGES; 689 kp->ki_swrss = vm->vm_swrss; 690 kp->ki_tsize = vm->vm_tsize; 691 kp->ki_dsize = vm->vm_dsize; 692 kp->ki_ssize = vm->vm_ssize; 693 } 694 if ((p->p_sflag & PS_INMEM) && p->p_stats) { 695 kp->ki_start = p->p_stats->p_start; 696 kp->ki_rusage = p->p_stats->p_ru; 697 kp->ki_childtime.tv_sec = p->p_stats->p_cru.ru_utime.tv_sec + 698 p->p_stats->p_cru.ru_stime.tv_sec; 699 kp->ki_childtime.tv_usec = p->p_stats->p_cru.ru_utime.tv_usec + 700 p->p_stats->p_cru.ru_stime.tv_usec; 701 } 702 td = FIRST_THREAD_IN_PROC(p); 703 if (td->td_wmesg != NULL) 704 strncpy(kp->ki_wmesg, td->td_wmesg, sizeof(kp->ki_wmesg) - 1); 705 if (p->p_stat == SMTX) { 706 kp->ki_kiflag |= KI_MTXBLOCK; 707 strncpy(kp->ki_mtxname, td->td_mtxname, 708 sizeof(kp->ki_mtxname) - 1); 709 } 710 kp->ki_stat = p->p_stat; 711 kp->ki_sflag = p->p_sflag; 712 kp->ki_swtime = p->p_swtime; 713 kp->ki_traceflag = p->p_traceflag; 714 kp->ki_pid = p->p_pid; 715 /* vvv XXXKSE */ 716 bintime2timeval(&p->p_runtime, &tv); 717 kp->ki_runtime = tv.tv_sec * (u_int64_t)1000000 + tv.tv_usec; 718 kp->ki_pctcpu = p->p_kse.ke_pctcpu; 719 kp->ki_estcpu = td->td_ksegrp->kg_estcpu; 720 kp->ki_slptime = td->td_ksegrp->kg_slptime; 721 kp->ki_wchan = td->td_wchan; 722 kp->ki_pri.pri_level = td->td_priority; 723 kp->ki_pri.pri_user = td->td_ksegrp->kg_user_pri; 724 kp->ki_pri.pri_class = td->td_ksegrp->kg_pri_class; 725 kp->ki_pri.pri_native = td->td_base_pri; 726 kp->ki_nice = td->td_ksegrp->kg_nice; 727 kp->ki_rqindex = p->p_kse.ke_rqindex; 728 kp->ki_oncpu = p->p_kse.ke_oncpu; 729 kp->ki_lastcpu = td->td_lastcpu; 730 kp->ki_tdflags = td->td_flags; 731 kp->ki_pcb = td->td_pcb; 732 kp->ki_kstack = (void *)td->td_kstack; 733 /* ^^^ XXXKSE */ 734 mtx_unlock_spin(&sched_lock); 735 sp = NULL;
|
| 736 tp = NULL;
|
622 if (p->p_pgrp) { 623 kp->ki_pgid = p->p_pgrp->pg_id; 624 kp->ki_jobc = p->p_pgrp->pg_jobc; 625 sp = p->p_pgrp->pg_session; 626 627 if (sp != NULL) { 628 kp->ki_sid = sp->s_sid;
| 737 if (p->p_pgrp) { 738 kp->ki_pgid = p->p_pgrp->pg_id; 739 kp->ki_jobc = p->p_pgrp->pg_jobc; 740 sp = p->p_pgrp->pg_session; 741 742 if (sp != NULL) { 743 kp->ki_sid = sp->s_sid;
|
| 744 SESS_LOCK(sp);
|
629 strncpy(kp->ki_login, sp->s_login, 630 sizeof(kp->ki_login) - 1); 631 if (sp->s_ttyvp) 632 kp->ki_kiflag |= KI_CTTY; 633 if (SESS_LEADER(p)) 634 kp->ki_kiflag |= KI_SLEADER;
| 745 strncpy(kp->ki_login, sp->s_login, 746 sizeof(kp->ki_login) - 1); 747 if (sp->s_ttyvp) 748 kp->ki_kiflag |= KI_CTTY; 749 if (SESS_LEADER(p)) 750 kp->ki_kiflag |= KI_SLEADER;
|
| 751 tp = sp->s_ttyp; 752 SESS_UNLOCK(sp);
|
635 } 636 }
| 753 } 754 }
|
637 if ((p->p_flag & P_CONTROLT) && sp && ((tp = sp->s_ttyp) != NULL)) {
| 755 if ((p->p_flag & P_CONTROLT) && tp != NULL) {
|
638 kp->ki_tdev = dev2udev(tp->t_dev); 639 kp->ki_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 640 if (tp->t_session) 641 kp->ki_tsid = tp->t_session->s_sid; 642 } else 643 kp->ki_tdev = NOUDEV; 644 if (p->p_comm[0] != '\0') { 645 strncpy(kp->ki_comm, p->p_comm, sizeof(kp->ki_comm) - 1); 646 strncpy(kp->ki_ocomm, p->p_comm, sizeof(kp->ki_ocomm) - 1); 647 } 648 kp->ki_siglist = p->p_siglist; 649 kp->ki_sigmask = p->p_sigmask; 650 kp->ki_xstat = p->p_xstat; 651 kp->ki_acflag = p->p_acflag; 652 kp->ki_flag = p->p_flag; 653 /* If jailed(p->p_ucred), emulate the old P_JAILED flag. */ 654 if (jailed(p->p_ucred)) 655 kp->ki_flag |= P_JAILED; 656 kp->ki_lock = p->p_lock; 657 if (p->p_pptr) 658 kp->ki_ppid = p->p_pptr->p_pid; 659 PROC_UNLOCK(p); 660} 661 662/* 663 * Locate a zombie process by number 664 */ 665struct proc * 666zpfind(pid_t pid) 667{ 668 struct proc *p; 669 670 sx_slock(&allproc_lock); 671 LIST_FOREACH(p, &zombproc, p_list) 672 if (p->p_pid == pid) { 673 PROC_LOCK(p); 674 break; 675 } 676 sx_sunlock(&allproc_lock); 677 return (p); 678} 679 680 681static int 682sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb) 683{ 684 struct kinfo_proc kinfo_proc; 685 int error; 686 struct proc *np; 687 pid_t pid = p->p_pid; 688 689 fill_kinfo_proc(p, &kinfo_proc); 690 error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, sizeof(kinfo_proc)); 691 if (error) 692 return (error); 693 if (doingzomb) 694 np = zpfind(pid); 695 else { 696 if (pid == 0) 697 return (0); 698 np = pfind(pid); 699 } 700 if (np == NULL) 701 return EAGAIN; 702 if (np != p) { 703 PROC_UNLOCK(np); 704 return EAGAIN; 705 } 706 PROC_UNLOCK(np); 707 return (0); 708} 709 710static int 711sysctl_kern_proc(SYSCTL_HANDLER_ARGS) 712{ 713 int *name = (int*) arg1; 714 u_int namelen = arg2; 715 struct proc *p; 716 int doingzomb; 717 int error = 0; 718 719 if (oidp->oid_number == KERN_PROC_PID) { 720 if (namelen != 1) 721 return (EINVAL); 722 p = pfind((pid_t)name[0]); 723 if (!p) 724 return (0); 725 if (p_cansee(curproc, p)) { 726 PROC_UNLOCK(p); 727 return (0); 728 } 729 PROC_UNLOCK(p); 730 error = sysctl_out_proc(p, req, 0); 731 return (error); 732 } 733 if (oidp->oid_number == KERN_PROC_ALL && !namelen) 734 ; 735 else if (oidp->oid_number != KERN_PROC_ALL && namelen == 1) 736 ; 737 else 738 return (EINVAL); 739 740 if (!req->oldptr) { 741 /* overestimate by 5 procs */ 742 error = SYSCTL_OUT(req, 0, sizeof (struct kinfo_proc) * 5); 743 if (error) 744 return (error); 745 } 746 sx_slock(&allproc_lock); 747 for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) { 748 if (!doingzomb) 749 p = LIST_FIRST(&allproc); 750 else 751 p = LIST_FIRST(&zombproc); 752 for (; p != 0; p = LIST_NEXT(p, p_list)) { 753 /* 754 * Show a user only appropriate processes. 755 */ 756 if (p_cansee(curproc, p)) 757 continue; 758 /* 759 * Skip embryonic processes. 760 */ 761 if (p->p_stat == SIDL) 762 continue; 763 /* 764 * TODO - make more efficient (see notes below). 765 * do by session. 766 */ 767 switch (oidp->oid_number) { 768 769 case KERN_PROC_PGRP: 770 /* could do this by traversing pgrp */
| 756 kp->ki_tdev = dev2udev(tp->t_dev); 757 kp->ki_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 758 if (tp->t_session) 759 kp->ki_tsid = tp->t_session->s_sid; 760 } else 761 kp->ki_tdev = NOUDEV; 762 if (p->p_comm[0] != '\0') { 763 strncpy(kp->ki_comm, p->p_comm, sizeof(kp->ki_comm) - 1); 764 strncpy(kp->ki_ocomm, p->p_comm, sizeof(kp->ki_ocomm) - 1); 765 } 766 kp->ki_siglist = p->p_siglist; 767 kp->ki_sigmask = p->p_sigmask; 768 kp->ki_xstat = p->p_xstat; 769 kp->ki_acflag = p->p_acflag; 770 kp->ki_flag = p->p_flag; 771 /* If jailed(p->p_ucred), emulate the old P_JAILED flag. */ 772 if (jailed(p->p_ucred)) 773 kp->ki_flag |= P_JAILED; 774 kp->ki_lock = p->p_lock; 775 if (p->p_pptr) 776 kp->ki_ppid = p->p_pptr->p_pid; 777 PROC_UNLOCK(p); 778} 779 780/* 781 * Locate a zombie process by number 782 */ 783struct proc * 784zpfind(pid_t pid) 785{ 786 struct proc *p; 787 788 sx_slock(&allproc_lock); 789 LIST_FOREACH(p, &zombproc, p_list) 790 if (p->p_pid == pid) { 791 PROC_LOCK(p); 792 break; 793 } 794 sx_sunlock(&allproc_lock); 795 return (p); 796} 797 798 799static int 800sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb) 801{ 802 struct kinfo_proc kinfo_proc; 803 int error; 804 struct proc *np; 805 pid_t pid = p->p_pid; 806 807 fill_kinfo_proc(p, &kinfo_proc); 808 error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, sizeof(kinfo_proc)); 809 if (error) 810 return (error); 811 if (doingzomb) 812 np = zpfind(pid); 813 else { 814 if (pid == 0) 815 return (0); 816 np = pfind(pid); 817 } 818 if (np == NULL) 819 return EAGAIN; 820 if (np != p) { 821 PROC_UNLOCK(np); 822 return EAGAIN; 823 } 824 PROC_UNLOCK(np); 825 return (0); 826} 827 828static int 829sysctl_kern_proc(SYSCTL_HANDLER_ARGS) 830{ 831 int *name = (int*) arg1; 832 u_int namelen = arg2; 833 struct proc *p; 834 int doingzomb; 835 int error = 0; 836 837 if (oidp->oid_number == KERN_PROC_PID) { 838 if (namelen != 1) 839 return (EINVAL); 840 p = pfind((pid_t)name[0]); 841 if (!p) 842 return (0); 843 if (p_cansee(curproc, p)) { 844 PROC_UNLOCK(p); 845 return (0); 846 } 847 PROC_UNLOCK(p); 848 error = sysctl_out_proc(p, req, 0); 849 return (error); 850 } 851 if (oidp->oid_number == KERN_PROC_ALL && !namelen) 852 ; 853 else if (oidp->oid_number != KERN_PROC_ALL && namelen == 1) 854 ; 855 else 856 return (EINVAL); 857 858 if (!req->oldptr) { 859 /* overestimate by 5 procs */ 860 error = SYSCTL_OUT(req, 0, sizeof (struct kinfo_proc) * 5); 861 if (error) 862 return (error); 863 } 864 sx_slock(&allproc_lock); 865 for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) { 866 if (!doingzomb) 867 p = LIST_FIRST(&allproc); 868 else 869 p = LIST_FIRST(&zombproc); 870 for (; p != 0; p = LIST_NEXT(p, p_list)) { 871 /* 872 * Show a user only appropriate processes. 873 */ 874 if (p_cansee(curproc, p)) 875 continue; 876 /* 877 * Skip embryonic processes. 878 */ 879 if (p->p_stat == SIDL) 880 continue; 881 /* 882 * TODO - make more efficient (see notes below). 883 * do by session. 884 */ 885 switch (oidp->oid_number) { 886 887 case KERN_PROC_PGRP: 888 /* could do this by traversing pgrp */
|
| 889 PROC_LOCK(p);
|
771 if (p->p_pgrp == NULL ||
| 890 if (p->p_pgrp == NULL ||
|
772 p->p_pgrp->pg_id != (pid_t)name[0])
| 891 p->p_pgrp->pg_id != (pid_t)name[0]) { 892 PROC_UNLOCK(p);
|
773 continue;
| 893 continue;
|
| 894 } 895 PROC_UNLOCK(p);
|
774 break; 775 776 case KERN_PROC_TTY:
| 896 break; 897 898 case KERN_PROC_TTY:
|
| 899 PROC_LOCK(p);
|
777 if ((p->p_flag & P_CONTROLT) == 0 ||
| 900 if ((p->p_flag & P_CONTROLT) == 0 ||
|
778 p->p_session == NULL || 779 p->p_session->s_ttyp == NULL ||
| 901 p->p_session == NULL) { 902 PROC_UNLOCK(p); 903 continue; 904 } 905 SESS_LOCK(p->p_session); 906 if (p->p_session->s_ttyp == NULL ||
|
780 dev2udev(p->p_session->s_ttyp->t_dev) !=
| 907 dev2udev(p->p_session->s_ttyp->t_dev) !=
|
781 (udev_t)name[0])
| 908 (udev_t)name[0]) { 909 SESS_UNLOCK(p->p_session); 910 PROC_UNLOCK(p);
|
782 continue;
| 911 continue;
|
| 912 } 913 SESS_UNLOCK(p->p_session); 914 PROC_UNLOCK(p);
|
783 break; 784 785 case KERN_PROC_UID: 786 if (p->p_ucred == NULL || 787 p->p_ucred->cr_uid != (uid_t)name[0]) 788 continue; 789 break; 790 791 case KERN_PROC_RUID: 792 if (p->p_ucred == NULL || 793 p->p_ucred->cr_ruid != (uid_t)name[0]) 794 continue; 795 break; 796 } 797 798 if (p_cansee(curproc, p)) 799 continue; 800 801 error = sysctl_out_proc(p, req, doingzomb); 802 if (error) { 803 sx_sunlock(&allproc_lock); 804 return (error); 805 } 806 } 807 } 808 sx_sunlock(&allproc_lock); 809 return (0); 810} 811 812/* 813 * This sysctl allows a process to retrieve the argument list or process 814 * title for another process without groping around in the address space 815 * of the other process. It also allow a process to set its own "process 816 * title to a string of its own choice. 817 */ 818static int 819sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS) 820{ 821 int *name = (int*) arg1; 822 u_int namelen = arg2; 823 struct proc *p; 824 struct pargs *pa; 825 int error = 0; 826 827 if (namelen != 1) 828 return (EINVAL); 829 830 p = pfind((pid_t)name[0]); 831 if (!p) 832 return (0); 833 834 if ((!ps_argsopen) && p_cansee(curproc, p)) { 835 PROC_UNLOCK(p); 836 return (0); 837 } 838 PROC_UNLOCK(p); 839 840 if (req->newptr && curproc != p) 841 return (EPERM); 842 843 if (req->oldptr && p->p_args != NULL) 844 error = SYSCTL_OUT(req, p->p_args->ar_args, p->p_args->ar_length); 845 if (req->newptr == NULL) 846 return (error); 847 848 PROC_LOCK(p); 849 pa = p->p_args; 850 p->p_args = NULL; 851 PROC_UNLOCK(p); 852 if (pa != NULL && --pa->ar_ref == 0) 853 FREE(pa, M_PARGS); 854 855 if (req->newlen + sizeof(struct pargs) > ps_arg_cache_limit) 856 return (error); 857 858 MALLOC(pa, struct pargs *, sizeof(struct pargs) + req->newlen, 859 M_PARGS, M_WAITOK); 860 pa->ar_ref = 1; 861 pa->ar_length = req->newlen; 862 error = SYSCTL_IN(req, pa->ar_args, req->newlen); 863 if (!error) { 864 PROC_LOCK(p); 865 p->p_args = pa; 866 PROC_UNLOCK(p); 867 } else 868 FREE(pa, M_PARGS); 869 return (error); 870} 871 872SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table"); 873 874SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT, 875 0, 0, sysctl_kern_proc, "S,proc", "Return entire process table"); 876 877SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, CTLFLAG_RD, 878 sysctl_kern_proc, "Process table"); 879 880SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD, 881 sysctl_kern_proc, "Process table"); 882 883SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD, 884 sysctl_kern_proc, "Process table"); 885 886SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD, 887 sysctl_kern_proc, "Process table"); 888 889SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD, 890 sysctl_kern_proc, "Process table"); 891 892SYSCTL_NODE(_kern_proc, KERN_PROC_ARGS, args, CTLFLAG_RW | CTLFLAG_ANYBODY, 893 sysctl_kern_proc_args, "Process argument list");
| 915 break; 916 917 case KERN_PROC_UID: 918 if (p->p_ucred == NULL || 919 p->p_ucred->cr_uid != (uid_t)name[0]) 920 continue; 921 break; 922 923 case KERN_PROC_RUID: 924 if (p->p_ucred == NULL || 925 p->p_ucred->cr_ruid != (uid_t)name[0]) 926 continue; 927 break; 928 } 929 930 if (p_cansee(curproc, p)) 931 continue; 932 933 error = sysctl_out_proc(p, req, doingzomb); 934 if (error) { 935 sx_sunlock(&allproc_lock); 936 return (error); 937 } 938 } 939 } 940 sx_sunlock(&allproc_lock); 941 return (0); 942} 943 944/* 945 * This sysctl allows a process to retrieve the argument list or process 946 * title for another process without groping around in the address space 947 * of the other process. It also allow a process to set its own "process 948 * title to a string of its own choice. 949 */ 950static int 951sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS) 952{ 953 int *name = (int*) arg1; 954 u_int namelen = arg2; 955 struct proc *p; 956 struct pargs *pa; 957 int error = 0; 958 959 if (namelen != 1) 960 return (EINVAL); 961 962 p = pfind((pid_t)name[0]); 963 if (!p) 964 return (0); 965 966 if ((!ps_argsopen) && p_cansee(curproc, p)) { 967 PROC_UNLOCK(p); 968 return (0); 969 } 970 PROC_UNLOCK(p); 971 972 if (req->newptr && curproc != p) 973 return (EPERM); 974 975 if (req->oldptr && p->p_args != NULL) 976 error = SYSCTL_OUT(req, p->p_args->ar_args, p->p_args->ar_length); 977 if (req->newptr == NULL) 978 return (error); 979 980 PROC_LOCK(p); 981 pa = p->p_args; 982 p->p_args = NULL; 983 PROC_UNLOCK(p); 984 if (pa != NULL && --pa->ar_ref == 0) 985 FREE(pa, M_PARGS); 986 987 if (req->newlen + sizeof(struct pargs) > ps_arg_cache_limit) 988 return (error); 989 990 MALLOC(pa, struct pargs *, sizeof(struct pargs) + req->newlen, 991 M_PARGS, M_WAITOK); 992 pa->ar_ref = 1; 993 pa->ar_length = req->newlen; 994 error = SYSCTL_IN(req, pa->ar_args, req->newlen); 995 if (!error) { 996 PROC_LOCK(p); 997 p->p_args = pa; 998 PROC_UNLOCK(p); 999 } else 1000 FREE(pa, M_PARGS); 1001 return (error); 1002} 1003 1004SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table"); 1005 1006SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT, 1007 0, 0, sysctl_kern_proc, "S,proc", "Return entire process table"); 1008 1009SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, CTLFLAG_RD, 1010 sysctl_kern_proc, "Process table"); 1011 1012SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD, 1013 sysctl_kern_proc, "Process table"); 1014 1015SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD, 1016 sysctl_kern_proc, "Process table"); 1017 1018SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD, 1019 sysctl_kern_proc, "Process table"); 1020 1021SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD, 1022 sysctl_kern_proc, "Process table"); 1023 1024SYSCTL_NODE(_kern_proc, KERN_PROC_ARGS, args, CTLFLAG_RW | CTLFLAG_ANYBODY, 1025 sysctl_kern_proc_args, "Process argument list");
|