kern_proc.c revision 1.44.2.1 1 /* $NetBSD: kern_proc.c,v 1.44.2.1 2001/03/05 22:49:41 nathanw Exp $ */
2
3 /*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * Copyright (c) 1982, 1986, 1989, 1991, 1993
42 * The Regents of the University of California. All rights reserved.
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 * 3. All advertising materials mentioning features or use of this software
53 * must display the following acknowledgement:
54 * This product includes software developed by the University of
55 * California, Berkeley and its contributors.
56 * 4. Neither the name of the University nor the names of its contributors
57 * may be used to endorse or promote products derived from this software
58 * without specific prior written permission.
59 *
60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70 * SUCH DAMAGE.
71 *
72 * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
73 */
74
75 #include <sys/param.h>
76 #include <sys/systm.h>
77 #include <sys/map.h>
78 #include <sys/kernel.h>
79 #include <sys/proc.h>
80 #include <sys/lwp.h>
81 #include <sys/resourcevar.h>
82 #include <sys/buf.h>
83 #include <sys/acct.h>
84 #include <sys/wait.h>
85 #include <sys/file.h>
86 #include <ufs/ufs/quota.h>
87 #include <sys/uio.h>
88 #include <sys/malloc.h>
89 #include <sys/pool.h>
90 #include <sys/mbuf.h>
91 #include <sys/ioctl.h>
92 #include <sys/tty.h>
93 #include <sys/signalvar.h>
94 #include <sys/sa.h>
95 #include <sys/savar.h>
96
97 /*
98 * Structure associated with user cacheing.
99 */
100 struct uidinfo {
101 LIST_ENTRY(uidinfo) ui_hash;
102 uid_t ui_uid;
103 long ui_proccnt;
104 };
105 #define UIHASH(uid) (&uihashtbl[(uid) & uihash])
106 LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
107 u_long uihash; /* size of hash table - 1 */
108
109 /*
110 * Other process lists
111 */
112 struct pidhashhead *pidhashtbl;
113 u_long pidhash;
114 struct pgrphashhead *pgrphashtbl;
115 u_long pgrphash;
116
117 struct proclist allproc;
118 struct proclist zombproc; /* resources have been freed */
119
120
121 /*
122 * Process list locking:
123 *
124 * We have two types of locks on the proclists: read locks and write
125 * locks. Read locks can be used in interrupt context, so while we
126 * hold the write lock, we must also block clock interrupts to
127 * lock out any scheduling changes that may happen in interrupt
128 * context.
129 *
130 * The proclist lock locks the following structures:
131 *
132 * allproc
133 * zombproc
134 * pidhashtbl
135 */
136 struct lock proclist_lock;
137
138 /*
139 * Locking of this proclist is special; it's accessed in a
140 * critical section of process exit, and thus locking it can't
141 * modify interrupt state. We use a simple spin lock for this
142 * proclist. Processes on this proclist are also on zombproc;
143 * we use the p_hash member to linkup to deadproc.
144 */
145 struct simplelock deadproc_slock;
146 struct proclist deadproc; /* dead, but not yet undead */
147
148 struct pool proc_pool;
149 struct pool lwp_pool;
150 struct pool lwp_uc_pool;
151 struct pool pcred_pool;
152 struct pool plimit_pool;
153 struct pool pstats_pool;
154 struct pool pgrp_pool;
155 struct pool rusage_pool;
156 struct pool sadata_pool;
157
158 /*
159 * The process list descriptors, used during pid allocation and
160 * by sysctl. No locking on this data structure is needed since
161 * it is completely static.
162 */
163 const struct proclist_desc proclists[] = {
164 { &allproc },
165 { &zombproc },
166 { NULL },
167 };
168
169 static void orphanpg __P((struct pgrp *));
170 #ifdef DEBUG
171 void pgrpdump __P((void));
172 #endif
173
174 /*
175 * Initialize global process hashing structures.
176 */
177 void
178 procinit()
179 {
180 const struct proclist_desc *pd;
181
182 for (pd = proclists; pd->pd_list != NULL; pd++)
183 LIST_INIT(pd->pd_list);
184
185 spinlockinit(&proclist_lock, "proclk", 0);
186
187 LIST_INIT(&deadproc);
188 simple_lock_init(&deadproc_slock);
189
190 LIST_INIT(&alllwp);
191 LIST_INIT(&deadlwp);
192 LIST_INIT(&zomblwp);
193
194 pidhashtbl =
195 hashinit(maxproc / 4, HASH_LIST, M_PROC, M_WAITOK, &pidhash);
196 pgrphashtbl =
197 hashinit(maxproc / 4, HASH_LIST, M_PROC, M_WAITOK, &pgrphash);
198 uihashtbl =
199 hashinit(maxproc / 16, HASH_LIST, M_PROC, M_WAITOK, &uihash);
200
201 pool_init(&proc_pool, sizeof(struct proc), 0, 0, 0, "procpl",
202 0, pool_page_alloc_nointr, pool_page_free_nointr, M_PROC);
203 pool_init(&lwp_pool, sizeof(struct lwp), 0, 0, 0, "lwppl",
204 0, pool_page_alloc_nointr, pool_page_free_nointr, M_ZOMBIE);
205 pool_init(&lwp_uc_pool, sizeof(ucontext_t), 0, 0, 0, "lwpucpl",
206 0, pool_page_alloc_nointr, pool_page_free_nointr, M_ZOMBIE);
207 pool_init(&pgrp_pool, sizeof(struct pgrp), 0, 0, 0, "pgrppl",
208 0, pool_page_alloc_nointr, pool_page_free_nointr, M_PGRP);
209 pool_init(&pcred_pool, sizeof(struct pcred), 0, 0, 0, "pcredpl",
210 0, pool_page_alloc_nointr, pool_page_free_nointr, M_SUBPROC);
211 pool_init(&plimit_pool, sizeof(struct plimit), 0, 0, 0, "plimitpl",
212 0, pool_page_alloc_nointr, pool_page_free_nointr, M_SUBPROC);
213 pool_init(&pstats_pool, sizeof(struct pstats), 0, 0, 0, "pstatspl",
214 0, pool_page_alloc_nointr, pool_page_free_nointr, M_SUBPROC);
215 pool_init(&rusage_pool, sizeof(struct rusage), 0, 0, 0, "rusgepl",
216 0, pool_page_alloc_nointr, pool_page_free_nointr, M_ZOMBIE);
217 pool_init(&sadata_pool, sizeof(struct sadata), 0, 0, 0, "sadatapl",
218 0, pool_page_alloc_nointr, pool_page_free_nointr, M_ZOMBIE);
219
220 }
221
222 /*
223 * Acquire a read lock on the proclist.
224 */
225 void
226 proclist_lock_read()
227 {
228 int error;
229
230 error = spinlockmgr(&proclist_lock, LK_SHARED, NULL);
231 #ifdef DIAGNOSTIC
232 if (__predict_false(error != 0))
233 panic("proclist_lock_read: failed to acquire lock");
234 #endif
235 }
236
237 /*
238 * Release a read lock on the proclist.
239 */
240 void
241 proclist_unlock_read()
242 {
243
244 (void) spinlockmgr(&proclist_lock, LK_RELEASE, NULL);
245 }
246
247 /*
248 * Acquire a write lock on the proclist.
249 */
250 int
251 proclist_lock_write()
252 {
253 int s, error;
254
255 s = splclock();
256 error = spinlockmgr(&proclist_lock, LK_EXCLUSIVE, NULL);
257 #ifdef DIAGNOSTIC
258 if (__predict_false(error != 0))
259 panic("proclist_lock: failed to acquire lock");
260 #endif
261 return (s);
262 }
263
264 /*
265 * Release a write lock on the proclist.
266 */
267 void
268 proclist_unlock_write(s)
269 int s;
270 {
271
272 (void) spinlockmgr(&proclist_lock, LK_RELEASE, NULL);
273 splx(s);
274 }
275
276 /*
277 * Change the count associated with number of processes
278 * a given user is using.
279 */
280 int
281 chgproccnt(uid, diff)
282 uid_t uid;
283 int diff;
284 {
285 struct uidinfo *uip;
286 struct uihashhead *uipp;
287
288 uipp = UIHASH(uid);
289 for (uip = uipp->lh_first; uip != 0; uip = uip->ui_hash.le_next)
290 if (uip->ui_uid == uid)
291 break;
292 if (uip) {
293 uip->ui_proccnt += diff;
294 if (uip->ui_proccnt > 0)
295 return (uip->ui_proccnt);
296 if (uip->ui_proccnt < 0)
297 panic("chgproccnt: procs < 0");
298 LIST_REMOVE(uip, ui_hash);
299 FREE(uip, M_PROC);
300 return (0);
301 }
302 if (diff <= 0) {
303 if (diff == 0)
304 return(0);
305 panic("chgproccnt: lost user");
306 }
307 MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK);
308 LIST_INSERT_HEAD(uipp, uip, ui_hash);
309 uip->ui_uid = uid;
310 uip->ui_proccnt = diff;
311 return (diff);
312 }
313
314 /*
315 * Is p an inferior of q?
316 */
317 int
318 inferior(p, q)
319 struct proc *p;
320 struct proc *q;
321 {
322
323 for (; p != q; p = p->p_pptr)
324 if (p->p_pid == 0)
325 return (0);
326 return (1);
327 }
328
329 /*
330 * Locate a process by number
331 */
332 struct proc *
333 pfind(pid)
334 pid_t pid;
335 {
336 struct proc *p;
337
338 proclist_lock_read();
339 for (p = PIDHASH(pid)->lh_first; p != 0; p = p->p_hash.le_next)
340 if (p->p_pid == pid)
341 goto out;
342 out:
343 proclist_unlock_read();
344 return (p);
345 }
346
347 /*
348 * Locate a process group by number
349 */
350 struct pgrp *
351 pgfind(pgid)
352 pid_t pgid;
353 {
354 struct pgrp *pgrp;
355
356 for (pgrp = PGRPHASH(pgid)->lh_first; pgrp != 0; pgrp = pgrp->pg_hash.le_next)
357 if (pgrp->pg_id == pgid)
358 return (pgrp);
359 return (NULL);
360 }
361
362 /*
363 * Move p to a new or existing process group (and session)
364 */
365 int
366 enterpgrp(p, pgid, mksess)
367 struct proc *p;
368 pid_t pgid;
369 int mksess;
370 {
371 struct pgrp *pgrp = pgfind(pgid);
372
373 #ifdef DIAGNOSTIC
374 if (__predict_false(pgrp != NULL && mksess)) /* firewalls */
375 panic("enterpgrp: setsid into non-empty pgrp");
376 if (__predict_false(SESS_LEADER(p)))
377 panic("enterpgrp: session leader attempted setpgrp");
378 #endif
379 if (pgrp == NULL) {
380 pid_t savepid = p->p_pid;
381 struct proc *np;
382 /*
383 * new process group
384 */
385 #ifdef DIAGNOSTIC
386 if (__predict_false(p->p_pid != pgid))
387 panic("enterpgrp: new pgrp and pid != pgid");
388 #endif
389 pgrp = pool_get(&pgrp_pool, PR_WAITOK);
390 if ((np = pfind(savepid)) == NULL || np != p)
391 return (ESRCH);
392 if (mksess) {
393 struct session *sess;
394
395 /*
396 * new session
397 */
398 MALLOC(sess, struct session *, sizeof(struct session),
399 M_SESSION, M_WAITOK);
400 sess->s_sid = p->p_pid;
401 sess->s_leader = p;
402 sess->s_count = 1;
403 sess->s_ttyvp = NULL;
404 sess->s_ttyp = NULL;
405 memcpy(sess->s_login, p->p_session->s_login,
406 sizeof(sess->s_login));
407 p->p_flag &= ~P_CONTROLT;
408 pgrp->pg_session = sess;
409 #ifdef DIAGNOSTIC
410 if (__predict_false(p != curproc->l_proc))
411 panic("enterpgrp: mksession and p != curproc");
412 #endif
413 } else {
414 pgrp->pg_session = p->p_session;
415 pgrp->pg_session->s_count++;
416 }
417 pgrp->pg_id = pgid;
418 LIST_INIT(&pgrp->pg_members);
419 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
420 pgrp->pg_jobc = 0;
421 } else if (pgrp == p->p_pgrp)
422 return (0);
423
424 /*
425 * Adjust eligibility of affected pgrps to participate in job control.
426 * Increment eligibility counts before decrementing, otherwise we
427 * could reach 0 spuriously during the first call.
428 */
429 fixjobc(p, pgrp, 1);
430 fixjobc(p, p->p_pgrp, 0);
431
432 LIST_REMOVE(p, p_pglist);
433 if (p->p_pgrp->pg_members.lh_first == 0)
434 pgdelete(p->p_pgrp);
435 p->p_pgrp = pgrp;
436 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
437 return (0);
438 }
439
440 /*
441 * remove process from process group
442 */
443 int
444 leavepgrp(p)
445 struct proc *p;
446 {
447
448 LIST_REMOVE(p, p_pglist);
449 if (p->p_pgrp->pg_members.lh_first == 0)
450 pgdelete(p->p_pgrp);
451 p->p_pgrp = 0;
452 return (0);
453 }
454
455 /*
456 * delete a process group
457 */
458 void
459 pgdelete(pgrp)
460 struct pgrp *pgrp;
461 {
462
463 /* Remove reference (if any) from tty to this process group */
464 if (pgrp->pg_session->s_ttyp != NULL &&
465 pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
466 pgrp->pg_session->s_ttyp->t_pgrp = NULL;
467 LIST_REMOVE(pgrp, pg_hash);
468 if (--pgrp->pg_session->s_count == 0) {
469 /* Remove reference (if any) from tty to this session */
470 if (pgrp->pg_session->s_ttyp != NULL)
471 pgrp->pg_session->s_ttyp->t_session = NULL;
472 FREE(pgrp->pg_session, M_SESSION);
473 }
474 pool_put(&pgrp_pool, pgrp);
475 }
476
477 /*
478 * Adjust pgrp jobc counters when specified process changes process group.
479 * We count the number of processes in each process group that "qualify"
480 * the group for terminal job control (those with a parent in a different
481 * process group of the same session). If that count reaches zero, the
482 * process group becomes orphaned. Check both the specified process'
483 * process group and that of its children.
484 * entering == 0 => p is leaving specified group.
485 * entering == 1 => p is entering specified group.
486 */
487 void
488 fixjobc(p, pgrp, entering)
489 struct proc *p;
490 struct pgrp *pgrp;
491 int entering;
492 {
493 struct pgrp *hispgrp;
494 struct session *mysession = pgrp->pg_session;
495
496 /*
497 * Check p's parent to see whether p qualifies its own process
498 * group; if so, adjust count for p's process group.
499 */
500 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
501 hispgrp->pg_session == mysession) {
502 if (entering)
503 pgrp->pg_jobc++;
504 else if (--pgrp->pg_jobc == 0)
505 orphanpg(pgrp);
506 }
507
508 /*
509 * Check this process' children to see whether they qualify
510 * their process groups; if so, adjust counts for children's
511 * process groups.
512 */
513 for (p = p->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
514 if ((hispgrp = p->p_pgrp) != pgrp &&
515 hispgrp->pg_session == mysession &&
516 P_ZOMBIE(p) == 0) {
517 if (entering)
518 hispgrp->pg_jobc++;
519 else if (--hispgrp->pg_jobc == 0)
520 orphanpg(hispgrp);
521 }
522 }
523 }
524
525 /*
526 * A process group has become orphaned;
527 * if there are any stopped processes in the group,
528 * hang-up all process in that group.
529 */
530 static void
531 orphanpg(pg)
532 struct pgrp *pg;
533 {
534 struct proc *p;
535
536 for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) {
537 if (p->p_stat == SSTOP) {
538 for (p = pg->pg_members.lh_first; p != 0;
539 p = p->p_pglist.le_next) {
540 psignal(p, SIGHUP);
541 psignal(p, SIGCONT);
542 }
543 return;
544 }
545 }
546 }
547
548 /* mark process as suid/sgid, reset some values do defaults */
549 void
550 p_sugid(p)
551 struct proc *p;
552 {
553 struct plimit *newlim;
554
555 p->p_flag |= P_SUGID;
556 /* reset what needs to be reset in plimit */
557 if (p->p_limit->pl_corename != defcorename) {
558 if (p->p_limit->p_refcnt > 1 &&
559 (p->p_limit->p_lflags & PL_SHAREMOD) == 0) {
560 newlim = limcopy(p->p_limit);
561 limfree(p->p_limit);
562 p->p_limit = newlim;
563 } else {
564 free(p->p_limit->pl_corename, M_TEMP);
565 }
566 p->p_limit->pl_corename = defcorename;
567 }
568 }
569
570
571 #ifdef DEBUG
572 void
573 pgrpdump()
574 {
575 struct pgrp *pgrp;
576 struct proc *p;
577 int i;
578
579 for (i = 0; i <= pgrphash; i++) {
580 if ((pgrp = pgrphashtbl[i].lh_first) != NULL) {
581 printf("\tindx %d\n", i);
582 for (; pgrp != 0; pgrp = pgrp->pg_hash.le_next) {
583 printf("\tpgrp %p, pgid %d, sess %p, sesscnt %d, mem %p\n",
584 pgrp, pgrp->pg_id, pgrp->pg_session,
585 pgrp->pg_session->s_count,
586 pgrp->pg_members.lh_first);
587 for (p = pgrp->pg_members.lh_first; p != 0;
588 p = p->p_pglist.le_next) {
589 printf("\t\tpid %d addr %p pgrp %p\n",
590 p->p_pid, p, p->p_pgrp);
591 }
592 }
593 }
594 }
595 }
596 #endif /* DEBUG */
597