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 --- 17 unchanged lines hidden (view full) --- 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 91140 2002-02-23 11:12:57Z tanimura $ |
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> --- 7 unchanged lines hidden (view full) --- 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/vm_zone.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 __P((register pid_t)); 64 65static void doenterpgrp __P((struct proc *, struct pgrp *)); 66 |
67static void pgdelete __P((struct pgrp *)); 68 |
69static void orphanpg __P((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; |
83vm_zone_t proc_zone; 84vm_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 = zinit("PROC", sizeof (struct proc), 0, 0, 5); 102 uihashinit(); 103 /* 104 * This should really be a compile time warning, but I do --- 161 unchanged lines hidden (view full) --- 266 */ 267struct proc * 268pfind(pid) 269 register pid_t pid; 270{ 271 register struct proc *p; 272 273 sx_slock(&allproc_lock); |
274 p = dopfind(pid); 275 sx_sunlock(&allproc_lock); 276 return (p); 277} 278 279static struct proc * 280dopfind(pid) 281 register pid_t pid; 282{ 283 register struct proc *p; 284 285 sx_assert(&allproc_lock, SX_LOCKED); 286 |
287 LIST_FOREACH(p, PIDHASH(pid), p_hash) 288 if (p->p_pid == pid) { 289 PROC_LOCK(p); 290 break; 291 } |
292 return (p); 293} 294 295/* |
296 * Locate a process group by number. 297 * The caller must hold pgrpsess_lock. |
298 */ 299struct pgrp * 300pgfind(pgid) 301 register pid_t pgid; 302{ 303 register struct pgrp *pgrp; 304 |
305 PGRPSESS_LOCK_ASSERT(SX_LOCKED); 306 307 LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash) { 308 if (pgrp->pg_id == pgid) { 309 PGRP_LOCK(pgrp); |
310 return (pgrp); |
311 } 312 } |
313 return (NULL); 314} 315 316/* |
317 * Create a new process group. 318 * pgid must be equal to the pid of p. 319 * Begin a new session if required. |
320 */ 321int |
322enterpgrp(p, pgid, pgrp, sess) |
323 register struct proc *p; 324 pid_t pgid; |
325 struct pgrp *pgrp; 326 struct session *sess; |
327{ |
328 struct pgrp *pgrp2; |
329 |
330 PGRPSESS_LOCK_ASSERT(SX_XLOCKED); 331 332 KASSERT(pgrp != NULL, ("enterpgrp: pgrp == NULL")); 333 KASSERT(p->p_pid == pgid, 334 ("enterpgrp: new pgrp and pid != pgid")); 335 336 pgrp2 = pgfind(pgid); 337 338 KASSERT(pgrp2 == NULL, 339 ("enterpgrp: pgrp with pgid exists")); |
340 KASSERT(!SESS_LEADER(p), 341 ("enterpgrp: session leader attempted setpgrp")); 342 |
343 mtx_init(&pgrp->pg_mtx, "process group", MTX_DEF); 344 345 if (sess != NULL) { |
346 /* |
347 * new session |
348 */ |
349 mtx_init(&sess->s_mtx, "session", MTX_DEF); 350 PROC_LOCK(p); 351 p->p_flag &= ~P_CONTROLT; 352 PROC_UNLOCK(p); 353 PGRP_LOCK(pgrp); 354 sess->s_leader = p; 355 sess->s_sid = p->p_pid; 356 sess->s_count = 1; 357 sess->s_ttyvp = NULL; 358 sess->s_ttyp = NULL; 359 bcopy(p->p_session->s_login, sess->s_login, |
360 sizeof(sess->s_login)); |
361 pgrp->pg_session = sess; 362 KASSERT(p == curproc, 363 ("enterpgrp: mksession and p != curproc")); 364 } else { 365 pgrp->pg_session = p->p_session; 366 SESS_LOCK(pgrp->pg_session); 367 pgrp->pg_session->s_count++; 368 SESS_UNLOCK(pgrp->pg_session); 369 PGRP_LOCK(pgrp); 370 } 371 pgrp->pg_id = pgid; 372 LIST_INIT(&pgrp->pg_members); |
373 374 /* |
375 * As we have an exclusive lock of pgrpsess_lock, 376 * this should not deadlock. 377 */ 378 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash); 379 pgrp->pg_jobc = 0; 380 SLIST_INIT(&pgrp->pg_sigiolst); 381 PGRP_UNLOCK(pgrp); 382 383 doenterpgrp(p, pgrp); 384 385 return (0); 386} 387 388/* 389 * Move p to an existing process group 390 */ 391int 392enterthispgrp(p, pgrp) 393 register struct proc *p; 394 struct pgrp *pgrp; 395{ 396 PGRPSESS_LOCK_ASSERT(SX_XLOCKED); 397 PROC_LOCK_ASSERT(p, MA_NOTOWNED); 398 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); 399 PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED); 400 SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED); 401 KASSERT(pgrp->pg_session == p->p_session, 402 ("%s: pgrp's session %p, p->p_session %p.\n", 403 __func__, 404 pgrp->pg_session, 405 p->p_session)); 406 KASSERT(pgrp != p->p_pgrp, 407 ("%s: p belongs to pgrp.", __func__)); 408 409 doenterpgrp(p, pgrp); 410 411 return (0); 412} 413 414/* 415 * Move p to a process group 416 */ 417static void 418doenterpgrp(p, pgrp) 419 struct proc *p; 420 struct pgrp *pgrp; 421{ 422 struct pgrp *savepgrp; 423 424 PGRPSESS_LOCK_ASSERT(SX_XLOCKED); 425 PROC_LOCK_ASSERT(p, MA_NOTOWNED); 426 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); 427 PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED); 428 SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED); 429 430 savepgrp = p->p_pgrp; 431 432 /* |
433 * Adjust eligibility of affected pgrps to participate in job control. 434 * Increment eligibility counts before decrementing, otherwise we 435 * could reach 0 spuriously during the first call. 436 */ 437 fixjobc(p, pgrp, 1); 438 fixjobc(p, p->p_pgrp, 0); 439 |
440 PGRP_LOCK(pgrp); 441 PGRP_LOCK(savepgrp); |
442 PROC_LOCK(p); 443 LIST_REMOVE(p, p_pglist); |
444 p->p_pgrp = pgrp; |
445 PROC_UNLOCK(p); |
446 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist); 447 PGRP_UNLOCK(savepgrp); 448 PGRP_UNLOCK(pgrp); 449 if (LIST_EMPTY(&savepgrp->pg_members)) 450 pgdelete(savepgrp); |
451} 452 453/* 454 * remove process from process group 455 */ 456int 457leavepgrp(p) 458 register struct proc *p; 459{ |
460 struct pgrp *savepgrp; |
461 |
462 PGRPSESS_XLOCK(); 463 savepgrp = p->p_pgrp; 464 PGRP_LOCK(savepgrp); |
465 PROC_LOCK(p); 466 LIST_REMOVE(p, p_pglist); |
467 p->p_pgrp = NULL; 468 PROC_UNLOCK(p); |
469 PGRP_UNLOCK(savepgrp); 470 if (LIST_EMPTY(&savepgrp->pg_members)) 471 pgdelete(savepgrp); 472 PGRPSESS_XUNLOCK(); |
473 return (0); 474} 475 476/* 477 * delete a process group 478 */ 479static void 480pgdelete(pgrp) 481 register struct pgrp *pgrp; 482{ |
483 struct session *savesess; |
484 |
485 PGRPSESS_LOCK_ASSERT(SX_XLOCKED); 486 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); 487 SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED); 488 489 PGRP_LOCK(pgrp); 490 |
491 /* 492 * Reset any sigio structures pointing to us as a result of 493 * F_SETOWN with our pgid. 494 */ 495 funsetownlst(&pgrp->pg_sigiolst); 496 497 if (pgrp->pg_session->s_ttyp != NULL && 498 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 499 pgrp->pg_session->s_ttyp->t_pgrp = NULL; 500 LIST_REMOVE(pgrp, pg_hash); |
501 savesess = pgrp->pg_session; 502 SESS_LOCK(savesess); 503 savesess->s_count--; 504 SESS_UNLOCK(savesess); 505 PGRP_UNLOCK(pgrp); 506 if (savesess->s_count == 0) { 507 mtx_destroy(&savesess->s_mtx); |
508 FREE(pgrp->pg_session, M_SESSION); |
509 } 510 mtx_destroy(&pgrp->pg_mtx); |
511 FREE(pgrp, M_PGRP); 512} 513 514/* 515 * Adjust pgrp jobc counters when specified process changes process group. 516 * We count the number of processes in each process group that "qualify" 517 * the group for terminal job control (those with a parent in a different 518 * process group of the same session). If that count reaches zero, the --- 4 unchanged lines hidden (view full) --- 523 */ 524void 525fixjobc(p, pgrp, entering) 526 register struct proc *p; 527 register struct pgrp *pgrp; 528 int entering; 529{ 530 register struct pgrp *hispgrp; |
531 register struct session *mysession; |
532 |
533 PGRPSESS_LOCK_ASSERT(SX_LOCKED); 534 PROC_LOCK_ASSERT(p, MA_NOTOWNED); 535 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); 536 SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED); 537 |
538 /* 539 * Check p's parent to see whether p qualifies its own process 540 * group; if so, adjust count for p's process group. 541 */ |
542 mysession = pgrp->pg_session; |
543 sx_slock(&proctree_lock); 544 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && 545 hispgrp->pg_session == mysession) { |
546 PGRP_LOCK(pgrp); |
547 if (entering) 548 pgrp->pg_jobc++; |
549 else { 550 --pgrp->pg_jobc; 551 if (pgrp->pg_jobc == 0) 552 orphanpg(pgrp); 553 } 554 PGRP_UNLOCK(pgrp); |
555 } 556 557 /* 558 * Check this process' children to see whether they qualify 559 * their process groups; if so, adjust counts for children's 560 * process groups. 561 */ |
562 LIST_FOREACH(p, &p->p_children, p_sibling) { |
563 if ((hispgrp = p->p_pgrp) != pgrp && 564 hispgrp->pg_session == mysession && 565 p->p_stat != SZOMB) { |
566 PGRP_LOCK(hispgrp); |
567 if (entering) 568 hispgrp->pg_jobc++; |
569 else { 570 --hispgrp->pg_jobc; 571 if (hispgrp->pg_jobc == 0) 572 orphanpg(hispgrp); 573 } 574 PGRP_UNLOCK(hispgrp); |
575 } |
576 } |
577 sx_sunlock(&proctree_lock); 578} 579 580/* 581 * A process group has become orphaned; 582 * if there are any stopped processes in the group, 583 * hang-up all process in that group. 584 */ 585static void 586orphanpg(pg) 587 struct pgrp *pg; 588{ 589 register struct proc *p; 590 |
591 PGRP_LOCK_ASSERT(pg, MA_OWNED); 592 |
593 mtx_lock_spin(&sched_lock); 594 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 595 if (p->p_stat == SSTOP) { 596 mtx_unlock_spin(&sched_lock); 597 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 598 PROC_LOCK(p); 599 psignal(p, SIGHUP); 600 psignal(p, SIGCONT); --- 127 unchanged lines hidden (view full) --- 728 kp->ki_oncpu = p->p_kse.ke_oncpu; 729 kp->ki_lastcpu = td->td_lastcpu; 730 kp->ki_tdflags = td->td_flags; 731 kp->ki_pcb = td->td_pcb; 732 kp->ki_kstack = (void *)td->td_kstack; 733 /* ^^^ XXXKSE */ 734 mtx_unlock_spin(&sched_lock); 735 sp = NULL; |
736 tp = NULL; |
737 if (p->p_pgrp) { 738 kp->ki_pgid = p->p_pgrp->pg_id; 739 kp->ki_jobc = p->p_pgrp->pg_jobc; 740 sp = p->p_pgrp->pg_session; 741 742 if (sp != NULL) { 743 kp->ki_sid = sp->s_sid; |
744 SESS_LOCK(sp); |
745 strncpy(kp->ki_login, sp->s_login, 746 sizeof(kp->ki_login) - 1); 747 if (sp->s_ttyvp) 748 kp->ki_kiflag |= KI_CTTY; 749 if (SESS_LEADER(p)) 750 kp->ki_kiflag |= KI_SLEADER; |
751 tp = sp->s_ttyp; 752 SESS_UNLOCK(sp); |
753 } 754 } |
755 if ((p->p_flag & P_CONTROLT) && tp != NULL) { |
756 kp->ki_tdev = dev2udev(tp->t_dev); 757 kp->ki_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 758 if (tp->t_session) 759 kp->ki_tsid = tp->t_session->s_sid; 760 } else 761 kp->ki_tdev = NOUDEV; 762 if (p->p_comm[0] != '\0') { 763 strncpy(kp->ki_comm, p->p_comm, sizeof(kp->ki_comm) - 1); --- 117 unchanged lines hidden (view full) --- 881 /* 882 * TODO - make more efficient (see notes below). 883 * do by session. 884 */ 885 switch (oidp->oid_number) { 886 887 case KERN_PROC_PGRP: 888 /* could do this by traversing pgrp */ |
889 PROC_LOCK(p); |
890 if (p->p_pgrp == NULL || |
891 p->p_pgrp->pg_id != (pid_t)name[0]) { 892 PROC_UNLOCK(p); |
893 continue; |
894 } 895 PROC_UNLOCK(p); |
896 break; 897 898 case KERN_PROC_TTY: |
899 PROC_LOCK(p); |
900 if ((p->p_flag & P_CONTROLT) == 0 || |
901 p->p_session == NULL) { 902 PROC_UNLOCK(p); 903 continue; 904 } 905 SESS_LOCK(p->p_session); 906 if (p->p_session->s_ttyp == NULL || |
907 dev2udev(p->p_session->s_ttyp->t_dev) != |
908 (udev_t)name[0]) { 909 SESS_UNLOCK(p->p_session); 910 PROC_UNLOCK(p); |
911 continue; |
912 } 913 SESS_UNLOCK(p->p_session); 914 PROC_UNLOCK(p); |
915 break; 916 917 case KERN_PROC_UID: 918 if (p->p_ucred == NULL || 919 p->p_ucred->cr_uid != (uid_t)name[0]) 920 continue; 921 break; 922 --- 103 unchanged lines hidden --- |