1 /* $NetBSD: kern_exit.c,v 1.64 1999/02/23 02:57:18 ross Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 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 * (c) UNIX System Laboratories, Inc. 44 * All or some portions of this file are derived from material licensed 45 * to the University of California by American Telephone and Telegraph 46 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 47 * the permission of UNIX System Laboratories, Inc. 48 * 49 * Redistribution and use in source and binary forms, with or without 50 * modification, are permitted provided that the following conditions 51 * are met: 52 * 1. Redistributions of source code must retain the above copyright 53 * notice, this list of conditions and the following disclaimer. 54 * 2. Redistributions in binary form must reproduce the above copyright 55 * notice, this list of conditions and the following disclaimer in the 56 * documentation and/or other materials provided with the distribution. 57 * 3. All advertising materials mentioning features or use of this software 58 * must display the following acknowledgement: 59 * This product includes software developed by the University of 60 * California, Berkeley and its contributors. 61 * 4. Neither the name of the University nor the names of its contributors 62 * may be used to endorse or promote products derived from this software 63 * without specific prior written permission. 64 * 65 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 66 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 67 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 68 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 69 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 70 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 71 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 72 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 73 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 74 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 75 * SUCH DAMAGE. 76 * 77 * @(#)kern_exit.c 8.10 (Berkeley) 2/23/95 78 */ 79 80 #include "opt_ktrace.h" 81 #include "opt_uvm.h" 82 #include "opt_sysv.h" 83 84 #include <sys/param.h> 85 #include <sys/systm.h> 86 #include <sys/map.h> 87 #include <sys/ioctl.h> 88 #include <sys/proc.h> 89 #include <sys/tty.h> 90 #include <sys/time.h> 91 #include <sys/resource.h> 92 #include <sys/kernel.h> 93 #include <sys/ktrace.h> 94 #include <sys/proc.h> 95 #include <sys/buf.h> 96 #include <sys/wait.h> 97 #include <sys/file.h> 98 #include <sys/vnode.h> 99 #include <sys/syslog.h> 100 #include <sys/malloc.h> 101 #include <sys/pool.h> 102 #include <sys/resourcevar.h> 103 #include <sys/ptrace.h> 104 #include <sys/acct.h> 105 #include <sys/filedesc.h> 106 #include <sys/signalvar.h> 107 #include <sys/sched.h> 108 #ifdef SYSVSHM 109 #include <sys/shm.h> 110 #endif 111 #ifdef SYSVSEM 112 #include <sys/sem.h> 113 #endif 114 115 #include <sys/mount.h> 116 #include <sys/syscallargs.h> 117 118 #include <machine/cpu.h> 119 120 #include <vm/vm.h> 121 #include <vm/vm_kern.h> 122 123 #if defined(UVM) 124 #include <uvm/uvm_extern.h> 125 #endif 126 127 /* 128 * exit -- 129 * Death of process. 130 */ 131 int 132 sys_exit(p, v, retval) 133 struct proc *p; 134 void *v; 135 register_t *retval; 136 { 137 struct sys_exit_args /* { 138 syscallarg(int) rval; 139 } */ *uap = v; 140 141 exit1(p, W_EXITCODE(SCARG(uap, rval), 0)); 142 /* NOTREACHED */ 143 return (0); 144 } 145 146 /* 147 * Exit: deallocate address space and other resources, change proc state 148 * to zombie, and unlink proc from allproc and parent's lists. Save exit 149 * status and rusage for wait(). Check for child processes and orphan them. 150 */ 151 void 152 exit1(p, rv) 153 register struct proc *p; 154 int rv; 155 { 156 register struct proc *q, *nq; 157 register struct vmspace *vm; 158 159 if (p->p_pid == 1) 160 panic("init died (signal %d, exit %d)", 161 WTERMSIG(rv), WEXITSTATUS(rv)); 162 #ifdef PGINPROF 163 vmsizmon(); 164 #endif 165 if (p->p_flag & P_PROFIL) 166 stopprofclock(p); 167 p->p_ru = pool_get(&rusage_pool, PR_WAITOK); 168 /* 169 * If parent is waiting for us to exit or exec, P_PPWAIT is set; we 170 * wake up the parent early to avoid deadlock. 171 */ 172 p->p_flag |= P_WEXIT; 173 if (p->p_flag & P_PPWAIT) { 174 p->p_flag &= ~P_PPWAIT; 175 wakeup((caddr_t)p->p_pptr); 176 } 177 sigfillset(&p->p_sigignore); 178 sigemptyset(&p->p_siglist); 179 p->p_sigcheck = 0; 180 untimeout(realitexpire, (caddr_t)p); 181 182 /* 183 * Close open files and release open-file table. 184 * This may block! 185 */ 186 fdfree(p); 187 188 /* The next three chunks should probably be moved to vmspace_exit. */ 189 vm = p->p_vmspace; 190 #ifdef SYSVSHM 191 if (vm->vm_shm && vm->vm_refcnt == 1) 192 shmexit(vm); 193 #endif 194 #ifdef SYSVSEM 195 semexit(p); 196 #endif 197 /* 198 * Release user portion of address space. 199 * This releases references to vnodes, 200 * which could cause I/O if the file has been unlinked. 201 * Need to do this early enough that we can still sleep. 202 * Can't free the entire vmspace as the kernel stack 203 * may be mapped within that space also. 204 */ 205 #if defined(UVM) 206 if (vm->vm_refcnt == 1) 207 (void) uvm_deallocate(&vm->vm_map, VM_MIN_ADDRESS, 208 VM_MAXUSER_ADDRESS - VM_MIN_ADDRESS); 209 #else 210 if (vm->vm_refcnt == 1) 211 (void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS, 212 VM_MAXUSER_ADDRESS); 213 #endif 214 215 if (SESS_LEADER(p)) { 216 register struct session *sp = p->p_session; 217 218 if (sp->s_ttyvp) { 219 /* 220 * Controlling process. 221 * Signal foreground pgrp, 222 * drain controlling terminal 223 * and revoke access to controlling terminal. 224 */ 225 if (sp->s_ttyp->t_session == sp) { 226 if (sp->s_ttyp->t_pgrp) 227 pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1); 228 (void) ttywait(sp->s_ttyp); 229 /* 230 * The tty could have been revoked 231 * if we blocked. 232 */ 233 if (sp->s_ttyvp) 234 VOP_REVOKE(sp->s_ttyvp, REVOKEALL); 235 } 236 if (sp->s_ttyvp) 237 vrele(sp->s_ttyvp); 238 sp->s_ttyvp = NULL; 239 /* 240 * s_ttyp is not zero'd; we use this to indicate 241 * that the session once had a controlling terminal. 242 * (for logging and informational purposes) 243 */ 244 } 245 sp->s_leader = NULL; 246 } 247 fixjobc(p, p->p_pgrp, 0); 248 p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; 249 (void)acct_process(p); 250 #ifdef KTRACE 251 /* 252 * release trace file 253 */ 254 ktrderef(p); 255 #endif 256 /* 257 * Remove proc from allproc queue and pidhash chain. 258 * Unlink from parent's child list. 259 */ 260 LIST_REMOVE(p, p_list); 261 p->p_stat = SZOMB; 262 263 /* 264 * NOTE: WE ARE NO LONGER ALLOWED TO SLEEP! 265 */ 266 267 LIST_REMOVE(p, p_hash); 268 269 q = p->p_children.lh_first; 270 if (q) /* only need this if any child is S_ZOMB */ 271 wakeup((caddr_t)initproc); 272 for (; q != 0; q = nq) { 273 nq = q->p_sibling.le_next; 274 proc_reparent(q, initproc); 275 /* 276 * Traced processes are killed 277 * since their existence means someone is screwing up. 278 */ 279 if (q->p_flag & P_TRACED) { 280 q->p_flag &= ~(P_TRACED|P_WAITED|P_FSTRACE); 281 psignal(q, SIGKILL); 282 } 283 } 284 285 /* 286 * Save exit status and final rusage info, adding in child rusage 287 * info and self times. 288 */ 289 p->p_xstat = rv; 290 *p->p_ru = p->p_stats->p_ru; 291 calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL); 292 ruadd(p->p_ru, &p->p_stats->p_cru); 293 294 /* 295 * Notify parent that we're gone. If parent has the P_NOCLDWAIT 296 * flag set, notify init instead (and hope it will handle 297 * this situation). 298 */ 299 if (p->p_pptr->p_flag & P_NOCLDWAIT) { 300 struct proc *pp = p->p_pptr; 301 proc_reparent(p, initproc); 302 /* 303 * If this was the last child of our parent, notify 304 * parent, so in case he was wait(2)ing, he will 305 * continue. 306 */ 307 if (pp->p_children.lh_first == NULL) 308 wakeup((caddr_t)pp); 309 } 310 311 /* 312 * Clear curproc after we've done all operations 313 * that could block, and before tearing down the rest 314 * of the process state that might be used from clock, etc. 315 * Also, can't clear curproc while we're still runnable, 316 * as we're not on a run queue (we are current, just not 317 * a proper proc any longer!). 318 * 319 * Other substructures are freed from wait(). 320 */ 321 curproc = NULL; 322 if (--p->p_limit->p_refcnt == 0) 323 pool_put(&plimit_pool, p->p_limit); 324 325 /* 326 * Finally, call machine-dependent code to switch to a new 327 * context (possibly the idle context). Once we are no longer 328 * using the dead process's vmspace and stack, exit2() will be 329 * called to schedule those resources to be released by the 330 * reaper thread. 331 * 332 * Note that cpu_exit() will end with a call equivalent to 333 * cpu_switch(), finishing our execution (pun intended). 334 */ 335 cpu_exit(p); 336 } 337 338 /* 339 * We are called from cpu_exit() once it is safe to schedule the 340 * dead process's resources to be freed. 341 */ 342 void 343 exit2(p) 344 struct proc *p; 345 { 346 347 LIST_INSERT_HEAD(&deadproc, p, p_list); 348 wakeup(&deadproc); 349 } 350 351 /* 352 * Process reaper. This is run by a kernel thread to free the resources 353 * of a dead process. Once the resources are free, the process becomes 354 * a zombie, and the parent is allowed to read the undead's status. 355 */ 356 void 357 reaper() 358 { 359 struct proc *p; 360 361 for (;;) { 362 p = LIST_FIRST(&deadproc); 363 if (p == NULL) { 364 /* No work for us; go to sleep until someone exits. */ 365 (void) tsleep(&deadproc, PVM, "reaper", 0); 366 continue; 367 } 368 369 /* Remove us from the deadproc list. */ 370 LIST_REMOVE(p, p_list); 371 372 /* 373 * Free the VM resources we're still holding on to. 374 * We must do this from a valid thread because doing 375 * so may block. 376 */ 377 #if defined(UVM) 378 uvm_exit(p); 379 #else 380 vm_exit(p); 381 #endif 382 383 /* Process is now a true zombie. */ 384 LIST_INSERT_HEAD(&zombproc, p, p_list); 385 386 /* Wake up the parent so it can get exit satus. */ 387 if ((p->p_flag & P_FSTRACE) == 0) 388 psignal(p->p_pptr, SIGCHLD); 389 wakeup((caddr_t)p->p_pptr); 390 } 391 } 392 393 int 394 sys_wait4(q, v, retval) 395 register struct proc *q; 396 void *v; 397 register_t *retval; 398 { 399 register struct sys_wait4_args /* { 400 syscallarg(int) pid; 401 syscallarg(int *) status; 402 syscallarg(int) options; 403 syscallarg(struct rusage *) rusage; 404 } */ *uap = v; 405 register int nfound; 406 register struct proc *p, *t; 407 int status, error; 408 409 if (SCARG(uap, pid) == 0) 410 SCARG(uap, pid) = -q->p_pgid; 411 if (SCARG(uap, options) &~ (WUNTRACED|WNOHANG)) 412 return (EINVAL); 413 414 loop: 415 nfound = 0; 416 for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) { 417 if (SCARG(uap, pid) != WAIT_ANY && 418 p->p_pid != SCARG(uap, pid) && 419 p->p_pgid != -SCARG(uap, pid)) 420 continue; 421 nfound++; 422 if (p->p_stat == SZOMB) { 423 retval[0] = p->p_pid; 424 425 if (SCARG(uap, status)) { 426 status = p->p_xstat; /* convert to int */ 427 error = copyout((caddr_t)&status, 428 (caddr_t)SCARG(uap, status), 429 sizeof(status)); 430 if (error) 431 return (error); 432 } 433 if (SCARG(uap, rusage) && 434 (error = copyout((caddr_t)p->p_ru, 435 (caddr_t)SCARG(uap, rusage), 436 sizeof(struct rusage)))) 437 return (error); 438 /* 439 * If we got the child via ptrace(2) or procfs, and 440 * the parent is different (meaning the process was 441 * attached, rather than run as a child), then we need 442 * to give it back to the old parent, and send the 443 * parent a SIGCHLD. The rest of the cleanup will be 444 * done when the old parent waits on the child. 445 */ 446 if ((p->p_flag & P_TRACED) && 447 p->p_oppid != p->p_pptr->p_pid) { 448 t = pfind(p->p_oppid); 449 proc_reparent(p, t ? t : initproc); 450 p->p_oppid = 0; 451 p->p_flag &= ~(P_TRACED|P_WAITED|P_FSTRACE); 452 psignal(p->p_pptr, SIGCHLD); 453 wakeup((caddr_t)p->p_pptr); 454 return (0); 455 } 456 scheduler_wait_hook(curproc, p); 457 p->p_xstat = 0; 458 ruadd(&q->p_stats->p_cru, p->p_ru); 459 pool_put(&rusage_pool, p->p_ru); 460 461 /* 462 * Finally finished with old proc entry. 463 * Unlink it from its process group and free it. 464 */ 465 leavepgrp(p); 466 467 LIST_REMOVE(p, p_list); /* off zombproc */ 468 469 LIST_REMOVE(p, p_sibling); 470 471 /* 472 * Decrement the count of procs running with this uid. 473 */ 474 (void)chgproccnt(p->p_cred->p_ruid, -1); 475 476 /* 477 * Free up credentials. 478 */ 479 if (--p->p_cred->p_refcnt == 0) { 480 crfree(p->p_cred->pc_ucred); 481 pool_put(&pcred_pool, p->p_cred); 482 } 483 484 /* 485 * Release reference to text vnode 486 */ 487 if (p->p_textvp) 488 vrele(p->p_textvp); 489 490 /* 491 * Give machine-dependent layer a chance 492 * to free anything that cpu_exit couldn't 493 * release while still running in process context. 494 */ 495 cpu_wait(p); 496 pool_put(&proc_pool, p); 497 nprocs--; 498 return (0); 499 } 500 if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 && 501 (p->p_flag & P_TRACED || SCARG(uap, options) & WUNTRACED)) { 502 p->p_flag |= P_WAITED; 503 retval[0] = p->p_pid; 504 505 if (SCARG(uap, status)) { 506 status = W_STOPCODE(p->p_xstat); 507 error = copyout((caddr_t)&status, 508 (caddr_t)SCARG(uap, status), 509 sizeof(status)); 510 } else 511 error = 0; 512 return (error); 513 } 514 } 515 if (nfound == 0) 516 return (ECHILD); 517 if (SCARG(uap, options) & WNOHANG) { 518 retval[0] = 0; 519 return (0); 520 } 521 if ((error = tsleep((caddr_t)q, PWAIT | PCATCH, "wait", 0)) != 0) 522 return (error); 523 goto loop; 524 } 525 526 /* 527 * make process 'parent' the new parent of process 'child'. 528 */ 529 void 530 proc_reparent(child, parent) 531 register struct proc *child; 532 register struct proc *parent; 533 { 534 535 if (child->p_pptr == parent) 536 return; 537 538 LIST_REMOVE(child, p_sibling); 539 LIST_INSERT_HEAD(&parent->p_children, child, p_sibling); 540 child->p_pptr = parent; 541 } 542