19454b2d8SWarner Losh /*- 2df8bae1dSRodney W. Grimes * Copyright (c) 1982, 1986, 1989, 1991, 1993 3df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 4df8bae1dSRodney W. Grimes * (c) UNIX System Laboratories, Inc. 5df8bae1dSRodney W. Grimes * All or some portions of this file are derived from material licensed 6df8bae1dSRodney W. Grimes * to the University of California by American Telephone and Telegraph 7df8bae1dSRodney W. Grimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8df8bae1dSRodney W. Grimes * the permission of UNIX System Laboratories, Inc. 9df8bae1dSRodney W. Grimes * 10df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 11df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 12df8bae1dSRodney W. Grimes * are met: 13df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 14df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 15df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 16df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 17df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 18df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 19df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 20df8bae1dSRodney W. Grimes * without specific prior written permission. 21df8bae1dSRodney W. Grimes * 22df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32df8bae1dSRodney W. Grimes * SUCH DAMAGE. 33df8bae1dSRodney W. Grimes * 34df8bae1dSRodney W. Grimes * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 35df8bae1dSRodney W. Grimes */ 36df8bae1dSRodney W. Grimes 37677b542eSDavid E. O'Brien #include <sys/cdefs.h> 38677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 39677b542eSDavid E. O'Brien 40db6a20e2SGarrett Wollman #include "opt_ktrace.h" 418a945d10SKonstantin Belousov #include "opt_kstack_pages.h" 42db6a20e2SGarrett Wollman 43df8bae1dSRodney W. Grimes #include <sys/param.h> 44df8bae1dSRodney W. Grimes #include <sys/systm.h> 45d2d3e875SBruce Evans #include <sys/sysproto.h> 4675b8b3b2SJohn Baldwin #include <sys/eventhandler.h> 47cfb5f768SJonathan Anderson #include <sys/fcntl.h> 48df8bae1dSRodney W. Grimes #include <sys/filedesc.h> 490304c731SJamie Gritton #include <sys/jail.h> 50df8bae1dSRodney W. Grimes #include <sys/kernel.h> 5170fca427SJohn Baldwin #include <sys/kthread.h> 52c76e95c3SPeter Wemm #include <sys/sysctl.h> 5319284646SJohn Baldwin #include <sys/lock.h> 54df8bae1dSRodney W. Grimes #include <sys/malloc.h> 5535e0e5b3SJohn Baldwin #include <sys/mutex.h> 56acd3428bSRobert Watson #include <sys/priv.h> 57df8bae1dSRodney W. Grimes #include <sys/proc.h> 58cfb5f768SJonathan Anderson #include <sys/procdesc.h> 599ccba881SMatthew N. Dodd #include <sys/pioctl.h> 60097055e2SEdward Tomasz Napierala #include <sys/racct.h> 61df8bae1dSRodney W. Grimes #include <sys/resourcevar.h> 62b43179fbSJeff Roberson #include <sys/sched.h> 63a7b124c3SJohn Baldwin #include <sys/syscall.h> 6470fca427SJohn Baldwin #include <sys/vmmeter.h> 65df8bae1dSRodney W. Grimes #include <sys/vnode.h> 66df8bae1dSRodney W. Grimes #include <sys/acct.h> 670384fff8SJason Evans #include <sys/ktr.h> 68df8bae1dSRodney W. Grimes #include <sys/ktrace.h> 69b71fec07SBruce Evans #include <sys/unistd.h> 705d217f17SJohn Birrell #include <sys/sdt.h> 7157934cd3SJohn Baldwin #include <sys/sx.h> 72e5d81ef1SDmitry Chagin #include <sys/sysent.h> 736004362eSDavid Schultz #include <sys/signalvar.h> 74df8bae1dSRodney W. Grimes 75fcf7f27aSRobert Watson #include <security/audit/audit.h> 76aed55708SRobert Watson #include <security/mac/mac_framework.h> 77fcf7f27aSRobert Watson 78d93f860cSPoul-Henning Kamp #include <vm/vm.h> 79dabee6feSPeter Wemm #include <vm/pmap.h> 80dabee6feSPeter Wemm #include <vm/vm_map.h> 81efeaf95aSDavid Greenman #include <vm/vm_extern.h> 82c897b813SJeff Roberson #include <vm/uma.h> 83d93f860cSPoul-Henning Kamp 845d217f17SJohn Birrell #ifdef KDTRACE_HOOKS 855d217f17SJohn Birrell #include <sys/dtrace_bsd.h> 865d217f17SJohn Birrell dtrace_fork_func_t dtrace_fasttrap_fork; 875d217f17SJohn Birrell #endif 885d217f17SJohn Birrell 895d217f17SJohn Birrell SDT_PROVIDER_DECLARE(proc); 90d9fae5abSAndriy Gapon SDT_PROBE_DEFINE3(proc, kernel, , create, "struct proc *", 917b77e1feSMark Johnston "struct proc *", "int"); 9288c5ea45SJulian Elischer 93d2d3e875SBruce Evans #ifndef _SYS_SYSPROTO_H_ 94ad7507e2SSteven Wallace struct fork_args { 95ad7507e2SSteven Wallace int dummy; 96ad7507e2SSteven Wallace }; 97d2d3e875SBruce Evans #endif 98ad7507e2SSteven Wallace 99df8bae1dSRodney W. Grimes /* ARGSUSED */ 10026f9a767SRodney W. Grimes int 1018451d0ddSKip Macy sys_fork(struct thread *td, struct fork_args *uap) 102df8bae1dSRodney W. Grimes { 103df8abd0bSPeter Wemm int error; 104df8abd0bSPeter Wemm struct proc *p2; 105be67169aSBruce Evans 106cfb5f768SJonathan Anderson error = fork1(td, RFFDG | RFPROC, 0, &p2, NULL, 0); 107df8abd0bSPeter Wemm if (error == 0) { 108b40ce416SJulian Elischer td->td_retval[0] = p2->p_pid; 109b40ce416SJulian Elischer td->td_retval[1] = 0; 110df8abd0bSPeter Wemm } 11170fca427SJohn Baldwin return (error); 112df8bae1dSRodney W. Grimes } 113df8bae1dSRodney W. Grimes 114cfb5f768SJonathan Anderson /* ARGUSED */ 115cfb5f768SJonathan Anderson int 1168451d0ddSKip Macy sys_pdfork(td, uap) 117cfb5f768SJonathan Anderson struct thread *td; 118cfb5f768SJonathan Anderson struct pdfork_args *uap; 119cfb5f768SJonathan Anderson { 120cfb5f768SJonathan Anderson int error, fd; 121cfb5f768SJonathan Anderson struct proc *p2; 122cfb5f768SJonathan Anderson 123cfb5f768SJonathan Anderson /* 124cfb5f768SJonathan Anderson * It is necessary to return fd by reference because 0 is a valid file 125cfb5f768SJonathan Anderson * descriptor number, and the child needs to be able to distinguish 126cfb5f768SJonathan Anderson * itself from the parent using the return value. 127cfb5f768SJonathan Anderson */ 128cfb5f768SJonathan Anderson error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2, 129cfb5f768SJonathan Anderson &fd, uap->flags); 130cfb5f768SJonathan Anderson if (error == 0) { 131cfb5f768SJonathan Anderson td->td_retval[0] = p2->p_pid; 132cfb5f768SJonathan Anderson td->td_retval[1] = 0; 133cfb5f768SJonathan Anderson error = copyout(&fd, uap->fdp, sizeof(fd)); 134cfb5f768SJonathan Anderson } 135cfb5f768SJonathan Anderson return (error); 136cfb5f768SJonathan Anderson } 137cfb5f768SJonathan Anderson 138df8bae1dSRodney W. Grimes /* ARGSUSED */ 13926f9a767SRodney W. Grimes int 1408451d0ddSKip Macy sys_vfork(struct thread *td, struct vfork_args *uap) 141df8bae1dSRodney W. Grimes { 14250d6e424SKip Macy int error, flags; 143df8abd0bSPeter Wemm struct proc *p2; 144be67169aSBruce Evans 14550d6e424SKip Macy flags = RFFDG | RFPROC | RFPPWAIT | RFMEM; 146cfb5f768SJonathan Anderson error = fork1(td, flags, 0, &p2, NULL, 0); 147df8abd0bSPeter Wemm if (error == 0) { 148b40ce416SJulian Elischer td->td_retval[0] = p2->p_pid; 149b40ce416SJulian Elischer td->td_retval[1] = 0; 150df8abd0bSPeter Wemm } 15170fca427SJohn Baldwin return (error); 152df8bae1dSRodney W. Grimes } 153df8bae1dSRodney W. Grimes 154dabee6feSPeter Wemm int 1558451d0ddSKip Macy sys_rfork(struct thread *td, struct rfork_args *uap) 156dabee6feSPeter Wemm { 157df8abd0bSPeter Wemm struct proc *p2; 158c8564ad4SBruce Evans int error; 159be67169aSBruce Evans 160c8564ad4SBruce Evans /* Don't allow kernel-only flags. */ 161885ccc61SJohn Baldwin if ((uap->flags & RFKERNELONLY) != 0) 162885ccc61SJohn Baldwin return (EINVAL); 163c8564ad4SBruce Evans 16414961ba7SRobert Watson AUDIT_ARG_FFLAGS(uap->flags); 165cfb5f768SJonathan Anderson error = fork1(td, uap->flags, 0, &p2, NULL, 0); 166df8abd0bSPeter Wemm if (error == 0) { 167b40ce416SJulian Elischer td->td_retval[0] = p2 ? p2->p_pid : 0; 168b40ce416SJulian Elischer td->td_retval[1] = 0; 169df8abd0bSPeter Wemm } 17070fca427SJohn Baldwin return (error); 171dabee6feSPeter Wemm } 172dabee6feSPeter Wemm 173df8bae1dSRodney W. Grimes int nprocs = 1; /* process 0 */ 1748f7e4eb5SDag-Erling Smørgrav int lastpid = 0; 1758f7e4eb5SDag-Erling Smørgrav SYSCTL_INT(_kern, OID_AUTO, lastpid, CTLFLAG_RD, &lastpid, 0, 176d941d475SRobert Watson "Last used PID"); 177df8bae1dSRodney W. Grimes 178bb6a234eSPeter Wemm /* 1798f7e4eb5SDag-Erling Smørgrav * Random component to lastpid generation. We mix in a random factor to make 180bb6a234eSPeter Wemm * it a little harder to predict. We sanity check the modulus value to avoid 181bb6a234eSPeter Wemm * doing it in critical paths. Don't let it be too small or we pointlessly 182bb6a234eSPeter Wemm * waste randomness entropy, and don't let it be impossibly large. Using a 183bb6a234eSPeter Wemm * modulus that is too big causes a LOT more process table scans and slows 184bb6a234eSPeter Wemm * down fork processing as the pidchecked caching is defeated. 185bb6a234eSPeter Wemm */ 186ee3fd601SDan Moschuk static int randompid = 0; 187bb6a234eSPeter Wemm 188bb6a234eSPeter Wemm static int 18982d9ae4eSPoul-Henning Kamp sysctl_kern_randompid(SYSCTL_HANDLER_ARGS) 190bb6a234eSPeter Wemm { 191bb6a234eSPeter Wemm int error, pid; 192bb6a234eSPeter Wemm 19347934cefSDon Lewis error = sysctl_wire_old_buffer(req, sizeof(int)); 19447934cefSDon Lewis if (error != 0) 19547934cefSDon Lewis return(error); 1963fc755c1SJohn Baldwin sx_xlock(&allproc_lock); 197bb6a234eSPeter Wemm pid = randompid; 198bb6a234eSPeter Wemm error = sysctl_handle_int(oidp, &pid, 0, req); 1993fc755c1SJohn Baldwin if (error == 0 && req->newptr != NULL) { 20002c6fc21SKonstantin Belousov if (pid < 0 || pid > pid_max - 100) /* out of range */ 20102c6fc21SKonstantin Belousov pid = pid_max - 100; 202bb6a234eSPeter Wemm else if (pid < 2) /* NOP */ 203bb6a234eSPeter Wemm pid = 0; 204bb6a234eSPeter Wemm else if (pid < 100) /* Make it reasonable */ 205bb6a234eSPeter Wemm pid = 100; 206bb6a234eSPeter Wemm randompid = pid; 2073fc755c1SJohn Baldwin } 2083fc755c1SJohn Baldwin sx_xunlock(&allproc_lock); 209bb6a234eSPeter Wemm return (error); 210bb6a234eSPeter Wemm } 211bb6a234eSPeter Wemm 212bb6a234eSPeter Wemm SYSCTL_PROC(_kern, OID_AUTO, randompid, CTLTYPE_INT|CTLFLAG_RW, 213bb6a234eSPeter Wemm 0, 0, sysctl_kern_randompid, "I", "Random PID modulus"); 214ee3fd601SDan Moschuk 2151d845e86SEdward Tomasz Napierala static int 216afd01097SEdward Tomasz Napierala fork_findpid(int flags) 217afd01097SEdward Tomasz Napierala { 218afd01097SEdward Tomasz Napierala struct proc *p; 219afd01097SEdward Tomasz Napierala int trypid; 220afd01097SEdward Tomasz Napierala static int pidchecked = 0; 221afd01097SEdward Tomasz Napierala 2223e73ff1eSEdward Tomasz Napierala /* 2233e73ff1eSEdward Tomasz Napierala * Requires allproc_lock in order to iterate over the list 2243e73ff1eSEdward Tomasz Napierala * of processes, and proctree_lock to access p_pgrp. 2253e73ff1eSEdward Tomasz Napierala */ 2263e73ff1eSEdward Tomasz Napierala sx_assert(&allproc_lock, SX_LOCKED); 2273e73ff1eSEdward Tomasz Napierala sx_assert(&proctree_lock, SX_LOCKED); 228afd01097SEdward Tomasz Napierala 229afd01097SEdward Tomasz Napierala /* 230afd01097SEdward Tomasz Napierala * Find an unused process ID. We remember a range of unused IDs 231afd01097SEdward Tomasz Napierala * ready to use (from lastpid+1 through pidchecked-1). 232afd01097SEdward Tomasz Napierala * 233afd01097SEdward Tomasz Napierala * If RFHIGHPID is set (used during system boot), do not allocate 234afd01097SEdward Tomasz Napierala * low-numbered pids. 235afd01097SEdward Tomasz Napierala */ 236afd01097SEdward Tomasz Napierala trypid = lastpid + 1; 237afd01097SEdward Tomasz Napierala if (flags & RFHIGHPID) { 238afd01097SEdward Tomasz Napierala if (trypid < 10) 239afd01097SEdward Tomasz Napierala trypid = 10; 240afd01097SEdward Tomasz Napierala } else { 241afd01097SEdward Tomasz Napierala if (randompid) 242afd01097SEdward Tomasz Napierala trypid += arc4random() % randompid; 243afd01097SEdward Tomasz Napierala } 244afd01097SEdward Tomasz Napierala retry: 245afd01097SEdward Tomasz Napierala /* 246afd01097SEdward Tomasz Napierala * If the process ID prototype has wrapped around, 247afd01097SEdward Tomasz Napierala * restart somewhat above 0, as the low-numbered procs 248afd01097SEdward Tomasz Napierala * tend to include daemons that don't exit. 249afd01097SEdward Tomasz Napierala */ 25002c6fc21SKonstantin Belousov if (trypid >= pid_max) { 25102c6fc21SKonstantin Belousov trypid = trypid % pid_max; 252afd01097SEdward Tomasz Napierala if (trypid < 100) 253afd01097SEdward Tomasz Napierala trypid += 100; 254afd01097SEdward Tomasz Napierala pidchecked = 0; 255afd01097SEdward Tomasz Napierala } 256afd01097SEdward Tomasz Napierala if (trypid >= pidchecked) { 257afd01097SEdward Tomasz Napierala int doingzomb = 0; 258afd01097SEdward Tomasz Napierala 259afd01097SEdward Tomasz Napierala pidchecked = PID_MAX; 260afd01097SEdward Tomasz Napierala /* 261afd01097SEdward Tomasz Napierala * Scan the active and zombie procs to check whether this pid 262afd01097SEdward Tomasz Napierala * is in use. Remember the lowest pid that's greater 263afd01097SEdward Tomasz Napierala * than trypid, so we can avoid checking for a while. 264*237623b0SKonstantin Belousov * 265*237623b0SKonstantin Belousov * Avoid reuse of the process group id, session id or 266*237623b0SKonstantin Belousov * the reaper subtree id. Note that for process group 267*237623b0SKonstantin Belousov * and sessions, the amount of reserved pids is 268*237623b0SKonstantin Belousov * limited by process limit. For the subtree ids, the 269*237623b0SKonstantin Belousov * id is kept reserved only while there is a 270*237623b0SKonstantin Belousov * non-reaped process in the subtree, so amount of 271*237623b0SKonstantin Belousov * reserved pids is limited by process limit times 272*237623b0SKonstantin Belousov * two. 273afd01097SEdward Tomasz Napierala */ 274afd01097SEdward Tomasz Napierala p = LIST_FIRST(&allproc); 275afd01097SEdward Tomasz Napierala again: 276afd01097SEdward Tomasz Napierala for (; p != NULL; p = LIST_NEXT(p, p_list)) { 277afd01097SEdward Tomasz Napierala while (p->p_pid == trypid || 278*237623b0SKonstantin Belousov p->p_reapsubtree == trypid || 279afd01097SEdward Tomasz Napierala (p->p_pgrp != NULL && 280afd01097SEdward Tomasz Napierala (p->p_pgrp->pg_id == trypid || 281afd01097SEdward Tomasz Napierala (p->p_session != NULL && 282afd01097SEdward Tomasz Napierala p->p_session->s_sid == trypid)))) { 283afd01097SEdward Tomasz Napierala trypid++; 284afd01097SEdward Tomasz Napierala if (trypid >= pidchecked) 285afd01097SEdward Tomasz Napierala goto retry; 286afd01097SEdward Tomasz Napierala } 287afd01097SEdward Tomasz Napierala if (p->p_pid > trypid && pidchecked > p->p_pid) 288afd01097SEdward Tomasz Napierala pidchecked = p->p_pid; 289afd01097SEdward Tomasz Napierala if (p->p_pgrp != NULL) { 290afd01097SEdward Tomasz Napierala if (p->p_pgrp->pg_id > trypid && 291afd01097SEdward Tomasz Napierala pidchecked > p->p_pgrp->pg_id) 292afd01097SEdward Tomasz Napierala pidchecked = p->p_pgrp->pg_id; 293afd01097SEdward Tomasz Napierala if (p->p_session != NULL && 294afd01097SEdward Tomasz Napierala p->p_session->s_sid > trypid && 295afd01097SEdward Tomasz Napierala pidchecked > p->p_session->s_sid) 296afd01097SEdward Tomasz Napierala pidchecked = p->p_session->s_sid; 297afd01097SEdward Tomasz Napierala } 298afd01097SEdward Tomasz Napierala } 299afd01097SEdward Tomasz Napierala if (!doingzomb) { 300afd01097SEdward Tomasz Napierala doingzomb = 1; 301afd01097SEdward Tomasz Napierala p = LIST_FIRST(&zombproc); 302afd01097SEdward Tomasz Napierala goto again; 303afd01097SEdward Tomasz Napierala } 304afd01097SEdward Tomasz Napierala } 305afd01097SEdward Tomasz Napierala 306afd01097SEdward Tomasz Napierala /* 307afd01097SEdward Tomasz Napierala * RFHIGHPID does not mess with the lastpid counter during boot. 308afd01097SEdward Tomasz Napierala */ 309afd01097SEdward Tomasz Napierala if (flags & RFHIGHPID) 310afd01097SEdward Tomasz Napierala pidchecked = 0; 311afd01097SEdward Tomasz Napierala else 312afd01097SEdward Tomasz Napierala lastpid = trypid; 313afd01097SEdward Tomasz Napierala 314afd01097SEdward Tomasz Napierala return (trypid); 315afd01097SEdward Tomasz Napierala } 316afd01097SEdward Tomasz Napierala 317afd01097SEdward Tomasz Napierala static int 3183e73ff1eSEdward Tomasz Napierala fork_norfproc(struct thread *td, int flags) 3191d845e86SEdward Tomasz Napierala { 3201d845e86SEdward Tomasz Napierala int error; 3211d845e86SEdward Tomasz Napierala struct proc *p1; 3221d845e86SEdward Tomasz Napierala 323087bfb0eSEdward Tomasz Napierala KASSERT((flags & RFPROC) == 0, 324087bfb0eSEdward Tomasz Napierala ("fork_norfproc called with RFPROC set")); 3251d845e86SEdward Tomasz Napierala p1 = td->td_proc; 3261d845e86SEdward Tomasz Napierala 3271d845e86SEdward Tomasz Napierala if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) && 3281d845e86SEdward Tomasz Napierala (flags & (RFCFDG | RFFDG))) { 3291d845e86SEdward Tomasz Napierala PROC_LOCK(p1); 3306ddcc233SKonstantin Belousov if (thread_single(p1, SINGLE_BOUNDARY)) { 3311d845e86SEdward Tomasz Napierala PROC_UNLOCK(p1); 3321d845e86SEdward Tomasz Napierala return (ERESTART); 3331d845e86SEdward Tomasz Napierala } 3341d845e86SEdward Tomasz Napierala PROC_UNLOCK(p1); 3351d845e86SEdward Tomasz Napierala } 3361d845e86SEdward Tomasz Napierala 3371d845e86SEdward Tomasz Napierala error = vm_forkproc(td, NULL, NULL, NULL, flags); 3381d845e86SEdward Tomasz Napierala if (error) 3391d845e86SEdward Tomasz Napierala goto fail; 3401d845e86SEdward Tomasz Napierala 3411d845e86SEdward Tomasz Napierala /* 3421d845e86SEdward Tomasz Napierala * Close all file descriptors. 3431d845e86SEdward Tomasz Napierala */ 3441d845e86SEdward Tomasz Napierala if (flags & RFCFDG) { 3451d845e86SEdward Tomasz Napierala struct filedesc *fdtmp; 346eb48fbd9SMateusz Guzik fdtmp = fdinit(td->td_proc->p_fd, false); 3472609222aSPawel Jakub Dawidek fdescfree(td); 3481d845e86SEdward Tomasz Napierala p1->p_fd = fdtmp; 3491d845e86SEdward Tomasz Napierala } 3501d845e86SEdward Tomasz Napierala 3511d845e86SEdward Tomasz Napierala /* 3521d845e86SEdward Tomasz Napierala * Unshare file descriptors (from parent). 3531d845e86SEdward Tomasz Napierala */ 3541d845e86SEdward Tomasz Napierala if (flags & RFFDG) 355b9d32c36SMateusz Guzik fdunshare(td); 3561d845e86SEdward Tomasz Napierala 3571d845e86SEdward Tomasz Napierala fail: 3581d845e86SEdward Tomasz Napierala if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) && 3591d845e86SEdward Tomasz Napierala (flags & (RFCFDG | RFFDG))) { 3601d845e86SEdward Tomasz Napierala PROC_LOCK(p1); 3616ddcc233SKonstantin Belousov thread_single_end(p1, SINGLE_BOUNDARY); 3621d845e86SEdward Tomasz Napierala PROC_UNLOCK(p1); 3631d845e86SEdward Tomasz Napierala } 3641d845e86SEdward Tomasz Napierala return (error); 3651d845e86SEdward Tomasz Napierala } 3661d845e86SEdward Tomasz Napierala 367afd01097SEdward Tomasz Napierala static void 368afd01097SEdward Tomasz Napierala do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, 369cfb5f768SJonathan Anderson struct vmspace *vm2, int pdflags) 370df8bae1dSRodney W. Grimes { 371afd01097SEdward Tomasz Napierala struct proc *p1, *pptr; 3726fa39a73SKonstantin Belousov int p2_held, trypid; 3735641ae5dSJohn Baldwin struct filedesc *fd; 374ad05d580STor Egge struct filedesc_to_leader *fdtol; 3753fc755c1SJohn Baldwin struct sigacts *newsigacts; 3765856e12eSJohn Dyson 377afd01097SEdward Tomasz Napierala sx_assert(&proctree_lock, SX_SLOCKED); 378afd01097SEdward Tomasz Napierala sx_assert(&allproc_lock, SX_XLOCKED); 379df8bae1dSRodney W. Grimes 3806fa39a73SKonstantin Belousov p2_held = 0; 38170fca427SJohn Baldwin p1 = td->td_proc; 38270fca427SJohn Baldwin 383df8bae1dSRodney W. Grimes /* 384ef5dc8a9SJohn Dyson * Increment the nprocs resource before blocking can occur. There 385ef5dc8a9SJohn Dyson * are hard-limits as to the number of processes that can run. 386ef5dc8a9SJohn Dyson */ 387ef5dc8a9SJohn Dyson nprocs++; 388ef5dc8a9SJohn Dyson 389afd01097SEdward Tomasz Napierala trypid = fork_findpid(flags); 390df8bae1dSRodney W. Grimes 3915ce2f678SJohn Baldwin sx_sunlock(&proctree_lock); 392df8bae1dSRodney W. Grimes 393e602ba25SJulian Elischer p2->p_state = PRS_NEW; /* protect against others */ 394553629ebSJake Burkholder p2->p_pid = trypid; 39514961ba7SRobert Watson AUDIT_ARG_PID(p2->p_pid); 396553629ebSJake Burkholder LIST_INSERT_HEAD(&allproc, p2, p_list); 3976ddcc233SKonstantin Belousov allproc_gen++; 398553629ebSJake Burkholder LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash); 399cf7d9a8cSDavid Xu tidhash_add(td2); 4001ad9ee86SXin LI PROC_LOCK(p2); 4011ad9ee86SXin LI PROC_LOCK(p1); 4021ad9ee86SXin LI 4031005a129SJohn Baldwin sx_xunlock(&allproc_lock); 404553629ebSJake Burkholder 4051ad9ee86SXin LI bcopy(&p1->p_startcopy, &p2->p_startcopy, 4061ad9ee86SXin LI __rangeof(struct proc, p_startcopy, p_endcopy)); 4078b4a2800SKonstantin Belousov pargs_hold(p2->p_args); 4081ad9ee86SXin LI PROC_UNLOCK(p1); 4091ad9ee86SXin LI 4101ad9ee86SXin LI bzero(&p2->p_startzero, 4111ad9ee86SXin LI __rangeof(struct proc, p_startzero, p_endzero)); 4121ad9ee86SXin LI 4131ad9ee86SXin LI p2->p_ucred = crhold(td->td_ucred); 414413628a7SBjoern A. Zeeb 4150304c731SJamie Gritton /* Tell the prison that we exist. */ 416413628a7SBjoern A. Zeeb prison_proc_hold(p2->p_ucred->cr_prison); 417413628a7SBjoern A. Zeeb 4181ad9ee86SXin LI PROC_UNLOCK(p2); 4191ad9ee86SXin LI 4200384fff8SJason Evans /* 4213fc755c1SJohn Baldwin * Malloc things while we don't hold any locks. 4223fc755c1SJohn Baldwin */ 42390af4afaSJohn Baldwin if (flags & RFSIGSHARE) 4243fc755c1SJohn Baldwin newsigacts = NULL; 42590af4afaSJohn Baldwin else 42690af4afaSJohn Baldwin newsigacts = sigacts_alloc(); 4273fc755c1SJohn Baldwin 4283fc755c1SJohn Baldwin /* 4293fc755c1SJohn Baldwin * Copy filedesc. 4303fc755c1SJohn Baldwin */ 431ad05d580STor Egge if (flags & RFCFDG) { 432eb48fbd9SMateusz Guzik fd = fdinit(p1->p_fd, false); 433ad05d580STor Egge fdtol = NULL; 434ad05d580STor Egge } else if (flags & RFFDG) { 435598b7ec8SPoul-Henning Kamp fd = fdcopy(p1->p_fd); 436ad05d580STor Egge fdtol = NULL; 437ad05d580STor Egge } else { 438c7f1c11bSAlfred Perlstein fd = fdshare(p1->p_fd); 439ad05d580STor Egge if (p1->p_fdtol == NULL) 4403e73ff1eSEdward Tomasz Napierala p1->p_fdtol = filedesc_to_leader_alloc(NULL, NULL, 441ad05d580STor Egge p1->p_leader); 442ad05d580STor Egge if ((flags & RFTHREAD) != 0) { 443ad05d580STor Egge /* 4443e73ff1eSEdward Tomasz Napierala * Shared file descriptor table, and shared 4453e73ff1eSEdward Tomasz Napierala * process leaders. 446ad05d580STor Egge */ 447ad05d580STor Egge fdtol = p1->p_fdtol; 4485e3f7694SRobert Watson FILEDESC_XLOCK(p1->p_fd); 449ad05d580STor Egge fdtol->fdl_refcount++; 4505e3f7694SRobert Watson FILEDESC_XUNLOCK(p1->p_fd); 451ad05d580STor Egge } else { 452ad05d580STor Egge /* 4533e73ff1eSEdward Tomasz Napierala * Shared file descriptor table, and different 4543e73ff1eSEdward Tomasz Napierala * process leaders. 455ad05d580STor Egge */ 456ad05d580STor Egge fdtol = filedesc_to_leader_alloc(p1->p_fdtol, 4573e73ff1eSEdward Tomasz Napierala p1->p_fd, p2); 458ad05d580STor Egge } 459ad05d580STor Egge } 4603fc755c1SJohn Baldwin /* 461df8bae1dSRodney W. Grimes * Make a proc table entry for the new process. 462df8bae1dSRodney W. Grimes * Start by zeroing the section of proc that is zero-initialized, 463df8bae1dSRodney W. Grimes * then copy the section that is copied directly from the parent. 464df8bae1dSRodney W. Grimes */ 465316ec49aSScott Long 4667d447c95SJohn Baldwin PROC_LOCK(p2); 4677d447c95SJohn Baldwin PROC_LOCK(p1); 4687d447c95SJohn Baldwin 469079b7badSJulian Elischer bzero(&td2->td_startzero, 4706db36923SDavid Schultz __rangeof(struct thread, td_startzero, td_endzero)); 471079b7badSJulian Elischer 472079b7badSJulian Elischer bcopy(&td->td_startcopy, &td2->td_startcopy, 4736db36923SDavid Schultz __rangeof(struct thread, td_startcopy, td_endcopy)); 474df8bae1dSRodney W. Grimes 4754b9322aeSJulian Elischer bcopy(&p2->p_comm, &td2->td_name, sizeof(td2->td_name)); 476a30ec4b9SDavid Xu td2->td_sigstk = td->td_sigstk; 477b61ce5b0SJeff Roberson td2->td_flags = TDF_INMEM; 478acbe332aSDavid Xu td2->td_lend_user_pri = PRI_MAX; 479a30ec4b9SDavid Xu 48021ca7b57SMarko Zec #ifdef VIMAGE 48121ca7b57SMarko Zec td2->td_vnet = NULL; 48221ca7b57SMarko Zec td2->td_vnet_lpush = NULL; 48321ca7b57SMarko Zec #endif 48421ca7b57SMarko Zec 485df8bae1dSRodney W. Grimes /* 48622d19207SJohn Baldwin * Allow the scheduler to initialize the child. 48722d19207SJohn Baldwin */ 48822d19207SJohn Baldwin thread_lock(td); 48922d19207SJohn Baldwin sched_fork(td, td2); 49022d19207SJohn Baldwin thread_unlock(td); 49122d19207SJohn Baldwin 49222d19207SJohn Baldwin /* 493df8bae1dSRodney W. Grimes * Duplicate sub-structures as needed. 494df8bae1dSRodney W. Grimes * Increase reference counts on shared objects. 495df8bae1dSRodney W. Grimes */ 496b61ce5b0SJeff Roberson p2->p_flag = P_INMEM; 49755648840SJohn Baldwin p2->p_flag2 = 0; 49854b0e65fSJeff Roberson p2->p_swtick = ticks; 4999752f794SJohn Baldwin if (p1->p_flag & P_PROFIL) 5009752f794SJohn Baldwin startprofclock(p2); 5018460a577SJohn Birrell td2->td_ucred = crhold(p2->p_ucred); 502b9df5231SPoul-Henning Kamp 5036626c604SJulian Elischer if (flags & RFSIGSHARE) { 50490af4afaSJohn Baldwin p2->p_sigacts = sigacts_hold(p1->p_sigacts); 5056626c604SJulian Elischer } else { 50690af4afaSJohn Baldwin sigacts_copy(newsigacts, p1->p_sigacts); 50790af4afaSJohn Baldwin p2->p_sigacts = newsigacts; 5086626c604SJulian Elischer } 509f49d8202SKonstantin Belousov 510f49d8202SKonstantin Belousov if (flags & RFTSIGZMB) 511f49d8202SKonstantin Belousov p2->p_sigparent = RFTSIGNUM(flags); 512f49d8202SKonstantin Belousov else if (flags & RFLINUXTHPN) 5136626c604SJulian Elischer p2->p_sigparent = SIGUSR1; 5144ac9ae70SJulian Elischer else 5154ac9ae70SJulian Elischer p2->p_sigparent = SIGCHLD; 51688c5ea45SJulian Elischer 517df8bae1dSRodney W. Grimes p2->p_textvp = p1->p_textvp; 5185641ae5dSJohn Baldwin p2->p_fd = fd; 519ad05d580STor Egge p2->p_fdtol = fdtol; 520dabee6feSPeter Wemm 52155648840SJohn Baldwin if (p1->p_flag2 & P2_INHERIT_PROTECTED) { 52255648840SJohn Baldwin p2->p_flag |= P_PROTECTED; 52355648840SJohn Baldwin p2->p_flag2 |= P2_INHERIT_PROTECTED; 52455648840SJohn Baldwin } 52555648840SJohn Baldwin 526df8bae1dSRodney W. Grimes /* 527c8564ad4SBruce Evans * p_limit is copy-on-write. Bump its refcount. 528df8bae1dSRodney W. Grimes */ 5291c4bcd05SJeff Roberson lim_fork(p1, p2); 5308b059651SDavid Schultz 5318b059651SDavid Schultz pstats_fork(p1->p_stats, p2->p_stats); 5328b059651SDavid Schultz 533299bc736SDavid Schultz PROC_UNLOCK(p1); 534cda5aba4SDavid Schultz PROC_UNLOCK(p2); 535df8bae1dSRodney W. Grimes 5363e73ff1eSEdward Tomasz Napierala /* Bump references to the text vnode (for procfs). */ 537a69d88afSPeter Wemm if (p2->p_textvp) 538a69d88afSPeter Wemm vref(p2->p_textvp); 539a69d88afSPeter Wemm 540c6544064SJohn Baldwin /* 541c8564ad4SBruce Evans * Set up linkage for kernel based threading. 542c6544064SJohn Baldwin */ 543c6544064SJohn Baldwin if ((flags & RFTHREAD) != 0) { 544c6544064SJohn Baldwin mtx_lock(&ppeers_lock); 545c6544064SJohn Baldwin p2->p_peers = p1->p_peers; 546c6544064SJohn Baldwin p1->p_peers = p2; 547c6544064SJohn Baldwin p2->p_leader = p1->p_leader; 548c6544064SJohn Baldwin mtx_unlock(&ppeers_lock); 549c6544064SJohn Baldwin PROC_LOCK(p1->p_leader); 550c6544064SJohn Baldwin if ((p1->p_leader->p_flag & P_WEXIT) != 0) { 551c6544064SJohn Baldwin PROC_UNLOCK(p1->p_leader); 552c6544064SJohn Baldwin /* 553c6544064SJohn Baldwin * The task leader is exiting, so process p1 is 554c6544064SJohn Baldwin * going to be killed shortly. Since p1 obviously 555c6544064SJohn Baldwin * isn't dead yet, we know that the leader is either 556c6544064SJohn Baldwin * sending SIGKILL's to all the processes in this 557c6544064SJohn Baldwin * task or is sleeping waiting for all the peers to 558c6544064SJohn Baldwin * exit. We let p1 complete the fork, but we need 559c6544064SJohn Baldwin * to go ahead and kill the new process p2 since 560c6544064SJohn Baldwin * the task leader may not get a chance to send 561c6544064SJohn Baldwin * SIGKILL to it. We leave it on the list so that 562c6544064SJohn Baldwin * the task leader will wait for this new process 563c6544064SJohn Baldwin * to commit suicide. 564c6544064SJohn Baldwin */ 565c6544064SJohn Baldwin PROC_LOCK(p2); 5668451d0ddSKip Macy kern_psignal(p2, SIGKILL); 567c6544064SJohn Baldwin PROC_UNLOCK(p2); 568293d2d22SRobert Watson } else 569293d2d22SRobert Watson PROC_UNLOCK(p1->p_leader); 570c6544064SJohn Baldwin } else { 571c6544064SJohn Baldwin p2->p_peers = NULL; 572c6544064SJohn Baldwin p2->p_leader = p2; 573c6544064SJohn Baldwin } 574c6544064SJohn Baldwin 5753fc755c1SJohn Baldwin sx_xlock(&proctree_lock); 5763fc755c1SJohn Baldwin PGRP_LOCK(p1->p_pgrp); 5773fc755c1SJohn Baldwin PROC_LOCK(p2); 5783fc755c1SJohn Baldwin PROC_LOCK(p1); 5793fc755c1SJohn Baldwin 58070e534e7SDavid Greenman /* 5819752f794SJohn Baldwin * Preserve some more flags in subprocess. P_PROFIL has already 582be67169aSBruce Evans * been preserved. 58370e534e7SDavid Greenman */ 584a30ec4b9SDavid Xu p2->p_flag |= p1->p_flag & P_SUGID; 585a30ec4b9SDavid Xu td2->td_pflags |= td->td_pflags & TDP_ALTSTACK; 586f591779bSSeigo Tanimura SESS_LOCK(p1->p_session); 587df8bae1dSRodney W. Grimes if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT) 588df8bae1dSRodney W. Grimes p2->p_flag |= P_CONTROLT; 589f591779bSSeigo Tanimura SESS_UNLOCK(p1->p_session); 5900e3eb7eeSSujal Patel if (flags & RFPPWAIT) 591df8bae1dSRodney W. Grimes p2->p_flag |= P_PPWAIT; 592be67169aSBruce Evans 5935cded904SOlivier Houchard p2->p_pgrp = p1->p_pgrp; 594b75356e1SJeffrey Hsu LIST_INSERT_AFTER(p1, p2, p_pglist); 5952a60b9b9SSeigo Tanimura PGRP_UNLOCK(p1->p_pgrp); 596b75356e1SJeffrey Hsu LIST_INIT(&p2->p_children); 597dcd43281SKonstantin Belousov LIST_INIT(&p2->p_orphans); 598b75356e1SJeffrey Hsu 599f7e50ea7SKonstantin Belousov callout_init_mtx(&p2->p_itcallout, &p2->p_mtx, 0); 6004f559836SJake Burkholder 601df8bae1dSRodney W. Grimes /* 602df95311aSMatthew N. Dodd * If PF_FORK is set, the child process inherits the 603df95311aSMatthew N. Dodd * procfs ioctl flags from its parent. 604df95311aSMatthew N. Dodd */ 605df95311aSMatthew N. Dodd if (p1->p_pfsflags & PF_FORK) { 606df95311aSMatthew N. Dodd p2->p_stops = p1->p_stops; 607df95311aSMatthew N. Dodd p2->p_pfsflags = p1->p_pfsflags; 608df95311aSMatthew N. Dodd } 609df95311aSMatthew N. Dodd 610df95311aSMatthew N. Dodd /* 611df8bae1dSRodney W. Grimes * This begins the section where we must prevent the parent 612cda5aba4SDavid Schultz * from being swapped. 613df8bae1dSRodney W. Grimes */ 614cda5aba4SDavid Schultz _PHOLD(p1); 61557934cd3SJohn Baldwin PROC_UNLOCK(p1); 6160d2afceeSDavid Greenman 617df8bae1dSRodney W. Grimes /* 6183fc755c1SJohn Baldwin * Attach the new process to its parent. 6193fc755c1SJohn Baldwin * 6203fc755c1SJohn Baldwin * If RFNOWAIT is set, the newly created process becomes a child 6213fc755c1SJohn Baldwin * of init. This effectively disassociates the child from the 6223fc755c1SJohn Baldwin * parent. 6233fc755c1SJohn Baldwin */ 624*237623b0SKonstantin Belousov if ((flags & RFNOWAIT) != 0) { 625*237623b0SKonstantin Belousov pptr = p1->p_reaper; 626*237623b0SKonstantin Belousov p2->p_reaper = pptr; 627*237623b0SKonstantin Belousov } else { 628*237623b0SKonstantin Belousov p2->p_reaper = (p1->p_treeflag & P_TREE_REAPER) != 0 ? 629*237623b0SKonstantin Belousov p1 : p1->p_reaper; 6303fc755c1SJohn Baldwin pptr = p1; 631*237623b0SKonstantin Belousov } 6323fc755c1SJohn Baldwin p2->p_pptr = pptr; 6333fc755c1SJohn Baldwin LIST_INSERT_HEAD(&pptr->p_children, p2, p_sibling); 634*237623b0SKonstantin Belousov LIST_INIT(&p2->p_reaplist); 635*237623b0SKonstantin Belousov LIST_INSERT_HEAD(&p2->p_reaper->p_reaplist, p2, p_reapsibling); 636*237623b0SKonstantin Belousov if (p2->p_reaper == p1) 637*237623b0SKonstantin Belousov p2->p_reapsubtree = p2->p_pid; 6383fc755c1SJohn Baldwin sx_xunlock(&proctree_lock); 6393fc755c1SJohn Baldwin 640bb0e8070SJohn Baldwin /* Inform accounting that we have forked. */ 641bb0e8070SJohn Baldwin p2->p_acflag = AFORK; 642bb0e8070SJohn Baldwin PROC_UNLOCK(p2); 643bb0e8070SJohn Baldwin 6447705d4b2SDmitry Chagin #ifdef KTRACE 6457705d4b2SDmitry Chagin ktrprocfork(p1, p2); 6467705d4b2SDmitry Chagin #endif 6477705d4b2SDmitry Chagin 6483fc755c1SJohn Baldwin /* 649a2a1c95cSPeter Wemm * Finish creating the child process. It will return via a different 650a2a1c95cSPeter Wemm * execution path later. (ie: directly into user mode) 651dabee6feSPeter Wemm */ 65289b57fcfSKonstantin Belousov vm_forkproc(td, p2, td2, vm2, flags); 653df8bae1dSRodney W. Grimes 6545d22597fSHajimu UMEMOTO if (flags == (RFFDG | RFPROC)) { 655393a081dSAttilio Rao PCPU_INC(cnt.v_forks); 656393a081dSAttilio Rao PCPU_ADD(cnt.v_forkpages, p2->p_vmspace->vm_dsize + 65794ddc707SAlan Cox p2->p_vmspace->vm_ssize); 6585d22597fSHajimu UMEMOTO } else if (flags == (RFFDG | RFPROC | RFPPWAIT | RFMEM)) { 659393a081dSAttilio Rao PCPU_INC(cnt.v_vforks); 660393a081dSAttilio Rao PCPU_ADD(cnt.v_vforkpages, p2->p_vmspace->vm_dsize + 66194ddc707SAlan Cox p2->p_vmspace->vm_ssize); 6625d22597fSHajimu UMEMOTO } else if (p1 == &proc0) { 663393a081dSAttilio Rao PCPU_INC(cnt.v_kthreads); 664393a081dSAttilio Rao PCPU_ADD(cnt.v_kthreadpages, p2->p_vmspace->vm_dsize + 66594ddc707SAlan Cox p2->p_vmspace->vm_ssize); 6665d22597fSHajimu UMEMOTO } else { 667393a081dSAttilio Rao PCPU_INC(cnt.v_rforks); 668393a081dSAttilio Rao PCPU_ADD(cnt.v_rforkpages, p2->p_vmspace->vm_dsize + 66994ddc707SAlan Cox p2->p_vmspace->vm_ssize); 6705d22597fSHajimu UMEMOTO } 6715d22597fSHajimu UMEMOTO 672cfb5f768SJonathan Anderson /* 673cfb5f768SJonathan Anderson * Associate the process descriptor with the process before anything 674cfb5f768SJonathan Anderson * can happen that might cause that process to need the descriptor. 675cfb5f768SJonathan Anderson * However, don't do this until after fork(2) can no longer fail. 676cfb5f768SJonathan Anderson */ 677cfb5f768SJonathan Anderson if (flags & RFPROCDESC) 678cfb5f768SJonathan Anderson procdesc_new(p2, pdflags); 679cfb5f768SJonathan Anderson 680df8bae1dSRodney W. Grimes /* 681e9189611SPeter Wemm * Both processes are set up, now check if any loadable modules want 682e0d898b4SJulian Elischer * to adjust anything. 683fed06968SJulian Elischer */ 68475b8b3b2SJohn Baldwin EVENTHANDLER_INVOKE(process_fork, p1, p2, flags); 685fed06968SJulian Elischer 686fed06968SJulian Elischer /* 6874c3558aaSJohn Baldwin * Set the child start time and mark the process as being complete. 6884c3558aaSJohn Baldwin */ 6898e6fa660SJohn Baldwin PROC_LOCK(p2); 6908e6fa660SJohn Baldwin PROC_LOCK(p1); 6914c3558aaSJohn Baldwin microuptime(&p2->p_stats->p_start); 69211bda9b8SJeff Roberson PROC_SLOCK(p2); 6934c3558aaSJohn Baldwin p2->p_state = PRS_NORMAL; 69411bda9b8SJeff Roberson PROC_SUNLOCK(p2); 6956fa39a73SKonstantin Belousov 696d3555b6fSRui Paulo #ifdef KDTRACE_HOOKS 697d3555b6fSRui Paulo /* 6987159310fSMark Johnston * Tell the DTrace fasttrap provider about the new process so that any 6997159310fSMark Johnston * tracepoints inherited from the parent can be removed. We have to do 7007159310fSMark Johnston * this only after p_state is PRS_NORMAL since the fasttrap module will 7017159310fSMark Johnston * use pfind() later on. 702d3555b6fSRui Paulo */ 7037159310fSMark Johnston if ((flags & RFMEM) == 0 && dtrace_fasttrap_fork) 704d3555b6fSRui Paulo dtrace_fasttrap_fork(p1, p2); 705d3555b6fSRui Paulo #endif 7066fa39a73SKonstantin Belousov if ((p1->p_flag & (P_TRACED | P_FOLLOWFORK)) == (P_TRACED | 7076fa39a73SKonstantin Belousov P_FOLLOWFORK)) { 7084c3558aaSJohn Baldwin /* 7096fa39a73SKonstantin Belousov * Arrange for debugger to receive the fork event. 7106fa39a73SKonstantin Belousov * 7116fa39a73SKonstantin Belousov * We can report PL_FLAG_FORKED regardless of 7126fa39a73SKonstantin Belousov * P_FOLLOWFORK settings, but it does not make a sense 7136fa39a73SKonstantin Belousov * for runaway child. 714df8bae1dSRodney W. Grimes */ 7156fa39a73SKonstantin Belousov td->td_dbgflags |= TDB_FORK; 7166fa39a73SKonstantin Belousov td->td_dbg_forked = p2->p_pid; 7176fa39a73SKonstantin Belousov td2->td_dbgflags |= TDB_STOPATFORK; 7186fa39a73SKonstantin Belousov _PHOLD(p2); 7196fa39a73SKonstantin Belousov p2_held = 1; 7206fa39a73SKonstantin Belousov } 7211d7ca9bbSKonstantin Belousov if (flags & RFPPWAIT) { 7221d7ca9bbSKonstantin Belousov td->td_pflags |= TDP_RFPPWAIT; 7231d7ca9bbSKonstantin Belousov td->td_rfppwait_p = p2; 7241d7ca9bbSKonstantin Belousov } 7258e6fa660SJohn Baldwin PROC_UNLOCK(p2); 7260384fff8SJason Evans if ((flags & RFSTOPPED) == 0) { 7276fa39a73SKonstantin Belousov /* 7286fa39a73SKonstantin Belousov * If RFSTOPPED not requested, make child runnable and 7296fa39a73SKonstantin Belousov * add to run queue. 7306fa39a73SKonstantin Belousov */ 73111bda9b8SJeff Roberson thread_lock(td2); 73271fad9fdSJulian Elischer TD_SET_CAN_RUN(td2); 733f0393f06SJeff Roberson sched_add(td2, SRQ_BORING); 73411bda9b8SJeff Roberson thread_unlock(td2); 7350384fff8SJason Evans } 736df8bae1dSRodney W. Grimes 737df8bae1dSRodney W. Grimes /* 738df8bae1dSRodney W. Grimes * Now can be swapped. 739df8bae1dSRodney W. Grimes */ 74057934cd3SJohn Baldwin _PRELE(p1); 7417054ee4eSKonstantin Belousov PROC_UNLOCK(p1); 742df8bae1dSRodney W. Grimes 743df8bae1dSRodney W. Grimes /* 74470fca427SJohn Baldwin * Tell any interested parties about the new process. 745cb679c38SJonathan Lemon */ 7467054ee4eSKonstantin Belousov knote_fork(&p1->p_klist, p2->p_pid); 7475d217f17SJohn Birrell SDT_PROBE(proc, kernel, , create, p2, p1, flags, 0, 0); 7485d217f17SJohn Birrell 749cb679c38SJonathan Lemon /* 7506fa39a73SKonstantin Belousov * Wait until debugger is attached to child. 7516fa39a73SKonstantin Belousov */ 7526fa39a73SKonstantin Belousov PROC_LOCK(p2); 7536fa39a73SKonstantin Belousov while ((td2->td_dbgflags & TDB_STOPATFORK) != 0) 7546fa39a73SKonstantin Belousov cv_wait(&p2->p_dbgwait, &p2->p_mtx); 7556fa39a73SKonstantin Belousov if (p2_held) 7566fa39a73SKonstantin Belousov _PRELE(p2); 75757934cd3SJohn Baldwin PROC_UNLOCK(p2); 758afd01097SEdward Tomasz Napierala } 759afd01097SEdward Tomasz Napierala 760afd01097SEdward Tomasz Napierala int 761cfb5f768SJonathan Anderson fork1(struct thread *td, int flags, int pages, struct proc **procp, 762cfb5f768SJonathan Anderson int *procdescp, int pdflags) 763afd01097SEdward Tomasz Napierala { 764afd01097SEdward Tomasz Napierala struct proc *p1; 765afd01097SEdward Tomasz Napierala struct proc *newproc; 766afd01097SEdward Tomasz Napierala int ok; 767afd01097SEdward Tomasz Napierala struct thread *td2; 768afd01097SEdward Tomasz Napierala struct vmspace *vm2; 769afd01097SEdward Tomasz Napierala vm_ooffset_t mem_charged; 770afd01097SEdward Tomasz Napierala int error; 771afd01097SEdward Tomasz Napierala static int curfail; 772afd01097SEdward Tomasz Napierala static struct timeval lastfail; 773cfb5f768SJonathan Anderson struct file *fp_procdesc = NULL; 774afd01097SEdward Tomasz Napierala 775f49d8202SKonstantin Belousov /* Check for the undefined or unimplemented flags. */ 776f49d8202SKonstantin Belousov if ((flags & ~(RFFLAGS | RFTSIGFLAGS(RFTSIGMASK))) != 0) 777f49d8202SKonstantin Belousov return (EINVAL); 778f49d8202SKonstantin Belousov 779f49d8202SKonstantin Belousov /* Signal value requires RFTSIGZMB. */ 780f49d8202SKonstantin Belousov if ((flags & RFTSIGFLAGS(RFTSIGMASK)) != 0 && (flags & RFTSIGZMB) == 0) 781f49d8202SKonstantin Belousov return (EINVAL); 782f49d8202SKonstantin Belousov 783afd01097SEdward Tomasz Napierala /* Can't copy and clear. */ 784afd01097SEdward Tomasz Napierala if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG)) 785afd01097SEdward Tomasz Napierala return (EINVAL); 786afd01097SEdward Tomasz Napierala 787f49d8202SKonstantin Belousov /* Check the validity of the signal number. */ 788f49d8202SKonstantin Belousov if ((flags & RFTSIGZMB) != 0 && (u_int)RFTSIGNUM(flags) > _SIG_MAXSIG) 789f49d8202SKonstantin Belousov return (EINVAL); 790f49d8202SKonstantin Belousov 791cfb5f768SJonathan Anderson if ((flags & RFPROCDESC) != 0) { 792cfb5f768SJonathan Anderson /* Can't not create a process yet get a process descriptor. */ 793cfb5f768SJonathan Anderson if ((flags & RFPROC) == 0) 794cfb5f768SJonathan Anderson return (EINVAL); 795cfb5f768SJonathan Anderson 796cfb5f768SJonathan Anderson /* Must provide a place to put a procdesc if creating one. */ 797cfb5f768SJonathan Anderson if (procdescp == NULL) 798cfb5f768SJonathan Anderson return (EINVAL); 799cfb5f768SJonathan Anderson } 800cfb5f768SJonathan Anderson 801afd01097SEdward Tomasz Napierala p1 = td->td_proc; 802afd01097SEdward Tomasz Napierala 803afd01097SEdward Tomasz Napierala /* 804afd01097SEdward Tomasz Napierala * Here we don't create a new process, but we divorce 805afd01097SEdward Tomasz Napierala * certain parts of a process from itself. 806afd01097SEdward Tomasz Napierala */ 8073e73ff1eSEdward Tomasz Napierala if ((flags & RFPROC) == 0) { 8083e73ff1eSEdward Tomasz Napierala *procp = NULL; 8093e73ff1eSEdward Tomasz Napierala return (fork_norfproc(td, flags)); 8103e73ff1eSEdward Tomasz Napierala } 811afd01097SEdward Tomasz Napierala 812cfb5f768SJonathan Anderson /* 813cfb5f768SJonathan Anderson * If required, create a process descriptor in the parent first; we 814cfb5f768SJonathan Anderson * will abandon it if something goes wrong. We don't finit() until 815cfb5f768SJonathan Anderson * later. 816cfb5f768SJonathan Anderson */ 817cfb5f768SJonathan Anderson if (flags & RFPROCDESC) { 818cfb5f768SJonathan Anderson error = falloc(td, &fp_procdesc, procdescp, 0); 819b38520f0SEdward Tomasz Napierala if (error != 0) 820cfb5f768SJonathan Anderson return (error); 821cfb5f768SJonathan Anderson } 822cfb5f768SJonathan Anderson 823afd01097SEdward Tomasz Napierala mem_charged = 0; 824afd01097SEdward Tomasz Napierala vm2 = NULL; 825afd01097SEdward Tomasz Napierala if (pages == 0) 826afd01097SEdward Tomasz Napierala pages = KSTACK_PAGES; 827afd01097SEdward Tomasz Napierala /* Allocate new proc. */ 828afd01097SEdward Tomasz Napierala newproc = uma_zalloc(proc_zone, M_WAITOK); 829afd01097SEdward Tomasz Napierala td2 = FIRST_THREAD_IN_PROC(newproc); 830afd01097SEdward Tomasz Napierala if (td2 == NULL) { 831afd01097SEdward Tomasz Napierala td2 = thread_alloc(pages); 832afd01097SEdward Tomasz Napierala if (td2 == NULL) { 833afd01097SEdward Tomasz Napierala error = ENOMEM; 834afd01097SEdward Tomasz Napierala goto fail1; 835afd01097SEdward Tomasz Napierala } 836afd01097SEdward Tomasz Napierala proc_linkup(newproc, td2); 837afd01097SEdward Tomasz Napierala } else { 838afd01097SEdward Tomasz Napierala if (td2->td_kstack == 0 || td2->td_kstack_pages != pages) { 839afd01097SEdward Tomasz Napierala if (td2->td_kstack != 0) 840afd01097SEdward Tomasz Napierala vm_thread_dispose(td2); 841afd01097SEdward Tomasz Napierala if (!thread_alloc_stack(td2, pages)) { 842afd01097SEdward Tomasz Napierala error = ENOMEM; 843afd01097SEdward Tomasz Napierala goto fail1; 844afd01097SEdward Tomasz Napierala } 845afd01097SEdward Tomasz Napierala } 846afd01097SEdward Tomasz Napierala } 847afd01097SEdward Tomasz Napierala 848afd01097SEdward Tomasz Napierala if ((flags & RFMEM) == 0) { 849afd01097SEdward Tomasz Napierala vm2 = vmspace_fork(p1->p_vmspace, &mem_charged); 850afd01097SEdward Tomasz Napierala if (vm2 == NULL) { 851afd01097SEdward Tomasz Napierala error = ENOMEM; 852afd01097SEdward Tomasz Napierala goto fail1; 853afd01097SEdward Tomasz Napierala } 854afd01097SEdward Tomasz Napierala if (!swap_reserve(mem_charged)) { 855afd01097SEdward Tomasz Napierala /* 856afd01097SEdward Tomasz Napierala * The swap reservation failed. The accounting 857afd01097SEdward Tomasz Napierala * from the entries of the copied vm2 will be 858afd01097SEdward Tomasz Napierala * substracted in vmspace_free(), so force the 859afd01097SEdward Tomasz Napierala * reservation there. 860afd01097SEdward Tomasz Napierala */ 861afd01097SEdward Tomasz Napierala swap_reserve_force(mem_charged); 862afd01097SEdward Tomasz Napierala error = ENOMEM; 863afd01097SEdward Tomasz Napierala goto fail1; 864afd01097SEdward Tomasz Napierala } 865afd01097SEdward Tomasz Napierala } else 866afd01097SEdward Tomasz Napierala vm2 = NULL; 867afd01097SEdward Tomasz Napierala 868097055e2SEdward Tomasz Napierala /* 869097055e2SEdward Tomasz Napierala * XXX: This is ugly; when we copy resource usage, we need to bump 870097055e2SEdward Tomasz Napierala * per-cred resource counters. 871097055e2SEdward Tomasz Napierala */ 872097055e2SEdward Tomasz Napierala newproc->p_ucred = p1->p_ucred; 873097055e2SEdward Tomasz Napierala 874097055e2SEdward Tomasz Napierala /* 875097055e2SEdward Tomasz Napierala * Initialize resource accounting for the child process. 876097055e2SEdward Tomasz Napierala */ 877097055e2SEdward Tomasz Napierala error = racct_proc_fork(p1, newproc); 878097055e2SEdward Tomasz Napierala if (error != 0) { 879097055e2SEdward Tomasz Napierala error = EAGAIN; 880097055e2SEdward Tomasz Napierala goto fail1; 881097055e2SEdward Tomasz Napierala } 882097055e2SEdward Tomasz Napierala 8831dbf9dccSEdward Tomasz Napierala #ifdef MAC 8841dbf9dccSEdward Tomasz Napierala mac_proc_init(newproc); 8851dbf9dccSEdward Tomasz Napierala #endif 8861dbf9dccSEdward Tomasz Napierala knlist_init_mtx(&newproc->p_klist, &newproc->p_mtx); 8871dbf9dccSEdward Tomasz Napierala STAILQ_INIT(&newproc->p_ktr); 8881dbf9dccSEdward Tomasz Napierala 889afd01097SEdward Tomasz Napierala /* We have to lock the process tree while we look for a pid. */ 890afd01097SEdward Tomasz Napierala sx_slock(&proctree_lock); 891afd01097SEdward Tomasz Napierala 892afd01097SEdward Tomasz Napierala /* 893afd01097SEdward Tomasz Napierala * Although process entries are dynamically created, we still keep 894afd01097SEdward Tomasz Napierala * a global limit on the maximum number we will create. Don't allow 895afd01097SEdward Tomasz Napierala * a nonprivileged user to use the last ten processes; don't let root 896afd01097SEdward Tomasz Napierala * exceed the limit. The variable nprocs is the current number of 897afd01097SEdward Tomasz Napierala * processes, maxproc is the limit. 898afd01097SEdward Tomasz Napierala */ 899afd01097SEdward Tomasz Napierala sx_xlock(&allproc_lock); 900afd01097SEdward Tomasz Napierala if ((nprocs >= maxproc - 10 && priv_check_cred(td->td_ucred, 901afd01097SEdward Tomasz Napierala PRIV_MAXPROC, 0) != 0) || nprocs >= maxproc) { 902afd01097SEdward Tomasz Napierala error = EAGAIN; 903afd01097SEdward Tomasz Napierala goto fail; 904afd01097SEdward Tomasz Napierala } 905afd01097SEdward Tomasz Napierala 90658c77a9dSEdward Tomasz Napierala /* 907afd01097SEdward Tomasz Napierala * Increment the count of procs running with this uid. Don't allow 908afd01097SEdward Tomasz Napierala * a nonprivileged user to exceed their current limit. 909afd01097SEdward Tomasz Napierala * 910afd01097SEdward Tomasz Napierala * XXXRW: Can we avoid privilege here if it's not needed? 911afd01097SEdward Tomasz Napierala */ 912afd01097SEdward Tomasz Napierala error = priv_check_cred(td->td_ucred, PRIV_PROC_LIMIT, 0); 913afd01097SEdward Tomasz Napierala if (error == 0) 914afd01097SEdward Tomasz Napierala ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, 0); 915afd01097SEdward Tomasz Napierala else { 916afd01097SEdward Tomasz Napierala PROC_LOCK(p1); 917afd01097SEdward Tomasz Napierala ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, 918afd01097SEdward Tomasz Napierala lim_cur(p1, RLIMIT_NPROC)); 919afd01097SEdward Tomasz Napierala PROC_UNLOCK(p1); 920afd01097SEdward Tomasz Napierala } 921afd01097SEdward Tomasz Napierala if (ok) { 922cfb5f768SJonathan Anderson do_fork(td, flags, newproc, td2, vm2, pdflags); 923afd01097SEdward Tomasz Napierala 92449539972SJulian Elischer /* 925df8abd0bSPeter Wemm * Return child proc pointer to parent. 926df8bae1dSRodney W. Grimes */ 927afd01097SEdward Tomasz Napierala *procp = newproc; 9280a7007b9SPawel Jakub Dawidek if (flags & RFPROCDESC) { 929cfb5f768SJonathan Anderson procdesc_finit(newproc->p_procdesc, fp_procdesc); 9300a7007b9SPawel Jakub Dawidek fdrop(fp_procdesc, td); 9310a7007b9SPawel Jakub Dawidek } 93272a401d9SEdward Tomasz Napierala racct_proc_fork_done(newproc); 933df8bae1dSRodney W. Grimes return (0); 934afd01097SEdward Tomasz Napierala } 935afd01097SEdward Tomasz Napierala 936afd01097SEdward Tomasz Napierala error = EAGAIN; 937c6544064SJohn Baldwin fail: 9385ce2f678SJohn Baldwin sx_sunlock(&proctree_lock); 939b083ea51SMike Silbersack if (ppsratecheck(&lastfail, &curfail, 1)) 940a208417cSJaakko Heinonen printf("maxproc limit exceeded by uid %u (pid %d); see tuning(7) and login.conf(5)\n", 941a208417cSJaakko Heinonen td->td_ucred->cr_ruid, p1->p_pid); 942c6544064SJohn Baldwin sx_xunlock(&allproc_lock); 9436bea667fSRobert Watson #ifdef MAC 94430d239bcSRobert Watson mac_proc_destroy(newproc); 9456bea667fSRobert Watson #endif 9461dbf9dccSEdward Tomasz Napierala racct_proc_exit(newproc); 947ab27d5d8SEdward Tomasz Napierala fail1: 94869aa768aSKonstantin Belousov if (vm2 != NULL) 94969aa768aSKonstantin Belousov vmspace_free(vm2); 950c6544064SJohn Baldwin uma_zfree(proc_zone, newproc); 951de265498SPawel Jakub Dawidek if ((flags & RFPROCDESC) != 0 && fp_procdesc != NULL) { 9520a7007b9SPawel Jakub Dawidek fdclose(td->td_proc->p_fd, fp_procdesc, *procdescp, td); 953cfb5f768SJonathan Anderson fdrop(fp_procdesc, td); 9540a7007b9SPawel Jakub Dawidek } 95584d37a46SJohn Baldwin pause("fork", hz / 2); 956c6544064SJohn Baldwin return (error); 957df8bae1dSRodney W. Grimes } 958fed06968SJulian Elischer 959e0d898b4SJulian Elischer /* 960a7b124c3SJohn Baldwin * Handle the return of a child process from fork1(). This function 961a7b124c3SJohn Baldwin * is called from the MD fork_trampoline() entry point. 962a7b124c3SJohn Baldwin */ 963a7b124c3SJohn Baldwin void 9641d845e86SEdward Tomasz Napierala fork_exit(void (*callout)(void *, struct trapframe *), void *arg, 9651d845e86SEdward Tomasz Napierala struct trapframe *frame) 966a7b124c3SJohn Baldwin { 967696058c3SJulian Elischer struct proc *p; 96870fca427SJohn Baldwin struct thread *td; 969fe54587fSJeff Roberson struct thread *dtd; 97070fca427SJohn Baldwin 9710047b9a9SBosko Milekic td = curthread; 9720047b9a9SBosko Milekic p = td->td_proc; 9730047b9a9SBosko Milekic KASSERT(p->p_state == PRS_NORMAL, ("executing process is still new")); 9740047b9a9SBosko Milekic 9756617724cSJeff Roberson CTR4(KTR_PROC, "fork_exit: new thread %p (td_sched %p, pid %d, %s)", 976e01eafefSJulian Elischer td, td->td_sched, p->p_pid, td->td_name); 9770047b9a9SBosko Milekic 97811bda9b8SJeff Roberson sched_fork_exit(td); 979a7b124c3SJohn Baldwin /* 980fe54587fSJeff Roberson * Processes normally resume in mi_switch() after being 981fe54587fSJeff Roberson * cpu_switch()'ed to, but when children start up they arrive here 982fe54587fSJeff Roberson * instead, so we must do much the same things as mi_switch() would. 983fe54587fSJeff Roberson */ 984fe54587fSJeff Roberson if ((dtd = PCPU_GET(deadthread))) { 985fe54587fSJeff Roberson PCPU_SET(deadthread, NULL); 986fe54587fSJeff Roberson thread_stash(dtd); 987fe54587fSJeff Roberson } 988fe54587fSJeff Roberson thread_unlock(td); 989fe54587fSJeff Roberson 990fe54587fSJeff Roberson /* 991a7b124c3SJohn Baldwin * cpu_set_fork_handler intercepts this function call to 992a7b124c3SJohn Baldwin * have this call a non-return function to stay in kernel mode. 993a7b124c3SJohn Baldwin * initproc has its own fork handler, but it does return. 994a7b124c3SJohn Baldwin */ 9955813dc03SJohn Baldwin KASSERT(callout != NULL, ("NULL callout in fork_exit")); 9968865286bSJohn Baldwin callout(arg, frame); 997a7b124c3SJohn Baldwin 998a7b124c3SJohn Baldwin /* 999a7b124c3SJohn Baldwin * Check if a kernel thread misbehaved and returned from its main 1000a7b124c3SJohn Baldwin * function. 1001a7b124c3SJohn Baldwin */ 1002a7b124c3SJohn Baldwin if (p->p_flag & P_KTHREAD) { 1003a7b124c3SJohn Baldwin printf("Kernel thread \"%s\" (pid %d) exited prematurely.\n", 1004e01eafefSJulian Elischer td->td_name, p->p_pid); 10053745c395SJulian Elischer kproc_exit(0); 1006a7b124c3SJohn Baldwin } 1007a7b124c3SJohn Baldwin mtx_assert(&Giant, MA_NOTOWNED); 1008993182e5SAlexander Leidinger 1009e5d81ef1SDmitry Chagin if (p->p_sysent->sv_schedtail != NULL) 1010e5d81ef1SDmitry Chagin (p->p_sysent->sv_schedtail)(td); 1011a7b124c3SJohn Baldwin } 1012a7b124c3SJohn Baldwin 1013a7b124c3SJohn Baldwin /* 1014a7b124c3SJohn Baldwin * Simplified back end of syscall(), used when returning from fork() 1015a7b124c3SJohn Baldwin * directly into user mode. Giant is not held on entry, and must not 1016a7b124c3SJohn Baldwin * be held on return. This function is passed in to fork_exit() as the 1017a7b124c3SJohn Baldwin * first parameter and is called when returning to a new userland process. 1018a7b124c3SJohn Baldwin */ 1019a7b124c3SJohn Baldwin void 10201d845e86SEdward Tomasz Napierala fork_return(struct thread *td, struct trapframe *frame) 1021a7b124c3SJohn Baldwin { 10226fa39a73SKonstantin Belousov struct proc *p, *dbg; 10236fa39a73SKonstantin Belousov 10246fa39a73SKonstantin Belousov if (td->td_dbgflags & TDB_STOPATFORK) { 10256fa39a73SKonstantin Belousov p = td->td_proc; 10266fa39a73SKonstantin Belousov sx_xlock(&proctree_lock); 10276fa39a73SKonstantin Belousov PROC_LOCK(p); 10286fa39a73SKonstantin Belousov if ((p->p_pptr->p_flag & (P_TRACED | P_FOLLOWFORK)) == 10296fa39a73SKonstantin Belousov (P_TRACED | P_FOLLOWFORK)) { 10306fa39a73SKonstantin Belousov /* 10316fa39a73SKonstantin Belousov * If debugger still wants auto-attach for the 10326fa39a73SKonstantin Belousov * parent's children, do it now. 10336fa39a73SKonstantin Belousov */ 10346fa39a73SKonstantin Belousov dbg = p->p_pptr->p_pptr; 10356fa39a73SKonstantin Belousov p->p_flag |= P_TRACED; 10366fa39a73SKonstantin Belousov p->p_oppid = p->p_pptr->p_pid; 10376fa39a73SKonstantin Belousov proc_reparent(p, dbg); 10386fa39a73SKonstantin Belousov sx_xunlock(&proctree_lock); 1039db327339SKonstantin Belousov td->td_dbgflags |= TDB_CHILD; 10406fa39a73SKonstantin Belousov ptracestop(td, SIGSTOP); 1041db327339SKonstantin Belousov td->td_dbgflags &= ~TDB_CHILD; 10426fa39a73SKonstantin Belousov } else { 10436fa39a73SKonstantin Belousov /* 10446fa39a73SKonstantin Belousov * ... otherwise clear the request. 10456fa39a73SKonstantin Belousov */ 10466fa39a73SKonstantin Belousov sx_xunlock(&proctree_lock); 10476fa39a73SKonstantin Belousov td->td_dbgflags &= ~TDB_STOPATFORK; 10486fa39a73SKonstantin Belousov cv_broadcast(&p->p_dbgwait); 10496fa39a73SKonstantin Belousov } 10506fa39a73SKonstantin Belousov PROC_UNLOCK(p); 10516fa39a73SKonstantin Belousov } 1052a7b124c3SJohn Baldwin 1053eb2da9a5SPoul-Henning Kamp userret(td, frame); 10546fa39a73SKonstantin Belousov 1055a7b124c3SJohn Baldwin #ifdef KTRACE 1056af300f23SJohn Baldwin if (KTRPOINT(td, KTR_SYSRET)) 1057af300f23SJohn Baldwin ktrsysret(SYS_fork, 0, 0); 1058a7b124c3SJohn Baldwin #endif 1059a7b124c3SJohn Baldwin } 1060