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