kern_proc.c revision 42453
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.7 (Berkeley) 2/14/95
34 * $Id: kern_proc.c,v 1.41 1999/01/08 17:31:09 eivind 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/proc.h>
42#include <sys/malloc.h>
43#include <sys/filedesc.h>
44#include <sys/tty.h>
45#include <sys/signalvar.h>
46#include <vm/vm.h>
47#include <sys/lock.h>
48#include <vm/pmap.h>
49#include <vm/vm_map.h>
50#include <sys/user.h>
51#include <vm/vm_zone.h>
52
53static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header");
54MALLOC_DEFINE(M_SESSION, "session", "session header");
55static MALLOC_DEFINE(M_PROC, "proc", "Proc structures");
56MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures");
57
58struct prochd qs[NQS];		/* as good a place as any... */
59struct prochd rtqs[NQS];	/* Space for REALTIME queues too */
60struct prochd idqs[NQS];	/* Space for IDLE queues too */
61
62static void pgdelete	__P((struct pgrp *));
63
64/*
65 * Structure associated with user cacheing.
66 */
67struct uidinfo {
68	LIST_ENTRY(uidinfo) ui_hash;
69	uid_t	ui_uid;
70	long	ui_proccnt;
71};
72#define	UIHASH(uid)	(&uihashtbl[(uid) & uihash])
73static LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
74static u_long uihash;		/* size of hash table - 1 */
75
76static void	orphanpg __P((struct pgrp *pg));
77
78/*
79 * Other process lists
80 */
81struct pidhashhead *pidhashtbl;
82u_long pidhash;
83struct pgrphashhead *pgrphashtbl;
84u_long pgrphash;
85struct proclist allproc;
86struct proclist zombproc;
87vm_zone_t proc_zone;
88
89/*
90 * Initialize global process hashing structures.
91 */
92void
93procinit()
94{
95
96	LIST_INIT(&allproc);
97	LIST_INIT(&zombproc);
98	pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
99	pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
100	uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash);
101	proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5);
102}
103
104/*
105 * Change the count associated with number of processes
106 * a given user is using.
107 */
108int
109chgproccnt(uid, diff)
110	uid_t	uid;
111	int	diff;
112{
113	register struct uidinfo *uip;
114	register struct uihashhead *uipp;
115
116	uipp = UIHASH(uid);
117	for (uip = uipp->lh_first; uip != 0; uip = uip->ui_hash.le_next)
118		if (uip->ui_uid == uid)
119			break;
120	if (uip) {
121		uip->ui_proccnt += diff;
122		if (uip->ui_proccnt > 0)
123			return (uip->ui_proccnt);
124		if (uip->ui_proccnt < 0)
125			panic("chgproccnt: procs < 0");
126		LIST_REMOVE(uip, ui_hash);
127		FREE(uip, M_PROC);
128		return (0);
129	}
130	if (diff <= 0) {
131		if (diff == 0)
132			return(0);
133		panic("chgproccnt: lost user");
134	}
135	MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK);
136	LIST_INSERT_HEAD(uipp, uip, ui_hash);
137	uip->ui_uid = uid;
138	uip->ui_proccnt = diff;
139	return (diff);
140}
141
142/*
143 * Is p an inferior of the current process?
144 */
145int
146inferior(p)
147	register struct proc *p;
148{
149
150	for (; p != curproc; p = p->p_pptr)
151		if (p->p_pid == 0)
152			return (0);
153	return (1);
154}
155
156/*
157 * Locate a process by number
158 */
159struct proc *
160pfind(pid)
161	register pid_t pid;
162{
163	register struct proc *p;
164
165	for (p = PIDHASH(pid)->lh_first; p != 0; p = p->p_hash.le_next)
166		if (p->p_pid == pid)
167			return (p);
168	return (NULL);
169}
170
171/*
172 * Locate a process group by number
173 */
174struct pgrp *
175pgfind(pgid)
176	register pid_t pgid;
177{
178	register struct pgrp *pgrp;
179
180	for (pgrp = PGRPHASH(pgid)->lh_first; pgrp != 0;
181	     pgrp = pgrp->pg_hash.le_next)
182		if (pgrp->pg_id == pgid)
183			return (pgrp);
184	return (NULL);
185}
186
187/*
188 * Move p to a new or existing process group (and session)
189 */
190int
191enterpgrp(p, pgid, mksess)
192	register struct proc *p;
193	pid_t pgid;
194	int mksess;
195{
196	register struct pgrp *pgrp = pgfind(pgid);
197
198	KASSERT(pgrp == NULL || !mksess,
199	    ("enterpgrp: setsid into non-empty pgrp"));
200	KASSERT(!SESS_LEADER(p),
201	    ("enterpgrp: session leader attempted setpgrp"));
202
203	if (pgrp == NULL) {
204		pid_t savepid = p->p_pid;
205		struct proc *np;
206		/*
207		 * new process group
208		 */
209		KASSERT(p->p_pid == pgid,
210		    ("enterpgrp: new pgrp and pid != pgid"));
211		MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
212		    M_WAITOK);
213		if ((np = pfind(savepid)) == NULL || np != p)
214			return (ESRCH);
215		if (mksess) {
216			register struct session *sess;
217
218			/*
219			 * new session
220			 */
221			MALLOC(sess, struct session *, sizeof(struct session),
222			    M_SESSION, M_WAITOK);
223			sess->s_leader = p;
224			sess->s_sid = p->p_pid;
225			sess->s_count = 1;
226			sess->s_ttyvp = NULL;
227			sess->s_ttyp = NULL;
228			bcopy(p->p_session->s_login, sess->s_login,
229			    sizeof(sess->s_login));
230			p->p_flag &= ~P_CONTROLT;
231			pgrp->pg_session = sess;
232			KASSERT(p == curproc,
233			    ("enterpgrp: mksession and p != curproc"));
234		} else {
235			pgrp->pg_session = p->p_session;
236			pgrp->pg_session->s_count++;
237		}
238		pgrp->pg_id = pgid;
239		LIST_INIT(&pgrp->pg_members);
240		LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
241		pgrp->pg_jobc = 0;
242		SLIST_INIT(&pgrp->pg_sigiolst);
243	} else if (pgrp == p->p_pgrp)
244		return (0);
245
246	/*
247	 * Adjust eligibility of affected pgrps to participate in job control.
248	 * Increment eligibility counts before decrementing, otherwise we
249	 * could reach 0 spuriously during the first call.
250	 */
251	fixjobc(p, pgrp, 1);
252	fixjobc(p, p->p_pgrp, 0);
253
254	LIST_REMOVE(p, p_pglist);
255	if (p->p_pgrp->pg_members.lh_first == 0)
256		pgdelete(p->p_pgrp);
257	p->p_pgrp = pgrp;
258	LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
259	return (0);
260}
261
262/*
263 * remove process from process group
264 */
265int
266leavepgrp(p)
267	register struct proc *p;
268{
269
270	LIST_REMOVE(p, p_pglist);
271	if (p->p_pgrp->pg_members.lh_first == 0)
272		pgdelete(p->p_pgrp);
273	p->p_pgrp = 0;
274	return (0);
275}
276
277/*
278 * delete a process group
279 */
280static void
281pgdelete(pgrp)
282	register struct pgrp *pgrp;
283{
284
285	/*
286	 * Reset any sigio structures pointing to us as a result of
287	 * F_SETOWN with our pgid.
288	 */
289	funsetownlst(&pgrp->pg_sigiolst);
290
291	if (pgrp->pg_session->s_ttyp != NULL &&
292	    pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
293		pgrp->pg_session->s_ttyp->t_pgrp = NULL;
294	LIST_REMOVE(pgrp, pg_hash);
295	if (--pgrp->pg_session->s_count == 0)
296		FREE(pgrp->pg_session, M_SESSION);
297	FREE(pgrp, M_PGRP);
298}
299
300/*
301 * Adjust pgrp jobc counters when specified process changes process group.
302 * We count the number of processes in each process group that "qualify"
303 * the group for terminal job control (those with a parent in a different
304 * process group of the same session).  If that count reaches zero, the
305 * process group becomes orphaned.  Check both the specified process'
306 * process group and that of its children.
307 * entering == 0 => p is leaving specified group.
308 * entering == 1 => p is entering specified group.
309 */
310void
311fixjobc(p, pgrp, entering)
312	register struct proc *p;
313	register struct pgrp *pgrp;
314	int entering;
315{
316	register struct pgrp *hispgrp;
317	register struct session *mysession = pgrp->pg_session;
318
319	/*
320	 * Check p's parent to see whether p qualifies its own process
321	 * group; if so, adjust count for p's process group.
322	 */
323	if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
324	    hispgrp->pg_session == mysession)
325		if (entering)
326			pgrp->pg_jobc++;
327		else if (--pgrp->pg_jobc == 0)
328			orphanpg(pgrp);
329
330	/*
331	 * Check this process' children to see whether they qualify
332	 * their process groups; if so, adjust counts for children's
333	 * process groups.
334	 */
335	for (p = p->p_children.lh_first; p != 0; p = p->p_sibling.le_next)
336		if ((hispgrp = p->p_pgrp) != pgrp &&
337		    hispgrp->pg_session == mysession &&
338		    p->p_stat != SZOMB)
339			if (entering)
340				hispgrp->pg_jobc++;
341			else if (--hispgrp->pg_jobc == 0)
342				orphanpg(hispgrp);
343}
344
345/*
346 * A process group has become orphaned;
347 * if there are any stopped processes in the group,
348 * hang-up all process in that group.
349 */
350static void
351orphanpg(pg)
352	struct pgrp *pg;
353{
354	register struct proc *p;
355
356	for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) {
357		if (p->p_stat == SSTOP) {
358			for (p = pg->pg_members.lh_first; p != 0;
359			    p = p->p_pglist.le_next) {
360				psignal(p, SIGHUP);
361				psignal(p, SIGCONT);
362			}
363			return;
364		}
365	}
366}
367
368#include "opt_ddb.h"
369#ifdef DDB
370#include <ddb/ddb.h>
371
372DB_SHOW_COMMAND(pgrpdump, pgrpdump)
373{
374	register struct pgrp *pgrp;
375	register struct proc *p;
376	register int i;
377
378	for (i = 0; i <= pgrphash; i++) {
379		if (pgrp = pgrphashtbl[i].lh_first) {
380			printf("\tindx %d\n", i);
381			for (; pgrp != 0; pgrp = pgrp->pg_hash.le_next) {
382				printf(
383			"\tpgrp %p, pgid %ld, sess %p, sesscnt %d, mem %p\n",
384				    (void *)pgrp, (long)pgrp->pg_id,
385				    (void *)pgrp->pg_session,
386				    pgrp->pg_session->s_count,
387				    (void *)pgrp->pg_members.lh_first);
388				for (p = pgrp->pg_members.lh_first; p != 0;
389				    p = p->p_pglist.le_next) {
390					printf("\t\tpid %ld addr %p pgrp %p\n",
391					    (long)p->p_pid, (void *)p,
392					    (void *)p->p_pgrp);
393				}
394			}
395		}
396	}
397}
398#endif /* DDB */
399
400/*
401 * Fill in an eproc structure for the specified process.
402 */
403void
404fill_eproc(p, ep)
405	register struct proc *p;
406	register struct eproc *ep;
407{
408	register struct tty *tp;
409
410	bzero(ep, sizeof(*ep));
411
412	ep->e_paddr = p;
413	if (p->p_cred) {
414		ep->e_pcred = *p->p_cred;
415		if (p->p_ucred)
416			ep->e_ucred = *p->p_ucred;
417	}
418	if (p->p_stat != SIDL && p->p_stat != SZOMB && p->p_vmspace != NULL) {
419		register struct vmspace *vm = p->p_vmspace;
420
421#ifdef pmap_resident_count
422		ep->e_vm.vm_rssize = pmap_resident_count(&vm->vm_pmap); /*XXX*/
423#else
424		ep->e_vm.vm_rssize = vm->vm_rssize;
425#endif
426		ep->e_vm.vm_tsize = vm->vm_tsize;
427		ep->e_vm.vm_dsize = vm->vm_dsize;
428		ep->e_vm.vm_ssize = vm->vm_ssize;
429		ep->e_vm.vm_taddr = vm->vm_taddr;
430		ep->e_vm.vm_daddr = vm->vm_daddr;
431		ep->e_vm.vm_minsaddr = vm->vm_minsaddr;
432		ep->e_vm.vm_maxsaddr = vm->vm_maxsaddr;
433		ep->e_vm.vm_map = vm->vm_map;
434#ifndef sparc
435		ep->e_vm.vm_pmap = vm->vm_pmap;
436#endif
437	}
438	if (p->p_pptr)
439		ep->e_ppid = p->p_pptr->p_pid;
440	if (p->p_pgrp) {
441		ep->e_pgid = p->p_pgrp->pg_id;
442		ep->e_jobc = p->p_pgrp->pg_jobc;
443		ep->e_sess = p->p_pgrp->pg_session;
444
445		if (ep->e_sess) {
446			bcopy(ep->e_sess->s_login, ep->e_login, sizeof(ep->e_login));
447			if (ep->e_sess->s_ttyvp)
448				ep->e_flag = EPROC_CTTY;
449			if (p->p_session && SESS_LEADER(p))
450				ep->e_flag |= EPROC_SLEADER;
451		}
452	}
453	if ((p->p_flag & P_CONTROLT) &&
454	    (ep->e_sess != NULL) &&
455	    ((tp = ep->e_sess->s_ttyp) != NULL)) {
456		ep->e_tdev = tp->t_dev;
457		ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
458		ep->e_tsess = tp->t_session;
459	} else
460		ep->e_tdev = NODEV;
461	if (p->p_wmesg) {
462		strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN);
463		ep->e_wmesg[WMESGLEN] = 0;
464	}
465}
466
467static struct proc *
468zpfind(pid_t pid)
469{
470	struct proc *p;
471
472	for (p = zombproc.lh_first; p != 0; p = p->p_list.le_next)
473		if (p->p_pid == pid)
474			return (p);
475	return (NULL);
476}
477
478
479static int
480sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb)
481{
482	struct eproc eproc;
483	int error;
484	pid_t pid = p->p_pid;
485
486	fill_eproc(p, &eproc);
487	error = SYSCTL_OUT(req,(caddr_t)p, sizeof(struct proc));
488	if (error)
489		return (error);
490	error = SYSCTL_OUT(req,(caddr_t)&eproc, sizeof(eproc));
491	if (error)
492		return (error);
493	if (!doingzomb && pid && (pfind(pid) != p))
494		return EAGAIN;
495	if (doingzomb && zpfind(pid) != p)
496		return EAGAIN;
497	return (0);
498}
499
500static int
501sysctl_kern_proc SYSCTL_HANDLER_ARGS
502{
503	int *name = (int*) arg1;
504	u_int namelen = arg2;
505	struct proc *p;
506	int doingzomb;
507	int error = 0;
508
509	if (oidp->oid_number == KERN_PROC_PID) {
510		if (namelen != 1)
511			return (EINVAL);
512		p = pfind((pid_t)name[0]);
513		if (!p)
514			return (0);
515		error = sysctl_out_proc(p, req, 0);
516		return (error);
517	}
518	if (oidp->oid_number == KERN_PROC_ALL && !namelen)
519		;
520	else if (oidp->oid_number != KERN_PROC_ALL && namelen == 1)
521		;
522	else
523		return (EINVAL);
524
525	if (!req->oldptr) {
526		/* overestimate by 5 procs */
527		error = SYSCTL_OUT(req, 0, sizeof (struct kinfo_proc) * 5);
528		if (error)
529			return (error);
530	}
531	for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) {
532		if (!doingzomb)
533			p = allproc.lh_first;
534		else
535			p = zombproc.lh_first;
536		for (; p != 0; p = p->p_list.le_next) {
537			/*
538			 * Skip embryonic processes.
539			 */
540			if (p->p_stat == SIDL)
541				continue;
542			/*
543			 * TODO - make more efficient (see notes below).
544			 * do by session.
545			 */
546			switch (oidp->oid_number) {
547
548			case KERN_PROC_PGRP:
549				/* could do this by traversing pgrp */
550				if (p->p_pgrp == NULL ||
551				    p->p_pgrp->pg_id != (pid_t)name[0])
552					continue;
553				break;
554
555			case KERN_PROC_TTY:
556				if ((p->p_flag & P_CONTROLT) == 0 ||
557				    p->p_session == NULL ||
558				    p->p_session->s_ttyp == NULL ||
559				    p->p_session->s_ttyp->t_dev != (dev_t)name[0])
560					continue;
561				break;
562
563			case KERN_PROC_UID:
564				if (p->p_ucred == NULL ||
565				    p->p_ucred->cr_uid != (uid_t)name[0])
566					continue;
567				break;
568
569			case KERN_PROC_RUID:
570				if (p->p_ucred == NULL ||
571				    p->p_cred->p_ruid != (uid_t)name[0])
572					continue;
573				break;
574			}
575
576			error = sysctl_out_proc(p, req, doingzomb);
577			if (error)
578				return (error);
579		}
580	}
581	return (0);
582}
583
584
585SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD,  0, "Process table");
586
587SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT,
588	0, 0, sysctl_kern_proc, "S,proc", "");
589
590SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, CTLFLAG_RD,
591	sysctl_kern_proc, "Process table");
592
593SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD,
594	sysctl_kern_proc, "Process table");
595
596SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD,
597	sysctl_kern_proc, "Process table");
598
599SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD,
600	sysctl_kern_proc, "Process table");
601
602SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD,
603	sysctl_kern_proc, "Process table");
604