The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_fork.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1982, 1986, 1989, 1991, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  * (c) UNIX System Laboratories, Inc.
    5  * All or some portions of this file are derived from material licensed
    6  * to the University of California by American Telephone and Telegraph
    7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
    8  * the permission of UNIX System Laboratories, Inc.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the University of
   21  *      California, Berkeley and its contributors.
   22  * 4. Neither the name of the University nor the names of its contributors
   23  *    may be used to endorse or promote products derived from this software
   24  *    without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36  * SUCH DAMAGE.
   37  *
   38  *      @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
   39  * $FreeBSD: src/sys/kern/kern_fork.c,v 1.27.2.3 1999/09/05 08:14:54 peter Exp $
   40  */
   41 
   42 #include "opt_ktrace.h"
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/sysproto.h>
   47 #include <sys/filedesc.h>
   48 #include <sys/kernel.h>
   49 #include <sys/malloc.h>
   50 #include <sys/proc.h>
   51 #include <sys/resourcevar.h>
   52 #include <sys/vnode.h>
   53 #include <sys/acct.h>
   54 #include <sys/ktrace.h>
   55 #include <sys/unistd.h> 
   56 
   57 #include <vm/vm.h>
   58 #include <vm/vm_param.h>
   59 #include <vm/lock.h>
   60 #include <vm/pmap.h>
   61 #include <vm/vm_map.h>
   62 #include <vm/vm_extern.h>
   63 #include <vm/vm_inherit.h>
   64 
   65 static int fork1 __P((struct proc *p, int flags, int *retval));
   66 
   67 /*
   68  * These are the stuctures used to create a callout list for things to do
   69  * when forking a process
   70  */
   71 typedef struct fork_list_element {
   72         struct fork_list_element *next;
   73         forklist_fn function;
   74 } *fle_p;
   75 
   76 static fle_p    fork_list;
   77 
   78 #ifndef _SYS_SYSPROTO_H_
   79 struct fork_args {
   80         int     dummy;
   81 };
   82 #endif
   83 
   84 /* ARGSUSED */
   85 int
   86 fork(p, uap, retval)
   87         struct proc *p;
   88         struct fork_args *uap;
   89         int retval[];
   90 {
   91         return (fork1(p, (RFFDG|RFPROC), retval));
   92 }
   93 
   94 /* ARGSUSED */
   95 int
   96 vfork(p, uap, retval)
   97         struct proc *p;
   98         struct vfork_args *uap;
   99         int retval[];
  100 {
  101         return (fork1(p, (RFFDG|RFPROC|RFPPWAIT), retval));
  102 }
  103 
  104 /* ARGSUSED */
  105 int
  106 rfork(p, uap, retval)
  107         struct proc *p;
  108         struct rfork_args *uap;
  109         int retval[];
  110 {
  111         return (fork1(p, uap->flags, retval));
  112 }
  113 
  114 
  115 int     nprocs = 1;             /* process 0 */
  116 static int nextpid = 0;
  117 
  118 static int
  119 fork1(p1, flags, retval)
  120         register struct proc *p1;
  121         int flags;
  122         int retval[];
  123 {
  124         register struct proc *p2, *pptr;
  125         register uid_t uid;
  126         struct proc *newproc;
  127         int count;
  128         static int pidchecked = 0;
  129         fle_p ep ;
  130 
  131         ep = fork_list;
  132         if ((flags & RFPROC) == 0)
  133                 return (EINVAL);
  134         if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
  135                 return (EINVAL);
  136 
  137         /*
  138          * Although process entries are dynamically created, we still keep
  139          * a global limit on the maximum number we will create.  Don't allow
  140          * a nonprivileged user to use the last process; don't let root
  141          * exceed the limit. The variable nprocs is the current number of
  142          * processes, maxproc is the limit.
  143          */
  144         uid = p1->p_cred->p_ruid;
  145         if ((nprocs >= maxproc - 1 && uid != 0) || nprocs >= maxproc) {
  146                 tablefull("proc");
  147                 return (EAGAIN);
  148         }
  149         /*
  150          * Increment the nprocs resource before blocking can occur.  There
  151          * are hard-limits as to the number of processes that can run.
  152          */
  153         nprocs++;
  154 
  155         /*
  156          * Increment the count of procs running with this uid. Don't allow
  157          * a nonprivileged user to exceed their current limit.
  158          */
  159         count = chgproccnt(uid, 1);
  160         if (uid != 0 && count > p1->p_rlimit[RLIMIT_NPROC].rlim_cur) {
  161                 (void)chgproccnt(uid, -1);
  162                 /*
  163                  * Back out the process count
  164                  */
  165                 nprocs--;
  166                 return (EAGAIN);
  167         }
  168 
  169         /* Allocate new proc. */
  170         MALLOC(newproc, struct proc *, sizeof(struct proc), M_PROC, M_WAITOK);
  171 
  172         /*
  173          * Find an unused process ID.  We remember a range of unused IDs
  174          * ready to use (from nextpid+1 through pidchecked-1).
  175          */
  176         nextpid++;
  177 retry:
  178         /*
  179          * If the process ID prototype has wrapped around,
  180          * restart somewhat above 0, as the low-numbered procs
  181          * tend to include daemons that don't exit.
  182          */
  183         if (nextpid >= PID_MAX) {
  184                 nextpid = 100;
  185                 pidchecked = 0;
  186         }
  187         if (nextpid >= pidchecked) {
  188                 int doingzomb = 0;
  189 
  190                 pidchecked = PID_MAX;
  191                 /*
  192                  * Scan the active and zombie procs to check whether this pid
  193                  * is in use.  Remember the lowest pid that's greater
  194                  * than nextpid, so we can avoid checking for a while.
  195                  */
  196                 p2 = allproc.lh_first;
  197 again:
  198                 for (; p2 != 0; p2 = p2->p_list.le_next) {
  199                         while (p2->p_pid == nextpid ||
  200                             p2->p_pgrp->pg_id == nextpid) {
  201                                 nextpid++;
  202                                 if (nextpid >= pidchecked)
  203                                         goto retry;
  204                         }
  205                         if (p2->p_pid > nextpid && pidchecked > p2->p_pid)
  206                                 pidchecked = p2->p_pid;
  207                         if (p2->p_pgrp->pg_id > nextpid &&
  208                             pidchecked > p2->p_pgrp->pg_id)
  209                                 pidchecked = p2->p_pgrp->pg_id;
  210                 }
  211                 if (!doingzomb) {
  212                         doingzomb = 1;
  213                         p2 = zombproc.lh_first;
  214                         goto again;
  215                 }
  216         }
  217 
  218         p2 = newproc;
  219         p2->p_stat = SIDL;                      /* protect against others */
  220         p2->p_pid = nextpid;
  221         LIST_INSERT_HEAD(&allproc, p2, p_list);
  222         LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
  223 
  224         /*
  225          * Make a proc table entry for the new process.
  226          * Start by zeroing the section of proc that is zero-initialized,
  227          * then copy the section that is copied directly from the parent.
  228          */
  229         bzero(&p2->p_startzero,
  230             (unsigned) ((caddr_t)&p2->p_endzero - (caddr_t)&p2->p_startzero));
  231         bcopy(&p1->p_startcopy, &p2->p_startcopy,
  232             (unsigned) ((caddr_t)&p2->p_endcopy - (caddr_t)&p2->p_startcopy));
  233 
  234         /*
  235          * XXX: this should be done as part of the startzero above
  236          */
  237         p2->p_vmspace = 0;              /* XXX */
  238 
  239         /*
  240          * Duplicate sub-structures as needed.
  241          * Increase reference counts on shared objects.
  242          * The p_stats and p_sigacts substructs are set in vm_fork.
  243          */
  244         p2->p_flag = P_INMEM;
  245         if (p1->p_flag & P_PROFIL)
  246                 startprofclock(p2);
  247         MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred),
  248             M_SUBPROC, M_WAITOK);
  249         bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred));
  250         p2->p_cred->p_refcnt = 1;
  251         crhold(p1->p_ucred);
  252 
  253         /* bump references to the text vnode (for procfs) */
  254         p2->p_textvp = p1->p_textvp;
  255         if (p2->p_textvp)
  256                 VREF(p2->p_textvp);
  257 
  258         if (flags & RFCFDG)
  259                 p2->p_fd = fdinit(p1);
  260         else if (flags & RFFDG)
  261                 p2->p_fd = fdcopy(p1);
  262         else
  263                 p2->p_fd = fdshare(p1);
  264 
  265         /*
  266          * If p_limit is still copy-on-write, bump refcnt,
  267          * otherwise get a copy that won't be modified.
  268          * (If PL_SHAREMOD is clear, the structure is shared
  269          * copy-on-write.)
  270          */
  271         if (p1->p_limit->p_lflags & PL_SHAREMOD)
  272                 p2->p_limit = limcopy(p1->p_limit);
  273         else {
  274                 p2->p_limit = p1->p_limit;
  275                 p2->p_limit->p_refcnt++;
  276         }
  277 
  278         /*
  279          * Preserve some flags in subprocess.
  280          */
  281         p2->p_flag |= p1->p_flag & P_SUGID;
  282         if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
  283                 p2->p_flag |= P_CONTROLT;
  284         if (flags & RFPPWAIT)
  285                 p2->p_flag |= P_PPWAIT;
  286         LIST_INSERT_AFTER(p1, p2, p_pglist);
  287 
  288         /*
  289          * Attach the new process to its parent.
  290          *
  291          * If RFNOWAIT is set, the newly created process becomes a child
  292          * of init.  This effectively disassociates the child from the
  293          * parent.
  294          */
  295         if (flags & RFNOWAIT)
  296                 pptr = initproc;
  297         else
  298                 pptr = p1;
  299         p2->p_pptr = pptr;
  300         LIST_INSERT_HEAD(&pptr->p_children, p2, p_sibling);
  301         LIST_INIT(&p2->p_children);
  302 
  303 #ifdef KTRACE
  304         /*
  305          * Copy traceflag and tracefile if enabled.
  306          * If not inherited, these were zeroed above.
  307          */
  308         if (p1->p_traceflag&KTRFAC_INHERIT) {
  309                 p2->p_traceflag = p1->p_traceflag;
  310                 if ((p2->p_tracep = p1->p_tracep) != NULL)
  311                         VREF(p2->p_tracep);
  312         }
  313 #endif
  314 
  315         /*
  316          * set priority of child to be that of parent
  317          */
  318         p2->p_estcpu = p1->p_estcpu;
  319 
  320         /*
  321          * This begins the section where we must prevent the parent
  322          * from being swapped.
  323          */
  324         p1->p_flag |= P_NOSWAP;
  325 
  326         /*
  327          * share as much address space as possible
  328          * XXX this should probably go in vm_fork()
  329          */
  330         if (flags & RFMEM)
  331                 (void) vm_map_inherit(&p1->p_vmspace->vm_map,
  332                     VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS - MAXSSIZ,
  333                     VM_INHERIT_SHARE);
  334 
  335         /*
  336          * Set return values for child before vm_fork,
  337          * so they can be copied to child stack.
  338          * We return parent pid, and mark as child in retval[1].
  339          * NOTE: the kernel stack may be at a different location in the child
  340          * process, and thus addresses of automatic variables (including retval)
  341          * may be invalid after vm_fork returns in the child process.
  342          */
  343         retval[0] = p1->p_pid;
  344         retval[1] = 1;
  345         if (vm_fork(p1, p2)) {
  346                 /*
  347                  * Child process.  Set start time and get to work.
  348                  */
  349                 microtime(&runtime);
  350                 (void) spl0();
  351                 p2->p_stats->p_start = runtime;
  352                 p2->p_acflag = AFORK;
  353                 return (0);
  354         }
  355 
  356         /*
  357          * Both processes are set up, now check if any LKMs want
  358          * to adjust anything.
  359          *   What if they have an error? XXX
  360          */
  361         while (ep) {
  362                 (*ep->function)(p1, p2, flags);
  363                 ep = ep->next;
  364         }
  365 
  366         /*
  367          * Make child runnable and add to run queue.
  368          */
  369         (void) splhigh();
  370         p2->p_stat = SRUN;
  371         setrunqueue(p2);
  372         (void) spl0();
  373 
  374         /*
  375          * Now can be swapped.
  376          */
  377         p1->p_flag &= ~P_NOSWAP;
  378 
  379         /*
  380          * Preserve synchronization semantics of vfork.  If waiting for
  381          * child to exec or exit, set P_PPWAIT on child, and sleep on our
  382          * proc (in case of exit).
  383          */
  384         while (p2->p_flag & P_PPWAIT)
  385                 tsleep(p1, PWAIT, "ppwait", 0);
  386 
  387         /*
  388          * Return child pid to parent process,
  389          * marking us as parent via retval[1].
  390          */
  391         retval[0] = p2->p_pid;
  392         retval[1] = 0;
  393         return (0);
  394 }
  395 
  396 /*
  397  * The next two functionms are general routines to handle adding/deleting
  398  * items on the fork callout list.
  399  *
  400  * at_fork():
  401  * Take the arguments given and put them onto the fork callout list,
  402  * However first make sure that it's not already there.
  403  * Returns 0 on success or a standard error number.
  404  */
  405 int
  406 at_fork(forklist_fn function)
  407 {
  408         fle_p ep;
  409 
  410         /* let the programmer know if he's been stupid */
  411         if (rm_at_fork(function)) 
  412                 printf("fork callout entry already present\n");
  413         ep = malloc(sizeof(*ep), M_TEMP, M_NOWAIT);
  414         if (ep == NULL)
  415                 return (ENOMEM);
  416         ep->next = fork_list;
  417         ep->function = function;
  418         fork_list = ep;
  419         return (0);
  420 }
  421 
  422 /*
  423  * Scan the exit callout list for the given items and remove them.
  424  * Returns the number of items removed.
  425  * Theoretically this value can only be 0 or 1.
  426  */
  427 int
  428 rm_at_fork(forklist_fn function)
  429 {
  430         fle_p *epp, ep;
  431         int count;
  432 
  433         count= 0;
  434         epp = &fork_list;
  435         ep = *epp;
  436         while (ep) {
  437                 if (ep->function == function) {
  438                         *epp = ep->next;
  439                         free(ep, M_TEMP);
  440                         count++;
  441                 } else {
  442                         epp = &ep->next;
  443                 }
  444                 ep = *epp;
  445         }
  446         return (count);
  447 }
  448 
  449 

Cache object: a5534eb46ff54398edf5b3b675a75469


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.