1 /* $NetBSD: kern_proc.c,v 1.38 2000/01/22 16:53:50 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Copyright (c) 1982, 1986, 1989, 1991, 1993 42 * The Regents of the University of California. All rights reserved. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. All advertising materials mentioning features or use of this software 53 * must display the following acknowledgement: 54 * This product includes software developed by the University of 55 * California, Berkeley and its contributors. 56 * 4. Neither the name of the University nor the names of its contributors 57 * may be used to endorse or promote products derived from this software 58 * without specific prior written permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 * 72 * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95 73 */ 74 75 #include <sys/param.h> 76 #include <sys/systm.h> 77 #include <sys/map.h> 78 #include <sys/kernel.h> 79 #include <sys/proc.h> 80 #include <sys/resourcevar.h> 81 #include <sys/buf.h> 82 #include <sys/acct.h> 83 #include <sys/wait.h> 84 #include <sys/file.h> 85 #include <ufs/ufs/quota.h> 86 #include <sys/uio.h> 87 #include <sys/malloc.h> 88 #include <sys/pool.h> 89 #include <sys/mbuf.h> 90 #include <sys/ioctl.h> 91 #include <sys/tty.h> 92 #include <sys/signalvar.h> 93 94 /* 95 * Structure associated with user cacheing. 96 */ 97 struct uidinfo { 98 LIST_ENTRY(uidinfo) ui_hash; 99 uid_t ui_uid; 100 long ui_proccnt; 101 }; 102 #define UIHASH(uid) (&uihashtbl[(uid) & uihash]) 103 LIST_HEAD(uihashhead, uidinfo) *uihashtbl; 104 u_long uihash; /* size of hash table - 1 */ 105 106 /* 107 * Other process lists 108 */ 109 struct pidhashhead *pidhashtbl; 110 u_long pidhash; 111 struct pgrphashhead *pgrphashtbl; 112 u_long pgrphash; 113 114 struct proclist allproc; 115 struct proclist zombproc; /* resources have been freed */ 116 117 /* 118 * Process list locking: 119 * 120 * We have two types of locks on the proclists: read locks and write 121 * locks. Read locks can be used in interrupt context, so while we 122 * hold the write lock, we must also block clock interrupts to 123 * lock out any scheduling changes that may happen in interrupt 124 * context. 125 * 126 * The proclist lock locks the following structures: 127 * 128 * allproc 129 * zombproc 130 * pidhashtbl 131 */ 132 struct lock proclist_lock; 133 134 /* 135 * Locking of this proclist is special; it's accessed in a 136 * critical section of process exit, and thus locking it can't 137 * modify interrupt state. We use a simple spin lock for this 138 * proclist. Processes on this proclist are also on zombproc; 139 * we use the p_hash member to linkup to deadproc. 140 */ 141 struct simplelock deadproc_slock; 142 struct proclist deadproc; /* dead, but not yet undead */ 143 144 struct pool proc_pool; 145 struct pool pcred_pool; 146 struct pool plimit_pool; 147 struct pool pgrp_pool; 148 struct pool rusage_pool; 149 150 /* 151 * The process list descriptors, used during pid allocation and 152 * by sysctl. No locking on this data structure is needed since 153 * it is completely static. 154 */ 155 const struct proclist_desc proclists[] = { 156 { &allproc }, 157 { &zombproc }, 158 { NULL }, 159 }; 160 161 static void orphanpg __P((struct pgrp *)); 162 #ifdef DEBUG 163 void pgrpdump __P((void)); 164 #endif 165 166 /* 167 * Initialize global process hashing structures. 168 */ 169 void 170 procinit() 171 { 172 const struct proclist_desc *pd; 173 174 for (pd = proclists; pd->pd_list != NULL; pd++) 175 LIST_INIT(pd->pd_list); 176 177 spinlockinit(&proclist_lock, "proclk", 0); 178 179 LIST_INIT(&deadproc); 180 simple_lock_init(&deadproc_slock); 181 182 pidhashtbl = hashinit(maxproc / 4, M_PROC, M_WAITOK, &pidhash); 183 pgrphashtbl = hashinit(maxproc / 4, M_PROC, M_WAITOK, &pgrphash); 184 uihashtbl = hashinit(maxproc / 16, M_PROC, M_WAITOK, &uihash); 185 186 pool_init(&proc_pool, sizeof(struct proc), 0, 0, 0, "procpl", 187 0, pool_page_alloc_nointr, pool_page_free_nointr, M_PROC); 188 pool_init(&pgrp_pool, sizeof(struct pgrp), 0, 0, 0, "pgrppl", 189 0, pool_page_alloc_nointr, pool_page_free_nointr, M_PGRP); 190 pool_init(&pcred_pool, sizeof(struct pcred), 0, 0, 0, "pcredpl", 191 0, pool_page_alloc_nointr, pool_page_free_nointr, M_SUBPROC); 192 pool_init(&plimit_pool, sizeof(struct plimit), 0, 0, 0, "plimitpl", 193 0, pool_page_alloc_nointr, pool_page_free_nointr, M_SUBPROC); 194 pool_init(&rusage_pool, sizeof(struct rusage), 0, 0, 0, "rusgepl", 195 0, pool_page_alloc_nointr, pool_page_free_nointr, M_ZOMBIE); 196 } 197 198 /* 199 * Acquire a read lock on the proclist. 200 */ 201 void 202 proclist_lock_read() 203 { 204 int error, s; 205 206 s = splclock(); 207 error = spinlockmgr(&proclist_lock, LK_SHARED, NULL); 208 #ifdef DIAGNOSTIC 209 if (error) 210 panic("proclist_lock_read: failed to acquire lock"); 211 #endif 212 splx(s); 213 } 214 215 /* 216 * Release a read lock on the proclist. 217 */ 218 void 219 proclist_unlock_read() 220 { 221 int s; 222 223 s = splclock(); 224 (void) spinlockmgr(&proclist_lock, LK_RELEASE, NULL); 225 splx(s); 226 } 227 228 /* 229 * Acquire a write lock on the proclist. 230 */ 231 int 232 proclist_lock_write() 233 { 234 int error, s; 235 236 s = splclock(); 237 error = spinlockmgr(&proclist_lock, LK_EXCLUSIVE, NULL); 238 #ifdef DIAGNOSTIC 239 if (error != 0) 240 panic("proclist_lock: failed to acquire lock"); 241 #endif 242 return (s); 243 } 244 245 /* 246 * Release a write lock on the proclist. 247 */ 248 void 249 proclist_unlock_write(s) 250 int s; 251 { 252 253 (void) spinlockmgr(&proclist_lock, LK_RELEASE, NULL); 254 splx(s); 255 } 256 257 /* 258 * Change the count associated with number of processes 259 * a given user is using. 260 */ 261 int 262 chgproccnt(uid, diff) 263 uid_t uid; 264 int diff; 265 { 266 register struct uidinfo *uip; 267 register struct uihashhead *uipp; 268 269 uipp = UIHASH(uid); 270 for (uip = uipp->lh_first; uip != 0; uip = uip->ui_hash.le_next) 271 if (uip->ui_uid == uid) 272 break; 273 if (uip) { 274 uip->ui_proccnt += diff; 275 if (uip->ui_proccnt > 0) 276 return (uip->ui_proccnt); 277 if (uip->ui_proccnt < 0) 278 panic("chgproccnt: procs < 0"); 279 LIST_REMOVE(uip, ui_hash); 280 FREE(uip, M_PROC); 281 return (0); 282 } 283 if (diff <= 0) { 284 if (diff == 0) 285 return(0); 286 panic("chgproccnt: lost user"); 287 } 288 MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK); 289 LIST_INSERT_HEAD(uipp, uip, ui_hash); 290 uip->ui_uid = uid; 291 uip->ui_proccnt = diff; 292 return (diff); 293 } 294 295 /* 296 * Is p an inferior of the current process? 297 */ 298 int 299 inferior(p) 300 register struct proc *p; 301 { 302 303 for (; p != curproc; p = p->p_pptr) 304 if (p->p_pid == 0) 305 return (0); 306 return (1); 307 } 308 309 /* 310 * Locate a process by number 311 */ 312 struct proc * 313 pfind(pid) 314 register pid_t pid; 315 { 316 struct proc *p; 317 318 proclist_lock_read(); 319 for (p = PIDHASH(pid)->lh_first; p != 0; p = p->p_hash.le_next) 320 if (p->p_pid == pid) 321 goto out; 322 out: 323 proclist_unlock_read(); 324 return (p); 325 } 326 327 /* 328 * Locate a process group by number 329 */ 330 struct pgrp * 331 pgfind(pgid) 332 register pid_t pgid; 333 { 334 register struct pgrp *pgrp; 335 336 for (pgrp = PGRPHASH(pgid)->lh_first; pgrp != 0; pgrp = pgrp->pg_hash.le_next) 337 if (pgrp->pg_id == pgid) 338 return (pgrp); 339 return (NULL); 340 } 341 342 /* 343 * Move p to a new or existing process group (and session) 344 */ 345 int 346 enterpgrp(p, pgid, mksess) 347 register struct proc *p; 348 pid_t pgid; 349 int mksess; 350 { 351 register struct pgrp *pgrp = pgfind(pgid); 352 353 #ifdef DIAGNOSTIC 354 if (pgrp != NULL && mksess) /* firewalls */ 355 panic("enterpgrp: setsid into non-empty pgrp"); 356 if (SESS_LEADER(p)) 357 panic("enterpgrp: session leader attempted setpgrp"); 358 #endif 359 if (pgrp == NULL) { 360 pid_t savepid = p->p_pid; 361 struct proc *np; 362 /* 363 * new process group 364 */ 365 #ifdef DIAGNOSTIC 366 if (p->p_pid != pgid) 367 panic("enterpgrp: new pgrp and pid != pgid"); 368 #endif 369 pgrp = pool_get(&pgrp_pool, PR_WAITOK); 370 if ((np = pfind(savepid)) == NULL || np != p) 371 return (ESRCH); 372 if (mksess) { 373 register struct session *sess; 374 375 /* 376 * new session 377 */ 378 MALLOC(sess, struct session *, sizeof(struct session), 379 M_SESSION, M_WAITOK); 380 sess->s_sid = p->p_pid; 381 sess->s_leader = p; 382 sess->s_count = 1; 383 sess->s_ttyvp = NULL; 384 sess->s_ttyp = NULL; 385 memcpy(sess->s_login, p->p_session->s_login, 386 sizeof(sess->s_login)); 387 p->p_flag &= ~P_CONTROLT; 388 pgrp->pg_session = sess; 389 #ifdef DIAGNOSTIC 390 if (p != curproc) 391 panic("enterpgrp: mksession and p != curproc"); 392 #endif 393 } else { 394 pgrp->pg_session = p->p_session; 395 pgrp->pg_session->s_count++; 396 } 397 pgrp->pg_id = pgid; 398 LIST_INIT(&pgrp->pg_members); 399 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash); 400 pgrp->pg_jobc = 0; 401 } else if (pgrp == p->p_pgrp) 402 return (0); 403 404 /* 405 * Adjust eligibility of affected pgrps to participate in job control. 406 * Increment eligibility counts before decrementing, otherwise we 407 * could reach 0 spuriously during the first call. 408 */ 409 fixjobc(p, pgrp, 1); 410 fixjobc(p, p->p_pgrp, 0); 411 412 LIST_REMOVE(p, p_pglist); 413 if (p->p_pgrp->pg_members.lh_first == 0) 414 pgdelete(p->p_pgrp); 415 p->p_pgrp = pgrp; 416 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist); 417 return (0); 418 } 419 420 /* 421 * remove process from process group 422 */ 423 int 424 leavepgrp(p) 425 register struct proc *p; 426 { 427 428 LIST_REMOVE(p, p_pglist); 429 if (p->p_pgrp->pg_members.lh_first == 0) 430 pgdelete(p->p_pgrp); 431 p->p_pgrp = 0; 432 return (0); 433 } 434 435 /* 436 * delete a process group 437 */ 438 void 439 pgdelete(pgrp) 440 register struct pgrp *pgrp; 441 { 442 443 if (pgrp->pg_session->s_ttyp != NULL && 444 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 445 pgrp->pg_session->s_ttyp->t_pgrp = NULL; 446 LIST_REMOVE(pgrp, pg_hash); 447 if (--pgrp->pg_session->s_count == 0) 448 FREE(pgrp->pg_session, M_SESSION); 449 pool_put(&pgrp_pool, pgrp); 450 } 451 452 /* 453 * Adjust pgrp jobc counters when specified process changes process group. 454 * We count the number of processes in each process group that "qualify" 455 * the group for terminal job control (those with a parent in a different 456 * process group of the same session). If that count reaches zero, the 457 * process group becomes orphaned. Check both the specified process' 458 * process group and that of its children. 459 * entering == 0 => p is leaving specified group. 460 * entering == 1 => p is entering specified group. 461 */ 462 void 463 fixjobc(p, pgrp, entering) 464 register struct proc *p; 465 register struct pgrp *pgrp; 466 int entering; 467 { 468 register struct pgrp *hispgrp; 469 register struct session *mysession = pgrp->pg_session; 470 471 /* 472 * Check p's parent to see whether p qualifies its own process 473 * group; if so, adjust count for p's process group. 474 */ 475 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && 476 hispgrp->pg_session == mysession) { 477 if (entering) 478 pgrp->pg_jobc++; 479 else if (--pgrp->pg_jobc == 0) 480 orphanpg(pgrp); 481 } 482 483 /* 484 * Check this process' children to see whether they qualify 485 * their process groups; if so, adjust counts for children's 486 * process groups. 487 */ 488 for (p = p->p_children.lh_first; p != 0; p = p->p_sibling.le_next) { 489 if ((hispgrp = p->p_pgrp) != pgrp && 490 hispgrp->pg_session == mysession && 491 P_ZOMBIE(p) == 0) { 492 if (entering) 493 hispgrp->pg_jobc++; 494 else if (--hispgrp->pg_jobc == 0) 495 orphanpg(hispgrp); 496 } 497 } 498 } 499 500 /* 501 * A process group has become orphaned; 502 * if there are any stopped processes in the group, 503 * hang-up all process in that group. 504 */ 505 static void 506 orphanpg(pg) 507 struct pgrp *pg; 508 { 509 register struct proc *p; 510 511 for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) { 512 if (p->p_stat == SSTOP) { 513 for (p = pg->pg_members.lh_first; p != 0; 514 p = p->p_pglist.le_next) { 515 psignal(p, SIGHUP); 516 psignal(p, SIGCONT); 517 } 518 return; 519 } 520 } 521 } 522 523 /* mark process as suid/sgid, reset some values do defaults */ 524 void 525 p_sugid(p) 526 struct proc *p; 527 { 528 struct plimit *newlim; 529 530 p->p_flag |= P_SUGID; 531 /* reset what needs to be reset in plimit */ 532 if (p->p_limit->pl_corename != defcorename) { 533 if (p->p_limit->p_refcnt > 1 && 534 (p->p_limit->p_lflags & PL_SHAREMOD) == 0) { 535 newlim = limcopy(p->p_limit); 536 limfree(p->p_limit); 537 p->p_limit = newlim; 538 } else { 539 free(p->p_limit->pl_corename, M_TEMP); 540 } 541 p->p_limit->pl_corename = defcorename; 542 } 543 } 544 545 546 #ifdef DEBUG 547 void 548 pgrpdump() 549 { 550 register struct pgrp *pgrp; 551 register struct proc *p; 552 register int i; 553 554 for (i = 0; i <= pgrphash; i++) { 555 if ((pgrp = pgrphashtbl[i].lh_first) != NULL) { 556 printf("\tindx %d\n", i); 557 for (; pgrp != 0; pgrp = pgrp->pg_hash.le_next) { 558 printf("\tpgrp %p, pgid %d, sess %p, sesscnt %d, mem %p\n", 559 pgrp, pgrp->pg_id, pgrp->pg_session, 560 pgrp->pg_session->s_count, 561 pgrp->pg_members.lh_first); 562 for (p = pgrp->pg_members.lh_first; p != 0; 563 p = p->p_pglist.le_next) { 564 printf("\t\tpid %d addr %p pgrp %p\n", 565 p->p_pid, p, p->p_pgrp); 566 } 567 } 568 } 569 } 570 } 571 #endif /* DEBUG */ 572