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*4253Sjimp * Copyright 2007 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 72*4253Sjimp * by the procset structure pointed to by psp. funcp points to a 73*4253Sjimp * function which dotoprocs will call for each process in the 74*4253Sjimp * specified set. The arguments to this function will be a pointer 75*4253Sjimp * 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 94*4253Sjimp ASSERT(funcp != NULL); 95*4253Sjimp 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; 137*4253Sjimp if (((prp = prfind((pid_t)pid)) == NULL) || 138*4253Sjimp (prp->p_stat == SIDL || prp->p_stat == SZOMB || 139*4253Sjimp prp->p_tlist == NULL || prp->p_flag & SSYS)) { 140*4253Sjimp /* 141*4253Sjimp * Specified proc doesn't exist or should 142*4253Sjimp * not be operated on. 143*4253Sjimp * Don't need to make HASZONEACCESS check 144*4253Sjimp * here since prfind() takes care of that. 145*4253Sjimp */ 1460Sstevel@tonic-gate mutex_exit(&pidlock); 1470Sstevel@tonic-gate return (ESRCH); 1480Sstevel@tonic-gate } 149*4253Sjimp /* 150*4253Sjimp * Operate only on the specified proc. It's okay 151*4253Sjimp * if it's init. 152*4253Sjimp */ 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; 1710Sstevel@tonic-gate if (prp->p_stat == SIDL || prp->p_stat == SZOMB || 1720Sstevel@tonic-gate prp->p_tlist == NULL || prp->p_flag & SSYS) 1730Sstevel@tonic-gate continue; 1740Sstevel@tonic-gate if (procinset(prp, psp)) { 1750Sstevel@tonic-gate nfound++; 1760Sstevel@tonic-gate lastprp = prp; 177*4253Sjimp if (prp != proc_init) { 1780Sstevel@tonic-gate error = (*funcp)(prp, arg); 1790Sstevel@tonic-gate if (error == -1) { 1800Sstevel@tonic-gate mutex_exit(&pidlock); 1810Sstevel@tonic-gate return (0); 1820Sstevel@tonic-gate } else if (error) { 1830Sstevel@tonic-gate mutex_exit(&pidlock); 1840Sstevel@tonic-gate return (error); 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate } 1870Sstevel@tonic-gate } 1880Sstevel@tonic-gate } 1890Sstevel@tonic-gate if (nfound == 0) { 1900Sstevel@tonic-gate mutex_exit(&pidlock); 1910Sstevel@tonic-gate return (ESRCH); 1920Sstevel@tonic-gate } 193*4253Sjimp if (nfound == 1 && lastprp == proc_init) 1940Sstevel@tonic-gate error = (*funcp)(lastprp, arg); 1950Sstevel@tonic-gate if (error == -1) 1960Sstevel@tonic-gate error = 0; 1970Sstevel@tonic-gate mutex_exit(&pidlock); 1980Sstevel@tonic-gate return (error); 1990Sstevel@tonic-gate } 2000Sstevel@tonic-gate 2010Sstevel@tonic-gate /* 2020Sstevel@tonic-gate * Check if a procset_t is valid. Return zero or an errno. 2030Sstevel@tonic-gate */ 2040Sstevel@tonic-gate int 2050Sstevel@tonic-gate checkprocset(procset_t *psp) 2060Sstevel@tonic-gate { 2070Sstevel@tonic-gate switch (psp->p_lidtype) { 2080Sstevel@tonic-gate case P_LWPID: 2090Sstevel@tonic-gate case P_PID: 2100Sstevel@tonic-gate case P_PPID: 2110Sstevel@tonic-gate case P_PGID: 2120Sstevel@tonic-gate case P_SID: 2130Sstevel@tonic-gate case P_TASKID: 2140Sstevel@tonic-gate case P_CID: 2150Sstevel@tonic-gate case P_UID: 2160Sstevel@tonic-gate case P_GID: 2170Sstevel@tonic-gate case P_PROJID: 2180Sstevel@tonic-gate case P_POOLID: 2190Sstevel@tonic-gate case P_ZONEID: 2200Sstevel@tonic-gate case P_CTID: 2210Sstevel@tonic-gate case P_ALL: 2220Sstevel@tonic-gate break; 2230Sstevel@tonic-gate default: 2240Sstevel@tonic-gate return (EINVAL); 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate switch (psp->p_ridtype) { 2280Sstevel@tonic-gate case P_LWPID: 2290Sstevel@tonic-gate case P_PID: 2300Sstevel@tonic-gate case P_PPID: 2310Sstevel@tonic-gate case P_PGID: 2320Sstevel@tonic-gate case P_SID: 2330Sstevel@tonic-gate case P_TASKID: 2340Sstevel@tonic-gate case P_CID: 2350Sstevel@tonic-gate case P_UID: 2360Sstevel@tonic-gate case P_GID: 2370Sstevel@tonic-gate case P_PROJID: 2380Sstevel@tonic-gate case P_POOLID: 2390Sstevel@tonic-gate case P_ZONEID: 2400Sstevel@tonic-gate case P_CTID: 2410Sstevel@tonic-gate case P_ALL: 2420Sstevel@tonic-gate break; 2430Sstevel@tonic-gate default: 2440Sstevel@tonic-gate return (EINVAL); 2450Sstevel@tonic-gate } 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate switch (psp->p_op) { 2480Sstevel@tonic-gate case POP_DIFF: 2490Sstevel@tonic-gate case POP_AND: 2500Sstevel@tonic-gate case POP_OR: 2510Sstevel@tonic-gate case POP_XOR: 2520Sstevel@tonic-gate break; 2530Sstevel@tonic-gate default: 2540Sstevel@tonic-gate return (EINVAL); 2550Sstevel@tonic-gate } 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate return (0); 2580Sstevel@tonic-gate } 2590Sstevel@tonic-gate 2600Sstevel@tonic-gate /* 2610Sstevel@tonic-gate * procinset returns 1 if the process pointed to 2620Sstevel@tonic-gate * by pp is in the process set specified by psp, otherwise 0 is returned. 2630Sstevel@tonic-gate * The caller should check that the process is not exiting and is not 2640Sstevel@tonic-gate * in the SYS scheduling class. 2650Sstevel@tonic-gate * 2660Sstevel@tonic-gate * This function expects to be called with a valid procset_t. 2670Sstevel@tonic-gate * The set should be checked using checkprocset() before calling 2680Sstevel@tonic-gate * this function. 2690Sstevel@tonic-gate */ 2700Sstevel@tonic-gate int 2710Sstevel@tonic-gate procinset(proc_t *pp, procset_t *psp) 2720Sstevel@tonic-gate { 2730Sstevel@tonic-gate int loperand = 0; 2740Sstevel@tonic-gate int roperand = 0; 2750Sstevel@tonic-gate int lwplinproc = 0; 2760Sstevel@tonic-gate int lwprinproc = 0; 2770Sstevel@tonic-gate kthread_t *tp = proctot(pp); 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate switch (psp->p_lidtype) { 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate case P_LWPID: 2820Sstevel@tonic-gate if (pp == ttoproc(curthread)) 2830Sstevel@tonic-gate if (getlwpptr(psp->p_lid) != NULL) 2840Sstevel@tonic-gate lwplinproc++; 2850Sstevel@tonic-gate break; 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate case P_PID: 2880Sstevel@tonic-gate if (pp->p_pid == psp->p_lid) 2890Sstevel@tonic-gate loperand++; 2900Sstevel@tonic-gate break; 2910Sstevel@tonic-gate 2920Sstevel@tonic-gate case P_PPID: 2930Sstevel@tonic-gate if (pp->p_ppid == psp->p_lid) 2940Sstevel@tonic-gate loperand++; 2950Sstevel@tonic-gate break; 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate case P_PGID: 2980Sstevel@tonic-gate if (pp->p_pgrp == psp->p_lid) 2990Sstevel@tonic-gate loperand++; 3000Sstevel@tonic-gate break; 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate case P_SID: 3032712Snn35248 mutex_enter(&pp->p_splock); 3040Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_lid) 3050Sstevel@tonic-gate loperand++; 3062712Snn35248 mutex_exit(&pp->p_splock); 3070Sstevel@tonic-gate break; 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate case P_CID: 3100Sstevel@tonic-gate ASSERT(tp != NULL); 3110Sstevel@tonic-gate /* This case is broken for now. Need to be fixed XXX */ 3120Sstevel@tonic-gate if (tp->t_cid == psp->p_lid) 3130Sstevel@tonic-gate /* 3140Sstevel@tonic-gate * if (checkcid(psp->p_lid)) 3150Sstevel@tonic-gate */ 3160Sstevel@tonic-gate loperand++; 3170Sstevel@tonic-gate break; 3180Sstevel@tonic-gate 3190Sstevel@tonic-gate case P_TASKID: 3200Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_lid) 3210Sstevel@tonic-gate loperand++; 3220Sstevel@tonic-gate break; 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate case P_UID: 3250Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 3260Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_lid) 3270Sstevel@tonic-gate loperand++; 3280Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 3290Sstevel@tonic-gate break; 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate case P_GID: 3320Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 3330Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_lid) 3340Sstevel@tonic-gate loperand++; 3350Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 3360Sstevel@tonic-gate break; 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate case P_PROJID: 3390Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 3400Sstevel@tonic-gate loperand++; 3410Sstevel@tonic-gate break; 3420Sstevel@tonic-gate 3430Sstevel@tonic-gate case P_POOLID: 3440Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_lid) 3450Sstevel@tonic-gate loperand++; 3460Sstevel@tonic-gate break; 3470Sstevel@tonic-gate 3480Sstevel@tonic-gate case P_ZONEID: 3490Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_lid) 3500Sstevel@tonic-gate loperand++; 3510Sstevel@tonic-gate break; 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate case P_CTID: 3540Sstevel@tonic-gate if (PRCTID(pp) == psp->p_lid) 3550Sstevel@tonic-gate loperand++; 3560Sstevel@tonic-gate break; 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate case P_ALL: 3590Sstevel@tonic-gate loperand++; 3600Sstevel@tonic-gate break; 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate default: 3630Sstevel@tonic-gate #ifdef DEBUG 3640Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 3650Sstevel@tonic-gate return (0); 3660Sstevel@tonic-gate #else 3670Sstevel@tonic-gate return (0); 3680Sstevel@tonic-gate #endif 3690Sstevel@tonic-gate } 3700Sstevel@tonic-gate 3710Sstevel@tonic-gate switch (psp->p_ridtype) { 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate case P_LWPID: 3740Sstevel@tonic-gate if (pp == ttoproc(curthread)) 3750Sstevel@tonic-gate if (getlwpptr(psp->p_rid) != NULL) 3760Sstevel@tonic-gate lwprinproc++; 3770Sstevel@tonic-gate break; 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate case P_PID: 3800Sstevel@tonic-gate if (pp->p_pid == psp->p_rid) 3810Sstevel@tonic-gate roperand++; 3820Sstevel@tonic-gate break; 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate case P_PPID: 3850Sstevel@tonic-gate if (pp->p_ppid == psp->p_rid) 3860Sstevel@tonic-gate roperand++; 3870Sstevel@tonic-gate break; 3880Sstevel@tonic-gate 3890Sstevel@tonic-gate case P_PGID: 3900Sstevel@tonic-gate if (pp->p_pgrp == psp->p_rid) 3910Sstevel@tonic-gate roperand++; 3920Sstevel@tonic-gate break; 3930Sstevel@tonic-gate 3940Sstevel@tonic-gate case P_SID: 3952712Snn35248 mutex_enter(&pp->p_splock); 3960Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_rid) 3970Sstevel@tonic-gate roperand++; 3982712Snn35248 mutex_exit(&pp->p_splock); 3990Sstevel@tonic-gate break; 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate case P_TASKID: 4020Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_rid) 4030Sstevel@tonic-gate roperand++; 4040Sstevel@tonic-gate break; 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate case P_CID: 4070Sstevel@tonic-gate ASSERT(tp != NULL); 4080Sstevel@tonic-gate /* This case is broken for now. Need to be fixed XXX */ 4090Sstevel@tonic-gate if (tp->t_cid == psp->p_rid) 4100Sstevel@tonic-gate /* 4110Sstevel@tonic-gate * if (checkcid(psp->p_rid)) 4120Sstevel@tonic-gate */ 4130Sstevel@tonic-gate roperand++; 4140Sstevel@tonic-gate break; 4150Sstevel@tonic-gate 4160Sstevel@tonic-gate case P_UID: 4170Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 4180Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_rid) 4190Sstevel@tonic-gate roperand++; 4200Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 4210Sstevel@tonic-gate break; 4220Sstevel@tonic-gate 4230Sstevel@tonic-gate case P_GID: 4240Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 4250Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_rid) 4260Sstevel@tonic-gate roperand++; 4270Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 4280Sstevel@tonic-gate break; 4290Sstevel@tonic-gate 4300Sstevel@tonic-gate case P_PROJID: 4310Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 4320Sstevel@tonic-gate roperand++; 4330Sstevel@tonic-gate break; 4340Sstevel@tonic-gate 4350Sstevel@tonic-gate case P_POOLID: 4360Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_rid) 4370Sstevel@tonic-gate roperand++; 4380Sstevel@tonic-gate break; 4390Sstevel@tonic-gate 4400Sstevel@tonic-gate case P_ZONEID: 4410Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_rid) 4420Sstevel@tonic-gate roperand++; 4430Sstevel@tonic-gate break; 4440Sstevel@tonic-gate 4450Sstevel@tonic-gate case P_CTID: 4460Sstevel@tonic-gate if (PRCTID(pp) == psp->p_rid) 4470Sstevel@tonic-gate roperand++; 4480Sstevel@tonic-gate break; 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate case P_ALL: 4510Sstevel@tonic-gate roperand++; 4520Sstevel@tonic-gate break; 4530Sstevel@tonic-gate 4540Sstevel@tonic-gate default: 4550Sstevel@tonic-gate #ifdef DEBUG 4560Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 4570Sstevel@tonic-gate return (0); 4580Sstevel@tonic-gate #else 4590Sstevel@tonic-gate return (0); 4600Sstevel@tonic-gate #endif 4610Sstevel@tonic-gate } 4620Sstevel@tonic-gate 4630Sstevel@tonic-gate switch (psp->p_op) { 4640Sstevel@tonic-gate 4650Sstevel@tonic-gate case POP_DIFF: 4660Sstevel@tonic-gate if (loperand && !lwprinproc && !roperand) 4670Sstevel@tonic-gate return (1); 4680Sstevel@tonic-gate else 4690Sstevel@tonic-gate return (0); 4700Sstevel@tonic-gate 4710Sstevel@tonic-gate case POP_AND: 4720Sstevel@tonic-gate if (loperand && roperand) 4730Sstevel@tonic-gate return (1); 4740Sstevel@tonic-gate else 4750Sstevel@tonic-gate return (0); 4760Sstevel@tonic-gate 4770Sstevel@tonic-gate case POP_OR: 4780Sstevel@tonic-gate if (loperand || roperand) 4790Sstevel@tonic-gate return (1); 4800Sstevel@tonic-gate else 4810Sstevel@tonic-gate return (0); 4820Sstevel@tonic-gate 4830Sstevel@tonic-gate case POP_XOR: 4840Sstevel@tonic-gate if ((loperand && !lwprinproc && !roperand) || 4850Sstevel@tonic-gate (roperand && !lwplinproc && !loperand)) 4860Sstevel@tonic-gate return (1); 4870Sstevel@tonic-gate else 4880Sstevel@tonic-gate return (0); 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate default: 4910Sstevel@tonic-gate #ifdef DEBUG 4920Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 4930Sstevel@tonic-gate return (0); 4940Sstevel@tonic-gate #else 4950Sstevel@tonic-gate return (0); 4960Sstevel@tonic-gate #endif 4970Sstevel@tonic-gate } 4980Sstevel@tonic-gate /* NOTREACHED */ 4990Sstevel@tonic-gate } 5000Sstevel@tonic-gate 5010Sstevel@tonic-gate /* 5020Sstevel@tonic-gate * lwpinset returns 1 if the thread pointed to 5030Sstevel@tonic-gate * by tp is in the process set specified by psp and is not in 5040Sstevel@tonic-gate * the sys scheduling class - otherwise 0 is returned. 5050Sstevel@tonic-gate * 5060Sstevel@tonic-gate * This function expects to be called with a valid procset_t. 5070Sstevel@tonic-gate * The set should be checked using checkprocset() before calling 5080Sstevel@tonic-gate * this function. 5090Sstevel@tonic-gate */ 5100Sstevel@tonic-gate int 5110Sstevel@tonic-gate lwpinset(proc_t *pp, procset_t *psp, kthread_t *tp, int *done) 5120Sstevel@tonic-gate { 5130Sstevel@tonic-gate int loperand = 0; 5140Sstevel@tonic-gate int roperand = 0; 5150Sstevel@tonic-gate int lwplinset = 0; 5160Sstevel@tonic-gate int lwprinset = 0; 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate ASSERT(ttoproc(tp) == pp); 5190Sstevel@tonic-gate 5200Sstevel@tonic-gate /* 5210Sstevel@tonic-gate * If process is in the sys class return (0). 5220Sstevel@tonic-gate */ 5230Sstevel@tonic-gate if (proctot(pp)->t_cid == 0) { 5240Sstevel@tonic-gate return (0); 5250Sstevel@tonic-gate } 5260Sstevel@tonic-gate 5270Sstevel@tonic-gate switch (psp->p_lidtype) { 5280Sstevel@tonic-gate 5290Sstevel@tonic-gate case P_LWPID: 5300Sstevel@tonic-gate if (tp->t_tid == psp->p_lid) 5310Sstevel@tonic-gate lwplinset ++; 5320Sstevel@tonic-gate break; 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate case P_PID: 5350Sstevel@tonic-gate if (pp->p_pid == psp->p_lid) 5360Sstevel@tonic-gate loperand++; 5370Sstevel@tonic-gate break; 5380Sstevel@tonic-gate 5390Sstevel@tonic-gate case P_PPID: 5400Sstevel@tonic-gate if (pp->p_ppid == psp->p_lid) 5410Sstevel@tonic-gate loperand++; 5420Sstevel@tonic-gate break; 5430Sstevel@tonic-gate 5440Sstevel@tonic-gate case P_PGID: 5450Sstevel@tonic-gate if (pp->p_pgrp == psp->p_lid) 5460Sstevel@tonic-gate loperand++; 5470Sstevel@tonic-gate break; 5480Sstevel@tonic-gate 5490Sstevel@tonic-gate case P_SID: 5502712Snn35248 mutex_enter(&pp->p_splock); 5510Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_lid) 5520Sstevel@tonic-gate loperand++; 5532712Snn35248 mutex_exit(&pp->p_splock); 5540Sstevel@tonic-gate break; 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate case P_TASKID: 5570Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_lid) 5580Sstevel@tonic-gate loperand++; 5590Sstevel@tonic-gate break; 5600Sstevel@tonic-gate 5610Sstevel@tonic-gate case P_CID: 5620Sstevel@tonic-gate if (tp->t_cid == psp->p_lid) 5630Sstevel@tonic-gate loperand++; 5640Sstevel@tonic-gate break; 5650Sstevel@tonic-gate 5660Sstevel@tonic-gate case P_UID: 5670Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 5680Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_lid) 5690Sstevel@tonic-gate loperand++; 5700Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 5710Sstevel@tonic-gate break; 5720Sstevel@tonic-gate 5730Sstevel@tonic-gate case P_GID: 5740Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 5750Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_lid) 5760Sstevel@tonic-gate loperand++; 5770Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 5780Sstevel@tonic-gate break; 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate case P_PROJID: 5810Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 5820Sstevel@tonic-gate loperand++; 5830Sstevel@tonic-gate break; 5840Sstevel@tonic-gate 5850Sstevel@tonic-gate case P_POOLID: 5860Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_lid) 5870Sstevel@tonic-gate loperand++; 5880Sstevel@tonic-gate break; 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate case P_ZONEID: 5910Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_lid) 5920Sstevel@tonic-gate loperand++; 5930Sstevel@tonic-gate break; 5940Sstevel@tonic-gate 5950Sstevel@tonic-gate case P_CTID: 5960Sstevel@tonic-gate if (PRCTID(pp) == psp->p_lid) 5970Sstevel@tonic-gate loperand++; 5980Sstevel@tonic-gate break; 5990Sstevel@tonic-gate 6000Sstevel@tonic-gate case P_ALL: 6010Sstevel@tonic-gate loperand++; 6020Sstevel@tonic-gate break; 6030Sstevel@tonic-gate 6040Sstevel@tonic-gate default: 6050Sstevel@tonic-gate #ifdef DEBUG 6060Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 6070Sstevel@tonic-gate return (0); 6080Sstevel@tonic-gate #else 6090Sstevel@tonic-gate return (0); 6100Sstevel@tonic-gate #endif 6110Sstevel@tonic-gate } 6120Sstevel@tonic-gate 6130Sstevel@tonic-gate switch (psp->p_ridtype) { 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate case P_LWPID: 6160Sstevel@tonic-gate if (tp->t_tid == psp->p_rid) 6170Sstevel@tonic-gate lwprinset ++; 6180Sstevel@tonic-gate break; 6190Sstevel@tonic-gate 6200Sstevel@tonic-gate case P_PID: 6210Sstevel@tonic-gate if (pp->p_pid == psp->p_rid) 6220Sstevel@tonic-gate roperand++; 6230Sstevel@tonic-gate break; 6240Sstevel@tonic-gate 6250Sstevel@tonic-gate case P_PPID: 6260Sstevel@tonic-gate if (pp->p_ppid == psp->p_rid) 6270Sstevel@tonic-gate roperand++; 6280Sstevel@tonic-gate break; 6290Sstevel@tonic-gate 6300Sstevel@tonic-gate case P_PGID: 6310Sstevel@tonic-gate if (pp->p_pgrp == psp->p_rid) 6320Sstevel@tonic-gate roperand++; 6330Sstevel@tonic-gate break; 6340Sstevel@tonic-gate 6350Sstevel@tonic-gate case P_SID: 6362712Snn35248 mutex_enter(&pp->p_splock); 6370Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_rid) 6380Sstevel@tonic-gate roperand++; 6392712Snn35248 mutex_exit(&pp->p_splock); 6400Sstevel@tonic-gate break; 6410Sstevel@tonic-gate 6420Sstevel@tonic-gate case P_TASKID: 6430Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_rid) 6440Sstevel@tonic-gate roperand++; 6450Sstevel@tonic-gate break; 6460Sstevel@tonic-gate 6470Sstevel@tonic-gate case P_CID: 6480Sstevel@tonic-gate if (tp->t_cid == psp->p_rid) 6490Sstevel@tonic-gate roperand++; 6500Sstevel@tonic-gate break; 6510Sstevel@tonic-gate 6520Sstevel@tonic-gate case P_UID: 6530Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 6540Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_rid) 6550Sstevel@tonic-gate roperand++; 6560Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 6570Sstevel@tonic-gate break; 6580Sstevel@tonic-gate 6590Sstevel@tonic-gate case P_GID: 6600Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 6610Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_rid) 6620Sstevel@tonic-gate roperand++; 6630Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 6640Sstevel@tonic-gate break; 6650Sstevel@tonic-gate 6660Sstevel@tonic-gate case P_PROJID: 6670Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 6680Sstevel@tonic-gate roperand++; 6690Sstevel@tonic-gate break; 6700Sstevel@tonic-gate 6710Sstevel@tonic-gate case P_POOLID: 6720Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_rid) 6730Sstevel@tonic-gate roperand++; 6740Sstevel@tonic-gate break; 6750Sstevel@tonic-gate 6760Sstevel@tonic-gate case P_ZONEID: 6770Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_rid) 6780Sstevel@tonic-gate roperand++; 6790Sstevel@tonic-gate break; 6800Sstevel@tonic-gate 6810Sstevel@tonic-gate case P_CTID: 6820Sstevel@tonic-gate if (PRCTID(pp) == psp->p_rid) 6830Sstevel@tonic-gate roperand++; 6840Sstevel@tonic-gate break; 6850Sstevel@tonic-gate 6860Sstevel@tonic-gate case P_ALL: 6870Sstevel@tonic-gate roperand++; 6880Sstevel@tonic-gate break; 6890Sstevel@tonic-gate 6900Sstevel@tonic-gate default: 6910Sstevel@tonic-gate #ifdef DEBUG 6920Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 6930Sstevel@tonic-gate return (0); 6940Sstevel@tonic-gate #else 6950Sstevel@tonic-gate return (0); 6960Sstevel@tonic-gate #endif 6970Sstevel@tonic-gate } 6980Sstevel@tonic-gate 6990Sstevel@tonic-gate if (lwplinset && lwprinset) 7000Sstevel@tonic-gate *done = 1; 7010Sstevel@tonic-gate 7020Sstevel@tonic-gate switch (psp->p_op) { 7030Sstevel@tonic-gate 7040Sstevel@tonic-gate case POP_DIFF: 7050Sstevel@tonic-gate if ((loperand || lwplinset) && !(lwprinset || roperand)) 7060Sstevel@tonic-gate return (1); 7070Sstevel@tonic-gate else 7080Sstevel@tonic-gate return (0); 7090Sstevel@tonic-gate 7100Sstevel@tonic-gate case POP_AND: 7110Sstevel@tonic-gate if ((loperand || lwplinset) && (roperand || lwprinset)) 7120Sstevel@tonic-gate return (1); 7130Sstevel@tonic-gate else 7140Sstevel@tonic-gate return (0); 7150Sstevel@tonic-gate 7160Sstevel@tonic-gate case POP_OR: 7170Sstevel@tonic-gate if (loperand || roperand || lwplinset || lwprinset) 7180Sstevel@tonic-gate return (1); 7190Sstevel@tonic-gate else 7200Sstevel@tonic-gate return (0); 7210Sstevel@tonic-gate 7220Sstevel@tonic-gate case POP_XOR: 7230Sstevel@tonic-gate if (((loperand || lwplinset) && 7240Sstevel@tonic-gate !(lwprinset || roperand)) || 7250Sstevel@tonic-gate ((roperand || lwprinset) && 7260Sstevel@tonic-gate !(lwplinset || loperand))) 7270Sstevel@tonic-gate return (1); 7280Sstevel@tonic-gate else 7290Sstevel@tonic-gate return (0); 7300Sstevel@tonic-gate 7310Sstevel@tonic-gate default: 7320Sstevel@tonic-gate #ifdef DEBUG 7330Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 7340Sstevel@tonic-gate return (0); 7350Sstevel@tonic-gate #else 7360Sstevel@tonic-gate return (0); 7370Sstevel@tonic-gate #endif 7380Sstevel@tonic-gate } 7390Sstevel@tonic-gate /* NOTREACHED */ 7400Sstevel@tonic-gate } 7410Sstevel@tonic-gate /* 7420Sstevel@tonic-gate * Check for common cases of procsets which specify only the 7430Sstevel@tonic-gate * current process. cur_inset_only() returns B_TRUE when 7440Sstevel@tonic-gate * the current process is the only one in the set. B_FALSE 7450Sstevel@tonic-gate * is returned to indicate that this may not be the case. 7460Sstevel@tonic-gate */ 7470Sstevel@tonic-gate boolean_t 7480Sstevel@tonic-gate cur_inset_only(procset_t *psp) 7490Sstevel@tonic-gate { 7500Sstevel@tonic-gate if (((psp->p_lidtype == P_PID && 7510Sstevel@tonic-gate (psp->p_lid == P_MYID || 7520Sstevel@tonic-gate psp->p_lid == ttoproc(curthread)->p_pid)) || 7530Sstevel@tonic-gate ((psp->p_lidtype == P_LWPID) && 7540Sstevel@tonic-gate (psp->p_lid == P_MYID || 7550Sstevel@tonic-gate psp->p_lid == curthread->t_tid))) && 7560Sstevel@tonic-gate psp->p_op == POP_AND && psp->p_ridtype == P_ALL) 7570Sstevel@tonic-gate return (B_TRUE); 7580Sstevel@tonic-gate 7590Sstevel@tonic-gate if (((psp->p_ridtype == P_PID && 7600Sstevel@tonic-gate (psp->p_rid == P_MYID || 7610Sstevel@tonic-gate psp->p_rid == ttoproc(curthread)->p_pid)) || 7620Sstevel@tonic-gate ((psp->p_ridtype == P_LWPID) && 7630Sstevel@tonic-gate (psp->p_rid == P_MYID || 7640Sstevel@tonic-gate psp->p_rid == curthread->t_tid))) && 7650Sstevel@tonic-gate psp->p_op == POP_AND && psp->p_lidtype == P_ALL) 7660Sstevel@tonic-gate return (B_TRUE); 7670Sstevel@tonic-gate 7680Sstevel@tonic-gate return (B_FALSE); 7690Sstevel@tonic-gate } 7700Sstevel@tonic-gate 7710Sstevel@tonic-gate id_t 7720Sstevel@tonic-gate getmyid(idtype_t idtype) 7730Sstevel@tonic-gate { 7740Sstevel@tonic-gate proc_t *pp; 7750Sstevel@tonic-gate uid_t uid; 7760Sstevel@tonic-gate gid_t gid; 7772712Snn35248 pid_t sid; 7780Sstevel@tonic-gate 7790Sstevel@tonic-gate pp = ttoproc(curthread); 7800Sstevel@tonic-gate 7810Sstevel@tonic-gate switch (idtype) { 7820Sstevel@tonic-gate case P_LWPID: 7830Sstevel@tonic-gate return (curthread->t_tid); 7840Sstevel@tonic-gate 7850Sstevel@tonic-gate case P_PID: 7860Sstevel@tonic-gate return (pp->p_pid); 7870Sstevel@tonic-gate 7880Sstevel@tonic-gate case P_PPID: 7890Sstevel@tonic-gate return (pp->p_ppid); 7900Sstevel@tonic-gate 7910Sstevel@tonic-gate case P_PGID: 7920Sstevel@tonic-gate return (pp->p_pgrp); 7930Sstevel@tonic-gate 7940Sstevel@tonic-gate case P_SID: 7952712Snn35248 mutex_enter(&pp->p_splock); 7962712Snn35248 sid = pp->p_sessp->s_sid; 7972712Snn35248 mutex_exit(&pp->p_splock); 7982712Snn35248 return (sid); 7990Sstevel@tonic-gate 8000Sstevel@tonic-gate case P_TASKID: 8010Sstevel@tonic-gate return (pp->p_task->tk_tkid); 8020Sstevel@tonic-gate 8030Sstevel@tonic-gate case P_CID: 8040Sstevel@tonic-gate return (curthread->t_cid); 8050Sstevel@tonic-gate 8060Sstevel@tonic-gate case P_UID: 8070Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 8080Sstevel@tonic-gate uid = crgetuid(pp->p_cred); 8090Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 8100Sstevel@tonic-gate return (uid); 8110Sstevel@tonic-gate 8120Sstevel@tonic-gate case P_GID: 8130Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 8140Sstevel@tonic-gate gid = crgetgid(pp->p_cred); 8150Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 8160Sstevel@tonic-gate return (gid); 8170Sstevel@tonic-gate 8180Sstevel@tonic-gate case P_PROJID: 8190Sstevel@tonic-gate return (pp->p_task->tk_proj->kpj_id); 8200Sstevel@tonic-gate 8210Sstevel@tonic-gate case P_POOLID: 8220Sstevel@tonic-gate return (pp->p_pool->pool_id); 8230Sstevel@tonic-gate 8240Sstevel@tonic-gate case P_ZONEID: 8250Sstevel@tonic-gate return (pp->p_zone->zone_id); 8260Sstevel@tonic-gate 8270Sstevel@tonic-gate case P_CTID: 8280Sstevel@tonic-gate return (PRCTID(pp)); 8290Sstevel@tonic-gate 8300Sstevel@tonic-gate case P_ALL: 8310Sstevel@tonic-gate /* 8320Sstevel@tonic-gate * The value doesn't matter for P_ALL. 8330Sstevel@tonic-gate */ 8340Sstevel@tonic-gate return (0); 8350Sstevel@tonic-gate 8360Sstevel@tonic-gate default: 8370Sstevel@tonic-gate return (-1); 8380Sstevel@tonic-gate } 8390Sstevel@tonic-gate } 8400Sstevel@tonic-gate 8410Sstevel@tonic-gate static kthread_t * 8420Sstevel@tonic-gate getlwpptr(id_t id) 8430Sstevel@tonic-gate { 8440Sstevel@tonic-gate proc_t *p; 8450Sstevel@tonic-gate kthread_t *t; 8460Sstevel@tonic-gate 8470Sstevel@tonic-gate if (id == P_MYID) 8480Sstevel@tonic-gate t = curthread; 8490Sstevel@tonic-gate else { 8500Sstevel@tonic-gate p = ttoproc(curthread); 8510Sstevel@tonic-gate mutex_enter(&p->p_lock); 8520Sstevel@tonic-gate t = idtot(p, id); 8530Sstevel@tonic-gate mutex_exit(&p->p_lock); 8540Sstevel@tonic-gate } 8550Sstevel@tonic-gate 8560Sstevel@tonic-gate return (t); 8570Sstevel@tonic-gate } 8580Sstevel@tonic-gate 8590Sstevel@tonic-gate /* 8600Sstevel@tonic-gate * The dotolwp function locates the LWP(s) specified by the procset structure 8610Sstevel@tonic-gate * pointed to by psp. If funcp is non-NULL then it points to a function 8620Sstevel@tonic-gate * which dotolwp will call for each LWP in the specified set. 8630Sstevel@tonic-gate * LWPIDs specified in the procset structure always refer to lwps in curproc. 8640Sstevel@tonic-gate * The arguments for this function must be "char *arg", and "kthread_t *tp", 8650Sstevel@tonic-gate * where tp is a pointer to the current thread from the set. 8660Sstevel@tonic-gate * Note that these arguments are passed to the function in reversed order 8670Sstevel@tonic-gate * than the order of arguments passed by dotoprocs() to its callback function. 8680Sstevel@tonic-gate * Also note that there are two separate cases where this routine returns zero. 8690Sstevel@tonic-gate * In the first case no mutex is grabbed, in the second the p_lock mutex 8700Sstevel@tonic-gate * is NOT RELEASED. The priocntl code is expecting this behaviour. 8710Sstevel@tonic-gate */ 8720Sstevel@tonic-gate int 8730Sstevel@tonic-gate dotolwp(procset_t *psp, int (*funcp)(), char *arg) 8740Sstevel@tonic-gate { 8750Sstevel@tonic-gate int error = 0; 8760Sstevel@tonic-gate int nfound = 0; 8770Sstevel@tonic-gate kthread_t *tp; 8780Sstevel@tonic-gate proc_t *pp; 8790Sstevel@tonic-gate int done = 0; 8800Sstevel@tonic-gate 8810Sstevel@tonic-gate /* 8820Sstevel@tonic-gate * Check that the procset_t is valid. 8830Sstevel@tonic-gate */ 8840Sstevel@tonic-gate error = checkprocset(psp); 8850Sstevel@tonic-gate if (error) { 8860Sstevel@tonic-gate return (error); 8870Sstevel@tonic-gate } 8880Sstevel@tonic-gate 8890Sstevel@tonic-gate mutex_enter(&pidlock); 8900Sstevel@tonic-gate 8910Sstevel@tonic-gate /* 8920Sstevel@tonic-gate * Check for the special value P_MYID in either operand 8930Sstevel@tonic-gate * and replace it with the correct value. We don't check 8940Sstevel@tonic-gate * for an error return from getmyid() because the idtypes 8950Sstevel@tonic-gate * have been validated by the checkprocset() call above. 8960Sstevel@tonic-gate */ 8970Sstevel@tonic-gate if (psp->p_lid == P_MYID) { 8980Sstevel@tonic-gate psp->p_lid = getmyid(psp->p_lidtype); 8990Sstevel@tonic-gate } 9000Sstevel@tonic-gate if (psp->p_rid == P_MYID) { 9010Sstevel@tonic-gate psp->p_rid = getmyid(psp->p_ridtype); 9020Sstevel@tonic-gate } 9030Sstevel@tonic-gate 9040Sstevel@tonic-gate pp = ttoproc(curthread); 9050Sstevel@tonic-gate 9060Sstevel@tonic-gate if (procinset(pp, psp)) { 9070Sstevel@tonic-gate mutex_exit(&pidlock); 9080Sstevel@tonic-gate return (0); 9090Sstevel@tonic-gate } 9100Sstevel@tonic-gate mutex_enter(&pp->p_lock); 9110Sstevel@tonic-gate if ((tp = pp->p_tlist) == NULL) { 9120Sstevel@tonic-gate mutex_exit(&pp->p_lock); 9130Sstevel@tonic-gate mutex_exit(&pidlock); 9140Sstevel@tonic-gate return (0); 9150Sstevel@tonic-gate } 9160Sstevel@tonic-gate do { 9170Sstevel@tonic-gate if (lwpinset(pp, psp, tp, &done)) { 9180Sstevel@tonic-gate nfound ++; 9190Sstevel@tonic-gate error = (*funcp)(arg, tp); 9200Sstevel@tonic-gate if (error) { 9210Sstevel@tonic-gate mutex_exit(&pp->p_lock); 9220Sstevel@tonic-gate mutex_exit(&pidlock); 9230Sstevel@tonic-gate return (error); 9240Sstevel@tonic-gate } 9250Sstevel@tonic-gate } 9260Sstevel@tonic-gate } while (((tp = tp->t_forw) != pp->p_tlist) && !done); 9270Sstevel@tonic-gate 9280Sstevel@tonic-gate if (nfound == 0) { 9290Sstevel@tonic-gate mutex_exit(&pp->p_lock); 9300Sstevel@tonic-gate mutex_exit(&pidlock); 9310Sstevel@tonic-gate return (ESRCH); 9320Sstevel@tonic-gate } 9330Sstevel@tonic-gate 9340Sstevel@tonic-gate mutex_exit(&pidlock); 9350Sstevel@tonic-gate return (error); 9360Sstevel@tonic-gate } 937