xref: /freebsd/sys/kern/kern_proc.c (revision 48991a368427cadb9cdac39581d1676c29619c52)
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	@(#)kern_proc.c	8.4 (Berkeley) 1/4/94
34  * $Id: kern_proc.c,v 1.10 1995/05/30 08:05:37 rgrimes Exp $
35  */
36 
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/sysctl.h>
41 #include <sys/user.h>
42 #include <sys/proc.h>
43 #include <sys/buf.h>
44 #include <sys/acct.h>
45 #include <sys/wait.h>
46 #include <sys/file.h>
47 #include <ufs/ufs/quota.h>
48 #include <sys/uio.h>
49 #include <sys/malloc.h>
50 #include <sys/mbuf.h>
51 #include <sys/ioctl.h>
52 #include <sys/tty.h>
53 #include <sys/signalvar.h>
54 
55 struct prochd qs[NQS];		/* as good a place as any... */
56 struct prochd rtqs[NQS];	/* Space for REALTIME queues too */
57 struct prochd idqs[NQS];	/* Space for IDLE queues too */
58 
59 volatile struct proc *allproc;	/* all processes */
60 struct proc *zombproc;		/* just zombies */
61 
62 void pgdelete	__P((struct pgrp *));
63 
64 /*
65  * Structure associated with user cacheing.
66  */
67 struct uidinfo {
68 	struct	uidinfo *ui_next;
69 	struct	uidinfo **ui_prev;
70 	uid_t	ui_uid;
71 	long	ui_proccnt;
72 } **uihashtbl;
73 u_long	uihash;		/* size of hash table - 1 */
74 #define	UIHASH(uid)	((uid) & uihash)
75 
76 /*
77  * Allocate a hash table.
78  */
79 void
80 usrinfoinit()
81 {
82 
83 	uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash);
84 }
85 
86 /*
87  * Change the count associated with number of processes
88  * a given user is using.
89  */
90 int
91 chgproccnt(uid, diff)
92 	uid_t	uid;
93 	int	diff;
94 {
95 	register struct uidinfo **uipp, *uip, *uiq;
96 
97 	uipp = &uihashtbl[UIHASH(uid)];
98 	for (uip = *uipp; uip; uip = uip->ui_next)
99 		if (uip->ui_uid == uid)
100 			break;
101 	if (uip) {
102 		uip->ui_proccnt += diff;
103 		if (uip->ui_proccnt > 0)
104 			return (uip->ui_proccnt);
105 		if (uip->ui_proccnt < 0)
106 			panic("chgproccnt: procs < 0");
107 		if ((uiq = uip->ui_next))
108 			uiq->ui_prev = uip->ui_prev;
109 		*uip->ui_prev = uiq;
110 		FREE(uip, M_PROC);
111 		return (0);
112 	}
113 	if (diff <= 0) {
114 		if (diff == 0)
115 			return(0);
116 		panic("chgproccnt: lost user");
117 	}
118 	MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK);
119 	if ((uiq = *uipp))
120 		uiq->ui_prev = &uip->ui_next;
121 	uip->ui_next = uiq;
122 	uip->ui_prev = uipp;
123 	*uipp = uip;
124 	uip->ui_uid = uid;
125 	uip->ui_proccnt = diff;
126 	return (diff);
127 }
128 
129 /*
130  * Is p an inferior of the current process?
131  */
132 int
133 inferior(p)
134 	register struct proc *p;
135 {
136 
137 	for (; p != curproc; p = p->p_pptr)
138 		if (p->p_pid == 0)
139 			return (0);
140 	return (1);
141 }
142 
143 /*
144  * Locate a process by number
145  */
146 struct proc *
147 pfind(pid)
148 	register pid_t pid;
149 {
150 	register struct proc *p;
151 
152 	for (p = pidhash[PIDHASH(pid)]; p != NULL; p = p->p_hash)
153 		if (p->p_pid == pid)
154 			return (p);
155 	return (NULL);
156 }
157 
158 /*
159  * Locate a process group by number
160  */
161 struct pgrp *
162 pgfind(pgid)
163 	register pid_t pgid;
164 {
165 	register struct pgrp *pgrp;
166 
167 	for (pgrp = pgrphash[PIDHASH(pgid)];
168 	    pgrp != NULL; pgrp = pgrp->pg_hforw)
169 		if (pgrp->pg_id == pgid)
170 			return (pgrp);
171 	return (NULL);
172 }
173 
174 /*
175  * Move p to a new or existing process group (and session)
176  */
177 int
178 enterpgrp(p, pgid, mksess)
179 	register struct proc *p;
180 	pid_t pgid;
181 	int mksess;
182 {
183 	register struct pgrp *pgrp = pgfind(pgid);
184 	register struct proc **pp;
185 	int n;
186 
187 #ifdef DIAGNOSTIC
188 	if (pgrp != NULL && mksess)	/* firewalls */
189 		panic("enterpgrp: setsid into non-empty pgrp");
190 	if (SESS_LEADER(p))
191 		panic("enterpgrp: session leader attempted setpgrp");
192 #endif
193 	if (pgrp == NULL) {
194 		pid_t savepid = p->p_pid;
195 		struct proc *np;
196 		/*
197 		 * new process group
198 		 */
199 #ifdef DIAGNOSTIC
200 		if (p->p_pid != pgid)
201 			panic("enterpgrp: new pgrp and pid != pgid");
202 #endif
203 		MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
204 		       M_WAITOK);
205 		if ((np = pfind(savepid)) == NULL || np != p)
206 			return (ESRCH);
207 		if (mksess) {
208 			register struct session *sess;
209 
210 			/*
211 			 * new session
212 			 */
213 			MALLOC(sess, struct session *, sizeof(struct session),
214 				M_SESSION, M_WAITOK);
215 			sess->s_leader = p;
216 			sess->s_count = 1;
217 			sess->s_ttyvp = NULL;
218 			sess->s_ttyp = NULL;
219 			bcopy(p->p_session->s_login, sess->s_login,
220 			    sizeof(sess->s_login));
221 			p->p_flag &= ~P_CONTROLT;
222 			pgrp->pg_session = sess;
223 #ifdef DIAGNOSTIC
224 			if (p != curproc)
225 				panic("enterpgrp: mksession and p != curproc");
226 #endif
227 		} else {
228 			pgrp->pg_session = p->p_session;
229 			pgrp->pg_session->s_count++;
230 		}
231 		pgrp->pg_id = pgid;
232 		pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)];
233 		pgrphash[n] = pgrp;
234 		pgrp->pg_jobc = 0;
235 		pgrp->pg_mem = NULL;
236 	} else if (pgrp == p->p_pgrp)
237 		return (0);
238 
239 	/*
240 	 * Adjust eligibility of affected pgrps to participate in job control.
241 	 * Increment eligibility counts before decrementing, otherwise we
242 	 * could reach 0 spuriously during the first call.
243 	 */
244 	fixjobc(p, pgrp, 1);
245 	fixjobc(p, p->p_pgrp, 0);
246 
247 	/*
248 	 * unlink p from old process group
249 	 */
250 	for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) {
251 		if (*pp == p) {
252 			*pp = p->p_pgrpnxt;
253 			break;
254 		}
255 	}
256 #ifdef DIAGNOSTIC
257 	if (pp == NULL)
258 		panic("enterpgrp: can't find p on old pgrp");
259 #endif
260 	/*
261 	 * delete old if empty
262 	 */
263 	if (p->p_pgrp->pg_mem == 0)
264 		pgdelete(p->p_pgrp);
265 	/*
266 	 * link into new one
267 	 */
268 	p->p_pgrp = pgrp;
269 	p->p_pgrpnxt = pgrp->pg_mem;
270 	pgrp->pg_mem = p;
271 	return (0);
272 }
273 
274 /*
275  * remove process from process group
276  */
277 int
278 leavepgrp(p)
279 	register struct proc *p;
280 {
281 	register struct proc **pp = &p->p_pgrp->pg_mem;
282 
283 	for (; *pp; pp = &(*pp)->p_pgrpnxt) {
284 		if (*pp == p) {
285 			*pp = p->p_pgrpnxt;
286 			break;
287 		}
288 	}
289 #ifdef DIAGNOSTIC
290 	if (pp == NULL)
291 		panic("leavepgrp: can't find p in pgrp");
292 #endif
293 	if (!p->p_pgrp->pg_mem)
294 		pgdelete(p->p_pgrp);
295 	p->p_pgrp = 0;
296 	return (0);
297 }
298 
299 /*
300  * delete a process group
301  */
302 void
303 pgdelete(pgrp)
304 	register struct pgrp *pgrp;
305 {
306 	register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
307 
308 	if (pgrp->pg_session->s_ttyp != NULL &&
309 	    pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
310 		pgrp->pg_session->s_ttyp->t_pgrp = NULL;
311 	for (; *pgp; pgp = &(*pgp)->pg_hforw) {
312 		if (*pgp == pgrp) {
313 			*pgp = pgrp->pg_hforw;
314 			break;
315 		}
316 	}
317 #ifdef DIAGNOSTIC
318 	if (pgp == NULL)
319 		panic("pgdelete: can't find pgrp on hash chain");
320 #endif
321 	if (--pgrp->pg_session->s_count == 0)
322 		FREE(pgrp->pg_session, M_SESSION);
323 	FREE(pgrp, M_PGRP);
324 }
325 
326 static void orphanpg();
327 
328 /*
329  * Adjust pgrp jobc counters when specified process changes process group.
330  * We count the number of processes in each process group that "qualify"
331  * the group for terminal job control (those with a parent in a different
332  * process group of the same session).  If that count reaches zero, the
333  * process group becomes orphaned.  Check both the specified process'
334  * process group and that of its children.
335  * entering == 0 => p is leaving specified group.
336  * entering == 1 => p is entering specified group.
337  */
338 void
339 fixjobc(p, pgrp, entering)
340 	register struct proc *p;
341 	register struct pgrp *pgrp;
342 	int entering;
343 {
344 	register struct pgrp *hispgrp;
345 	register struct session *mysession = pgrp->pg_session;
346 
347 	/*
348 	 * Check p's parent to see whether p qualifies its own process
349 	 * group; if so, adjust count for p's process group.
350 	 */
351 	if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
352 	    hispgrp->pg_session == mysession)
353 		if (entering)
354 			pgrp->pg_jobc++;
355 		else if (--pgrp->pg_jobc == 0)
356 			orphanpg(pgrp);
357 
358 	/*
359 	 * Check this process' children to see whether they qualify
360 	 * their process groups; if so, adjust counts for children's
361 	 * process groups.
362 	 */
363 	for (p = p->p_cptr; p; p = p->p_osptr)
364 		if ((hispgrp = p->p_pgrp) != pgrp &&
365 		    hispgrp->pg_session == mysession &&
366 		    p->p_stat != SZOMB)
367 			if (entering)
368 				hispgrp->pg_jobc++;
369 			else if (--hispgrp->pg_jobc == 0)
370 				orphanpg(hispgrp);
371 }
372 
373 /*
374  * A process group has become orphaned;
375  * if there are any stopped processes in the group,
376  * hang-up all process in that group.
377  */
378 static void
379 orphanpg(pg)
380 	struct pgrp *pg;
381 {
382 	register struct proc *p;
383 
384 	for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
385 		if (p->p_stat == SSTOP) {
386 			for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
387 				psignal(p, SIGHUP);
388 				psignal(p, SIGCONT);
389 			}
390 			return;
391 		}
392 	}
393 }
394 
395 #ifdef debug
396 /* DEBUG */
397 pgrpdump()
398 {
399 	register struct pgrp *pgrp;
400 	register struct proc *p;
401 	register i;
402 
403 	for (i=0; i<PIDHSZ; i++) {
404 		if (pgrphash[i]) {
405 		  printf("\tindx %d\n", i);
406 		  for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
407 		    printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
408 			pgrp, pgrp->pg_id, pgrp->pg_session,
409 			pgrp->pg_session->s_count, pgrp->pg_mem);
410 		    for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
411 			printf("\t\tpid %d addr %x pgrp %x\n",
412 				p->p_pid, p, p->p_pgrp);
413 		    }
414 		  }
415 
416 		}
417 	}
418 }
419 #endif /* debug */
420 
421 /*
422  * Fill in an eproc structure for the specified process.
423  */
424 void
425 fill_eproc(p, ep)
426 	register struct proc *p;
427 	register struct eproc *ep;
428 {
429 	register struct tty *tp;
430 
431 	bzero(ep, sizeof(*ep));
432 
433 	ep->e_paddr = p;
434 	if (p->p_cred) {
435 		ep->e_pcred = *p->p_cred;
436 		if (p->p_ucred)
437 			ep->e_ucred = *p->p_ucred;
438 	}
439 	if (p->p_stat != SIDL && p->p_stat != SZOMB && p->p_vmspace != NULL) {
440 		register struct vmspace *vm = p->p_vmspace;
441 
442 #ifdef pmap_resident_count
443 		ep->e_vm.vm_rssize = pmap_resident_count(&vm->vm_pmap); /*XXX*/
444 #else
445 		ep->e_vm.vm_rssize = vm->vm_rssize;
446 #endif
447 		ep->e_vm.vm_tsize = vm->vm_tsize;
448 		ep->e_vm.vm_dsize = vm->vm_dsize;
449 		ep->e_vm.vm_ssize = vm->vm_ssize;
450 #ifndef sparc
451 		ep->e_vm.vm_pmap = vm->vm_pmap;
452 #endif
453 	}
454 	if (p->p_pptr)
455 		ep->e_ppid = p->p_pptr->p_pid;
456 	if (p->p_pgrp) {
457 		ep->e_sess = p->p_pgrp->pg_session;
458 		ep->e_pgid = p->p_pgrp->pg_id;
459 		ep->e_jobc = p->p_pgrp->pg_jobc;
460 	}
461 	if ((p->p_flag & P_CONTROLT) &&
462 	    (ep->e_sess != NULL) &&
463 	    ((tp = ep->e_sess->s_ttyp) != NULL)) {
464 		ep->e_tdev = tp->t_dev;
465 		ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
466 		ep->e_tsess = tp->t_session;
467 	} else
468 		ep->e_tdev = NODEV;
469 	if (ep->e_sess && ep->e_sess->s_ttyvp)
470 		ep->e_flag = EPROC_CTTY;
471 	if (SESS_LEADER(p))
472 		ep->e_flag |= EPROC_SLEADER;
473 	if (p->p_wmesg) {
474 		strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN);
475 		ep->e_wmesg[WMESGLEN] = 0;
476 	}
477 }
478 
479 static int
480 sysctl_kern_proc SYSCTL_HANDLER_ARGS
481 {
482 	int *name = (int*) arg1;
483 	u_int namelen = arg2;
484 	struct proc *p;
485 	int doingzomb;
486 	struct eproc eproc;
487 	int error = 0;
488 
489 	if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))
490 		return (EINVAL);
491 	if (!req->oldptr) {
492 		/*
493 		 * try over estimating by 5 procs
494 		 */
495 		error = SYSCTL_OUT(req, 0, sizeof (struct kinfo_proc) * 5);
496 		if (error)
497 			return (error);
498 	}
499 	p = (struct proc *)allproc;
500 	doingzomb = 0;
501 again:
502 	for (; p != NULL; p = p->p_next) {
503 		/*
504 		 * Skip embryonic processes.
505 		 */
506 		if (p->p_stat == SIDL)
507 			continue;
508 		/*
509 		 * TODO - make more efficient (see notes below).
510 		 * do by session.
511 		 */
512 		switch (name[0]) {
513 
514 		case KERN_PROC_PID:
515 			/* could do this with just a lookup */
516 			if (p->p_pid != (pid_t)name[1])
517 				continue;
518 			break;
519 
520 		case KERN_PROC_PGRP:
521 			/* could do this by traversing pgrp */
522 			if (p->p_pgrp == NULL || p->p_pgrp->pg_id != (pid_t)name[1])
523 				continue;
524 			break;
525 
526 		case KERN_PROC_TTY:
527 			if ((p->p_flag & P_CONTROLT) == 0 ||
528 			    p->p_session == NULL ||
529 			    p->p_session->s_ttyp == NULL ||
530 			    p->p_session->s_ttyp->t_dev != (dev_t)name[1])
531 				continue;
532 			break;
533 
534 		case KERN_PROC_UID:
535 			if (p->p_ucred == NULL || p->p_ucred->cr_uid != (uid_t)name[1])
536 				continue;
537 			break;
538 
539 		case KERN_PROC_RUID:
540 			if (p->p_ucred == NULL || p->p_cred->p_ruid != (uid_t)name[1])
541 				continue;
542 			break;
543 		}
544 
545 		fill_eproc(p, &eproc);
546 		error = SYSCTL_OUT(req,(caddr_t)p, sizeof(struct proc));
547 		if (error)
548 			return (error);
549 		error = SYSCTL_OUT(req,(caddr_t)&eproc, sizeof(eproc));
550 		if (error)
551 			return (error);
552 	}
553 	if (doingzomb == 0) {
554 		p = zombproc;
555 		doingzomb++;
556 		goto again;
557 	}
558 	return (0);
559 }
560 
561 SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD,
562 	sysctl_kern_proc, "Process table");
563