| 807 | |
| 808 | |
| 809 | static void |
| 810 | fixjobc_kill(struct proc *p) |
| 811 | { |
| 812 | struct proc *q; |
| 813 | struct pgrp *pgrp; |
| 814 | |
| 815 | sx_assert(&proctree_lock, SX_LOCKED); |
| 816 | PROC_LOCK_ASSERT(p, MA_NOTOWNED); |
| 817 | pgrp = p->p_pgrp; |
| 818 | PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); |
| 819 | SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED); |
| 820 | |
| 821 | /* |
| 822 | * p no longer affects process group orphanage for children. |
| 823 | * It is marked by the flag because p is only physically |
| 824 | * removed from its process group on wait(2). |
| 825 | */ |
| 826 | MPASS((p->p_treeflag & P_TREE_GRPEXITED) == 0); |
| 827 | p->p_treeflag |= P_TREE_GRPEXITED; |
| 828 | |
| 829 | /* |
| 830 | * Check if exiting p orphans its own group. |
| 831 | */ |
| 832 | pgrp = p->p_pgrp; |
| 833 | if (isjobproc(jobc_parent(p, NULL), pgrp)) { |
| 834 | PGRP_LOCK(pgrp); |
| 835 | if (pgrp_calc_jobc(pgrp) == 0) |
| 836 | orphanpg(pgrp); |
| 837 | PGRP_UNLOCK(pgrp); |
| 838 | } |
| 839 | |
| 840 | /* |
| 841 | * Check this process' children to see whether they qualify |
| 842 | * their process groups after reparenting to reaper. |
| 843 | */ |
| 844 | LIST_FOREACH(q, &p->p_children, p_sibling) { |
| 845 | pgrp = q->p_pgrp; |
| 846 | PGRP_LOCK(pgrp); |
| 847 | if (pgrp_calc_jobc(pgrp) == 0) { |
| 848 | /* |
| 849 | * We want to handle exactly the children that |
| 850 | * has p as realparent. Then, when calculating |
| 851 | * jobc_parent for children, we should ignore |
| 852 | * P_TREE_GRPEXITED flag already set on p. |
| 853 | */ |
| 854 | if (jobc_parent(q, p) == p && isjobproc(p, pgrp)) |
| 855 | orphanpg(pgrp); |
| 856 | } else |
| 857 | pgrp->pg_flags &= ~PGRP_ORPHANED; |
| 858 | PGRP_UNLOCK(pgrp); |
| 859 | } |
| 860 | LIST_FOREACH(q, &p->p_orphans, p_orphan) { |
| 861 | pgrp = q->p_pgrp; |
| 862 | PGRP_LOCK(pgrp); |
| 863 | if (pgrp_calc_jobc(pgrp) == 0) { |
| 864 | if (isjobproc(p, pgrp)) |
| 865 | orphanpg(pgrp); |
| 866 | } else |
no test coverage detected