1 /* $OpenBSD: kern_proc.c,v 1.69 2016/09/02 18:11:28 tedu Exp $ */ 2 /* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */ 3 4 /* 5 * Copyright (c) 1982, 1986, 1989, 1991, 1993 6 * The Regents of the University of California. All rights reserved. 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 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)kern_proc.c 8.4 (Berkeley) 1/4/94 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/proc.h> 39 #include <sys/buf.h> 40 #include <sys/acct.h> 41 #include <sys/wait.h> 42 #include <sys/file.h> 43 #include <ufs/ufs/quota.h> 44 #include <sys/uio.h> 45 #include <sys/malloc.h> 46 #include <sys/mbuf.h> 47 #include <sys/ioctl.h> 48 #include <sys/tty.h> 49 #include <sys/signalvar.h> 50 #include <sys/pool.h> 51 52 #define UIHASH(uid) (&uihashtbl[(uid) & uihash]) 53 LIST_HEAD(uihashhead, uidinfo) *uihashtbl; 54 u_long uihash; /* size of hash table - 1 */ 55 56 /* 57 * Other process lists 58 */ 59 struct pidhashhead *pidhashtbl; 60 u_long pidhash; 61 struct pgrphashhead *pgrphashtbl; 62 u_long pgrphash; 63 struct processlist allprocess; 64 struct processlist zombprocess; 65 struct proclist allproc; 66 67 struct pool proc_pool; 68 struct pool process_pool; 69 struct pool rusage_pool; 70 struct pool ucred_pool; 71 struct pool pgrp_pool; 72 struct pool session_pool; 73 74 static void orphanpg(struct pgrp *); 75 #ifdef DEBUG 76 void pgrpdump(void); 77 #endif 78 79 /* 80 * Initialize global process hashing structures. 81 */ 82 void 83 procinit(void) 84 { 85 LIST_INIT(&allprocess); 86 LIST_INIT(&zombprocess); 87 LIST_INIT(&allproc); 88 89 90 pidhashtbl = hashinit(maxthread / 4, M_PROC, M_NOWAIT, &pidhash); 91 pgrphashtbl = hashinit(maxprocess / 4, M_PROC, M_NOWAIT, &pgrphash); 92 uihashtbl = hashinit(maxprocess / 16, M_PROC, M_NOWAIT, &uihash); 93 if (!pidhashtbl || !pgrphashtbl || !uihashtbl) 94 panic("procinit: malloc"); 95 96 pool_init(&proc_pool, sizeof(struct proc), 0, 0, PR_WAITOK, 97 "procpl", NULL); 98 pool_setipl(&proc_pool, IPL_NONE); 99 pool_init(&process_pool, sizeof(struct process), 0, 0, PR_WAITOK, 100 "processpl", NULL); 101 pool_setipl(&process_pool, IPL_NONE); 102 pool_init(&rusage_pool, sizeof(struct rusage), 0, 0, PR_WAITOK, 103 "zombiepl", NULL); 104 pool_setipl(&rusage_pool, IPL_NONE); 105 pool_init(&ucred_pool, sizeof(struct ucred), 0, 0, PR_WAITOK, 106 "ucredpl", NULL); 107 pool_setipl(&ucred_pool, IPL_NONE); 108 pool_init(&pgrp_pool, sizeof(struct pgrp), 0, 0, PR_WAITOK, 109 "pgrppl", NULL); 110 pool_setipl(&pgrp_pool, IPL_NONE); 111 pool_init(&session_pool, sizeof(struct session), 0, 0, PR_WAITOK, 112 "sessionpl", NULL); 113 pool_setipl(&session_pool, IPL_NONE); 114 } 115 116 struct uidinfo * 117 uid_find(uid_t uid) 118 { 119 struct uidinfo *uip, *nuip; 120 struct uihashhead *uipp; 121 122 uipp = UIHASH(uid); 123 LIST_FOREACH(uip, uipp, ui_hash) 124 if (uip->ui_uid == uid) 125 break; 126 if (uip) 127 return (uip); 128 nuip = malloc(sizeof(*nuip), M_PROC, M_WAITOK|M_ZERO); 129 LIST_FOREACH(uip, uipp, ui_hash) 130 if (uip->ui_uid == uid) 131 break; 132 if (uip) { 133 free(nuip, M_PROC, sizeof(*nuip)); 134 return (uip); 135 } 136 nuip->ui_uid = uid; 137 LIST_INSERT_HEAD(uipp, nuip, ui_hash); 138 139 return (nuip); 140 } 141 142 /* 143 * Change the count associated with number of threads 144 * a given user is using. 145 */ 146 int 147 chgproccnt(uid_t uid, int diff) 148 { 149 struct uidinfo *uip; 150 151 uip = uid_find(uid); 152 uip->ui_proccnt += diff; 153 if (uip->ui_proccnt < 0) 154 panic("chgproccnt: procs < 0"); 155 return (uip->ui_proccnt); 156 } 157 158 /* 159 * Is pr an inferior of parent? 160 */ 161 int 162 inferior(struct process *pr, struct process *parent) 163 { 164 165 for (; pr != parent; pr = pr->ps_pptr) 166 if (pr->ps_pid == 0 || pr->ps_pid == 1) 167 return (0); 168 return (1); 169 } 170 171 /* 172 * Locate a proc (thread) by number 173 */ 174 struct proc * 175 pfind(pid_t pid) 176 { 177 struct proc *p; 178 179 LIST_FOREACH(p, PIDHASH(pid), p_hash) 180 if (p->p_pid == pid) 181 return (p); 182 return (NULL); 183 } 184 185 /* 186 * Locate a process by number 187 */ 188 struct process * 189 prfind(pid_t pid) 190 { 191 struct proc *p; 192 193 LIST_FOREACH(p, PIDHASH(pid), p_hash) 194 if (p->p_pid == pid) 195 return (p->p_flag & P_THREAD ? NULL : p->p_p); 196 return (NULL); 197 } 198 199 /* 200 * Locate a process group by number 201 */ 202 struct pgrp * 203 pgfind(pid_t pgid) 204 { 205 struct pgrp *pgrp; 206 207 LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash) 208 if (pgrp->pg_id == pgid) 209 return (pgrp); 210 return (NULL); 211 } 212 213 /* 214 * Locate a zombie process 215 */ 216 struct process * 217 zombiefind(pid_t pid) 218 { 219 struct process *pr; 220 221 LIST_FOREACH(pr, &zombprocess, ps_list) 222 if (pr->ps_mainproc->p_pid == pid) 223 return (pr); 224 return (NULL); 225 } 226 227 /* 228 * Move p to a new or existing process group (and session) 229 * Caller provides a pre-allocated pgrp and session that should 230 * be freed if they are not used. 231 * XXX need proctree lock 232 */ 233 int 234 enterpgrp(struct process *pr, pid_t pgid, struct pgrp *newpgrp, 235 struct session *newsess) 236 { 237 struct pgrp *pgrp = pgfind(pgid); 238 239 #ifdef DIAGNOSTIC 240 if (pgrp != NULL && newsess) /* firewalls */ 241 panic("enterpgrp: setsid into non-empty pgrp"); 242 if (SESS_LEADER(pr)) 243 panic("enterpgrp: session leader attempted setpgrp"); 244 #endif 245 if (pgrp == NULL) { 246 /* 247 * new process group 248 */ 249 #ifdef DIAGNOSTIC 250 if (pr->ps_pid != pgid) 251 panic("enterpgrp: new pgrp and pid != pgid"); 252 #endif 253 254 pgrp = newpgrp; 255 if (newsess) { 256 /* 257 * new session 258 */ 259 newsess->s_leader = pr; 260 newsess->s_count = 1; 261 newsess->s_ttyvp = NULL; 262 newsess->s_ttyp = NULL; 263 memcpy(newsess->s_login, pr->ps_session->s_login, 264 sizeof(newsess->s_login)); 265 atomic_clearbits_int(&pr->ps_flags, PS_CONTROLT); 266 pgrp->pg_session = newsess; 267 #ifdef DIAGNOSTIC 268 if (pr != curproc->p_p) 269 panic("enterpgrp: mksession but not curproc"); 270 #endif 271 } else { 272 pgrp->pg_session = pr->ps_session; 273 pgrp->pg_session->s_count++; 274 } 275 pgrp->pg_id = pgid; 276 LIST_INIT(&pgrp->pg_members); 277 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash); 278 pgrp->pg_jobc = 0; 279 } else if (pgrp == pr->ps_pgrp) { 280 if (newsess) 281 pool_put(&session_pool, newsess); 282 pool_put(&pgrp_pool, newpgrp); 283 return (0); 284 } else { 285 if (newsess) 286 pool_put(&session_pool, newsess); 287 pool_put(&pgrp_pool, newpgrp); 288 } 289 290 /* 291 * Adjust eligibility of affected pgrps to participate in job control. 292 * Increment eligibility counts before decrementing, otherwise we 293 * could reach 0 spuriously during the first call. 294 */ 295 fixjobc(pr, pgrp, 1); 296 fixjobc(pr, pr->ps_pgrp, 0); 297 298 LIST_REMOVE(pr, ps_pglist); 299 if (LIST_EMPTY(&pr->ps_pgrp->pg_members)) 300 pgdelete(pr->ps_pgrp); 301 pr->ps_pgrp = pgrp; 302 LIST_INSERT_HEAD(&pgrp->pg_members, pr, ps_pglist); 303 return (0); 304 } 305 306 /* 307 * remove process from process group 308 */ 309 void 310 leavepgrp(struct process *pr) 311 { 312 313 if (pr->ps_session->s_verauthppid == pr->ps_pid) 314 zapverauth(pr->ps_session); 315 LIST_REMOVE(pr, ps_pglist); 316 if (LIST_EMPTY(&pr->ps_pgrp->pg_members)) 317 pgdelete(pr->ps_pgrp); 318 pr->ps_pgrp = 0; 319 } 320 321 /* 322 * delete a process group 323 */ 324 void 325 pgdelete(struct pgrp *pgrp) 326 { 327 328 if (pgrp->pg_session->s_ttyp != NULL && 329 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 330 pgrp->pg_session->s_ttyp->t_pgrp = NULL; 331 LIST_REMOVE(pgrp, pg_hash); 332 SESSRELE(pgrp->pg_session); 333 pool_put(&pgrp_pool, pgrp); 334 } 335 336 void 337 zapverauth(void *v) 338 { 339 struct session *sess = v; 340 sess->s_verauthuid = 0; 341 sess->s_verauthppid = 0; 342 } 343 344 /* 345 * Adjust pgrp jobc counters when specified process changes process group. 346 * We count the number of processes in each process group that "qualify" 347 * the group for terminal job control (those with a parent in a different 348 * process group of the same session). If that count reaches zero, the 349 * process group becomes orphaned. Check both the specified process' 350 * process group and that of its children. 351 * entering == 0 => pr is leaving specified group. 352 * entering == 1 => pr is entering specified group. 353 * XXX need proctree lock 354 */ 355 void 356 fixjobc(struct process *pr, struct pgrp *pgrp, int entering) 357 { 358 struct pgrp *hispgrp; 359 struct session *mysession = pgrp->pg_session; 360 361 /* 362 * Check pr's parent to see whether pr qualifies its own process 363 * group; if so, adjust count for pr's process group. 364 */ 365 if ((hispgrp = pr->ps_pptr->ps_pgrp) != pgrp && 366 hispgrp->pg_session == mysession) { 367 if (entering) 368 pgrp->pg_jobc++; 369 else if (--pgrp->pg_jobc == 0) 370 orphanpg(pgrp); 371 } 372 373 /* 374 * Check this process' children to see whether they qualify 375 * their process groups; if so, adjust counts for children's 376 * process groups. 377 */ 378 LIST_FOREACH(pr, &pr->ps_children, ps_sibling) 379 if ((hispgrp = pr->ps_pgrp) != pgrp && 380 hispgrp->pg_session == mysession && 381 (pr->ps_flags & PS_ZOMBIE) == 0) { 382 if (entering) 383 hispgrp->pg_jobc++; 384 else if (--hispgrp->pg_jobc == 0) 385 orphanpg(hispgrp); 386 } 387 } 388 389 /* 390 * A process group has become orphaned; 391 * if there are any stopped processes in the group, 392 * hang-up all process in that group. 393 */ 394 static void 395 orphanpg(struct pgrp *pg) 396 { 397 struct process *pr; 398 399 LIST_FOREACH(pr, &pg->pg_members, ps_pglist) { 400 if (pr->ps_mainproc->p_stat == SSTOP) { 401 LIST_FOREACH(pr, &pg->pg_members, ps_pglist) { 402 prsignal(pr, SIGHUP); 403 prsignal(pr, SIGCONT); 404 } 405 return; 406 } 407 } 408 } 409 410 #ifdef DDB 411 void 412 proc_printit(struct proc *p, const char *modif, 413 int (*pr)(const char *, ...) __attribute__((__format__(__kprintf__,1,2)))) 414 { 415 static const char *const pstat[] = { 416 "idle", "run", "sleep", "stop", "zombie", "dead", "onproc" 417 }; 418 char pstbuf[5]; 419 const char *pst = pstbuf; 420 421 422 if (p->p_stat < 1 || p->p_stat > sizeof(pstat) / sizeof(pstat[0])) 423 snprintf(pstbuf, sizeof(pstbuf), "%d", p->p_stat); 424 else 425 pst = pstat[(int)p->p_stat - 1]; 426 427 (*pr)("PROC (%s) pid=%d stat=%s\n", p->p_comm, p->p_pid, pst); 428 (*pr)(" flags process=%b proc=%b\n", 429 p->p_p->ps_flags, PS_BITS, p->p_flag, P_BITS); 430 (*pr)(" pri=%u, usrpri=%u, nice=%d\n", 431 p->p_priority, p->p_usrpri, p->p_p->ps_nice); 432 (*pr)(" forw=%p, list=%p,%p\n", 433 TAILQ_NEXT(p, p_runq), p->p_list.le_next, p->p_list.le_prev); 434 (*pr)(" process=%p user=%p, vmspace=%p\n", 435 p->p_p, p->p_addr, p->p_vmspace); 436 (*pr)(" estcpu=%u, cpticks=%d, pctcpu=%u.%u\n", 437 p->p_estcpu, p->p_cpticks, p->p_pctcpu / 100, p->p_pctcpu % 100); 438 (*pr)(" user=%u, sys=%u, intr=%u\n", 439 p->p_uticks, p->p_sticks, p->p_iticks); 440 } 441 #include <machine/db_machdep.h> 442 443 #include <ddb/db_output.h> 444 445 void 446 db_show_all_procs(db_expr_t addr, int haddr, db_expr_t count, char *modif) 447 { 448 char *mode; 449 int skipzomb = 0; 450 struct proc *p; 451 struct process *pr, *ppr; 452 453 if (modif[0] == 0) 454 modif[0] = 'n'; /* default == normal mode */ 455 456 mode = "mawno"; 457 while (*mode && *mode != modif[0]) 458 mode++; 459 if (*mode == 0 || *mode == 'm') { 460 db_printf("usage: show all procs [/a] [/n] [/w]\n"); 461 db_printf("\t/a == show process address info\n"); 462 db_printf("\t/n == show normal process info [default]\n"); 463 db_printf("\t/w == show process wait/emul info\n"); 464 db_printf("\t/o == show normal info for non-idle SONPROC\n"); 465 return; 466 } 467 468 pr = LIST_FIRST(&allprocess); 469 470 switch (*mode) { 471 472 case 'a': 473 db_printf(" TID %-10s %18s %18s %18s\n", 474 "COMMAND", "STRUCT PROC *", "UAREA *", "VMSPACE/VM_MAP"); 475 break; 476 case 'n': 477 db_printf(" TID %5s %5s %5s S %10s %-12s %-16s\n", 478 "PPID", "PGRP", "UID", "FLAGS", "WAIT", "COMMAND"); 479 break; 480 case 'w': 481 db_printf(" TID %-16s %-8s %18s %s\n", 482 "COMMAND", "EMUL", "WAIT-CHANNEL", "WAIT-MSG"); 483 break; 484 case 'o': 485 skipzomb = 1; 486 db_printf(" TID %5s %5s %10s %10s %3s %-31s\n", 487 "PID", "UID", "PRFLAGS", "PFLAGS", "CPU", "COMMAND"); 488 break; 489 } 490 491 while (pr != NULL) { 492 ppr = pr->ps_pptr; 493 494 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) { 495 if (p->p_stat) { 496 if (*mode == 'o') { 497 if (p->p_stat != SONPROC) 498 continue; 499 if (p->p_cpu != NULL && p->p_cpu-> 500 ci_schedstate.spc_idleproc == p) 501 continue; 502 } 503 db_printf("%c%5d ", p == curproc ? '*' : ' ', 504 p->p_pid); 505 506 switch (*mode) { 507 508 case 'a': 509 db_printf("%-10.10s %18p %18p %18p\n", 510 p->p_comm, p, p->p_addr, p->p_vmspace); 511 break; 512 513 case 'n': 514 db_printf("%5d %5d %5d %d %#10x " 515 "%-12.12s %-16s\n", 516 ppr ? ppr->ps_pid : -1, 517 pr->ps_pgrp ? pr->ps_pgrp->pg_id : -1, 518 pr->ps_ucred->cr_ruid, p->p_stat, 519 p->p_flag | pr->ps_flags, 520 (p->p_wchan && p->p_wmesg) ? 521 p->p_wmesg : "", p->p_comm); 522 break; 523 524 case 'w': 525 db_printf("%-16s %-8s %18p %s\n", p->p_comm, 526 pr->ps_emul->e_name, p->p_wchan, 527 (p->p_wchan && p->p_wmesg) ? 528 p->p_wmesg : ""); 529 break; 530 531 case 'o': 532 db_printf("%5d %5d %#10x %#10x %3d" 533 " %-31s\n", 534 pr->ps_pid, pr->ps_ucred->cr_ruid, 535 pr->ps_flags, p->p_flag, 536 CPU_INFO_UNIT(p->p_cpu), 537 p->p_comm); 538 break; 539 540 } 541 } 542 } 543 pr = LIST_NEXT(pr, ps_list); 544 if (pr == NULL && skipzomb == 0) { 545 skipzomb = 1; 546 pr = LIST_FIRST(&zombprocess); 547 } 548 } 549 } 550 #endif 551 552 #ifdef DEBUG 553 void 554 pgrpdump(void) 555 { 556 struct pgrp *pgrp; 557 struct process *pr; 558 int i; 559 560 for (i = 0; i <= pgrphash; i++) { 561 if (!LIST_EMPTY(&pgrphashtbl[i])) { 562 printf("\tindx %d\n", i); 563 LIST_FOREACH(pgrp, &pgrphashtbl[i], pg_hash) { 564 printf("\tpgrp %p, pgid %d, sess %p, sesscnt %d, mem %p\n", 565 pgrp, pgrp->pg_id, pgrp->pg_session, 566 pgrp->pg_session->s_count, 567 LIST_FIRST(&pgrp->pg_members)); 568 LIST_FOREACH(pr, &pgrp->pg_members, ps_pglist) { 569 printf("\t\tpid %d addr %p pgrp %p\n", 570 pr->ps_pid, pr, pr->ps_pgrp); 571 } 572 } 573 } 574 } 575 } 576 #endif /* DEBUG */ 577