10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 52712Snn35248 * Common Development and Distribution License (the "License"). 62712Snn35248 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*6618Srh87107 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 270Sstevel@tonic-gate /* All Rights Reserved */ 280Sstevel@tonic-gate 290Sstevel@tonic-gate 300Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 1.25 */ 310Sstevel@tonic-gate 320Sstevel@tonic-gate #include <sys/types.h> 330Sstevel@tonic-gate #include <sys/sysmacros.h> 340Sstevel@tonic-gate #include <sys/param.h> 350Sstevel@tonic-gate #include <sys/systm.h> 360Sstevel@tonic-gate #include <sys/vfs.h> 370Sstevel@tonic-gate #include <sys/cred.h> 380Sstevel@tonic-gate #include <sys/vnode.h> 390Sstevel@tonic-gate #include <sys/file.h> 400Sstevel@tonic-gate #include <sys/errno.h> 410Sstevel@tonic-gate #include <sys/kmem.h> 420Sstevel@tonic-gate #include <sys/user.h> 430Sstevel@tonic-gate #include <sys/buf.h> 440Sstevel@tonic-gate #include <sys/var.h> 450Sstevel@tonic-gate #include <sys/conf.h> 460Sstevel@tonic-gate #include <sys/debug.h> 470Sstevel@tonic-gate #include <sys/proc.h> 480Sstevel@tonic-gate #include <sys/signal.h> 490Sstevel@tonic-gate #include <sys/siginfo.h> 500Sstevel@tonic-gate #include <sys/acct.h> 510Sstevel@tonic-gate #include <sys/procset.h> 520Sstevel@tonic-gate #include <sys/cmn_err.h> 530Sstevel@tonic-gate #include <sys/fault.h> 540Sstevel@tonic-gate #include <sys/syscall.h> 550Sstevel@tonic-gate #include <sys/ucontext.h> 560Sstevel@tonic-gate #include <sys/procfs.h> 570Sstevel@tonic-gate #include <sys/session.h> 580Sstevel@tonic-gate #include <sys/task.h> 590Sstevel@tonic-gate #include <sys/project.h> 600Sstevel@tonic-gate #include <sys/pool.h> 610Sstevel@tonic-gate #include <sys/zone.h> 620Sstevel@tonic-gate #include <sys/contract/process_impl.h> 630Sstevel@tonic-gate 640Sstevel@tonic-gate id_t getmyid(idtype_t); 650Sstevel@tonic-gate int checkprocset(procset_t *); 660Sstevel@tonic-gate static kthread_t *getlwpptr(id_t); 670Sstevel@tonic-gate int procinset(proc_t *, procset_t *); 680Sstevel@tonic-gate static int lwpinset(proc_t *, procset_t *, kthread_t *, int *); 690Sstevel@tonic-gate 700Sstevel@tonic-gate /* 710Sstevel@tonic-gate * The dotoprocs function locates the process(es) specified 724253Sjimp * by the procset structure pointed to by psp. funcp points to a 734253Sjimp * function which dotoprocs will call for each process in the 744253Sjimp * specified set. The arguments to this function will be a pointer 754253Sjimp * to the current process from the set and arg. 760Sstevel@tonic-gate * If the called function returns -1, it means that processing of the 770Sstevel@tonic-gate * procset should stop and a normal (non-error) return should be made 780Sstevel@tonic-gate * to the caller of dotoprocs. 790Sstevel@tonic-gate * If the called function returns any other non-zero value the search 800Sstevel@tonic-gate * is terminated and the function's return value is returned to 810Sstevel@tonic-gate * the caller of dotoprocs. This will normally be an error code. 820Sstevel@tonic-gate * Otherwise, dotoprocs will return zero after processing the entire 830Sstevel@tonic-gate * process set unless no processes were found in which case ESRCH will 840Sstevel@tonic-gate * be returned. 850Sstevel@tonic-gate */ 860Sstevel@tonic-gate int 870Sstevel@tonic-gate dotoprocs(procset_t *psp, int (*funcp)(), char *arg) 880Sstevel@tonic-gate { 890Sstevel@tonic-gate proc_t *prp; /* A process from the set */ 900Sstevel@tonic-gate int error; 910Sstevel@tonic-gate int nfound; /* Nbr of processes found. */ 920Sstevel@tonic-gate proc_t *lastprp; /* Last proc found. */ 930Sstevel@tonic-gate 944253Sjimp ASSERT(funcp != NULL); 954253Sjimp 960Sstevel@tonic-gate /* 970Sstevel@tonic-gate * Check that the procset_t is valid. 980Sstevel@tonic-gate */ 990Sstevel@tonic-gate error = checkprocset(psp); 1000Sstevel@tonic-gate if (error) { 1010Sstevel@tonic-gate return (error); 1020Sstevel@tonic-gate } 1030Sstevel@tonic-gate /* 1040Sstevel@tonic-gate * Check for the special value P_MYID in either operand 1050Sstevel@tonic-gate * and replace it with the correct value. We don't check 1060Sstevel@tonic-gate * for an error return from getmyid() because the idtypes 1070Sstevel@tonic-gate * have been validated by the checkprocset() call above. 1080Sstevel@tonic-gate */ 1090Sstevel@tonic-gate mutex_enter(&pidlock); 1100Sstevel@tonic-gate if (psp->p_lid == P_MYID) { 1110Sstevel@tonic-gate psp->p_lid = getmyid(psp->p_lidtype); 1120Sstevel@tonic-gate } 1130Sstevel@tonic-gate if (psp->p_rid == P_MYID) { 1140Sstevel@tonic-gate psp->p_rid = getmyid(psp->p_ridtype); 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate /* 1180Sstevel@tonic-gate * If psp only acts on a single proc, we can reduce pidlock hold time 1190Sstevel@tonic-gate * by avoiding a needless scan of the entire proc list. Although 1200Sstevel@tonic-gate * there are many procset_t combinations which might boil down to a 1210Sstevel@tonic-gate * single proc, the most common case is an AND operation where one 1220Sstevel@tonic-gate * side is a specific pid, and the other side is P_ALL, so that is 1230Sstevel@tonic-gate * the case for which we will provide a fast path. Other cases could 1240Sstevel@tonic-gate * be added in a similar fashion if they were to become significant 1250Sstevel@tonic-gate * pidlock bottlenecks. 1260Sstevel@tonic-gate * 1270Sstevel@tonic-gate * Perform the check symmetrically: either the left or right side may 1280Sstevel@tonic-gate * specify a pid, with the opposite side being 'all'. 1290Sstevel@tonic-gate */ 1300Sstevel@tonic-gate if (psp->p_op == POP_AND) { 1310Sstevel@tonic-gate if (((psp->p_lidtype == P_PID) && (psp->p_ridtype == P_ALL)) || 1320Sstevel@tonic-gate ((psp->p_ridtype == P_PID) && (psp->p_lidtype == P_ALL))) { 1330Sstevel@tonic-gate id_t pid; 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate pid = (psp->p_lidtype == P_PID) ? 1360Sstevel@tonic-gate psp->p_lid : psp->p_rid; 1374253Sjimp if (((prp = prfind((pid_t)pid)) == NULL) || 1384253Sjimp (prp->p_stat == SIDL || prp->p_stat == SZOMB || 1394253Sjimp prp->p_tlist == NULL || prp->p_flag & SSYS)) { 1404253Sjimp /* 1414253Sjimp * Specified proc doesn't exist or should 1424253Sjimp * not be operated on. 1434253Sjimp * Don't need to make HASZONEACCESS check 1444253Sjimp * here since prfind() takes care of that. 1454253Sjimp */ 1460Sstevel@tonic-gate mutex_exit(&pidlock); 1470Sstevel@tonic-gate return (ESRCH); 1480Sstevel@tonic-gate } 1494253Sjimp /* 1504253Sjimp * Operate only on the specified proc. It's okay 1514253Sjimp * if it's init. 1524253Sjimp */ 1530Sstevel@tonic-gate error = (*funcp)(prp, arg); 1540Sstevel@tonic-gate mutex_exit(&pidlock); 1550Sstevel@tonic-gate if (error == -1) 1560Sstevel@tonic-gate error = 0; 1570Sstevel@tonic-gate return (error); 1580Sstevel@tonic-gate } 1590Sstevel@tonic-gate } 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate nfound = 0; 1620Sstevel@tonic-gate error = 0; 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate for (prp = practive; prp != NULL; prp = prp->p_next) { 1650Sstevel@tonic-gate /* 1660Sstevel@tonic-gate * If caller is in a non-global zone, skip processes 1670Sstevel@tonic-gate * in other zones. 1680Sstevel@tonic-gate */ 1690Sstevel@tonic-gate if (!HASZONEACCESS(curproc, prp->p_zone->zone_id)) 1700Sstevel@tonic-gate continue; 171*6618Srh87107 172*6618Srh87107 /* 173*6618Srh87107 * Ignore this process if it's coming or going, 174*6618Srh87107 * if it's a system process or if it's not in 175*6618Srh87107 * the given procset_t. 176*6618Srh87107 */ 177*6618Srh87107 if (prp->p_stat == SIDL || prp->p_stat == SZOMB) 1780Sstevel@tonic-gate continue; 179*6618Srh87107 180*6618Srh87107 mutex_enter(&prp->p_lock); 181*6618Srh87107 if (prp->p_flag & SSYS || procinset(prp, psp) == 0) { 182*6618Srh87107 mutex_exit(&prp->p_lock); 183*6618Srh87107 } else { 184*6618Srh87107 mutex_exit(&prp->p_lock); 1850Sstevel@tonic-gate nfound++; 1860Sstevel@tonic-gate lastprp = prp; 1874253Sjimp if (prp != proc_init) { 1880Sstevel@tonic-gate error = (*funcp)(prp, arg); 1890Sstevel@tonic-gate if (error == -1) { 1900Sstevel@tonic-gate mutex_exit(&pidlock); 1910Sstevel@tonic-gate return (0); 1920Sstevel@tonic-gate } else if (error) { 1930Sstevel@tonic-gate mutex_exit(&pidlock); 1940Sstevel@tonic-gate return (error); 1950Sstevel@tonic-gate } 1960Sstevel@tonic-gate } 1970Sstevel@tonic-gate } 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate if (nfound == 0) { 2000Sstevel@tonic-gate mutex_exit(&pidlock); 2010Sstevel@tonic-gate return (ESRCH); 2020Sstevel@tonic-gate } 2034253Sjimp if (nfound == 1 && lastprp == proc_init) 2040Sstevel@tonic-gate error = (*funcp)(lastprp, arg); 2050Sstevel@tonic-gate if (error == -1) 2060Sstevel@tonic-gate error = 0; 2070Sstevel@tonic-gate mutex_exit(&pidlock); 2080Sstevel@tonic-gate return (error); 2090Sstevel@tonic-gate } 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate /* 2120Sstevel@tonic-gate * Check if a procset_t is valid. Return zero or an errno. 2130Sstevel@tonic-gate */ 2140Sstevel@tonic-gate int 2150Sstevel@tonic-gate checkprocset(procset_t *psp) 2160Sstevel@tonic-gate { 2170Sstevel@tonic-gate switch (psp->p_lidtype) { 2180Sstevel@tonic-gate case P_LWPID: 2190Sstevel@tonic-gate case P_PID: 2200Sstevel@tonic-gate case P_PPID: 2210Sstevel@tonic-gate case P_PGID: 2220Sstevel@tonic-gate case P_SID: 2230Sstevel@tonic-gate case P_TASKID: 2240Sstevel@tonic-gate case P_CID: 2250Sstevel@tonic-gate case P_UID: 2260Sstevel@tonic-gate case P_GID: 2270Sstevel@tonic-gate case P_PROJID: 2280Sstevel@tonic-gate case P_POOLID: 2290Sstevel@tonic-gate case P_ZONEID: 2300Sstevel@tonic-gate case P_CTID: 2310Sstevel@tonic-gate case P_ALL: 2320Sstevel@tonic-gate break; 2330Sstevel@tonic-gate default: 2340Sstevel@tonic-gate return (EINVAL); 2350Sstevel@tonic-gate } 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate switch (psp->p_ridtype) { 2380Sstevel@tonic-gate case P_LWPID: 2390Sstevel@tonic-gate case P_PID: 2400Sstevel@tonic-gate case P_PPID: 2410Sstevel@tonic-gate case P_PGID: 2420Sstevel@tonic-gate case P_SID: 2430Sstevel@tonic-gate case P_TASKID: 2440Sstevel@tonic-gate case P_CID: 2450Sstevel@tonic-gate case P_UID: 2460Sstevel@tonic-gate case P_GID: 2470Sstevel@tonic-gate case P_PROJID: 2480Sstevel@tonic-gate case P_POOLID: 2490Sstevel@tonic-gate case P_ZONEID: 2500Sstevel@tonic-gate case P_CTID: 2510Sstevel@tonic-gate case P_ALL: 2520Sstevel@tonic-gate break; 2530Sstevel@tonic-gate default: 2540Sstevel@tonic-gate return (EINVAL); 2550Sstevel@tonic-gate } 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate switch (psp->p_op) { 2580Sstevel@tonic-gate case POP_DIFF: 2590Sstevel@tonic-gate case POP_AND: 2600Sstevel@tonic-gate case POP_OR: 2610Sstevel@tonic-gate case POP_XOR: 2620Sstevel@tonic-gate break; 2630Sstevel@tonic-gate default: 2640Sstevel@tonic-gate return (EINVAL); 2650Sstevel@tonic-gate } 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate return (0); 2680Sstevel@tonic-gate } 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate /* 271*6618Srh87107 * procinset returns 1 if the process pointed to by pp is in the process 272*6618Srh87107 * set specified by psp, otherwise 0 is returned. A process that is 273*6618Srh87107 * exiting, by which we mean that its p_tlist is NULL, cannot belong 274*6618Srh87107 * to any set; pp's p_lock must be held across the call to this function. 275*6618Srh87107 * The caller should ensure that the process does not belong to the SYS 276*6618Srh87107 * scheduling class. 2770Sstevel@tonic-gate * 2780Sstevel@tonic-gate * This function expects to be called with a valid procset_t. 2790Sstevel@tonic-gate * The set should be checked using checkprocset() before calling 2800Sstevel@tonic-gate * this function. 2810Sstevel@tonic-gate */ 2820Sstevel@tonic-gate int 2830Sstevel@tonic-gate procinset(proc_t *pp, procset_t *psp) 2840Sstevel@tonic-gate { 2850Sstevel@tonic-gate int loperand = 0; 2860Sstevel@tonic-gate int roperand = 0; 2870Sstevel@tonic-gate int lwplinproc = 0; 2880Sstevel@tonic-gate int lwprinproc = 0; 2890Sstevel@tonic-gate kthread_t *tp = proctot(pp); 2900Sstevel@tonic-gate 291*6618Srh87107 ASSERT(MUTEX_HELD(&pp->p_lock)); 292*6618Srh87107 293*6618Srh87107 if (tp == NULL) 294*6618Srh87107 return (0); 295*6618Srh87107 2960Sstevel@tonic-gate switch (psp->p_lidtype) { 2970Sstevel@tonic-gate 2980Sstevel@tonic-gate case P_LWPID: 2990Sstevel@tonic-gate if (pp == ttoproc(curthread)) 3000Sstevel@tonic-gate if (getlwpptr(psp->p_lid) != NULL) 3010Sstevel@tonic-gate lwplinproc++; 3020Sstevel@tonic-gate break; 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate case P_PID: 3050Sstevel@tonic-gate if (pp->p_pid == psp->p_lid) 3060Sstevel@tonic-gate loperand++; 3070Sstevel@tonic-gate break; 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate case P_PPID: 3100Sstevel@tonic-gate if (pp->p_ppid == psp->p_lid) 3110Sstevel@tonic-gate loperand++; 3120Sstevel@tonic-gate break; 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate case P_PGID: 3150Sstevel@tonic-gate if (pp->p_pgrp == psp->p_lid) 3160Sstevel@tonic-gate loperand++; 3170Sstevel@tonic-gate break; 3180Sstevel@tonic-gate 3190Sstevel@tonic-gate case P_SID: 3202712Snn35248 mutex_enter(&pp->p_splock); 3210Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_lid) 3220Sstevel@tonic-gate loperand++; 3232712Snn35248 mutex_exit(&pp->p_splock); 3240Sstevel@tonic-gate break; 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate case P_CID: 3270Sstevel@tonic-gate ASSERT(tp != NULL); 3280Sstevel@tonic-gate /* This case is broken for now. Need to be fixed XXX */ 3290Sstevel@tonic-gate if (tp->t_cid == psp->p_lid) 3300Sstevel@tonic-gate /* 3310Sstevel@tonic-gate * if (checkcid(psp->p_lid)) 3320Sstevel@tonic-gate */ 3330Sstevel@tonic-gate loperand++; 3340Sstevel@tonic-gate break; 3350Sstevel@tonic-gate 3360Sstevel@tonic-gate case P_TASKID: 3370Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_lid) 3380Sstevel@tonic-gate loperand++; 3390Sstevel@tonic-gate break; 3400Sstevel@tonic-gate 3410Sstevel@tonic-gate case P_UID: 3420Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 3430Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_lid) 3440Sstevel@tonic-gate loperand++; 3450Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 3460Sstevel@tonic-gate break; 3470Sstevel@tonic-gate 3480Sstevel@tonic-gate case P_GID: 3490Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 3500Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_lid) 3510Sstevel@tonic-gate loperand++; 3520Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 3530Sstevel@tonic-gate break; 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate case P_PROJID: 3560Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 3570Sstevel@tonic-gate loperand++; 3580Sstevel@tonic-gate break; 3590Sstevel@tonic-gate 3600Sstevel@tonic-gate case P_POOLID: 3610Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_lid) 3620Sstevel@tonic-gate loperand++; 3630Sstevel@tonic-gate break; 3640Sstevel@tonic-gate 3650Sstevel@tonic-gate case P_ZONEID: 3660Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_lid) 3670Sstevel@tonic-gate loperand++; 3680Sstevel@tonic-gate break; 3690Sstevel@tonic-gate 3700Sstevel@tonic-gate case P_CTID: 3710Sstevel@tonic-gate if (PRCTID(pp) == psp->p_lid) 3720Sstevel@tonic-gate loperand++; 3730Sstevel@tonic-gate break; 3740Sstevel@tonic-gate 3750Sstevel@tonic-gate case P_ALL: 3760Sstevel@tonic-gate loperand++; 3770Sstevel@tonic-gate break; 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate default: 3800Sstevel@tonic-gate #ifdef DEBUG 3810Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 3820Sstevel@tonic-gate return (0); 3830Sstevel@tonic-gate #else 3840Sstevel@tonic-gate return (0); 3850Sstevel@tonic-gate #endif 3860Sstevel@tonic-gate } 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate switch (psp->p_ridtype) { 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate case P_LWPID: 3910Sstevel@tonic-gate if (pp == ttoproc(curthread)) 3920Sstevel@tonic-gate if (getlwpptr(psp->p_rid) != NULL) 3930Sstevel@tonic-gate lwprinproc++; 3940Sstevel@tonic-gate break; 3950Sstevel@tonic-gate 3960Sstevel@tonic-gate case P_PID: 3970Sstevel@tonic-gate if (pp->p_pid == psp->p_rid) 3980Sstevel@tonic-gate roperand++; 3990Sstevel@tonic-gate break; 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate case P_PPID: 4020Sstevel@tonic-gate if (pp->p_ppid == psp->p_rid) 4030Sstevel@tonic-gate roperand++; 4040Sstevel@tonic-gate break; 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate case P_PGID: 4070Sstevel@tonic-gate if (pp->p_pgrp == psp->p_rid) 4080Sstevel@tonic-gate roperand++; 4090Sstevel@tonic-gate break; 4100Sstevel@tonic-gate 4110Sstevel@tonic-gate case P_SID: 4122712Snn35248 mutex_enter(&pp->p_splock); 4130Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_rid) 4140Sstevel@tonic-gate roperand++; 4152712Snn35248 mutex_exit(&pp->p_splock); 4160Sstevel@tonic-gate break; 4170Sstevel@tonic-gate 4180Sstevel@tonic-gate case P_TASKID: 4190Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_rid) 4200Sstevel@tonic-gate roperand++; 4210Sstevel@tonic-gate break; 4220Sstevel@tonic-gate 4230Sstevel@tonic-gate case P_CID: 4240Sstevel@tonic-gate ASSERT(tp != NULL); 4250Sstevel@tonic-gate /* This case is broken for now. Need to be fixed XXX */ 4260Sstevel@tonic-gate if (tp->t_cid == psp->p_rid) 4270Sstevel@tonic-gate /* 4280Sstevel@tonic-gate * if (checkcid(psp->p_rid)) 4290Sstevel@tonic-gate */ 4300Sstevel@tonic-gate roperand++; 4310Sstevel@tonic-gate break; 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate case P_UID: 4340Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 4350Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_rid) 4360Sstevel@tonic-gate roperand++; 4370Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 4380Sstevel@tonic-gate break; 4390Sstevel@tonic-gate 4400Sstevel@tonic-gate case P_GID: 4410Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 4420Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_rid) 4430Sstevel@tonic-gate roperand++; 4440Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 4450Sstevel@tonic-gate break; 4460Sstevel@tonic-gate 4470Sstevel@tonic-gate case P_PROJID: 4480Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 4490Sstevel@tonic-gate roperand++; 4500Sstevel@tonic-gate break; 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate case P_POOLID: 4530Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_rid) 4540Sstevel@tonic-gate roperand++; 4550Sstevel@tonic-gate break; 4560Sstevel@tonic-gate 4570Sstevel@tonic-gate case P_ZONEID: 4580Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_rid) 4590Sstevel@tonic-gate roperand++; 4600Sstevel@tonic-gate break; 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate case P_CTID: 4630Sstevel@tonic-gate if (PRCTID(pp) == psp->p_rid) 4640Sstevel@tonic-gate roperand++; 4650Sstevel@tonic-gate break; 4660Sstevel@tonic-gate 4670Sstevel@tonic-gate case P_ALL: 4680Sstevel@tonic-gate roperand++; 4690Sstevel@tonic-gate break; 4700Sstevel@tonic-gate 4710Sstevel@tonic-gate default: 4720Sstevel@tonic-gate #ifdef DEBUG 4730Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 4740Sstevel@tonic-gate return (0); 4750Sstevel@tonic-gate #else 4760Sstevel@tonic-gate return (0); 4770Sstevel@tonic-gate #endif 4780Sstevel@tonic-gate } 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate switch (psp->p_op) { 4810Sstevel@tonic-gate 4820Sstevel@tonic-gate case POP_DIFF: 4830Sstevel@tonic-gate if (loperand && !lwprinproc && !roperand) 4840Sstevel@tonic-gate return (1); 4850Sstevel@tonic-gate else 4860Sstevel@tonic-gate return (0); 4870Sstevel@tonic-gate 4880Sstevel@tonic-gate case POP_AND: 4890Sstevel@tonic-gate if (loperand && roperand) 4900Sstevel@tonic-gate return (1); 4910Sstevel@tonic-gate else 4920Sstevel@tonic-gate return (0); 4930Sstevel@tonic-gate 4940Sstevel@tonic-gate case POP_OR: 4950Sstevel@tonic-gate if (loperand || roperand) 4960Sstevel@tonic-gate return (1); 4970Sstevel@tonic-gate else 4980Sstevel@tonic-gate return (0); 4990Sstevel@tonic-gate 5000Sstevel@tonic-gate case POP_XOR: 5010Sstevel@tonic-gate if ((loperand && !lwprinproc && !roperand) || 5020Sstevel@tonic-gate (roperand && !lwplinproc && !loperand)) 5030Sstevel@tonic-gate return (1); 5040Sstevel@tonic-gate else 5050Sstevel@tonic-gate return (0); 5060Sstevel@tonic-gate 5070Sstevel@tonic-gate default: 5080Sstevel@tonic-gate #ifdef DEBUG 5090Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 5100Sstevel@tonic-gate return (0); 5110Sstevel@tonic-gate #else 5120Sstevel@tonic-gate return (0); 5130Sstevel@tonic-gate #endif 5140Sstevel@tonic-gate } 5150Sstevel@tonic-gate /* NOTREACHED */ 5160Sstevel@tonic-gate } 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate /* 5190Sstevel@tonic-gate * lwpinset returns 1 if the thread pointed to 5200Sstevel@tonic-gate * by tp is in the process set specified by psp and is not in 5210Sstevel@tonic-gate * the sys scheduling class - otherwise 0 is returned. 5220Sstevel@tonic-gate * 5230Sstevel@tonic-gate * This function expects to be called with a valid procset_t. 5240Sstevel@tonic-gate * The set should be checked using checkprocset() before calling 5250Sstevel@tonic-gate * this function. 5260Sstevel@tonic-gate */ 5270Sstevel@tonic-gate int 5280Sstevel@tonic-gate lwpinset(proc_t *pp, procset_t *psp, kthread_t *tp, int *done) 5290Sstevel@tonic-gate { 5300Sstevel@tonic-gate int loperand = 0; 5310Sstevel@tonic-gate int roperand = 0; 5320Sstevel@tonic-gate int lwplinset = 0; 5330Sstevel@tonic-gate int lwprinset = 0; 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate ASSERT(ttoproc(tp) == pp); 5360Sstevel@tonic-gate 5370Sstevel@tonic-gate /* 5380Sstevel@tonic-gate * If process is in the sys class return (0). 5390Sstevel@tonic-gate */ 5400Sstevel@tonic-gate if (proctot(pp)->t_cid == 0) { 5410Sstevel@tonic-gate return (0); 5420Sstevel@tonic-gate } 5430Sstevel@tonic-gate 5440Sstevel@tonic-gate switch (psp->p_lidtype) { 5450Sstevel@tonic-gate 5460Sstevel@tonic-gate case P_LWPID: 5470Sstevel@tonic-gate if (tp->t_tid == psp->p_lid) 5480Sstevel@tonic-gate lwplinset ++; 5490Sstevel@tonic-gate break; 5500Sstevel@tonic-gate 5510Sstevel@tonic-gate case P_PID: 5520Sstevel@tonic-gate if (pp->p_pid == psp->p_lid) 5530Sstevel@tonic-gate loperand++; 5540Sstevel@tonic-gate break; 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate case P_PPID: 5570Sstevel@tonic-gate if (pp->p_ppid == psp->p_lid) 5580Sstevel@tonic-gate loperand++; 5590Sstevel@tonic-gate break; 5600Sstevel@tonic-gate 5610Sstevel@tonic-gate case P_PGID: 5620Sstevel@tonic-gate if (pp->p_pgrp == psp->p_lid) 5630Sstevel@tonic-gate loperand++; 5640Sstevel@tonic-gate break; 5650Sstevel@tonic-gate 5660Sstevel@tonic-gate case P_SID: 5672712Snn35248 mutex_enter(&pp->p_splock); 5680Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_lid) 5690Sstevel@tonic-gate loperand++; 5702712Snn35248 mutex_exit(&pp->p_splock); 5710Sstevel@tonic-gate break; 5720Sstevel@tonic-gate 5730Sstevel@tonic-gate case P_TASKID: 5740Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_lid) 5750Sstevel@tonic-gate loperand++; 5760Sstevel@tonic-gate break; 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate case P_CID: 5790Sstevel@tonic-gate if (tp->t_cid == psp->p_lid) 5800Sstevel@tonic-gate loperand++; 5810Sstevel@tonic-gate break; 5820Sstevel@tonic-gate 5830Sstevel@tonic-gate case P_UID: 5840Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 5850Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_lid) 5860Sstevel@tonic-gate loperand++; 5870Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 5880Sstevel@tonic-gate break; 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate case P_GID: 5910Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 5920Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_lid) 5930Sstevel@tonic-gate loperand++; 5940Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 5950Sstevel@tonic-gate break; 5960Sstevel@tonic-gate 5970Sstevel@tonic-gate case P_PROJID: 5980Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 5990Sstevel@tonic-gate loperand++; 6000Sstevel@tonic-gate break; 6010Sstevel@tonic-gate 6020Sstevel@tonic-gate case P_POOLID: 6030Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_lid) 6040Sstevel@tonic-gate loperand++; 6050Sstevel@tonic-gate break; 6060Sstevel@tonic-gate 6070Sstevel@tonic-gate case P_ZONEID: 6080Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_lid) 6090Sstevel@tonic-gate loperand++; 6100Sstevel@tonic-gate break; 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate case P_CTID: 6130Sstevel@tonic-gate if (PRCTID(pp) == psp->p_lid) 6140Sstevel@tonic-gate loperand++; 6150Sstevel@tonic-gate break; 6160Sstevel@tonic-gate 6170Sstevel@tonic-gate case P_ALL: 6180Sstevel@tonic-gate loperand++; 6190Sstevel@tonic-gate break; 6200Sstevel@tonic-gate 6210Sstevel@tonic-gate default: 6220Sstevel@tonic-gate #ifdef DEBUG 6230Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 6240Sstevel@tonic-gate return (0); 6250Sstevel@tonic-gate #else 6260Sstevel@tonic-gate return (0); 6270Sstevel@tonic-gate #endif 6280Sstevel@tonic-gate } 6290Sstevel@tonic-gate 6300Sstevel@tonic-gate switch (psp->p_ridtype) { 6310Sstevel@tonic-gate 6320Sstevel@tonic-gate case P_LWPID: 6330Sstevel@tonic-gate if (tp->t_tid == psp->p_rid) 6340Sstevel@tonic-gate lwprinset ++; 6350Sstevel@tonic-gate break; 6360Sstevel@tonic-gate 6370Sstevel@tonic-gate case P_PID: 6380Sstevel@tonic-gate if (pp->p_pid == psp->p_rid) 6390Sstevel@tonic-gate roperand++; 6400Sstevel@tonic-gate break; 6410Sstevel@tonic-gate 6420Sstevel@tonic-gate case P_PPID: 6430Sstevel@tonic-gate if (pp->p_ppid == psp->p_rid) 6440Sstevel@tonic-gate roperand++; 6450Sstevel@tonic-gate break; 6460Sstevel@tonic-gate 6470Sstevel@tonic-gate case P_PGID: 6480Sstevel@tonic-gate if (pp->p_pgrp == psp->p_rid) 6490Sstevel@tonic-gate roperand++; 6500Sstevel@tonic-gate break; 6510Sstevel@tonic-gate 6520Sstevel@tonic-gate case P_SID: 6532712Snn35248 mutex_enter(&pp->p_splock); 6540Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_rid) 6550Sstevel@tonic-gate roperand++; 6562712Snn35248 mutex_exit(&pp->p_splock); 6570Sstevel@tonic-gate break; 6580Sstevel@tonic-gate 6590Sstevel@tonic-gate case P_TASKID: 6600Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_rid) 6610Sstevel@tonic-gate roperand++; 6620Sstevel@tonic-gate break; 6630Sstevel@tonic-gate 6640Sstevel@tonic-gate case P_CID: 6650Sstevel@tonic-gate if (tp->t_cid == psp->p_rid) 6660Sstevel@tonic-gate roperand++; 6670Sstevel@tonic-gate break; 6680Sstevel@tonic-gate 6690Sstevel@tonic-gate case P_UID: 6700Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 6710Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_rid) 6720Sstevel@tonic-gate roperand++; 6730Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 6740Sstevel@tonic-gate break; 6750Sstevel@tonic-gate 6760Sstevel@tonic-gate case P_GID: 6770Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 6780Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_rid) 6790Sstevel@tonic-gate roperand++; 6800Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 6810Sstevel@tonic-gate break; 6820Sstevel@tonic-gate 6830Sstevel@tonic-gate case P_PROJID: 6840Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 6850Sstevel@tonic-gate roperand++; 6860Sstevel@tonic-gate break; 6870Sstevel@tonic-gate 6880Sstevel@tonic-gate case P_POOLID: 6890Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_rid) 6900Sstevel@tonic-gate roperand++; 6910Sstevel@tonic-gate break; 6920Sstevel@tonic-gate 6930Sstevel@tonic-gate case P_ZONEID: 6940Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_rid) 6950Sstevel@tonic-gate roperand++; 6960Sstevel@tonic-gate break; 6970Sstevel@tonic-gate 6980Sstevel@tonic-gate case P_CTID: 6990Sstevel@tonic-gate if (PRCTID(pp) == psp->p_rid) 7000Sstevel@tonic-gate roperand++; 7010Sstevel@tonic-gate break; 7020Sstevel@tonic-gate 7030Sstevel@tonic-gate case P_ALL: 7040Sstevel@tonic-gate roperand++; 7050Sstevel@tonic-gate break; 7060Sstevel@tonic-gate 7070Sstevel@tonic-gate default: 7080Sstevel@tonic-gate #ifdef DEBUG 7090Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 7100Sstevel@tonic-gate return (0); 7110Sstevel@tonic-gate #else 7120Sstevel@tonic-gate return (0); 7130Sstevel@tonic-gate #endif 7140Sstevel@tonic-gate } 7150Sstevel@tonic-gate 7160Sstevel@tonic-gate if (lwplinset && lwprinset) 7170Sstevel@tonic-gate *done = 1; 7180Sstevel@tonic-gate 7190Sstevel@tonic-gate switch (psp->p_op) { 7200Sstevel@tonic-gate 7210Sstevel@tonic-gate case POP_DIFF: 7220Sstevel@tonic-gate if ((loperand || lwplinset) && !(lwprinset || roperand)) 7230Sstevel@tonic-gate return (1); 7240Sstevel@tonic-gate else 7250Sstevel@tonic-gate return (0); 7260Sstevel@tonic-gate 7270Sstevel@tonic-gate case POP_AND: 7280Sstevel@tonic-gate if ((loperand || lwplinset) && (roperand || lwprinset)) 7290Sstevel@tonic-gate return (1); 7300Sstevel@tonic-gate else 7310Sstevel@tonic-gate return (0); 7320Sstevel@tonic-gate 7330Sstevel@tonic-gate case POP_OR: 7340Sstevel@tonic-gate if (loperand || roperand || lwplinset || lwprinset) 7350Sstevel@tonic-gate return (1); 7360Sstevel@tonic-gate else 7370Sstevel@tonic-gate return (0); 7380Sstevel@tonic-gate 7390Sstevel@tonic-gate case POP_XOR: 7400Sstevel@tonic-gate if (((loperand || lwplinset) && 741*6618Srh87107 !(lwprinset || roperand)) || 7420Sstevel@tonic-gate ((roperand || lwprinset) && 743*6618Srh87107 !(lwplinset || loperand))) 7440Sstevel@tonic-gate return (1); 7450Sstevel@tonic-gate else 7460Sstevel@tonic-gate return (0); 7470Sstevel@tonic-gate 7480Sstevel@tonic-gate default: 7490Sstevel@tonic-gate #ifdef DEBUG 7500Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 7510Sstevel@tonic-gate return (0); 7520Sstevel@tonic-gate #else 7530Sstevel@tonic-gate return (0); 7540Sstevel@tonic-gate #endif 7550Sstevel@tonic-gate } 7560Sstevel@tonic-gate /* NOTREACHED */ 7570Sstevel@tonic-gate } 7580Sstevel@tonic-gate /* 7590Sstevel@tonic-gate * Check for common cases of procsets which specify only the 7600Sstevel@tonic-gate * current process. cur_inset_only() returns B_TRUE when 7610Sstevel@tonic-gate * the current process is the only one in the set. B_FALSE 7620Sstevel@tonic-gate * is returned to indicate that this may not be the case. 7630Sstevel@tonic-gate */ 7640Sstevel@tonic-gate boolean_t 7650Sstevel@tonic-gate cur_inset_only(procset_t *psp) 7660Sstevel@tonic-gate { 7670Sstevel@tonic-gate if (((psp->p_lidtype == P_PID && 768*6618Srh87107 (psp->p_lid == P_MYID || 769*6618Srh87107 psp->p_lid == ttoproc(curthread)->p_pid)) || 770*6618Srh87107 ((psp->p_lidtype == P_LWPID) && 771*6618Srh87107 (psp->p_lid == P_MYID || 772*6618Srh87107 psp->p_lid == curthread->t_tid))) && 773*6618Srh87107 psp->p_op == POP_AND && psp->p_ridtype == P_ALL) 774*6618Srh87107 return (B_TRUE); 7750Sstevel@tonic-gate 7760Sstevel@tonic-gate if (((psp->p_ridtype == P_PID && 777*6618Srh87107 (psp->p_rid == P_MYID || 778*6618Srh87107 psp->p_rid == ttoproc(curthread)->p_pid)) || 779*6618Srh87107 ((psp->p_ridtype == P_LWPID) && 780*6618Srh87107 (psp->p_rid == P_MYID || 781*6618Srh87107 psp->p_rid == curthread->t_tid))) && 782*6618Srh87107 psp->p_op == POP_AND && psp->p_lidtype == P_ALL) 783*6618Srh87107 return (B_TRUE); 7840Sstevel@tonic-gate 7850Sstevel@tonic-gate return (B_FALSE); 7860Sstevel@tonic-gate } 7870Sstevel@tonic-gate 7880Sstevel@tonic-gate id_t 7890Sstevel@tonic-gate getmyid(idtype_t idtype) 7900Sstevel@tonic-gate { 7910Sstevel@tonic-gate proc_t *pp; 7920Sstevel@tonic-gate uid_t uid; 7930Sstevel@tonic-gate gid_t gid; 7942712Snn35248 pid_t sid; 7950Sstevel@tonic-gate 7960Sstevel@tonic-gate pp = ttoproc(curthread); 7970Sstevel@tonic-gate 7980Sstevel@tonic-gate switch (idtype) { 7990Sstevel@tonic-gate case P_LWPID: 8000Sstevel@tonic-gate return (curthread->t_tid); 8010Sstevel@tonic-gate 8020Sstevel@tonic-gate case P_PID: 8030Sstevel@tonic-gate return (pp->p_pid); 8040Sstevel@tonic-gate 8050Sstevel@tonic-gate case P_PPID: 8060Sstevel@tonic-gate return (pp->p_ppid); 8070Sstevel@tonic-gate 8080Sstevel@tonic-gate case P_PGID: 8090Sstevel@tonic-gate return (pp->p_pgrp); 8100Sstevel@tonic-gate 8110Sstevel@tonic-gate case P_SID: 8122712Snn35248 mutex_enter(&pp->p_splock); 8132712Snn35248 sid = pp->p_sessp->s_sid; 8142712Snn35248 mutex_exit(&pp->p_splock); 8152712Snn35248 return (sid); 8160Sstevel@tonic-gate 8170Sstevel@tonic-gate case P_TASKID: 8180Sstevel@tonic-gate return (pp->p_task->tk_tkid); 8190Sstevel@tonic-gate 8200Sstevel@tonic-gate case P_CID: 8210Sstevel@tonic-gate return (curthread->t_cid); 8220Sstevel@tonic-gate 8230Sstevel@tonic-gate case P_UID: 8240Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 8250Sstevel@tonic-gate uid = crgetuid(pp->p_cred); 8260Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 8270Sstevel@tonic-gate return (uid); 8280Sstevel@tonic-gate 8290Sstevel@tonic-gate case P_GID: 8300Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 8310Sstevel@tonic-gate gid = crgetgid(pp->p_cred); 8320Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 8330Sstevel@tonic-gate return (gid); 8340Sstevel@tonic-gate 8350Sstevel@tonic-gate case P_PROJID: 8360Sstevel@tonic-gate return (pp->p_task->tk_proj->kpj_id); 8370Sstevel@tonic-gate 8380Sstevel@tonic-gate case P_POOLID: 8390Sstevel@tonic-gate return (pp->p_pool->pool_id); 8400Sstevel@tonic-gate 8410Sstevel@tonic-gate case P_ZONEID: 8420Sstevel@tonic-gate return (pp->p_zone->zone_id); 8430Sstevel@tonic-gate 8440Sstevel@tonic-gate case P_CTID: 8450Sstevel@tonic-gate return (PRCTID(pp)); 8460Sstevel@tonic-gate 8470Sstevel@tonic-gate case P_ALL: 8480Sstevel@tonic-gate /* 8490Sstevel@tonic-gate * The value doesn't matter for P_ALL. 8500Sstevel@tonic-gate */ 8510Sstevel@tonic-gate return (0); 8520Sstevel@tonic-gate 8530Sstevel@tonic-gate default: 8540Sstevel@tonic-gate return (-1); 8550Sstevel@tonic-gate } 8560Sstevel@tonic-gate } 8570Sstevel@tonic-gate 8580Sstevel@tonic-gate static kthread_t * 8590Sstevel@tonic-gate getlwpptr(id_t id) 8600Sstevel@tonic-gate { 8610Sstevel@tonic-gate proc_t *p; 8620Sstevel@tonic-gate kthread_t *t; 8630Sstevel@tonic-gate 864*6618Srh87107 ASSERT(MUTEX_HELD(&(ttoproc(curthread)->p_lock))); 865*6618Srh87107 8660Sstevel@tonic-gate if (id == P_MYID) 8670Sstevel@tonic-gate t = curthread; 8680Sstevel@tonic-gate else { 8690Sstevel@tonic-gate p = ttoproc(curthread); 8700Sstevel@tonic-gate t = idtot(p, id); 8710Sstevel@tonic-gate } 8720Sstevel@tonic-gate 8730Sstevel@tonic-gate return (t); 8740Sstevel@tonic-gate } 8750Sstevel@tonic-gate 8760Sstevel@tonic-gate /* 8770Sstevel@tonic-gate * The dotolwp function locates the LWP(s) specified by the procset structure 8780Sstevel@tonic-gate * pointed to by psp. If funcp is non-NULL then it points to a function 8790Sstevel@tonic-gate * which dotolwp will call for each LWP in the specified set. 8800Sstevel@tonic-gate * LWPIDs specified in the procset structure always refer to lwps in curproc. 8810Sstevel@tonic-gate * The arguments for this function must be "char *arg", and "kthread_t *tp", 8820Sstevel@tonic-gate * where tp is a pointer to the current thread from the set. 8830Sstevel@tonic-gate * Note that these arguments are passed to the function in reversed order 8840Sstevel@tonic-gate * than the order of arguments passed by dotoprocs() to its callback function. 8850Sstevel@tonic-gate * Also note that there are two separate cases where this routine returns zero. 8860Sstevel@tonic-gate * In the first case no mutex is grabbed, in the second the p_lock mutex 8870Sstevel@tonic-gate * is NOT RELEASED. The priocntl code is expecting this behaviour. 8880Sstevel@tonic-gate */ 8890Sstevel@tonic-gate int 8900Sstevel@tonic-gate dotolwp(procset_t *psp, int (*funcp)(), char *arg) 8910Sstevel@tonic-gate { 8920Sstevel@tonic-gate int error = 0; 8930Sstevel@tonic-gate int nfound = 0; 8940Sstevel@tonic-gate kthread_t *tp; 8950Sstevel@tonic-gate proc_t *pp; 8960Sstevel@tonic-gate int done = 0; 8970Sstevel@tonic-gate 8980Sstevel@tonic-gate /* 8990Sstevel@tonic-gate * Check that the procset_t is valid. 9000Sstevel@tonic-gate */ 9010Sstevel@tonic-gate error = checkprocset(psp); 9020Sstevel@tonic-gate if (error) { 9030Sstevel@tonic-gate return (error); 9040Sstevel@tonic-gate } 9050Sstevel@tonic-gate 9060Sstevel@tonic-gate mutex_enter(&pidlock); 9070Sstevel@tonic-gate 9080Sstevel@tonic-gate /* 9090Sstevel@tonic-gate * Check for the special value P_MYID in either operand 9100Sstevel@tonic-gate * and replace it with the correct value. We don't check 9110Sstevel@tonic-gate * for an error return from getmyid() because the idtypes 9120Sstevel@tonic-gate * have been validated by the checkprocset() call above. 9130Sstevel@tonic-gate */ 9140Sstevel@tonic-gate if (psp->p_lid == P_MYID) { 9150Sstevel@tonic-gate psp->p_lid = getmyid(psp->p_lidtype); 9160Sstevel@tonic-gate } 9170Sstevel@tonic-gate if (psp->p_rid == P_MYID) { 9180Sstevel@tonic-gate psp->p_rid = getmyid(psp->p_ridtype); 9190Sstevel@tonic-gate } 9200Sstevel@tonic-gate 9210Sstevel@tonic-gate pp = ttoproc(curthread); 9220Sstevel@tonic-gate 9230Sstevel@tonic-gate mutex_enter(&pp->p_lock); 924*6618Srh87107 if (procinset(pp, psp) || 925*6618Srh87107 (tp = pp->p_tlist) == NULL) { 9260Sstevel@tonic-gate mutex_exit(&pp->p_lock); 9270Sstevel@tonic-gate mutex_exit(&pidlock); 9280Sstevel@tonic-gate return (0); 9290Sstevel@tonic-gate } 9300Sstevel@tonic-gate do { 9310Sstevel@tonic-gate if (lwpinset(pp, psp, tp, &done)) { 9320Sstevel@tonic-gate nfound ++; 9330Sstevel@tonic-gate error = (*funcp)(arg, tp); 9340Sstevel@tonic-gate if (error) { 9350Sstevel@tonic-gate mutex_exit(&pp->p_lock); 9360Sstevel@tonic-gate mutex_exit(&pidlock); 9370Sstevel@tonic-gate return (error); 9380Sstevel@tonic-gate } 9390Sstevel@tonic-gate } 9400Sstevel@tonic-gate } while (((tp = tp->t_forw) != pp->p_tlist) && !done); 9410Sstevel@tonic-gate 9420Sstevel@tonic-gate if (nfound == 0) { 9430Sstevel@tonic-gate mutex_exit(&pp->p_lock); 9440Sstevel@tonic-gate mutex_exit(&pidlock); 9450Sstevel@tonic-gate return (ESRCH); 9460Sstevel@tonic-gate } 9470Sstevel@tonic-gate 9480Sstevel@tonic-gate mutex_exit(&pidlock); 9490Sstevel@tonic-gate return (error); 9500Sstevel@tonic-gate } 951