1 | /* $NetBSD: kern_exit.c,v 1.267 2016/11/13 15:25:01 christos Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 1998, 1999, 2006, 2007, 2008 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, and by Andrew Doran. |
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 | * |
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | * POSSIBILITY OF SUCH DAMAGE. |
31 | */ |
32 | |
33 | /* |
34 | * Copyright (c) 1982, 1986, 1989, 1991, 1993 |
35 | * The Regents of the University of California. All rights reserved. |
36 | * (c) UNIX System Laboratories, Inc. |
37 | * All or some portions of this file are derived from material licensed |
38 | * to the University of California by American Telephone and Telegraph |
39 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with |
40 | * the permission of UNIX System Laboratories, Inc. |
41 | * |
42 | * Redistribution and use in source and binary forms, with or without |
43 | * modification, are permitted provided that the following conditions |
44 | * are met: |
45 | * 1. Redistributions of source code must retain the above copyright |
46 | * notice, this list of conditions and the following disclaimer. |
47 | * 2. Redistributions in binary form must reproduce the above copyright |
48 | * notice, this list of conditions and the following disclaimer in the |
49 | * documentation and/or other materials provided with the distribution. |
50 | * 3. Neither the name of the University nor the names of its contributors |
51 | * may be used to endorse or promote products derived from this software |
52 | * without specific prior written permission. |
53 | * |
54 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
55 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
56 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
57 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
58 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
59 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
60 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
62 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
63 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
64 | * SUCH DAMAGE. |
65 | * |
66 | * @(#)kern_exit.c 8.10 (Berkeley) 2/23/95 |
67 | */ |
68 | |
69 | #include <sys/cdefs.h> |
70 | __KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.267 2016/11/13 15:25:01 christos Exp $" ); |
71 | |
72 | #include "opt_ktrace.h" |
73 | #include "opt_dtrace.h" |
74 | #include "opt_perfctrs.h" |
75 | #include "opt_sysv.h" |
76 | |
77 | #include <sys/param.h> |
78 | #include <sys/systm.h> |
79 | #include <sys/ioctl.h> |
80 | #include <sys/tty.h> |
81 | #include <sys/time.h> |
82 | #include <sys/resource.h> |
83 | #include <sys/kernel.h> |
84 | #include <sys/proc.h> |
85 | #include <sys/buf.h> |
86 | #include <sys/wait.h> |
87 | #include <sys/file.h> |
88 | #include <sys/vnode.h> |
89 | #include <sys/syslog.h> |
90 | #include <sys/pool.h> |
91 | #include <sys/uidinfo.h> |
92 | #if defined(PERFCTRS) |
93 | #include <sys/pmc.h> |
94 | #endif |
95 | #include <sys/ptrace.h> |
96 | #include <sys/acct.h> |
97 | #include <sys/filedesc.h> |
98 | #include <sys/ras.h> |
99 | #include <sys/signalvar.h> |
100 | #include <sys/sched.h> |
101 | #include <sys/mount.h> |
102 | #include <sys/syscallargs.h> |
103 | #include <sys/kauth.h> |
104 | #include <sys/sleepq.h> |
105 | #include <sys/lockdebug.h> |
106 | #include <sys/ktrace.h> |
107 | #include <sys/cpu.h> |
108 | #include <sys/lwpctl.h> |
109 | #include <sys/atomic.h> |
110 | #include <sys/sdt.h> |
111 | |
112 | #include <uvm/uvm_extern.h> |
113 | |
114 | #ifdef DEBUG_EXIT |
115 | int debug_exit = 0; |
116 | #define DPRINTF(x) if (debug_exit) printf x |
117 | #else |
118 | #define DPRINTF(x) |
119 | #endif |
120 | |
121 | static int find_stopped_child(struct proc *, idtype_t, id_t, int, |
122 | struct proc **, struct wrusage *, siginfo_t *); |
123 | static void proc_free(struct proc *, struct wrusage *); |
124 | |
125 | /* |
126 | * DTrace SDT provider definitions |
127 | */ |
128 | SDT_PROVIDER_DECLARE(proc); |
129 | SDT_PROBE_DEFINE1(proc, kernel, , exit, "int" ); |
130 | |
131 | /* |
132 | * Fill in the appropriate signal information, and signal the parent. |
133 | */ |
134 | /* XXX noclone works around a gcc 4.5 bug on arm */ |
135 | static void __noclone |
136 | exit_psignal(struct proc *p, struct proc *pp, ksiginfo_t *ksi) |
137 | { |
138 | |
139 | KSI_INIT(ksi); |
140 | if ((ksi->ksi_signo = P_EXITSIG(p)) == SIGCHLD) { |
141 | if (p->p_xsig) { |
142 | if (p->p_sflag & PS_COREDUMP) |
143 | ksi->ksi_code = CLD_DUMPED; |
144 | else |
145 | ksi->ksi_code = CLD_KILLED; |
146 | ksi->ksi_status = p->p_xsig; |
147 | } else { |
148 | ksi->ksi_code = CLD_EXITED; |
149 | ksi->ksi_status = p->p_xexit; |
150 | } |
151 | } else { |
152 | ksi->ksi_code = SI_USER; |
153 | ksi->ksi_status = p->p_xsig; |
154 | } |
155 | /* |
156 | * We fill those in, even for non-SIGCHLD. |
157 | * It's safe to access p->p_cred unlocked here. |
158 | */ |
159 | ksi->ksi_pid = p->p_pid; |
160 | ksi->ksi_uid = kauth_cred_geteuid(p->p_cred); |
161 | /* XXX: is this still valid? */ |
162 | ksi->ksi_utime = p->p_stats->p_ru.ru_utime.tv_sec; |
163 | ksi->ksi_stime = p->p_stats->p_ru.ru_stime.tv_sec; |
164 | } |
165 | |
166 | /* |
167 | * exit -- |
168 | * Death of process. |
169 | */ |
170 | int |
171 | sys_exit(struct lwp *l, const struct sys_exit_args *uap, register_t *retval) |
172 | { |
173 | /* { |
174 | syscallarg(int) rval; |
175 | } */ |
176 | struct proc *p = l->l_proc; |
177 | |
178 | /* Don't call exit1() multiple times in the same process. */ |
179 | mutex_enter(p->p_lock); |
180 | if (p->p_sflag & PS_WEXIT) { |
181 | mutex_exit(p->p_lock); |
182 | lwp_exit(l); |
183 | } |
184 | |
185 | /* exit1() will release the mutex. */ |
186 | exit1(l, SCARG(uap, rval), 0); |
187 | /* NOTREACHED */ |
188 | return (0); |
189 | } |
190 | |
191 | /* |
192 | * Exit: deallocate address space and other resources, change proc state |
193 | * to zombie, and unlink proc from allproc and parent's lists. Save exit |
194 | * status and rusage for wait(). Check for child processes and orphan them. |
195 | * |
196 | * Must be called with p->p_lock held. Does not return. |
197 | */ |
198 | void |
199 | exit1(struct lwp *l, int exitcode, int signo) |
200 | { |
201 | struct proc *p, *child, *next_child, *old_parent, *new_parent; |
202 | struct pgrp *pgrp; |
203 | ksiginfo_t ksi; |
204 | ksiginfoq_t kq; |
205 | int wakeinit; |
206 | |
207 | p = l->l_proc; |
208 | |
209 | KASSERT(mutex_owned(p->p_lock)); |
210 | KASSERT(p->p_vmspace != NULL); |
211 | |
212 | if (__predict_false(p == initproc)) { |
213 | panic("init died (signal %d, exit %d)" , signo, exitcode); |
214 | } |
215 | |
216 | p->p_sflag |= PS_WEXIT; |
217 | |
218 | /* |
219 | * Force all other LWPs to exit before we do. Only then can we |
220 | * begin to tear down the rest of the process state. |
221 | */ |
222 | if (p->p_nlwps > 1) { |
223 | exit_lwps(l); |
224 | } |
225 | |
226 | ksiginfo_queue_init(&kq); |
227 | |
228 | /* |
229 | * If we have been asked to stop on exit, do so now. |
230 | */ |
231 | if (__predict_false(p->p_sflag & PS_STOPEXIT)) { |
232 | KERNEL_UNLOCK_ALL(l, &l->l_biglocks); |
233 | sigclearall(p, &contsigmask, &kq); |
234 | |
235 | if (!mutex_tryenter(proc_lock)) { |
236 | mutex_exit(p->p_lock); |
237 | mutex_enter(proc_lock); |
238 | mutex_enter(p->p_lock); |
239 | } |
240 | p->p_waited = 0; |
241 | p->p_pptr->p_nstopchild++; |
242 | p->p_stat = SSTOP; |
243 | mutex_exit(proc_lock); |
244 | lwp_lock(l); |
245 | p->p_nrlwps--; |
246 | l->l_stat = LSSTOP; |
247 | lwp_unlock(l); |
248 | mutex_exit(p->p_lock); |
249 | lwp_lock(l); |
250 | mi_switch(l); |
251 | KERNEL_LOCK(l->l_biglocks, l); |
252 | mutex_enter(p->p_lock); |
253 | } |
254 | |
255 | /* |
256 | * Bin any remaining signals and mark the process as dying so it will |
257 | * not be found for, e.g. signals. |
258 | */ |
259 | sigfillset(&p->p_sigctx.ps_sigignore); |
260 | sigclearall(p, NULL, &kq); |
261 | p->p_stat = SDYING; |
262 | mutex_exit(p->p_lock); |
263 | ksiginfo_queue_drain(&kq); |
264 | |
265 | /* Destroy any lwpctl info. */ |
266 | if (p->p_lwpctl != NULL) |
267 | lwp_ctl_exit(); |
268 | |
269 | /* |
270 | * Drain all remaining references that procfs, ptrace and others may |
271 | * have on the process. |
272 | */ |
273 | rw_enter(&p->p_reflock, RW_WRITER); |
274 | |
275 | DPRINTF(("%s: %d.%d exiting.\n" , __func__, p->p_pid, l->l_lid)); |
276 | |
277 | timers_free(p, TIMERS_ALL); |
278 | #if defined(__HAVE_RAS) |
279 | ras_purgeall(); |
280 | #endif |
281 | |
282 | /* |
283 | * Close open files, release open-file table and free signal |
284 | * actions. This may block! |
285 | */ |
286 | fd_free(); |
287 | cwdfree(p->p_cwdi); |
288 | p->p_cwdi = NULL; |
289 | doexithooks(p); |
290 | sigactsfree(p->p_sigacts); |
291 | |
292 | /* |
293 | * Write out accounting data. |
294 | */ |
295 | (void)acct_process(l); |
296 | |
297 | #ifdef KTRACE |
298 | /* |
299 | * Release trace file. |
300 | */ |
301 | if (p->p_tracep != NULL) { |
302 | mutex_enter(&ktrace_lock); |
303 | ktrderef(p); |
304 | mutex_exit(&ktrace_lock); |
305 | } |
306 | #endif |
307 | |
308 | p->p_xexit = exitcode; |
309 | p->p_xsig = signo; |
310 | |
311 | /* |
312 | * If emulation has process exit hook, call it now. |
313 | * Set the exit status now so that the exit hook has |
314 | * an opportunity to tweak it (COMPAT_LINUX requires |
315 | * this for thread group emulation) |
316 | */ |
317 | if (p->p_emul->e_proc_exit) |
318 | (*p->p_emul->e_proc_exit)(p); |
319 | |
320 | /* |
321 | * Free the VM resources we're still holding on to. |
322 | * We must do this from a valid thread because doing |
323 | * so may block. This frees vmspace, which we don't |
324 | * need anymore. The only remaining lwp is the one |
325 | * we run at this moment, nothing runs in userland |
326 | * anymore. |
327 | */ |
328 | uvm_proc_exit(p); |
329 | |
330 | /* |
331 | * Stop profiling. |
332 | */ |
333 | if (__predict_false((p->p_stflag & PST_PROFIL) != 0)) { |
334 | mutex_spin_enter(&p->p_stmutex); |
335 | stopprofclock(p); |
336 | mutex_spin_exit(&p->p_stmutex); |
337 | } |
338 | |
339 | /* |
340 | * If parent is waiting for us to exit or exec, PL_PPWAIT is set; we |
341 | * wake up the parent early to avoid deadlock. We can do this once |
342 | * the VM resources are released. |
343 | */ |
344 | mutex_enter(proc_lock); |
345 | if (p->p_lflag & PL_PPWAIT) { |
346 | #if 0 |
347 | lwp_t *lp; |
348 | |
349 | l->l_lwpctl = NULL; /* was on loan from blocked parent */ |
350 | p->p_lflag &= ~PL_PPWAIT; |
351 | |
352 | lp = p->p_vforklwp; |
353 | p->p_vforklwp = NULL; |
354 | lp->l_pflag &= ~LP_VFORKWAIT; /* XXX */ |
355 | cv_broadcast(&lp->l_waitcv); |
356 | #else |
357 | l->l_lwpctl = NULL; /* was on loan from blocked parent */ |
358 | p->p_lflag &= ~PL_PPWAIT; |
359 | cv_broadcast(&p->p_pptr->p_waitcv); |
360 | #endif |
361 | } |
362 | |
363 | if (SESS_LEADER(p)) { |
364 | struct vnode *vprele = NULL, *vprevoke = NULL; |
365 | struct session *sp = p->p_session; |
366 | struct tty *tp; |
367 | |
368 | if (sp->s_ttyvp) { |
369 | /* |
370 | * Controlling process. |
371 | * Signal foreground pgrp, |
372 | * drain controlling terminal |
373 | * and revoke access to controlling terminal. |
374 | */ |
375 | tp = sp->s_ttyp; |
376 | mutex_spin_enter(&tty_lock); |
377 | if (tp->t_session == sp) { |
378 | /* we can't guarantee the revoke will do this */ |
379 | pgrp = tp->t_pgrp; |
380 | tp->t_pgrp = NULL; |
381 | tp->t_session = NULL; |
382 | mutex_spin_exit(&tty_lock); |
383 | if (pgrp != NULL) { |
384 | pgsignal(pgrp, SIGHUP, 1); |
385 | } |
386 | mutex_exit(proc_lock); |
387 | (void) ttywait(tp); |
388 | mutex_enter(proc_lock); |
389 | |
390 | /* The tty could have been revoked. */ |
391 | vprevoke = sp->s_ttyvp; |
392 | } else |
393 | mutex_spin_exit(&tty_lock); |
394 | vprele = sp->s_ttyvp; |
395 | sp->s_ttyvp = NULL; |
396 | /* |
397 | * s_ttyp is not zero'd; we use this to indicate |
398 | * that the session once had a controlling terminal. |
399 | * (for logging and informational purposes) |
400 | */ |
401 | } |
402 | sp->s_leader = NULL; |
403 | |
404 | if (vprevoke != NULL || vprele != NULL) { |
405 | if (vprevoke != NULL) { |
406 | /* Releases proc_lock. */ |
407 | proc_sessrele(sp); |
408 | VOP_REVOKE(vprevoke, REVOKEALL); |
409 | } else |
410 | mutex_exit(proc_lock); |
411 | if (vprele != NULL) |
412 | vrele(vprele); |
413 | mutex_enter(proc_lock); |
414 | } |
415 | } |
416 | fixjobc(p, p->p_pgrp, 0); |
417 | |
418 | /* |
419 | * Finalize the last LWP's specificdata, as well as the |
420 | * specificdata for the proc itself. |
421 | */ |
422 | lwp_finispecific(l); |
423 | proc_finispecific(p); |
424 | |
425 | /* |
426 | * Notify interested parties of our demise. |
427 | */ |
428 | KNOTE(&p->p_klist, NOTE_EXIT); |
429 | |
430 | SDT_PROBE(proc, kernel, , exit, |
431 | ((p->p_sflag & PS_COREDUMP) ? CLD_DUMPED : |
432 | (p->p_xsig ? CLD_KILLED : CLD_EXITED)), |
433 | 0,0,0,0); |
434 | |
435 | #if PERFCTRS |
436 | /* |
437 | * Save final PMC information in parent process & clean up. |
438 | */ |
439 | if (PMC_ENABLED(p)) { |
440 | pmc_save_context(p); |
441 | pmc_accumulate(p->p_pptr, p); |
442 | pmc_process_exit(p); |
443 | } |
444 | #endif |
445 | |
446 | /* |
447 | * Reset p_opptr pointer of all former children which got |
448 | * traced by another process and were reparented. We reset |
449 | * it to NULL here; the trace detach code then reparents |
450 | * the child to initproc. We only check allproc list, since |
451 | * eventual former children on zombproc list won't reference |
452 | * p_opptr anymore. |
453 | */ |
454 | if (__predict_false(p->p_slflag & PSL_CHTRACED)) { |
455 | struct proc *q; |
456 | PROCLIST_FOREACH(q, &allproc) { |
457 | if (q->p_opptr == p) |
458 | q->p_opptr = NULL; |
459 | } |
460 | PROCLIST_FOREACH(q, &zombproc) { |
461 | if (q->p_opptr == p) |
462 | q->p_opptr = NULL; |
463 | } |
464 | } |
465 | |
466 | /* |
467 | * Give orphaned children to init(8). |
468 | */ |
469 | child = LIST_FIRST(&p->p_children); |
470 | wakeinit = (child != NULL); |
471 | for (; child != NULL; child = next_child) { |
472 | next_child = LIST_NEXT(child, p_sibling); |
473 | |
474 | /* |
475 | * Traced processes are killed since their existence |
476 | * means someone is screwing up. Since we reset the |
477 | * trace flags, the logic in sys_wait4() would not be |
478 | * triggered to reparent the process to its |
479 | * original parent, so we must do this here. |
480 | */ |
481 | if (__predict_false(child->p_slflag & PSL_TRACED)) { |
482 | mutex_enter(p->p_lock); |
483 | child->p_slflag &= |
484 | ~(PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL); |
485 | mutex_exit(p->p_lock); |
486 | if (child->p_opptr != child->p_pptr) { |
487 | struct proc *t = child->p_opptr; |
488 | proc_reparent(child, t ? t : initproc); |
489 | child->p_opptr = NULL; |
490 | } else |
491 | proc_reparent(child, initproc); |
492 | killproc(child, "orphaned traced process" ); |
493 | } else |
494 | proc_reparent(child, initproc); |
495 | } |
496 | |
497 | /* |
498 | * Move proc from allproc to zombproc, it's now nearly ready to be |
499 | * collected by parent. |
500 | */ |
501 | LIST_REMOVE(l, l_list); |
502 | LIST_REMOVE(p, p_list); |
503 | LIST_INSERT_HEAD(&zombproc, p, p_list); |
504 | |
505 | /* |
506 | * Mark the process as dead. We must do this before we signal |
507 | * the parent. |
508 | */ |
509 | p->p_stat = SDEAD; |
510 | |
511 | /* Put in front of parent's sibling list for parent to collect it */ |
512 | old_parent = p->p_pptr; |
513 | old_parent->p_nstopchild++; |
514 | if (LIST_FIRST(&old_parent->p_children) != p) { |
515 | /* Put child where it can be found quickly */ |
516 | LIST_REMOVE(p, p_sibling); |
517 | LIST_INSERT_HEAD(&old_parent->p_children, p, p_sibling); |
518 | } |
519 | |
520 | /* |
521 | * Notify parent that we're gone. If parent has the P_NOCLDWAIT |
522 | * flag set, notify init instead (and hope it will handle |
523 | * this situation). |
524 | */ |
525 | if (old_parent->p_flag & (PK_NOCLDWAIT|PK_CLDSIGIGN)) { |
526 | proc_reparent(p, initproc); |
527 | wakeinit = 1; |
528 | |
529 | /* |
530 | * If this was the last child of our parent, notify |
531 | * parent, so in case he was wait(2)ing, he will |
532 | * continue. |
533 | */ |
534 | if (LIST_FIRST(&old_parent->p_children) == NULL) |
535 | cv_broadcast(&old_parent->p_waitcv); |
536 | } |
537 | |
538 | /* Reload parent pointer, since p may have been reparented above */ |
539 | new_parent = p->p_pptr; |
540 | |
541 | if (__predict_false((p->p_slflag & PSL_FSTRACE) == 0 && |
542 | p->p_exitsig != 0)) { |
543 | exit_psignal(p, new_parent, &ksi); |
544 | kpsignal(new_parent, &ksi, NULL); |
545 | } |
546 | |
547 | /* Calculate the final rusage info. */ |
548 | calcru(p, &p->p_stats->p_ru.ru_utime, &p->p_stats->p_ru.ru_stime, |
549 | NULL, NULL); |
550 | |
551 | if (wakeinit) |
552 | cv_broadcast(&initproc->p_waitcv); |
553 | |
554 | callout_destroy(&l->l_timeout_ch); |
555 | |
556 | /* |
557 | * Release any PCU resources before becoming a zombie. |
558 | */ |
559 | pcu_discard_all(l); |
560 | |
561 | mutex_enter(p->p_lock); |
562 | /* Free the linux lwp id */ |
563 | if ((l->l_pflag & LP_PIDLID) != 0 && l->l_lid != p->p_pid) |
564 | proc_free_pid(l->l_lid); |
565 | lwp_drainrefs(l); |
566 | lwp_lock(l); |
567 | l->l_prflag &= ~LPR_DETACHED; |
568 | l->l_stat = LSZOMB; |
569 | lwp_unlock(l); |
570 | KASSERT(curlwp == l); |
571 | KASSERT(p->p_nrlwps == 1); |
572 | KASSERT(p->p_nlwps == 1); |
573 | p->p_stat = SZOMB; |
574 | p->p_nrlwps--; |
575 | p->p_nzlwps++; |
576 | p->p_ndlwps = 0; |
577 | mutex_exit(p->p_lock); |
578 | |
579 | /* |
580 | * Signal the parent to collect us, and drop the proclist lock. |
581 | * Drop debugger/procfs lock; no new references can be gained. |
582 | */ |
583 | cv_broadcast(&p->p_pptr->p_waitcv); |
584 | rw_exit(&p->p_reflock); |
585 | mutex_exit(proc_lock); |
586 | |
587 | /* Verify that we hold no locks other than the kernel lock. */ |
588 | LOCKDEBUG_BARRIER(&kernel_lock, 0); |
589 | |
590 | /* |
591 | * NOTE: WE ARE NO LONGER ALLOWED TO SLEEP! |
592 | */ |
593 | |
594 | /* |
595 | * Give machine-dependent code a chance to free any MD LWP |
596 | * resources. This must be done before uvm_lwp_exit(), in |
597 | * case these resources are in the PCB. |
598 | */ |
599 | cpu_lwp_free(l, 1); |
600 | |
601 | pmap_deactivate(l); |
602 | |
603 | /* This process no longer needs to hold the kernel lock. */ |
604 | #ifdef notyet |
605 | /* XXXSMP hold in lwp_userret() */ |
606 | KERNEL_UNLOCK_LAST(l); |
607 | #else |
608 | KERNEL_UNLOCK_ALL(l, NULL); |
609 | #endif |
610 | |
611 | lwp_exit_switchaway(l); |
612 | } |
613 | |
614 | void |
615 | exit_lwps(struct lwp *l) |
616 | { |
617 | proc_t *p = l->l_proc; |
618 | lwp_t *l2; |
619 | int nlocks; |
620 | |
621 | KERNEL_UNLOCK_ALL(l, &nlocks); |
622 | retry: |
623 | KASSERT(mutex_owned(p->p_lock)); |
624 | |
625 | /* |
626 | * Interrupt LWPs in interruptable sleep, unsuspend suspended |
627 | * LWPs and then wait for everyone else to finish. |
628 | */ |
629 | LIST_FOREACH(l2, &p->p_lwps, l_sibling) { |
630 | if (l2 == l) |
631 | continue; |
632 | lwp_lock(l2); |
633 | l2->l_flag |= LW_WEXIT; |
634 | if ((l2->l_stat == LSSLEEP && (l2->l_flag & LW_SINTR)) || |
635 | l2->l_stat == LSSUSPENDED || l2->l_stat == LSSTOP) { |
636 | /* setrunnable() will release the lock. */ |
637 | setrunnable(l2); |
638 | continue; |
639 | } |
640 | lwp_unlock(l2); |
641 | } |
642 | |
643 | /* |
644 | * Wait for every LWP to exit. Note: LWPs can get suspended/slept |
645 | * behind us or there may even be new LWPs created. Therefore, a |
646 | * full retry is required on error. |
647 | */ |
648 | while (p->p_nlwps > 1) { |
649 | if (lwp_wait(l, 0, NULL, true)) { |
650 | goto retry; |
651 | } |
652 | } |
653 | |
654 | KERNEL_LOCK(nlocks, l); |
655 | KASSERT(p->p_nlwps == 1); |
656 | } |
657 | |
658 | int |
659 | do_sys_waitid(idtype_t idtype, id_t id, int *pid, int *status, int options, |
660 | struct wrusage *wru, siginfo_t *si) |
661 | { |
662 | proc_t *child; |
663 | int error; |
664 | |
665 | |
666 | if (wru != NULL) |
667 | memset(wru, 0, sizeof(*wru)); |
668 | if (si != NULL) |
669 | memset(si, 0, sizeof(*si)); |
670 | |
671 | mutex_enter(proc_lock); |
672 | error = find_stopped_child(curproc, idtype, id, options, &child, |
673 | wru, si); |
674 | if (child == NULL) { |
675 | mutex_exit(proc_lock); |
676 | *pid = 0; |
677 | return error; |
678 | } |
679 | *pid = child->p_pid; |
680 | |
681 | if (child->p_stat == SZOMB) { |
682 | /* Child is exiting */ |
683 | *status = P_WAITSTATUS(child); |
684 | /* proc_free() will release the proc_lock. */ |
685 | if (options & WNOWAIT) { |
686 | mutex_exit(proc_lock); |
687 | } else { |
688 | proc_free(child, wru); |
689 | } |
690 | } else { |
691 | /* Don't mark SIGCONT if we are being stopped */ |
692 | *status = (child->p_xsig == SIGCONT && child->p_stat != SSTOP) ? |
693 | W_CONTCODE() : W_STOPCODE(child->p_xsig); |
694 | mutex_exit(proc_lock); |
695 | } |
696 | return 0; |
697 | } |
698 | |
699 | int |
700 | do_sys_wait(int *pid, int *status, int options, struct rusage *ru) |
701 | { |
702 | idtype_t idtype; |
703 | id_t id; |
704 | int ret; |
705 | struct wrusage wru; |
706 | |
707 | /* |
708 | * Translate the special pid values into the (idtype, pid) |
709 | * pair for wait6. The WAIT_MYPGRP case is handled by |
710 | * find_stopped_child() on its own. |
711 | */ |
712 | if (*pid == WAIT_ANY) { |
713 | idtype = P_ALL; |
714 | id = 0; |
715 | } else if (*pid < 0) { |
716 | idtype = P_PGID; |
717 | id = (id_t)-*pid; |
718 | } else { |
719 | idtype = P_PID; |
720 | id = (id_t)*pid; |
721 | } |
722 | options |= WEXITED | WTRAPPED; |
723 | ret = do_sys_waitid(idtype, id, pid, status, options, ru ? &wru : NULL, |
724 | NULL); |
725 | if (ru) |
726 | *ru = wru.wru_self; |
727 | return ret; |
728 | } |
729 | |
730 | int |
731 | sys___wait450(struct lwp *l, const struct sys___wait450_args *uap, |
732 | register_t *retval) |
733 | { |
734 | /* { |
735 | syscallarg(int) pid; |
736 | syscallarg(int *) status; |
737 | syscallarg(int) options; |
738 | syscallarg(struct rusage *) rusage; |
739 | } */ |
740 | int error, status, pid = SCARG(uap, pid); |
741 | struct rusage ru; |
742 | |
743 | error = do_sys_wait(&pid, &status, SCARG(uap, options), |
744 | SCARG(uap, rusage) != NULL ? &ru : NULL); |
745 | |
746 | retval[0] = pid; |
747 | if (pid == 0) { |
748 | return error; |
749 | } |
750 | if (SCARG(uap, status)) { |
751 | error = copyout(&status, SCARG(uap, status), sizeof(status)); |
752 | } |
753 | if (SCARG(uap, rusage) && error == 0) { |
754 | error = copyout(&ru, SCARG(uap, rusage), sizeof(ru)); |
755 | } |
756 | return error; |
757 | } |
758 | |
759 | int |
760 | sys_wait6(struct lwp *l, const struct sys_wait6_args *uap, register_t *retval) |
761 | { |
762 | /* { |
763 | syscallarg(idtype_t) idtype; |
764 | syscallarg(id_t) id; |
765 | syscallarg(int *) status; |
766 | syscallarg(int) options; |
767 | syscallarg(struct wrusage *) wru; |
768 | syscallarg(siginfo_t *) si; |
769 | } */ |
770 | struct wrusage wru, *wrup; |
771 | siginfo_t si, *sip; |
772 | idtype_t idtype; |
773 | int pid; |
774 | id_t id; |
775 | int error, status; |
776 | |
777 | idtype = SCARG(uap, idtype); |
778 | id = SCARG(uap, id); |
779 | |
780 | if (SCARG(uap, wru) != NULL) |
781 | wrup = &wru; |
782 | else |
783 | wrup = NULL; |
784 | |
785 | if (SCARG(uap, info) != NULL) |
786 | sip = &si; |
787 | else |
788 | sip = NULL; |
789 | |
790 | /* |
791 | * We expect all callers of wait6() to know about WEXITED and |
792 | * WTRAPPED. |
793 | */ |
794 | error = do_sys_waitid(idtype, id, &pid, &status, SCARG(uap, options), |
795 | wrup, sip); |
796 | |
797 | retval[0] = pid; /* tell userland who it was */ |
798 | |
799 | #if 0 |
800 | /* |
801 | * should we copyout if there was no process, hence no useful data? |
802 | * We don't for an old sytle wait4() (etc) but I believe |
803 | * FreeBSD does for wait6(), so a tossup... Go with FreeBSD for now. |
804 | */ |
805 | if (pid == 0) |
806 | return error; |
807 | #endif |
808 | |
809 | if (SCARG(uap, status) != NULL && error == 0) |
810 | error = copyout(&status, SCARG(uap, status), sizeof(status)); |
811 | if (SCARG(uap, wru) != NULL && error == 0) |
812 | error = copyout(&wru, SCARG(uap, wru), sizeof(wru)); |
813 | if (SCARG(uap, info) != NULL && error == 0) |
814 | error = copyout(&si, SCARG(uap, info), sizeof(si)); |
815 | return error; |
816 | } |
817 | |
818 | |
819 | /* |
820 | * Find a process that matches the provided criteria, and fill siginfo |
821 | * and resources if found. |
822 | * Returns: |
823 | * -1: Not found, abort early |
824 | * 0: Not matched |
825 | * 1: Matched, there might be more matches |
826 | * 2: This is the only match |
827 | */ |
828 | static int |
829 | match_process(const struct proc *pp, struct proc **q, idtype_t idtype, id_t id, |
830 | int options, struct wrusage *wrusage, siginfo_t *siginfo) |
831 | { |
832 | struct rusage *rup; |
833 | struct proc *p = *q; |
834 | int rv = 1; |
835 | |
836 | mutex_enter(p->p_lock); |
837 | switch (idtype) { |
838 | case P_ALL: |
839 | break; |
840 | case P_PID: |
841 | if (p->p_pid != (pid_t)id) { |
842 | mutex_exit(p->p_lock); |
843 | p = *q = proc_find_raw((pid_t)id); |
844 | if (p == NULL || p->p_stat == SIDL || p->p_pptr != pp) { |
845 | *q = NULL; |
846 | return -1; |
847 | } |
848 | mutex_enter(p->p_lock); |
849 | } |
850 | rv++; |
851 | break; |
852 | case P_PGID: |
853 | if (p->p_pgid != (pid_t)id) |
854 | goto out; |
855 | break; |
856 | case P_SID: |
857 | if (p->p_session->s_sid != (pid_t)id) |
858 | goto out; |
859 | break; |
860 | case P_UID: |
861 | if (kauth_cred_geteuid(p->p_cred) != (uid_t)id) |
862 | goto out; |
863 | break; |
864 | case P_GID: |
865 | if (kauth_cred_getegid(p->p_cred) != (gid_t)id) |
866 | goto out; |
867 | break; |
868 | case P_CID: |
869 | case P_PSETID: |
870 | case P_CPUID: |
871 | /* XXX: Implement me */ |
872 | default: |
873 | out: |
874 | mutex_exit(p->p_lock); |
875 | return 0; |
876 | } |
877 | |
878 | if ((options & WEXITED) == 0 && p->p_stat == SZOMB) |
879 | goto out; |
880 | |
881 | if (siginfo != NULL) { |
882 | siginfo->si_errno = 0; |
883 | |
884 | /* |
885 | * SUSv4 requires that the si_signo value is always |
886 | * SIGCHLD. Obey it despite the rfork(2) interface |
887 | * allows to request other signal for child exit |
888 | * notification. |
889 | */ |
890 | siginfo->si_signo = SIGCHLD; |
891 | |
892 | /* |
893 | * This is still a rough estimate. We will fix the |
894 | * cases TRAPPED, STOPPED, and CONTINUED later. |
895 | */ |
896 | if (p->p_sflag & PS_COREDUMP) { |
897 | siginfo->si_code = CLD_DUMPED; |
898 | siginfo->si_status = p->p_xsig; |
899 | } else if (p->p_xsig) { |
900 | siginfo->si_code = CLD_KILLED; |
901 | siginfo->si_status = p->p_xsig; |
902 | } else { |
903 | siginfo->si_code = CLD_EXITED; |
904 | siginfo->si_status = p->p_xexit; |
905 | } |
906 | |
907 | siginfo->si_pid = p->p_pid; |
908 | siginfo->si_uid = kauth_cred_geteuid(p->p_cred); |
909 | siginfo->si_utime = p->p_stats->p_ru.ru_utime.tv_sec; |
910 | siginfo->si_stime = p->p_stats->p_ru.ru_stime.tv_sec; |
911 | } |
912 | |
913 | /* |
914 | * There should be no reason to limit resources usage info to |
915 | * exited processes only. A snapshot about any resources used |
916 | * by a stopped process may be exactly what is needed. |
917 | */ |
918 | if (wrusage != NULL) { |
919 | rup = &wrusage->wru_self; |
920 | *rup = p->p_stats->p_ru; |
921 | calcru(p, &rup->ru_utime, &rup->ru_stime, NULL, NULL); |
922 | |
923 | rup = &wrusage->wru_children; |
924 | *rup = p->p_stats->p_cru; |
925 | calcru(p, &rup->ru_utime, &rup->ru_stime, NULL, NULL); |
926 | } |
927 | |
928 | mutex_exit(p->p_lock); |
929 | return rv; |
930 | } |
931 | |
932 | /* |
933 | * Determine if there are existing processes being debugged |
934 | * that used to be (and sometime later will be again) children |
935 | * of a specific parent (while matching wait criteria) |
936 | */ |
937 | static bool |
938 | debugged_child_exists(idtype_t idtype, id_t id, int options, siginfo_t *si, |
939 | const struct proc *parent) |
940 | { |
941 | struct proc *pp; |
942 | |
943 | /* |
944 | * If we are searching for a specific pid, we can optimise a little |
945 | */ |
946 | if (idtype == P_PID) { |
947 | /* |
948 | * Check the specific process to see if its real parent is us |
949 | */ |
950 | pp = proc_find_raw((pid_t)id); |
951 | if (pp != NULL && pp->p_stat != SIDL && pp->p_opptr == parent) { |
952 | /* |
953 | * using P_ALL here avoids match_process() doing the |
954 | * same work that we just did, but incorrectly for |
955 | * this scenario. |
956 | */ |
957 | if (match_process(parent, &pp, P_ALL, id, options, |
958 | NULL, si)) |
959 | return true; |
960 | } |
961 | return false; |
962 | } |
963 | |
964 | /* |
965 | * For the hard cases, just look everywhere to see if some |
966 | * stolen (reparented) process is really our lost child. |
967 | * Then check if that process could satisfy the wait conditions. |
968 | */ |
969 | |
970 | /* |
971 | * XXX inefficient, but hopefully fairly rare. |
972 | * XXX should really use a list of reparented processes. |
973 | */ |
974 | PROCLIST_FOREACH(pp, &allproc) { |
975 | if (pp->p_stat == SIDL) /* XXX impossible ?? */ |
976 | continue; |
977 | if (pp->p_opptr == parent && |
978 | match_process(parent, &pp, idtype, id, options, NULL, si)) |
979 | return true; |
980 | } |
981 | PROCLIST_FOREACH(pp, &zombproc) { |
982 | if (pp->p_stat == SIDL) /* XXX impossible ?? */ |
983 | continue; |
984 | if (pp->p_opptr == parent && |
985 | match_process(parent, &pp, idtype, id, options, NULL, si)) |
986 | return true; |
987 | } |
988 | |
989 | return false; |
990 | } |
991 | |
992 | /* |
993 | * Scan list of child processes for a child process that has stopped or |
994 | * exited. Used by sys_wait4 and 'compat' equivalents. |
995 | * |
996 | * Must be called with the proc_lock held, and may release while waiting. |
997 | */ |
998 | static int |
999 | find_stopped_child(struct proc *parent, idtype_t idtype, id_t id, int options, |
1000 | struct proc **child_p, struct wrusage *wru, siginfo_t *si) |
1001 | { |
1002 | struct proc *child, *dead; |
1003 | int error; |
1004 | |
1005 | KASSERT(mutex_owned(proc_lock)); |
1006 | |
1007 | if (options & ~WALLOPTS) { |
1008 | *child_p = NULL; |
1009 | return EINVAL; |
1010 | } |
1011 | |
1012 | if ((options & WSELECTOPTS) == 0) { |
1013 | /* |
1014 | * We will be unable to find any matching processes, |
1015 | * because there are no known events to look for. |
1016 | * Prefer to return error instead of blocking |
1017 | * indefinitely. |
1018 | */ |
1019 | *child_p = NULL; |
1020 | return EINVAL; |
1021 | } |
1022 | |
1023 | if ((pid_t)id == WAIT_MYPGRP && (idtype == P_PID || idtype == P_PGID)) { |
1024 | mutex_enter(parent->p_lock); |
1025 | id = (id_t)parent->p_pgid; |
1026 | mutex_exit(parent->p_lock); |
1027 | idtype = P_PGID; |
1028 | } |
1029 | |
1030 | for (;;) { |
1031 | error = ECHILD; |
1032 | dead = NULL; |
1033 | |
1034 | LIST_FOREACH(child, &parent->p_children, p_sibling) { |
1035 | int rv = match_process(parent, &child, idtype, id, |
1036 | options, wru, si); |
1037 | if (rv == -1) |
1038 | break; |
1039 | if (rv == 0) |
1040 | continue; |
1041 | |
1042 | /* |
1043 | * Wait for processes with p_exitsig != SIGCHLD |
1044 | * processes only if WALTSIG is set; wait for |
1045 | * processes with p_exitsig == SIGCHLD only |
1046 | * if WALTSIG is clear. |
1047 | */ |
1048 | if (((options & WALLSIG) == 0) && |
1049 | (options & WALTSIG ? child->p_exitsig == SIGCHLD |
1050 | : P_EXITSIG(child) != SIGCHLD)){ |
1051 | if (rv == 2) { |
1052 | child = NULL; |
1053 | break; |
1054 | } |
1055 | continue; |
1056 | } |
1057 | |
1058 | error = 0; |
1059 | if ((options & WNOZOMBIE) == 0) { |
1060 | if (child->p_stat == SZOMB) |
1061 | break; |
1062 | if (child->p_stat == SDEAD) { |
1063 | /* |
1064 | * We may occasionally arrive here |
1065 | * after receiving a signal, but |
1066 | * immediately before the child |
1067 | * process is zombified. The wait |
1068 | * will be short, so avoid returning |
1069 | * to userspace. |
1070 | */ |
1071 | dead = child; |
1072 | } |
1073 | } |
1074 | |
1075 | if ((options & WCONTINUED) != 0 && |
1076 | child->p_xsig == SIGCONT && |
1077 | (child->p_sflag & PS_CONTINUED)) { |
1078 | if ((options & WNOWAIT) == 0) { |
1079 | child->p_sflag &= ~PS_CONTINUED; |
1080 | child->p_waited = 1; |
1081 | parent->p_nstopchild--; |
1082 | } |
1083 | if (si) { |
1084 | si->si_status = child->p_xsig; |
1085 | si->si_code = CLD_CONTINUED; |
1086 | } |
1087 | break; |
1088 | } |
1089 | |
1090 | if ((options & (WTRAPPED|WSTOPPED)) != 0 && |
1091 | child->p_stat == SSTOP && |
1092 | child->p_waited == 0 && |
1093 | ((child->p_slflag & PSL_TRACED) || |
1094 | options & (WUNTRACED|WSTOPPED))) { |
1095 | if ((options & WNOWAIT) == 0) { |
1096 | child->p_waited = 1; |
1097 | parent->p_nstopchild--; |
1098 | } |
1099 | if (si) { |
1100 | si->si_status = child->p_xsig; |
1101 | si->si_code = |
1102 | (child->p_slflag & PSL_TRACED) ? |
1103 | CLD_TRAPPED : CLD_STOPPED; |
1104 | } |
1105 | break; |
1106 | } |
1107 | if (parent->p_nstopchild == 0 || rv == 2) { |
1108 | child = NULL; |
1109 | break; |
1110 | } |
1111 | } |
1112 | |
1113 | /* |
1114 | * If we found nothing, but we are the bereaved parent |
1115 | * of a stolen child, look and see if that child (or |
1116 | * one of them) meets our search criteria. If so, then |
1117 | * we cannot succeed, but we can hang (wait...), |
1118 | * or if WNOHANG, return 0 instead of ECHILD |
1119 | */ |
1120 | if (child == NULL && error == ECHILD && |
1121 | (parent->p_slflag & PSL_CHTRACED) && |
1122 | debugged_child_exists(idtype, id, options, si, parent)) |
1123 | error = 0; |
1124 | |
1125 | if (child != NULL || error != 0 || |
1126 | ((options & WNOHANG) != 0 && dead == NULL)) { |
1127 | *child_p = child; |
1128 | return error; |
1129 | } |
1130 | |
1131 | /* |
1132 | * Wait for another child process to stop. |
1133 | */ |
1134 | error = cv_wait_sig(&parent->p_waitcv, proc_lock); |
1135 | |
1136 | if (error != 0) { |
1137 | *child_p = NULL; |
1138 | return error; |
1139 | } |
1140 | } |
1141 | } |
1142 | |
1143 | /* |
1144 | * Free a process after parent has taken all the state info. Must be called |
1145 | * with the proclist lock held, and will release before returning. |
1146 | * |
1147 | * *ru is returned to the caller, and must be freed by the caller. |
1148 | */ |
1149 | static void |
1150 | proc_free(struct proc *p, struct wrusage *wru) |
1151 | { |
1152 | struct proc *parent = p->p_pptr; |
1153 | struct lwp *l; |
1154 | ksiginfo_t ksi; |
1155 | kauth_cred_t cred1, cred2; |
1156 | uid_t uid; |
1157 | |
1158 | KASSERT(mutex_owned(proc_lock)); |
1159 | KASSERT(p->p_nlwps == 1); |
1160 | KASSERT(p->p_nzlwps == 1); |
1161 | KASSERT(p->p_nrlwps == 0); |
1162 | KASSERT(p->p_stat == SZOMB); |
1163 | |
1164 | /* |
1165 | * If we got the child via ptrace(2) or procfs, and |
1166 | * the parent is different (meaning the process was |
1167 | * attached, rather than run as a child), then we need |
1168 | * to give it back to the old parent, and send the |
1169 | * parent the exit signal. The rest of the cleanup |
1170 | * will be done when the old parent waits on the child. |
1171 | */ |
1172 | if ((p->p_slflag & PSL_TRACED) != 0 && p->p_opptr != parent) { |
1173 | mutex_enter(p->p_lock); |
1174 | p->p_slflag &= ~(PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL); |
1175 | mutex_exit(p->p_lock); |
1176 | parent = (p->p_opptr == NULL) ? initproc : p->p_opptr; |
1177 | proc_reparent(p, parent); |
1178 | p->p_opptr = NULL; |
1179 | if (p->p_exitsig != 0) { |
1180 | exit_psignal(p, parent, &ksi); |
1181 | kpsignal(parent, &ksi, NULL); |
1182 | } |
1183 | cv_broadcast(&parent->p_waitcv); |
1184 | mutex_exit(proc_lock); |
1185 | return; |
1186 | } |
1187 | |
1188 | sched_proc_exit(parent, p); |
1189 | |
1190 | /* |
1191 | * Add child times of exiting process onto its own times. |
1192 | * This cannot be done any earlier else it might get done twice. |
1193 | */ |
1194 | l = LIST_FIRST(&p->p_lwps); |
1195 | p->p_stats->p_ru.ru_nvcsw += (l->l_ncsw - l->l_nivcsw); |
1196 | p->p_stats->p_ru.ru_nivcsw += l->l_nivcsw; |
1197 | ruadd(&p->p_stats->p_ru, &l->l_ru); |
1198 | ruadd(&p->p_stats->p_ru, &p->p_stats->p_cru); |
1199 | ruadd(&parent->p_stats->p_cru, &p->p_stats->p_ru); |
1200 | if (wru != NULL) { |
1201 | wru->wru_self = p->p_stats->p_ru; |
1202 | wru->wru_children = p->p_stats->p_cru; |
1203 | } |
1204 | p->p_xsig = 0; |
1205 | p->p_xexit = 0; |
1206 | |
1207 | /* |
1208 | * At this point we are going to start freeing the final resources. |
1209 | * If anyone tries to access the proc structure after here they will |
1210 | * get a shock - bits are missing. Attempt to make it hard! We |
1211 | * don't bother with any further locking past this point. |
1212 | */ |
1213 | p->p_stat = SIDL; /* not even a zombie any more */ |
1214 | LIST_REMOVE(p, p_list); /* off zombproc */ |
1215 | parent->p_nstopchild--; |
1216 | LIST_REMOVE(p, p_sibling); |
1217 | |
1218 | /* |
1219 | * Let pid be reallocated. |
1220 | */ |
1221 | proc_free_pid(p->p_pid); |
1222 | |
1223 | /* |
1224 | * Unlink process from its process group. |
1225 | * Releases the proc_lock. |
1226 | */ |
1227 | proc_leavepgrp(p); |
1228 | |
1229 | /* |
1230 | * Delay release until after lwp_free. |
1231 | */ |
1232 | cred2 = l->l_cred; |
1233 | |
1234 | /* |
1235 | * Free the last LWP's resources. |
1236 | * |
1237 | * lwp_free ensures the LWP is no longer running on another CPU. |
1238 | */ |
1239 | lwp_free(l, false, true); |
1240 | |
1241 | /* |
1242 | * Now no one except us can reach the process p. |
1243 | */ |
1244 | |
1245 | /* |
1246 | * Decrement the count of procs running with this uid. |
1247 | */ |
1248 | cred1 = p->p_cred; |
1249 | uid = kauth_cred_getuid(cred1); |
1250 | (void)chgproccnt(uid, -1); |
1251 | |
1252 | /* |
1253 | * Release substructures. |
1254 | */ |
1255 | |
1256 | lim_free(p->p_limit); |
1257 | pstatsfree(p->p_stats); |
1258 | kauth_cred_free(cred1); |
1259 | kauth_cred_free(cred2); |
1260 | |
1261 | /* |
1262 | * Release reference to text vnode |
1263 | */ |
1264 | if (p->p_textvp) |
1265 | vrele(p->p_textvp); |
1266 | |
1267 | mutex_destroy(&p->p_auxlock); |
1268 | mutex_obj_free(p->p_lock); |
1269 | mutex_destroy(&p->p_stmutex); |
1270 | cv_destroy(&p->p_waitcv); |
1271 | cv_destroy(&p->p_lwpcv); |
1272 | rw_destroy(&p->p_reflock); |
1273 | |
1274 | proc_free_mem(p); |
1275 | } |
1276 | |
1277 | /* |
1278 | * Change the parent of a process for tracing purposes. |
1279 | */ |
1280 | void |
1281 | proc_changeparent(struct proc *t, struct proc *p) |
1282 | { |
1283 | SET(t->p_slflag, PSL_TRACED); |
1284 | t->p_opptr = t->p_pptr; |
1285 | if (t->p_pptr == p) |
1286 | return; |
1287 | struct proc *parent = t->p_pptr; |
1288 | |
1289 | if (parent->p_lock < t->p_lock) { |
1290 | if (!mutex_tryenter(parent->p_lock)) { |
1291 | mutex_exit(t->p_lock); |
1292 | mutex_enter(parent->p_lock); |
1293 | mutex_enter(t->p_lock); |
1294 | } |
1295 | } else if (parent->p_lock > t->p_lock) { |
1296 | mutex_enter(parent->p_lock); |
1297 | } |
1298 | parent->p_slflag |= PSL_CHTRACED; |
1299 | proc_reparent(t, p); |
1300 | if (parent->p_lock != t->p_lock) |
1301 | mutex_exit(parent->p_lock); |
1302 | } |
1303 | |
1304 | /* |
1305 | * make process 'parent' the new parent of process 'child'. |
1306 | * |
1307 | * Must be called with proc_lock held. |
1308 | */ |
1309 | void |
1310 | proc_reparent(struct proc *child, struct proc *parent) |
1311 | { |
1312 | |
1313 | KASSERT(mutex_owned(proc_lock)); |
1314 | |
1315 | if (child->p_pptr == parent) |
1316 | return; |
1317 | |
1318 | if (child->p_stat == SZOMB || child->p_stat == SDEAD || |
1319 | (child->p_stat == SSTOP && !child->p_waited)) { |
1320 | child->p_pptr->p_nstopchild--; |
1321 | parent->p_nstopchild++; |
1322 | } |
1323 | if (parent == initproc) { |
1324 | child->p_exitsig = SIGCHLD; |
1325 | child->p_ppid = parent->p_pid; |
1326 | } |
1327 | |
1328 | LIST_REMOVE(child, p_sibling); |
1329 | LIST_INSERT_HEAD(&parent->p_children, child, p_sibling); |
1330 | child->p_pptr = parent; |
1331 | } |
1332 | |