Change logging to core dumps, to log as LOG_INFO - this should appease
[unix-history] / sys / kern / kern_fork.c
CommitLineData
169d8a33
RG
1/*
2 * Copyright (c) UNIX System Laboratories, Inc. All or some portions
3 * of this file are derived from material licensed to the
4 * University of California by American Telephone and Telegraph Co.
5 * or UNIX System Laboratories, Inc. and are reproduced herein with
6 * the permission of UNIX System Laboratories, Inc.
7 */
15637ed4
RG
8/*
9 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
10 * All rights reserved.
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 *
600f7f07 40 * from: @(#)kern_fork.c 7.29 (Berkeley) 5/15/91
169d8a33 41 * $Id: kern_fork.c,v 1.7 1994/03/14 21:54:15 davidg Exp $
15637ed4
RG
42 */
43
44#include "param.h"
45#include "systm.h"
46#include "filedesc.h"
47#include "kernel.h"
48#include "malloc.h"
49#include "proc.h"
50#include "resourcevar.h"
51#include "vnode.h"
52#include "file.h"
53#include "acct.h"
54#include "ktrace.h"
55#include "vm/vm.h"
56
fde1aeb2
GW
57static int fork1(struct proc *, int, int *);
58
15637ed4 59/* ARGSUSED */
4c45483e 60int
15637ed4
RG
61fork(p, uap, retval)
62 struct proc *p;
63 void *uap;
64 int retval[];
65{
66
67 return (fork1(p, 0, retval));
68}
69
70/* ARGSUSED */
4c45483e 71int
15637ed4
RG
72vfork(p, uap, retval)
73 struct proc *p;
74 void *uap;
75 int retval[];
76{
77
78 return (fork1(p, 1, retval));
79}
80
81int nprocs = 1; /* process 0 */
82
fde1aeb2 83static int
15637ed4
RG
84fork1(p1, isvfork, retval)
85 register struct proc *p1;
86 int isvfork, retval[];
87{
88 register struct proc *p2;
89 register int count, uid;
90 static int nextpid, pidchecked = 0;
91
92 count = 0;
93 if ((uid = p1->p_ucred->cr_uid) != 0) {
94 for (p2 = allproc; p2; p2 = p2->p_nxt)
95 if (p2->p_ucred->cr_uid == uid)
96 count++;
97 for (p2 = zombproc; p2; p2 = p2->p_nxt)
98 if (p2->p_ucred->cr_uid == uid)
99 count++;
100 }
101 /*
102 * Although process entries are dynamically entries,
103 * we still keep a global limit on the maximum number
104 * we will create. Don't allow a nonprivileged user
105 * to exceed its current limit or to bring us within one
106 * of the global limit; don't let root exceed the limit.
107 * nprocs is the current number of processes,
108 * maxproc is the limit.
109 */
110 if (nprocs >= maxproc || uid == 0 && nprocs >= maxproc + 1) {
111 tablefull("proc");
112 return (EAGAIN);
113 }
114 if (count > p1->p_rlimit[RLIMIT_NPROC].rlim_cur)
115 return (EAGAIN);
116
117 /*
118 * Find an unused process ID.
119 * We remember a range of unused IDs ready to use
120 * (from nextpid+1 through pidchecked-1).
121 */
122 nextpid++;
123retry:
124 /*
125 * If the process ID prototype has wrapped around,
126 * restart somewhat above 0, as the low-numbered procs
127 * tend to include daemons that don't exit.
128 */
129 if (nextpid >= PID_MAX) {
130 nextpid = 100;
131 pidchecked = 0;
132 }
133 if (nextpid >= pidchecked) {
134 int doingzomb = 0;
135
136 pidchecked = PID_MAX;
137 /*
138 * Scan the active and zombie procs to check whether this pid
139 * is in use. Remember the lowest pid that's greater
140 * than nextpid, so we can avoid checking for a while.
141 */
142 p2 = allproc;
143again:
144 for (; p2 != NULL; p2 = p2->p_nxt) {
145 if (p2->p_pid == nextpid ||
146 p2->p_pgrp->pg_id == nextpid) {
147 nextpid++;
148 if (nextpid >= pidchecked)
149 goto retry;
150 }
151 if (p2->p_pid > nextpid && pidchecked > p2->p_pid)
152 pidchecked = p2->p_pid;
153 if (p2->p_pgrp->pg_id > nextpid &&
154 pidchecked > p2->p_pgrp->pg_id)
155 pidchecked = p2->p_pgrp->pg_id;
156 }
157 if (!doingzomb) {
158 doingzomb = 1;
159 p2 = zombproc;
160 goto again;
161 }
162 }
163
164
165 /*
166 * Allocate new proc.
167 * Link onto allproc (this should probably be delayed).
168 */
169 MALLOC(p2, struct proc *, sizeof(struct proc), M_PROC, M_WAITOK);
170 nprocs++;
a9d36f61
DG
171
172 /* Initialize all fields to zero */
173 bzero((struct proc *)p2, sizeof(struct proc));
174
15637ed4
RG
175 p2->p_nxt = allproc;
176 p2->p_nxt->p_prev = &p2->p_nxt; /* allproc is never NULL */
177 p2->p_prev = &allproc;
178 allproc = p2;
15637ed4
RG
179
180 /*
181 * Make a proc table entry for the new process.
a9d36f61 182 * Copy the section that is copied directly from the parent.
15637ed4 183 */
15637ed4
RG
184 bcopy(&p1->p_startcopy, &p2->p_startcopy,
185 (unsigned) ((caddr_t)&p2->p_endcopy - (caddr_t)&p2->p_startcopy));
15637ed4
RG
186
187 /*
188 * Duplicate sub-structures as needed.
189 * Increase reference counts on shared objects.
190 * The p_stats and p_sigacts substructs are set in vm_fork.
191 */
192 MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred),
193 M_SUBPROC, M_WAITOK);
194 bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred));
195 p2->p_cred->p_refcnt = 1;
196 crhold(p1->p_ucred);
197
198 p2->p_fd = fdcopy(p1);
199 /*
200 * If p_limit is still copy-on-write, bump refcnt,
201 * otherwise get a copy that won't be modified.
202 * (If PL_SHAREMOD is clear, the structure is shared
203 * copy-on-write.)
204 */
205 if (p1->p_limit->p_lflags & PL_SHAREMOD)
206 p2->p_limit = limcopy(p1->p_limit);
207 else {
208 p2->p_limit = p1->p_limit;
209 p2->p_limit->p_refcnt++;
210 }
211
212 p2->p_flag = SLOAD | (p1->p_flag & SHPUX);
213 if (p1->p_session->s_ttyvp != NULL && p1->p_flag & SCTTY)
214 p2->p_flag |= SCTTY;
215 if (isvfork)
216 p2->p_flag |= SPPWAIT;
217 p2->p_stat = SIDL;
218 p2->p_pid = nextpid;
219 {
220 struct proc **hash = &pidhash[PIDHASH(p2->p_pid)];
221
222 p2->p_hash = *hash;
223 *hash = p2;
224 }
225 p2->p_pgrpnxt = p1->p_pgrpnxt;
226 p1->p_pgrpnxt = p2;
227 p2->p_pptr = p1;
228 p2->p_osptr = p1->p_cptr;
229 if (p1->p_cptr)
230 p1->p_cptr->p_ysptr = p2;
231 p1->p_cptr = p2;
232#ifdef KTRACE
233 /*
234 * Copy traceflag and tracefile if enabled.
235 * If not inherited, these were zeroed above.
236 */
237 if (p1->p_traceflag&KTRFAC_INHERIT) {
238 p2->p_traceflag = p1->p_traceflag;
239 if ((p2->p_tracep = p1->p_tracep) != NULL)
240 VREF(p2->p_tracep);
241 }
242#endif
243
244#if defined(tahoe)
245 p2->p_vmspace->p_ckey = p1->p_vmspace->p_ckey; /* XXX move this */
246#endif
247
41aefbec
DG
248 /*
249 * set priority of child to be that of parent
250 */
251 p2->p_cpu = p1->p_cpu;
252
15637ed4
RG
253 /*
254 * This begins the section where we must prevent the parent
255 * from being swapped.
256 */
257 p1->p_flag |= SKEEP;
258 /*
259 * Set return values for child before vm_fork,
260 * so they can be copied to child stack.
261 * We return parent pid, and mark as child in retval[1].
262 * NOTE: the kernel stack may be at a different location in the child
263 * process, and thus addresses of automatic variables (including retval)
264 * may be invalid after vm_fork returns in the child process.
265 */
266 retval[0] = p1->p_pid;
267 retval[1] = 1;
268 if (vm_fork(p1, p2, isvfork)) {
269 /*
270 * Child process. Set start time and get to work.
271 */
272 (void) splclock();
273 p2->p_stats->p_start = time;
274 (void) spl0();
275 p2->p_acflag = AFORK;
41aefbec
DG
276/*
277 vm_map_init_pmap(&p2->p_vmspace->vm_map);
278*/
15637ed4
RG
279 return (0);
280 }
281
282 /*
283 * Make child runnable and add to run queue.
284 */
285 (void) splhigh();
286 p2->p_stat = SRUN;
287 setrq(p2);
288 (void) spl0();
289
290 /*
291 * Now can be swapped.
292 */
293 p1->p_flag &= ~SKEEP;
294
295 /*
296 * Preserve synchronization semantics of vfork.
297 * If waiting for child to exec or exit, set SPPWAIT
298 * on child, and sleep on our proc (in case of exit).
299 */
300 if (isvfork)
301 while (p2->p_flag & SPPWAIT)
302 tsleep((caddr_t)p1, PWAIT, "ppwait", 0);
303
304 /*
305 * Return child pid to parent process,
306 * marking us as parent via retval[1].
307 */
308 retval[0] = p2->p_pid;
309 retval[1] = 0;
310 return (0);
311}