Annotation of src/sys/kern/kern_fork.c, Revision 1.27
1.27 ! mycroft 1: /* $NetBSD: kern_fork.c,v 1.26 1995/12/09 04:23:07 mycroft Exp $ */
1.19 cgd 2:
1.16 cgd 3: /*
1.17 cgd 4: * Copyright (c) 1982, 1986, 1989, 1991, 1993
5: * The Regents of the University of California. All rights reserved.
1.16 cgd 6: * (c) UNIX System Laboratories, Inc.
7: * All or some portions of this file are derived from material licensed
8: * to the University of California by American Telephone and Telegraph
9: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10: * the permission of UNIX System Laboratories, Inc.
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: * 3. All advertising materials mentioning features or use of this software
21: * must display the following acknowledgement:
22: * This product includes software developed by the University of
23: * California, Berkeley and its contributors.
24: * 4. Neither the name of the University nor the names of its contributors
25: * may be used to endorse or promote products derived from this software
26: * without specific prior written permission.
27: *
28: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38: * SUCH DAMAGE.
39: *
1.19 cgd 40: * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
1.16 cgd 41: */
42:
43: #include <sys/param.h>
44: #include <sys/systm.h>
1.17 cgd 45: #include <sys/map.h>
1.16 cgd 46: #include <sys/filedesc.h>
47: #include <sys/kernel.h>
48: #include <sys/malloc.h>
49: #include <sys/proc.h>
50: #include <sys/resourcevar.h>
51: #include <sys/vnode.h>
52: #include <sys/file.h>
53: #include <sys/acct.h>
54: #include <sys/ktrace.h>
55:
1.26 mycroft 56: int nprocs = 1; /* process 0 */
57:
58: int
1.25 mycroft 59: sys_fork(p, v, retval)
1.16 cgd 60: struct proc *p;
1.25 mycroft 61: void *v;
1.22 cgd 62: register_t *retval;
1.16 cgd 63: {
64:
65: return (fork1(p, 0, retval));
66: }
67:
1.26 mycroft 68: int
1.25 mycroft 69: sys_vfork(p, v, retval)
1.16 cgd 70: struct proc *p;
1.25 mycroft 71: void *v;
1.22 cgd 72: register_t *retval;
1.16 cgd 73: {
74:
75: return (fork1(p, 1, retval));
76: }
77:
1.26 mycroft 78: int
1.16 cgd 79: fork1(p1, isvfork, retval)
80: register struct proc *p1;
1.22 cgd 81: int isvfork;
82: register_t *retval;
1.16 cgd 83: {
84: register struct proc *p2;
1.17 cgd 85: register uid_t uid;
86: struct proc *newproc;
87: struct proc **hash;
88: int count;
1.16 cgd 89: static int nextpid, pidchecked = 0;
90:
91: /*
1.17 cgd 92: * Although process entries are dynamically created, we still keep
1.16 cgd 93: * a global limit on the maximum number we will create. Don't allow
94: * a nonprivileged user to use the last process; don't let root
1.17 cgd 95: * exceed the limit. The variable nprocs is the current number of
1.16 cgd 96: * processes, maxproc is the limit.
97: */
1.17 cgd 98: uid = p1->p_cred->p_ruid;
1.16 cgd 99: if ((nprocs >= maxproc - 1 && uid != 0) || nprocs >= maxproc) {
100: tablefull("proc");
101: return (EAGAIN);
102: }
1.21 mycroft 103:
1.17 cgd 104: /*
105: * Increment the count of procs running with this uid. Don't allow
106: * a nonprivileged user to exceed their current limit.
107: */
108: count = chgproccnt(uid, 1);
109: if (uid != 0 && count > p1->p_rlimit[RLIMIT_NPROC].rlim_cur) {
110: (void)chgproccnt(uid, -1);
1.16 cgd 111: return (EAGAIN);
1.17 cgd 112: }
113:
114: /* Allocate new proc. */
115: MALLOC(newproc, struct proc *, sizeof(struct proc), M_PROC, M_WAITOK);
1.16 cgd 116:
117: /*
1.17 cgd 118: * Find an unused process ID. We remember a range of unused IDs
119: * ready to use (from nextpid+1 through pidchecked-1).
1.16 cgd 120: */
121: nextpid++;
122: retry:
123: /*
124: * If the process ID prototype has wrapped around,
125: * restart somewhat above 0, as the low-numbered procs
126: * tend to include daemons that don't exit.
127: */
128: if (nextpid >= PID_MAX) {
129: nextpid = 100;
130: pidchecked = 0;
131: }
132: if (nextpid >= pidchecked) {
133: int doingzomb = 0;
134:
135: pidchecked = PID_MAX;
136: /*
137: * Scan the active and zombie procs to check whether this pid
138: * is in use. Remember the lowest pid that's greater
139: * than nextpid, so we can avoid checking for a while.
140: */
1.20 mycroft 141: p2 = allproc.lh_first;
1.16 cgd 142: again:
1.20 mycroft 143: for (; p2 != 0; p2 = p2->p_list.le_next) {
1.16 cgd 144: while (p2->p_pid == nextpid ||
145: p2->p_pgrp->pg_id == nextpid) {
146: nextpid++;
147: if (nextpid >= pidchecked)
148: goto retry;
149: }
150: if (p2->p_pid > nextpid && pidchecked > p2->p_pid)
151: pidchecked = p2->p_pid;
152: if (p2->p_pgrp->pg_id > nextpid &&
153: pidchecked > p2->p_pgrp->pg_id)
154: pidchecked = p2->p_pgrp->pg_id;
155: }
156: if (!doingzomb) {
157: doingzomb = 1;
1.20 mycroft 158: p2 = zombproc.lh_first;
1.16 cgd 159: goto again;
160: }
161: }
162:
163: nprocs++;
1.17 cgd 164: p2 = newproc;
1.20 mycroft 165: p2->p_stat = SIDL; /* protect against others */
166: p2->p_pid = nextpid;
167: LIST_INSERT_HEAD(&allproc, p2, p_list);
1.17 cgd 168: p2->p_forw = p2->p_back = NULL; /* shouldn't be necessary */
1.20 mycroft 169: LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
1.16 cgd 170:
171: /*
172: * Make a proc table entry for the new process.
173: * Start by zeroing the section of proc that is zero-initialized,
174: * then copy the section that is copied directly from the parent.
175: */
176: bzero(&p2->p_startzero,
177: (unsigned) ((caddr_t)&p2->p_endzero - (caddr_t)&p2->p_startzero));
178: bcopy(&p1->p_startcopy, &p2->p_startcopy,
179: (unsigned) ((caddr_t)&p2->p_endcopy - (caddr_t)&p2->p_startcopy));
180:
181: /*
182: * Duplicate sub-structures as needed.
183: * Increase reference counts on shared objects.
184: * The p_stats and p_sigacts substructs are set in vm_fork.
185: */
1.17 cgd 186: p2->p_flag = P_INMEM;
1.21 mycroft 187: p2->p_emul = p1->p_emul;
1.17 cgd 188: if (p1->p_flag & P_PROFIL)
189: startprofclock(p2);
1.16 cgd 190: MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred),
191: M_SUBPROC, M_WAITOK);
192: bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred));
193: p2->p_cred->p_refcnt = 1;
194: crhold(p1->p_ucred);
195:
1.17 cgd 196: /* bump references to the text vnode (for procfs) */
197: p2->p_textvp = p1->p_textvp;
198: if (p2->p_textvp)
1.16 cgd 199: VREF(p2->p_textvp);
200:
201: p2->p_fd = fdcopy(p1);
202: /*
203: * If p_limit is still copy-on-write, bump refcnt,
204: * otherwise get a copy that won't be modified.
205: * (If PL_SHAREMOD is clear, the structure is shared
206: * copy-on-write.)
207: */
208: if (p1->p_limit->p_lflags & PL_SHAREMOD)
209: p2->p_limit = limcopy(p1->p_limit);
210: else {
211: p2->p_limit = p1->p_limit;
212: p2->p_limit->p_refcnt++;
213: }
214:
215: if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
216: p2->p_flag |= P_CONTROLT;
217: if (isvfork)
218: p2->p_flag |= P_PPWAIT;
1.20 mycroft 219: LIST_INSERT_AFTER(p1, p2, p_pglist);
1.16 cgd 220: p2->p_pptr = p1;
1.20 mycroft 221: LIST_INSERT_HEAD(&p1->p_children, p2, p_sibling);
222: LIST_INIT(&p2->p_children);
223:
1.16 cgd 224: #ifdef KTRACE
225: /*
226: * Copy traceflag and tracefile if enabled.
227: * If not inherited, these were zeroed above.
228: */
229: if (p1->p_traceflag&KTRFAC_INHERIT) {
230: p2->p_traceflag = p1->p_traceflag;
231: if ((p2->p_tracep = p1->p_tracep) != NULL)
232: VREF(p2->p_tracep);
233: }
234: #endif
235:
236: /*
237: * This begins the section where we must prevent the parent
238: * from being swapped.
239: */
1.18 mycroft 240: p1->p_holdcnt++;
1.26 mycroft 241:
242: #ifdef __FORK_BRAINDAMAGE
1.16 cgd 243: /*
244: * Set return values for child before vm_fork,
245: * so they can be copied to child stack.
1.26 mycroft 246: * We return 0, rather than the traditional behaviour of modifying the
247: * return value in the system call stub.
1.16 cgd 248: * NOTE: the kernel stack may be at a different location in the child
249: * process, and thus addresses of automatic variables (including retval)
250: * may be invalid after vm_fork returns in the child process.
251: */
1.26 mycroft 252: retval[0] = 0;
1.27 ! mycroft 253: retval[1] = 1;
1.26 mycroft 254: if (vm_fork(p1, p2))
1.16 cgd 255: return (0);
1.26 mycroft 256: #else
257: /*
258: * Finish creating the child process. It will return through a
259: * different path later.
260: */
261: vm_fork(p1, p2);
262: #endif
1.16 cgd 263:
264: /*
1.24 mycroft 265: * Make child runnable, set start time, and add to run queue.
1.16 cgd 266: */
1.26 mycroft 267: (void) splstatclock();
1.23 mycroft 268: p2->p_stats->p_start = time;
269: p2->p_acflag = AFORK;
1.16 cgd 270: p2->p_stat = SRUN;
271: setrunqueue(p2);
272: (void) spl0();
273:
274: /*
275: * Now can be swapped.
276: */
1.18 mycroft 277: p1->p_holdcnt--;
1.16 cgd 278:
279: /*
1.17 cgd 280: * Preserve synchronization semantics of vfork. If waiting for
281: * child to exec or exit, set P_PPWAIT on child, and sleep on our
282: * proc (in case of exit).
1.16 cgd 283: */
284: if (isvfork)
285: while (p2->p_flag & P_PPWAIT)
1.17 cgd 286: tsleep(p1, PWAIT, "ppwait", 0);
1.16 cgd 287:
288: /*
289: * Return child pid to parent process,
290: * marking us as parent via retval[1].
291: */
292: retval[0] = p2->p_pid;
293: retval[1] = 0;
294: return (0);
295: }
CVSweb <webmaster@jp.NetBSD.org>