]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/kern_exit.c
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.git] / sys / kern / kern_exit.c
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1991, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *      @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
39  * $FreeBSD$
40  */
41
42 #include "opt_compat.h"
43 #include "opt_ktrace.h"
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/sysproto.h>
48 #include <sys/kernel.h>
49 #include <sys/malloc.h>
50 #include <sys/proc.h>
51 #include <sys/pioctl.h>
52 #include <sys/tty.h>
53 #include <sys/wait.h>
54 #include <sys/vnode.h>
55 #include <sys/resourcevar.h>
56 #include <sys/signalvar.h>
57 #include <sys/ptrace.h>
58 #include <sys/acct.h>           /* for acct_process() function prototype */
59 #include <sys/filedesc.h>
60 #include <sys/shm.h>
61 #include <sys/sem.h>
62 #include <sys/aio.h>
63 #include <sys/jail.h>
64
65 #include <vm/vm.h>
66 #include <vm/vm_param.h>
67 #include <sys/lock.h>
68 #include <vm/pmap.h>
69 #include <vm/vm_map.h>
70 #include <vm/vm_zone.h>
71 #include <sys/user.h>
72
73 /* Required to be non-static for SysVR4 emulator */
74 MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status");
75
76 static MALLOC_DEFINE(M_ATEXIT, "atexit", "atexit callback");
77
78 static int wait1 __P((struct proc *, struct wait_args *, int));
79
80 /*
81  * callout list for things to do at exit time
82  */
83 struct exitlist {
84         exitlist_fn function;
85         TAILQ_ENTRY(exitlist) next;
86 };
87
88 TAILQ_HEAD(exit_list_head, exitlist);
89 static struct exit_list_head exit_list = TAILQ_HEAD_INITIALIZER(exit_list);
90
91 /*
92  * exit --
93  *      Death of process.
94  */
95 void
96 exit(p, uap)
97         struct proc *p;
98         struct rexit_args /* {
99                 int     rval;
100         } */ *uap;
101 {
102
103         exit1(p, W_EXITCODE(uap->rval, 0));
104         /* NOTREACHED */
105 }
106
107 /*
108  * Exit: deallocate address space and other resources, change proc state
109  * to zombie, and unlink proc from allproc and parent's lists.  Save exit
110  * status and rusage for wait().  Check for child processes and orphan them.
111  */
112 void
113 exit1(p, rv)
114         register struct proc *p;
115         int rv;
116 {
117         register struct proc *q, *nq;
118         register struct vmspace *vm;
119         struct exitlist *ep;
120
121         if (p->p_pid == 1) {
122                 printf("init died (signal %d, exit %d)\n",
123                     WTERMSIG(rv), WEXITSTATUS(rv));
124                 panic("Going nowhere without my init!");
125         }
126
127         aio_proc_rundown(p);
128
129         /* are we a task leader? */
130         if(p == p->p_leader) {
131                 struct kill_args killArgs;
132                 killArgs.signum = SIGKILL;
133                 q = p->p_peers;
134                 while(q) {
135                         killArgs.pid = q->p_pid;
136                         /*
137                          * The interface for kill is better
138                          * than the internal signal
139                          */
140                         kill(p, &killArgs);
141                         nq = q;
142                         q = q->p_peers;
143                 }
144                 while (p->p_peers) 
145                   tsleep((caddr_t)p, PWAIT, "exit1", 0);
146         } 
147
148 #ifdef PGINPROF
149         vmsizmon();
150 #endif
151         STOPEVENT(p, S_EXIT, rv);
152         wakeup(&p->p_stype);    /* Wakeup anyone in procfs' PIOCWAIT */
153
154         /* 
155          * Check if any loadable modules need anything done at process exit.
156          * e.g. SYSV IPC stuff
157          * XXX what if one of these generates an error?
158          */
159         TAILQ_FOREACH(ep, &exit_list, next) 
160                 (*ep->function)(p);
161
162         if (p->p_flag & P_PROFIL)
163                 stopprofclock(p);
164         MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage),
165                 M_ZOMBIE, M_WAITOK);
166         /*
167          * If parent is waiting for us to exit or exec,
168          * P_PPWAIT is set; we will wakeup the parent below.
169          */
170         p->p_flag &= ~(P_TRACED | P_PPWAIT);
171         p->p_flag |= P_WEXIT;
172         SIGEMPTYSET(p->p_siglist);
173         if (timevalisset(&p->p_realtimer.it_value))
174                 untimeout(realitexpire, (caddr_t)p, p->p_ithandle);
175
176         /*
177          * Reset any sigio structures pointing to us as a result of
178          * F_SETOWN with our pid.
179          */
180         funsetownlst(&p->p_sigiolst);
181
182         /*
183          * Close open files and release open-file table.
184          * This may block!
185          */
186         fdfree(p);
187
188         if(p->p_leader->p_peers) {
189                 q = p->p_leader;
190                 while(q->p_peers != p)
191                         q = q->p_peers;
192                 q->p_peers = p->p_peers;
193                 wakeup((caddr_t)p->p_leader);
194         }
195
196         /*
197          * XXX Shutdown SYSV semaphores
198          */
199         semexit(p);
200
201         /* The next two chunks should probably be moved to vmspace_exit. */
202         vm = p->p_vmspace;
203         /*
204          * Release user portion of address space.
205          * This releases references to vnodes,
206          * which could cause I/O if the file has been unlinked.
207          * Need to do this early enough that we can still sleep.
208          * Can't free the entire vmspace as the kernel stack
209          * may be mapped within that space also.
210          */
211         if (vm->vm_refcnt == 1) {
212                 if (vm->vm_shm)
213                         shmexit(p);
214                 pmap_remove_pages(vmspace_pmap(vm), VM_MIN_ADDRESS,
215                     VM_MAXUSER_ADDRESS);
216                 (void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS,
217                     VM_MAXUSER_ADDRESS);
218         }
219
220         if (SESS_LEADER(p)) {
221                 register struct session *sp = p->p_session;
222
223                 if (sp->s_ttyvp) {
224                         /*
225                          * Controlling process.
226                          * Signal foreground pgrp,
227                          * drain controlling terminal
228                          * and revoke access to controlling terminal.
229                          */
230                         if (sp->s_ttyp && (sp->s_ttyp->t_session == sp)) {
231                                 if (sp->s_ttyp->t_pgrp)
232                                         pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
233                                 (void) ttywait(sp->s_ttyp);
234                                 /*
235                                  * The tty could have been revoked
236                                  * if we blocked.
237                                  */
238                                 if (sp->s_ttyvp)
239                                         VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
240                         }
241                         if (sp->s_ttyvp)
242                                 vrele(sp->s_ttyvp);
243                         sp->s_ttyvp = NULL;
244                         /*
245                          * s_ttyp is not zero'd; we use this to indicate
246                          * that the session once had a controlling terminal.
247                          * (for logging and informational purposes)
248                          */
249                 }
250                 sp->s_leader = NULL;
251         }
252         fixjobc(p, p->p_pgrp, 0);
253         (void)acct_process(p);
254 #ifdef KTRACE
255         /*
256          * release trace file
257          */
258         p->p_traceflag = 0;     /* don't trace the vrele() */
259         if (p->p_tracep)
260                 vrele(p->p_tracep);
261 #endif
262         /*
263          * Remove proc from allproc queue and pidhash chain.
264          * Place onto zombproc.  Unlink from parent's child list.
265          */
266         LIST_REMOVE(p, p_list);
267         LIST_INSERT_HEAD(&zombproc, p, p_list);
268         p->p_stat = SZOMB;
269
270         LIST_REMOVE(p, p_hash);
271
272         q = LIST_FIRST(&p->p_children);
273         if (q)          /* only need this if any child is S_ZOMB */
274                 wakeup((caddr_t) initproc);
275         for (; q != 0; q = nq) {
276                 nq = LIST_NEXT(q, p_sibling);
277                 LIST_REMOVE(q, p_sibling);
278                 LIST_INSERT_HEAD(&initproc->p_children, q, p_sibling);
279                 q->p_pptr = initproc;
280                 q->p_sigparent = SIGCHLD;
281                 /*
282                  * Traced processes are killed
283                  * since their existence means someone is screwing up.
284                  */
285                 if (q->p_flag & P_TRACED) {
286                         q->p_flag &= ~P_TRACED;
287                         psignal(q, SIGKILL);
288                 }
289         }
290
291         /*
292          * Save exit status and final rusage info, adding in child rusage
293          * info and self times.
294          */
295         p->p_xstat = rv;
296         *p->p_ru = p->p_stats->p_ru;
297         calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL);
298         ruadd(p->p_ru, &p->p_stats->p_cru);
299
300         /*
301          * Pretend that an mi_switch() to the next process occurs now.  We
302          * must set `switchtime' directly since we will call cpu_switch()
303          * directly.  Set it now so that the rest of the exit time gets
304          * counted somewhere if possible.
305          */
306         microuptime(&switchtime);
307         switchticks = ticks;
308
309         /*
310          * Notify parent that we're gone.  If parent has the PS_NOCLDWAIT
311          * flag set, notify process 1 instead (and hope it will handle
312          * this situation).
313          */
314         if (p->p_pptr->p_procsig->ps_flag & PS_NOCLDWAIT) {
315                 struct proc *pp = p->p_pptr;
316                 proc_reparent(p, initproc);
317                 /*
318                  * If this was the last child of our parent, notify
319                  * parent, so in case he was wait(2)ing, he will
320                  * continue.
321                  */
322                 if (LIST_EMPTY(&pp->p_children))
323                         wakeup((caddr_t)pp);
324         }
325
326         if (p->p_sigparent && p->p_pptr != initproc) {
327                 psignal(p->p_pptr, p->p_sigparent);
328         } else {
329                 psignal(p->p_pptr, SIGCHLD);
330         }
331
332         wakeup((caddr_t)p->p_pptr);
333 #if defined(tahoe)
334         /* move this to cpu_exit */
335         p->p_addr->u_pcb.pcb_savacc.faddr = (float *)NULL;
336 #endif
337         /*
338          * Clear curproc after we've done all operations
339          * that could block, and before tearing down the rest
340          * of the process state that might be used from clock, etc.
341          * Also, can't clear curproc while we're still runnable,
342          * as we're not on a run queue (we are current, just not
343          * a proper proc any longer!).
344          *
345          * Other substructures are freed from wait().
346          */
347         SET_CURPROC(NULL);
348         if (--p->p_limit->p_refcnt == 0) {
349                 FREE(p->p_limit, M_SUBPROC);
350                 p->p_limit = NULL;
351         }
352
353         /*
354          * Finally, call machine-dependent code to release the remaining
355          * resources including address space, the kernel stack and pcb.
356          * The address space is released by "vmspace_free(p->p_vmspace)";
357          * This is machine-dependent, as we may have to change stacks
358          * or ensure that the current one isn't reallocated before we
359          * finish.  cpu_exit will end with a call to cpu_switch(), finishing
360          * our execution (pun intended).
361          */
362         cpu_exit(p);
363 }
364
365 #ifdef COMPAT_43
366 int
367 owait(p, uap)
368         struct proc *p;
369         register struct owait_args /* {
370                 int     dummy;
371         } */ *uap;
372 {
373         struct wait_args w;
374
375         w.options = 0;
376         w.rusage = NULL;
377         w.pid = WAIT_ANY;
378         w.status = NULL;
379         return (wait1(p, &w, 1));
380 }
381 #endif /* COMPAT_43 */
382
383 int
384 wait4(p, uap)
385         struct proc *p;
386         struct wait_args *uap;
387 {
388
389         return (wait1(p, uap, 0));
390 }
391
392 static int
393 wait1(q, uap, compat)
394         register struct proc *q;
395         register struct wait_args /* {
396                 int pid;
397                 int *status;
398                 int options;
399                 struct rusage *rusage;
400         } */ *uap;
401         int compat;
402 {
403         register int nfound;
404         register struct proc *p, *t;
405         int status, error;
406
407         if (uap->pid == 0)
408                 uap->pid = -q->p_pgid;
409         if (uap->options &~ (WUNTRACED|WNOHANG|WLINUXCLONE))
410                 return (EINVAL);
411 loop:
412         nfound = 0;
413         LIST_FOREACH(p, &q->p_children, p_sibling) {
414                 if (uap->pid != WAIT_ANY &&
415                     p->p_pid != uap->pid && p->p_pgid != -uap->pid)
416                         continue;
417
418                 /* This special case handles a kthread spawned by linux_clone 
419                  * (see linux_misc.c).  The linux_wait4 and linux_waitpid functions
420                  * need to be able to distinguish between waiting on a process and
421                  * waiting on a thread.  It is a thread if p_sigparent is not SIGCHLD,
422                  * and the WLINUXCLONE option signifies we want to wait for threads
423                  * and not processes.
424                  */
425                 if ((p->p_sigparent != SIGCHLD) ^ ((uap->options & WLINUXCLONE) != 0))
426                         continue;
427
428                 nfound++;
429                 if (p->p_stat == SZOMB) {
430                         /* charge childs scheduling cpu usage to parent */
431                         if (curproc->p_pid != 1) {
432                                 curproc->p_estcpu =
433                                     ESTCPULIM(curproc->p_estcpu + p->p_estcpu);
434                         }
435
436                         q->p_retval[0] = p->p_pid;
437 #ifdef COMPAT_43
438                         if (compat)
439                                 q->p_retval[1] = p->p_xstat;
440                         else
441 #endif
442                         if (uap->status) {
443                                 status = p->p_xstat;    /* convert to int */
444                                 if ((error = copyout((caddr_t)&status,
445                                     (caddr_t)uap->status, sizeof(status))))
446                                         return (error);
447                         }
448                         if (uap->rusage && (error = copyout((caddr_t)p->p_ru,
449                             (caddr_t)uap->rusage, sizeof (struct rusage))))
450                                 return (error);
451                         /*
452                          * If we got the child via a ptrace 'attach',
453                          * we need to give it back to the old parent.
454                          */
455                         if (p->p_oppid && (t = pfind(p->p_oppid))) {
456                                 p->p_oppid = 0;
457                                 proc_reparent(p, t);
458                                 psignal(t, SIGCHLD);
459                                 wakeup((caddr_t)t);
460                                 return (0);
461                         }
462                         p->p_xstat = 0;
463                         ruadd(&q->p_stats->p_cru, p->p_ru);
464                         FREE(p->p_ru, M_ZOMBIE);
465                         p->p_ru = NULL;
466
467                         /*
468                          * Decrement the count of procs running with this uid.
469                          */
470                         (void)chgproccnt(p->p_cred->p_ruid, -1);
471
472                         /*
473                          * Release reference to text vnode
474                          */
475                         if (p->p_textvp)
476                                 vrele(p->p_textvp);
477
478                         /*
479                          * Free up credentials.
480                          */
481                         if (--p->p_cred->p_refcnt == 0) {
482                                 crfree(p->p_ucred);
483                                 FREE(p->p_cred, M_SUBPROC);
484                                 p->p_cred = NULL;
485                         }
486
487                         /*
488                          * Destroy empty prisons
489                          */
490                         if (p->p_prison && !--p->p_prison->pr_ref) {
491                                 if (p->p_prison->pr_linux != NULL)
492                                         FREE(p->p_prison->pr_linux, M_PRISON);
493                                 FREE(p->p_prison, M_PRISON);
494                         }
495
496                         /*
497                          * Remove unused arguments
498                          */
499                         if (p->p_args && --p->p_args->ar_ref == 0)
500                                 FREE(p->p_args, M_PARGS);
501
502                         /*
503                          * Finally finished with old proc entry.
504                          * Unlink it from its process group and free it.
505                          */
506                         leavepgrp(p);
507                         LIST_REMOVE(p, p_list); /* off zombproc */
508                         LIST_REMOVE(p, p_sibling);
509
510                         if (--p->p_procsig->ps_refcnt == 0) {
511                                 if (p->p_sigacts != &p->p_addr->u_sigacts)
512                                         FREE(p->p_sigacts, M_SUBPROC);
513                                 FREE(p->p_procsig, M_SUBPROC);
514                                 p->p_procsig = NULL;
515                         }
516
517                         /*
518                          * Give machine-dependent layer a chance
519                          * to free anything that cpu_exit couldn't
520                          * release while still running in process context.
521                          */
522                         cpu_wait(p);
523                         zfree(proc_zone, p);
524                         nprocs--;
525                         return (0);
526                 }
527                 if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
528                     (p->p_flag & P_TRACED || uap->options & WUNTRACED)) {
529                         p->p_flag |= P_WAITED;
530                         q->p_retval[0] = p->p_pid;
531 #ifdef COMPAT_43
532                         if (compat) {
533                                 q->p_retval[1] = W_STOPCODE(p->p_xstat);
534                                 error = 0;
535                         } else
536 #endif
537                         if (uap->status) {
538                                 status = W_STOPCODE(p->p_xstat);
539                                 error = copyout((caddr_t)&status,
540                                         (caddr_t)uap->status, sizeof(status));
541                         } else
542                                 error = 0;
543                         return (error);
544                 }
545         }
546         if (nfound == 0)
547                 return (ECHILD);
548         if (uap->options & WNOHANG) {
549                 q->p_retval[0] = 0;
550                 return (0);
551         }
552         if ((error = tsleep((caddr_t)q, PWAIT | PCATCH, "wait", 0)))
553                 return (error);
554         goto loop;
555 }
556
557 /*
558  * make process 'parent' the new parent of process 'child'.
559  */
560 void
561 proc_reparent(child, parent)
562         register struct proc *child;
563         register struct proc *parent;
564 {
565
566         if (child->p_pptr == parent)
567                 return;
568
569         LIST_REMOVE(child, p_sibling);
570         LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
571         child->p_pptr = parent;
572 }
573
574 /*
575  * The next two functions are to handle adding/deleting items on the
576  * exit callout list
577  * 
578  * at_exit():
579  * Take the arguments given and put them onto the exit callout list,
580  * However first make sure that it's not already there.
581  * returns 0 on success.
582  */
583
584 int
585 at_exit(function)
586         exitlist_fn function;
587 {
588         struct exitlist *ep;
589
590 #ifdef INVARIANTS
591         /* Be noisy if the programmer has lost track of things */
592         if (rm_at_exit(function)) 
593                 printf("WARNING: exit callout entry (%p) already present\n",
594                     function);
595 #endif
596         ep = malloc(sizeof(*ep), M_ATEXIT, M_NOWAIT);
597         if (ep == NULL)
598                 return (ENOMEM);
599         ep->function = function;
600         TAILQ_INSERT_TAIL(&exit_list, ep, next);
601         return (0);
602 }
603
604 /*
605  * Scan the exit callout list for the given item and remove it.
606  * Returns the number of items removed (0 or 1)
607  */
608 int
609 rm_at_exit(function)
610         exitlist_fn function;
611 {
612         struct exitlist *ep;
613
614         TAILQ_FOREACH(ep, &exit_list, next) {
615                 if (ep->function == function) {
616                         TAILQ_REMOVE(&exit_list, ep, next);
617                         free(ep, M_ATEXIT);
618                         return(1);
619                 }
620         }       
621         return (0);
622 }
623
624 void check_sigacts (void)
625 {
626         struct proc *p = curproc;
627         struct sigacts *pss;
628         int s;
629
630         if (p->p_procsig->ps_refcnt == 1 &&
631             p->p_sigacts != &p->p_addr->u_sigacts) {
632                 pss = p->p_sigacts;
633                 s = splhigh();
634                 p->p_addr->u_sigacts = *pss;
635                 p->p_sigacts = &p->p_addr->u_sigacts;
636                 splx(s);
637                 FREE(pss, M_SUBPROC);
638         }
639 }
640