kern_proc.c revision 93076
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 * $FreeBSD: head/sys/kern/kern_proc.c 93076 2002-03-24 05:09:11Z bde $
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>
40#include <sys/lock.h>
41#include <sys/malloc.h>
42#include <sys/mutex.h>
43#include <sys/proc.h>
44#include <sys/sysproto.h>
45#include <sys/sysctl.h>
46#include <sys/filedesc.h>
47#include <sys/tty.h>
48#include <sys/signalvar.h>
49#include <sys/sx.h>
50#include <sys/user.h>
51#include <sys/jail.h>
52
53#include <vm/vm.h>
54#include <vm/pmap.h>
55#include <vm/vm_map.h>
56#include <vm/uma.h>
57
58MALLOC_DEFINE(M_PGRP, "pgrp", "process group header");
59MALLOC_DEFINE(M_SESSION, "session", "session header");
60static MALLOC_DEFINE(M_PROC, "proc", "Proc structures");
61MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures");
62
63static struct proc *dopfind(register pid_t);
64
65static void doenterpgrp(struct proc *, struct pgrp *);
66
67static void pgdelete(struct pgrp *);
68
69static void orphanpg(struct pgrp *pg);
70
71/*
72 * Other process lists
73 */
74struct pidhashhead *pidhashtbl;
75u_long pidhash;
76struct pgrphashhead *pgrphashtbl;
77u_long pgrphash;
78struct proclist allproc;
79struct proclist zombproc;
80struct sx allproc_lock;
81struct sx proctree_lock;
82struct sx pgrpsess_lock;
83uma_zone_t proc_zone;
84uma_zone_t ithread_zone;
85
86/*
87 * Initialize global process hashing structures.
88 */
89void
90procinit()
91{
92	int i, j;
93
94	sx_init(&allproc_lock, "allproc");
95	sx_init(&proctree_lock, "proctree");
96	sx_init(&pgrpsess_lock, "pgrpsess");
97	LIST_INIT(&allproc);
98	LIST_INIT(&zombproc);
99	pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
100	pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
101	proc_zone = uma_zcreate("PROC", sizeof (struct proc), NULL, NULL,
102	    NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
103	uihashinit();
104	/*
105	 * This should really be a compile time warning, but I do
106	 * not know of any way to do that...
107	 */
108	if (sizeof(struct kinfo_proc) != KINFO_PROC_SIZE) {
109		printf("This message will repeat for the next 20 seconds\n");
110		for (i = 0; i < 20; i++) {
111			printf("WARNING: size of kinfo_proc (%ld) should be %d!!!\n",
112			    (long)sizeof(struct kinfo_proc), KINFO_PROC_SIZE);
113			printf("The kinfo_proc structure was changed ");
114			printf("incorrectly in <sys/user.h>\n");
115			for (j = 0; j < 0x7ffffff; j++);
116		}
117
118	}
119}
120
121/*
122 * Note that we do not link to the proc's ucred here
123 * The thread is linked as if running but no KSE assigned
124 */
125static  void
126thread_link(struct thread *td, struct ksegrp *kg)
127{
128	struct proc *p = kg->kg_proc;
129
130	td->td_proc     = p;
131	td->td_ksegrp   = kg;
132	td->td_last_kse = &p->p_kse;
133
134	TAILQ_INSERT_HEAD(&p->p_threads, td, td_plist);
135	TAILQ_INSERT_HEAD(&kg->kg_threads, td, td_kglist);
136	td->td_critnest = 0;
137	td->td_savecrit = 0;
138	td->td_kse      = NULL;
139}
140
141/*
142 * KSE is linked onto the idle queue.
143 */
144static void
145kse_link(struct kse *ke, struct ksegrp *kg)
146{
147	struct proc *p = kg->kg_proc;
148
149	TAILQ_INSERT_HEAD(&kg->kg_kseq, ke, ke_kglist);
150	kg->kg_kses++;
151	TAILQ_INSERT_HEAD(&kg->kg_iq, ke, ke_kgrlist);
152	ke->ke_proc	= p;
153	ke->ke_ksegrp	= kg;
154	ke->ke_thread	= NULL;
155	ke->ke_oncpu = NOCPU;
156}
157
158static void
159ksegrp_link(struct ksegrp *kg, struct proc *p)
160{
161
162	TAILQ_INIT(&kg->kg_threads);
163	TAILQ_INIT(&kg->kg_runq);	/* links with td_runq */
164	TAILQ_INIT(&kg->kg_slpq);	/* links with td_runq */
165	TAILQ_INIT(&kg->kg_kseq);	/* all kses in ksegrp */
166	TAILQ_INIT(&kg->kg_iq);		/* all kses in ksegrp */
167	kg->kg_proc	= p;
168/* the following counters are in the -zero- section and may not need clearing */
169	kg->kg_runnable = 0;
170	kg->kg_kses = 0;
171	kg->kg_runq_kses = 0; /* XXXKSE change name */
172/* link it in now that it's consitant */
173	TAILQ_INSERT_HEAD(&p->p_ksegrps, kg, kg_ksegrp);
174}
175
176/*
177 * for a newly created process,
178 * link up a the structure and its initial threads etc.
179 */
180void
181proc_linkup(struct proc *p, struct ksegrp *kg,
182			struct kse *ke, struct thread *td)
183{
184
185	TAILQ_INIT(&p->p_ksegrps);	     /* all ksegrps in proc */
186	TAILQ_INIT(&p->p_threads);	     /* all threads in proc */
187
188	ksegrp_link(kg, p);
189	kse_link(ke, kg);
190	thread_link(td, kg);
191	/* link them together for 1:1 */
192	td->td_kse = ke;
193	ke->ke_thread = td;
194}
195
196/* temporary version is ultra simple while we are in 1:1 mode */
197struct thread *
198thread_get(struct proc *p)
199{
200	struct thread *td = &p->p_xxthread;
201
202	return (td);
203}
204
205
206/*********************
207* STUB KSE syscalls
208*********************/
209
210/* struct thread_wakeup_args { struct thread_mailbox *tmbx; }; */
211int
212thread_wakeup(struct thread *td, struct  thread_wakeup_args *uap)
213{
214
215	return(ENOSYS);
216}
217
218int
219kse_exit(struct thread *td, struct kse_exit_args *uap)
220{
221
222	return(ENOSYS);
223}
224
225int
226kse_yield(struct thread *td, struct kse_yield_args *uap)
227{
228
229	return(ENOSYS);
230}
231
232int kse_wakeup(struct thread *td, struct kse_wakeup_args *uap)
233{
234
235	return(ENOSYS);
236}
237
238
239int
240kse_new(struct thread *td, struct kse_new_args *uap)
241/* struct kse_new_args {
242	struct kse_mailbox *mbx;
243	int	new_grp_flag;
244}; */
245{
246
247	return (ENOSYS);
248}
249
250/*
251 * Is p an inferior of the current process?
252 */
253int
254inferior(p)
255	register struct proc *p;
256{
257
258	sx_assert(&proctree_lock, SX_LOCKED);
259	for (; p != curproc; p = p->p_pptr)
260		if (p->p_pid == 0)
261			return (0);
262	return (1);
263}
264
265/*
266 * Locate a process by number
267 */
268struct proc *
269pfind(pid)
270	register pid_t pid;
271{
272	register struct proc *p;
273
274	sx_slock(&allproc_lock);
275	p = dopfind(pid);
276	sx_sunlock(&allproc_lock);
277	return (p);
278}
279
280static struct proc *
281dopfind(pid)
282	register pid_t pid;
283{
284	register struct proc *p;
285
286	sx_assert(&allproc_lock, SX_LOCKED);
287
288	LIST_FOREACH(p, PIDHASH(pid), p_hash)
289		if (p->p_pid == pid) {
290			PROC_LOCK(p);
291			break;
292		}
293	return (p);
294}
295
296/*
297 * Locate a process group by number.
298 * The caller must hold pgrpsess_lock.
299 */
300struct pgrp *
301pgfind(pgid)
302	register pid_t pgid;
303{
304	register struct pgrp *pgrp;
305
306	PGRPSESS_LOCK_ASSERT(SX_LOCKED);
307
308	LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash) {
309		if (pgrp->pg_id == pgid) {
310			PGRP_LOCK(pgrp);
311			return (pgrp);
312		}
313	}
314	return (NULL);
315}
316
317/*
318 * Create a new process group.
319 * pgid must be equal to the pid of p.
320 * Begin a new session if required.
321 */
322int
323enterpgrp(p, pgid, pgrp, sess)
324	register struct proc *p;
325	pid_t pgid;
326	struct pgrp *pgrp;
327	struct session *sess;
328{
329	struct pgrp *pgrp2;
330
331	PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
332
333	KASSERT(pgrp != NULL, ("enterpgrp: pgrp == NULL"));
334	KASSERT(p->p_pid == pgid,
335	    ("enterpgrp: new pgrp and pid != pgid"));
336
337	pgrp2 = pgfind(pgid);
338
339	KASSERT(pgrp2 == NULL,
340	    ("enterpgrp: pgrp with pgid exists"));
341	KASSERT(!SESS_LEADER(p),
342	    ("enterpgrp: session leader attempted setpgrp"));
343
344	mtx_init(&pgrp->pg_mtx, "process group", MTX_DEF);
345
346	if (sess != NULL) {
347		/*
348		 * new session
349		 */
350		mtx_init(&sess->s_mtx, "session", MTX_DEF);
351		PROC_LOCK(p);
352		p->p_flag &= ~P_CONTROLT;
353		PROC_UNLOCK(p);
354		PGRP_LOCK(pgrp);
355		sess->s_leader = p;
356		sess->s_sid = p->p_pid;
357		sess->s_count = 1;
358		sess->s_ttyvp = NULL;
359		sess->s_ttyp = NULL;
360		bcopy(p->p_session->s_login, sess->s_login,
361			    sizeof(sess->s_login));
362		pgrp->pg_session = sess;
363		KASSERT(p == curproc,
364		    ("enterpgrp: mksession and p != curproc"));
365	} else {
366		pgrp->pg_session = p->p_session;
367		SESS_LOCK(pgrp->pg_session);
368		pgrp->pg_session->s_count++;
369		SESS_UNLOCK(pgrp->pg_session);
370		PGRP_LOCK(pgrp);
371	}
372	pgrp->pg_id = pgid;
373	LIST_INIT(&pgrp->pg_members);
374
375	/*
376	 * As we have an exclusive lock of pgrpsess_lock,
377	 * this should not deadlock.
378	 */
379	LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
380	pgrp->pg_jobc = 0;
381	SLIST_INIT(&pgrp->pg_sigiolst);
382	PGRP_UNLOCK(pgrp);
383
384	doenterpgrp(p, pgrp);
385
386	return (0);
387}
388
389/*
390 * Move p to an existing process group
391 */
392int
393enterthispgrp(p, pgrp)
394	register struct proc *p;
395	struct pgrp *pgrp;
396{
397	PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
398	PROC_LOCK_ASSERT(p, MA_NOTOWNED);
399	PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
400	PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED);
401	SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED);
402	KASSERT(pgrp->pg_session == p->p_session,
403		("%s: pgrp's session %p, p->p_session %p.\n",
404		__func__,
405		pgrp->pg_session,
406		p->p_session));
407	KASSERT(pgrp != p->p_pgrp,
408		("%s: p belongs to pgrp.", __func__));
409
410	doenterpgrp(p, pgrp);
411
412	return (0);
413}
414
415/*
416 * Move p to a process group
417 */
418static void
419doenterpgrp(p, pgrp)
420	struct proc *p;
421	struct pgrp *pgrp;
422{
423	struct pgrp *savepgrp;
424
425	PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
426	PROC_LOCK_ASSERT(p, MA_NOTOWNED);
427	PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
428	PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED);
429	SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED);
430
431	savepgrp = p->p_pgrp;
432
433	/*
434	 * Adjust eligibility of affected pgrps to participate in job control.
435	 * Increment eligibility counts before decrementing, otherwise we
436	 * could reach 0 spuriously during the first call.
437	 */
438	fixjobc(p, pgrp, 1);
439	fixjobc(p, p->p_pgrp, 0);
440
441	PGRP_LOCK(pgrp);
442	PGRP_LOCK(savepgrp);
443	PROC_LOCK(p);
444	LIST_REMOVE(p, p_pglist);
445	p->p_pgrp = pgrp;
446	PROC_UNLOCK(p);
447	LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
448	PGRP_UNLOCK(savepgrp);
449	PGRP_UNLOCK(pgrp);
450	if (LIST_EMPTY(&savepgrp->pg_members))
451		pgdelete(savepgrp);
452}
453
454/*
455 * remove process from process group
456 */
457int
458leavepgrp(p)
459	register struct proc *p;
460{
461	struct pgrp *savepgrp;
462
463	PGRPSESS_XLOCK();
464	savepgrp = p->p_pgrp;
465	PGRP_LOCK(savepgrp);
466	PROC_LOCK(p);
467	LIST_REMOVE(p, p_pglist);
468	p->p_pgrp = NULL;
469	PROC_UNLOCK(p);
470	PGRP_UNLOCK(savepgrp);
471	if (LIST_EMPTY(&savepgrp->pg_members))
472		pgdelete(savepgrp);
473	PGRPSESS_XUNLOCK();
474	return (0);
475}
476
477/*
478 * delete a process group
479 */
480static void
481pgdelete(pgrp)
482	register struct pgrp *pgrp;
483{
484	struct session *savesess;
485
486	PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
487	PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
488	SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED);
489
490	PGRP_LOCK(pgrp);
491
492	/*
493	 * Reset any sigio structures pointing to us as a result of
494	 * F_SETOWN with our pgid.
495	 */
496	funsetownlst(&pgrp->pg_sigiolst);
497
498	if (pgrp->pg_session->s_ttyp != NULL &&
499	    pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
500		pgrp->pg_session->s_ttyp->t_pgrp = NULL;
501	LIST_REMOVE(pgrp, pg_hash);
502	savesess = pgrp->pg_session;
503	SESS_LOCK(savesess);
504	savesess->s_count--;
505	SESS_UNLOCK(savesess);
506	PGRP_UNLOCK(pgrp);
507	if (savesess->s_count == 0) {
508		mtx_destroy(&savesess->s_mtx);
509		FREE(pgrp->pg_session, M_SESSION);
510	}
511	mtx_destroy(&pgrp->pg_mtx);
512	FREE(pgrp, M_PGRP);
513}
514
515/*
516 * Adjust pgrp jobc counters when specified process changes process group.
517 * We count the number of processes in each process group that "qualify"
518 * the group for terminal job control (those with a parent in a different
519 * process group of the same session).  If that count reaches zero, the
520 * process group becomes orphaned.  Check both the specified process'
521 * process group and that of its children.
522 * entering == 0 => p is leaving specified group.
523 * entering == 1 => p is entering specified group.
524 */
525void
526fixjobc(p, pgrp, entering)
527	register struct proc *p;
528	register struct pgrp *pgrp;
529	int entering;
530{
531	register struct pgrp *hispgrp;
532	register struct session *mysession;
533
534	PGRPSESS_LOCK_ASSERT(SX_LOCKED);
535	PROC_LOCK_ASSERT(p, MA_NOTOWNED);
536	PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
537	SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED);
538
539	/*
540	 * Check p's parent to see whether p qualifies its own process
541	 * group; if so, adjust count for p's process group.
542	 */
543	mysession = pgrp->pg_session;
544	sx_slock(&proctree_lock);
545	if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
546	    hispgrp->pg_session == mysession) {
547		PGRP_LOCK(pgrp);
548		if (entering)
549			pgrp->pg_jobc++;
550		else {
551			--pgrp->pg_jobc;
552			if (pgrp->pg_jobc == 0)
553				orphanpg(pgrp);
554		}
555		PGRP_UNLOCK(pgrp);
556	}
557
558	/*
559	 * Check this process' children to see whether they qualify
560	 * their process groups; if so, adjust counts for children's
561	 * process groups.
562	 */
563	LIST_FOREACH(p, &p->p_children, p_sibling) {
564		if ((hispgrp = p->p_pgrp) != pgrp &&
565		    hispgrp->pg_session == mysession &&
566		    p->p_stat != SZOMB) {
567			PGRP_LOCK(hispgrp);
568			if (entering)
569				hispgrp->pg_jobc++;
570			else {
571				--hispgrp->pg_jobc;
572				if (hispgrp->pg_jobc == 0)
573					orphanpg(hispgrp);
574			}
575			PGRP_UNLOCK(hispgrp);
576		}
577	}
578	sx_sunlock(&proctree_lock);
579}
580
581/*
582 * A process group has become orphaned;
583 * if there are any stopped processes in the group,
584 * hang-up all process in that group.
585 */
586static void
587orphanpg(pg)
588	struct pgrp *pg;
589{
590	register struct proc *p;
591
592	PGRP_LOCK_ASSERT(pg, MA_OWNED);
593
594	mtx_lock_spin(&sched_lock);
595	LIST_FOREACH(p, &pg->pg_members, p_pglist) {
596		if (p->p_stat == SSTOP) {
597			mtx_unlock_spin(&sched_lock);
598			LIST_FOREACH(p, &pg->pg_members, p_pglist) {
599				PROC_LOCK(p);
600				psignal(p, SIGHUP);
601				psignal(p, SIGCONT);
602				PROC_UNLOCK(p);
603			}
604			return;
605		}
606	}
607	mtx_unlock_spin(&sched_lock);
608}
609
610#include "opt_ddb.h"
611#ifdef DDB
612#include <ddb/ddb.h>
613
614DB_SHOW_COMMAND(pgrpdump, pgrpdump)
615{
616	register struct pgrp *pgrp;
617	register struct proc *p;
618	register int i;
619
620	for (i = 0; i <= pgrphash; i++) {
621		if (!LIST_EMPTY(&pgrphashtbl[i])) {
622			printf("\tindx %d\n", i);
623			LIST_FOREACH(pgrp, &pgrphashtbl[i], pg_hash) {
624				printf(
625			"\tpgrp %p, pgid %ld, sess %p, sesscnt %d, mem %p\n",
626				    (void *)pgrp, (long)pgrp->pg_id,
627				    (void *)pgrp->pg_session,
628				    pgrp->pg_session->s_count,
629				    (void *)LIST_FIRST(&pgrp->pg_members));
630				LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
631					printf("\t\tpid %ld addr %p pgrp %p\n",
632					    (long)p->p_pid, (void *)p,
633					    (void *)p->p_pgrp);
634				}
635			}
636		}
637	}
638}
639#endif /* DDB */
640
641/*
642 * Fill in an kinfo_proc structure for the specified process.
643 */
644void
645fill_kinfo_proc(p, kp)
646	struct proc *p;
647	struct kinfo_proc *kp;
648{
649	struct thread *td;
650	struct tty *tp;
651	struct session *sp;
652	struct timeval tv;
653
654	bzero(kp, sizeof(*kp));
655
656	kp->ki_structsize = sizeof(*kp);
657	kp->ki_paddr = p;
658	PROC_LOCK(p);
659	kp->ki_addr =/* p->p_addr; */0; /* XXXKSE */
660	kp->ki_args = p->p_args;
661	kp->ki_tracep = p->p_tracep;
662	kp->ki_textvp = p->p_textvp;
663	kp->ki_fd = p->p_fd;
664	kp->ki_vmspace = p->p_vmspace;
665	if (p->p_ucred) {
666		kp->ki_uid = p->p_ucred->cr_uid;
667		kp->ki_ruid = p->p_ucred->cr_ruid;
668		kp->ki_svuid = p->p_ucred->cr_svuid;
669		/* XXX bde doesn't like KI_NGROUPS */
670		kp->ki_ngroups = min(p->p_ucred->cr_ngroups, KI_NGROUPS);
671		bcopy(p->p_ucred->cr_groups, kp->ki_groups,
672		    kp->ki_ngroups * sizeof(gid_t));
673		kp->ki_rgid = p->p_ucred->cr_rgid;
674		kp->ki_svgid = p->p_ucred->cr_svgid;
675	}
676	if (p->p_procsig) {
677		kp->ki_sigignore = p->p_procsig->ps_sigignore;
678		kp->ki_sigcatch = p->p_procsig->ps_sigcatch;
679	}
680	mtx_lock_spin(&sched_lock);
681	if (p->p_stat != SIDL && p->p_stat != SZOMB && p->p_vmspace != NULL) {
682		struct vmspace *vm = p->p_vmspace;
683
684		kp->ki_size = vm->vm_map.size;
685		kp->ki_rssize = vmspace_resident_count(vm); /*XXX*/
686		if (p->p_sflag & PS_INMEM)
687			kp->ki_rssize += UAREA_PAGES;
688		FOREACH_THREAD_IN_PROC(p, td) /* XXXKSE: thread swapout check */
689			kp->ki_rssize += KSTACK_PAGES;
690		kp->ki_swrss = vm->vm_swrss;
691		kp->ki_tsize = vm->vm_tsize;
692		kp->ki_dsize = vm->vm_dsize;
693		kp->ki_ssize = vm->vm_ssize;
694	}
695	if ((p->p_sflag & PS_INMEM) && p->p_stats) {
696		kp->ki_start = p->p_stats->p_start;
697		kp->ki_rusage = p->p_stats->p_ru;
698		kp->ki_childtime.tv_sec = p->p_stats->p_cru.ru_utime.tv_sec +
699		    p->p_stats->p_cru.ru_stime.tv_sec;
700		kp->ki_childtime.tv_usec = p->p_stats->p_cru.ru_utime.tv_usec +
701		    p->p_stats->p_cru.ru_stime.tv_usec;
702	}
703	td = FIRST_THREAD_IN_PROC(p);
704	if (td->td_wmesg != NULL)
705		strncpy(kp->ki_wmesg, td->td_wmesg, sizeof(kp->ki_wmesg) - 1);
706	if (p->p_stat == SMTX) {
707		kp->ki_kiflag |= KI_MTXBLOCK;
708		strncpy(kp->ki_mtxname, td->td_mtxname,
709		    sizeof(kp->ki_mtxname) - 1);
710	}
711	kp->ki_stat = p->p_stat;
712	kp->ki_sflag = p->p_sflag;
713	kp->ki_swtime = p->p_swtime;
714	kp->ki_traceflag = p->p_traceflag;
715	kp->ki_pid = p->p_pid;
716	/* vvv XXXKSE */
717	bintime2timeval(&p->p_runtime, &tv);
718	kp->ki_runtime = tv.tv_sec * (u_int64_t)1000000 + tv.tv_usec;
719	kp->ki_pctcpu = p->p_kse.ke_pctcpu;
720	kp->ki_estcpu = td->td_ksegrp->kg_estcpu;
721	kp->ki_slptime = td->td_ksegrp->kg_slptime;
722	kp->ki_wchan = td->td_wchan;
723	kp->ki_pri.pri_level = td->td_priority;
724	kp->ki_pri.pri_user = td->td_ksegrp->kg_user_pri;
725	kp->ki_pri.pri_class = td->td_ksegrp->kg_pri_class;
726	kp->ki_pri.pri_native = td->td_base_pri;
727	kp->ki_nice = td->td_ksegrp->kg_nice;
728	kp->ki_rqindex = p->p_kse.ke_rqindex;
729	kp->ki_oncpu = p->p_kse.ke_oncpu;
730	kp->ki_lastcpu = td->td_lastcpu;
731	kp->ki_tdflags = td->td_flags;
732	kp->ki_pcb = td->td_pcb;
733	kp->ki_kstack = (void *)td->td_kstack;
734	/* ^^^ XXXKSE */
735	mtx_unlock_spin(&sched_lock);
736	sp = NULL;
737	tp = NULL;
738	if (p->p_pgrp) {
739		kp->ki_pgid = p->p_pgrp->pg_id;
740		kp->ki_jobc = p->p_pgrp->pg_jobc;
741		sp = p->p_pgrp->pg_session;
742
743		if (sp != NULL) {
744			kp->ki_sid = sp->s_sid;
745			SESS_LOCK(sp);
746			strncpy(kp->ki_login, sp->s_login,
747			    sizeof(kp->ki_login) - 1);
748			if (sp->s_ttyvp)
749				kp->ki_kiflag |= KI_CTTY;
750			if (SESS_LEADER(p))
751				kp->ki_kiflag |= KI_SLEADER;
752			tp = sp->s_ttyp;
753			SESS_UNLOCK(sp);
754		}
755	}
756	if ((p->p_flag & P_CONTROLT) && tp != NULL) {
757		kp->ki_tdev = dev2udev(tp->t_dev);
758		kp->ki_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
759		if (tp->t_session)
760			kp->ki_tsid = tp->t_session->s_sid;
761	} else
762		kp->ki_tdev = NOUDEV;
763	if (p->p_comm[0] != '\0') {
764		strncpy(kp->ki_comm, p->p_comm, sizeof(kp->ki_comm) - 1);
765		strncpy(kp->ki_ocomm, p->p_comm, sizeof(kp->ki_ocomm) - 1);
766	}
767	kp->ki_siglist = p->p_siglist;
768	kp->ki_sigmask = p->p_sigmask;
769	kp->ki_xstat = p->p_xstat;
770	kp->ki_acflag = p->p_acflag;
771	kp->ki_flag = p->p_flag;
772	/* If jailed(p->p_ucred), emulate the old P_JAILED flag. */
773	if (jailed(p->p_ucred))
774		kp->ki_flag |= P_JAILED;
775	kp->ki_lock = p->p_lock;
776	if (p->p_pptr)
777		kp->ki_ppid = p->p_pptr->p_pid;
778	PROC_UNLOCK(p);
779}
780
781/*
782 * Locate a zombie process by number
783 */
784struct proc *
785zpfind(pid_t pid)
786{
787	struct proc *p;
788
789	sx_slock(&allproc_lock);
790	LIST_FOREACH(p, &zombproc, p_list)
791		if (p->p_pid == pid) {
792			PROC_LOCK(p);
793			break;
794		}
795	sx_sunlock(&allproc_lock);
796	return (p);
797}
798
799
800static int
801sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb)
802{
803	struct kinfo_proc kinfo_proc;
804	int error;
805	struct proc *np;
806	pid_t pid = p->p_pid;
807
808	fill_kinfo_proc(p, &kinfo_proc);
809	error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, sizeof(kinfo_proc));
810	if (error)
811		return (error);
812	if (doingzomb)
813		np = zpfind(pid);
814	else {
815		if (pid == 0)
816			return (0);
817		np = pfind(pid);
818	}
819	if (np == NULL)
820		return EAGAIN;
821	if (np != p) {
822		PROC_UNLOCK(np);
823		return EAGAIN;
824	}
825	PROC_UNLOCK(np);
826	return (0);
827}
828
829static int
830sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
831{
832	int *name = (int*) arg1;
833	u_int namelen = arg2;
834	struct proc *p;
835	int doingzomb;
836	int error = 0;
837
838	if (oidp->oid_number == KERN_PROC_PID) {
839		if (namelen != 1)
840			return (EINVAL);
841		p = pfind((pid_t)name[0]);
842		if (!p)
843			return (0);
844		if (p_cansee(curproc, p)) {
845			PROC_UNLOCK(p);
846			return (0);
847		}
848		PROC_UNLOCK(p);
849		error = sysctl_out_proc(p, req, 0);
850		return (error);
851	}
852	if (oidp->oid_number == KERN_PROC_ALL && !namelen)
853		;
854	else if (oidp->oid_number != KERN_PROC_ALL && namelen == 1)
855		;
856	else
857		return (EINVAL);
858
859	if (!req->oldptr) {
860		/* overestimate by 5 procs */
861		error = SYSCTL_OUT(req, 0, sizeof (struct kinfo_proc) * 5);
862		if (error)
863			return (error);
864	}
865	sx_slock(&allproc_lock);
866	for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) {
867		if (!doingzomb)
868			p = LIST_FIRST(&allproc);
869		else
870			p = LIST_FIRST(&zombproc);
871		for (; p != 0; p = LIST_NEXT(p, p_list)) {
872			/*
873			 * Show a user only appropriate processes.
874			 */
875			if (p_cansee(curproc, p))
876				continue;
877			/*
878			 * Skip embryonic processes.
879			 */
880			if (p->p_stat == SIDL)
881				continue;
882			/*
883			 * TODO - make more efficient (see notes below).
884			 * do by session.
885			 */
886			switch (oidp->oid_number) {
887
888			case KERN_PROC_PGRP:
889				/* could do this by traversing pgrp */
890				PROC_LOCK(p);
891				if (p->p_pgrp == NULL ||
892				    p->p_pgrp->pg_id != (pid_t)name[0]) {
893					PROC_UNLOCK(p);
894					continue;
895				}
896				PROC_UNLOCK(p);
897				break;
898
899			case KERN_PROC_TTY:
900				PROC_LOCK(p);
901				if ((p->p_flag & P_CONTROLT) == 0 ||
902				    p->p_session == NULL) {
903					PROC_UNLOCK(p);
904					continue;
905				}
906				SESS_LOCK(p->p_session);
907				if (p->p_session->s_ttyp == NULL ||
908				    dev2udev(p->p_session->s_ttyp->t_dev) !=
909				    (udev_t)name[0]) {
910					SESS_UNLOCK(p->p_session);
911					PROC_UNLOCK(p);
912					continue;
913				}
914				SESS_UNLOCK(p->p_session);
915				PROC_UNLOCK(p);
916				break;
917
918			case KERN_PROC_UID:
919				if (p->p_ucred == NULL ||
920				    p->p_ucred->cr_uid != (uid_t)name[0])
921					continue;
922				break;
923
924			case KERN_PROC_RUID:
925				if (p->p_ucred == NULL ||
926				    p->p_ucred->cr_ruid != (uid_t)name[0])
927					continue;
928				break;
929			}
930
931			if (p_cansee(curproc, p))
932				continue;
933
934			error = sysctl_out_proc(p, req, doingzomb);
935			if (error) {
936				sx_sunlock(&allproc_lock);
937				return (error);
938			}
939		}
940	}
941	sx_sunlock(&allproc_lock);
942	return (0);
943}
944
945/*
946 * This sysctl allows a process to retrieve the argument list or process
947 * title for another process without groping around in the address space
948 * of the other process.  It also allow a process to set its own "process
949 * title to a string of its own choice.
950 */
951static int
952sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS)
953{
954	int *name = (int*) arg1;
955	u_int namelen = arg2;
956	struct proc *p;
957	struct pargs *pa;
958	int error = 0;
959
960	if (namelen != 1)
961		return (EINVAL);
962
963	p = pfind((pid_t)name[0]);
964	if (!p)
965		return (0);
966
967	if ((!ps_argsopen) && p_cansee(curproc, p)) {
968		PROC_UNLOCK(p);
969		return (0);
970	}
971	PROC_UNLOCK(p);
972
973	if (req->newptr && curproc != p)
974		return (EPERM);
975
976	if (req->oldptr && p->p_args != NULL)
977		error = SYSCTL_OUT(req, p->p_args->ar_args, p->p_args->ar_length);
978	if (req->newptr == NULL)
979		return (error);
980
981	PROC_LOCK(p);
982	pa = p->p_args;
983	p->p_args = NULL;
984	PROC_UNLOCK(p);
985	if (pa != NULL && --pa->ar_ref == 0)
986		FREE(pa, M_PARGS);
987
988	if (req->newlen + sizeof(struct pargs) > ps_arg_cache_limit)
989		return (error);
990
991	MALLOC(pa, struct pargs *, sizeof(struct pargs) + req->newlen,
992	    M_PARGS, M_WAITOK);
993	pa->ar_ref = 1;
994	pa->ar_length = req->newlen;
995	error = SYSCTL_IN(req, pa->ar_args, req->newlen);
996	if (!error) {
997		PROC_LOCK(p);
998		p->p_args = pa;
999		PROC_UNLOCK(p);
1000	} else
1001		FREE(pa, M_PARGS);
1002	return (error);
1003}
1004
1005SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD,  0, "Process table");
1006
1007SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT,
1008	0, 0, sysctl_kern_proc, "S,proc", "Return entire process table");
1009
1010SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, CTLFLAG_RD,
1011	sysctl_kern_proc, "Process table");
1012
1013SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD,
1014	sysctl_kern_proc, "Process table");
1015
1016SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD,
1017	sysctl_kern_proc, "Process table");
1018
1019SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD,
1020	sysctl_kern_proc, "Process table");
1021
1022SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD,
1023	sysctl_kern_proc, "Process table");
1024
1025SYSCTL_NODE(_kern_proc, KERN_PROC_ARGS, args, CTLFLAG_RW | CTLFLAG_ANYBODY,
1026	sysctl_kern_proc_args, "Process argument list");
1027