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 5*2712Snn35248 * Common Development and Distribution License (the "License"). 6*2712Snn35248 * 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*2712Snn35248 * Copyright 2006 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 720Sstevel@tonic-gate * by the procset structure pointed to by psp. If funcp 730Sstevel@tonic-gate * is non-NULL then it points to a function which dotoprocs 740Sstevel@tonic-gate * will call for each process in the specified set. The 750Sstevel@tonic-gate * arguments to this function will be a pointer to the 760Sstevel@tonic-gate * current process from the set and arg. 770Sstevel@tonic-gate * If the called function returns -1, it means that processing of the 780Sstevel@tonic-gate * procset should stop and a normal (non-error) return should be made 790Sstevel@tonic-gate * to the caller of dotoprocs. 800Sstevel@tonic-gate * If the called function returns any other non-zero value the search 810Sstevel@tonic-gate * is terminated and the function's return value is returned to 820Sstevel@tonic-gate * the caller of dotoprocs. This will normally be an error code. 830Sstevel@tonic-gate * Otherwise, dotoprocs will return zero after processing the entire 840Sstevel@tonic-gate * process set unless no processes were found in which case ESRCH will 850Sstevel@tonic-gate * be returned. 860Sstevel@tonic-gate */ 870Sstevel@tonic-gate int 880Sstevel@tonic-gate dotoprocs(procset_t *psp, int (*funcp)(), char *arg) 890Sstevel@tonic-gate { 900Sstevel@tonic-gate proc_t *prp; /* A process from the set */ 910Sstevel@tonic-gate int error; 920Sstevel@tonic-gate int nfound; /* Nbr of processes found. */ 930Sstevel@tonic-gate proc_t *lastprp; /* Last proc found. */ 940Sstevel@tonic-gate 950Sstevel@tonic-gate /* 960Sstevel@tonic-gate * Check that the procset_t is valid. 970Sstevel@tonic-gate */ 980Sstevel@tonic-gate error = checkprocset(psp); 990Sstevel@tonic-gate if (error) { 1000Sstevel@tonic-gate return (error); 1010Sstevel@tonic-gate } 1020Sstevel@tonic-gate /* 1030Sstevel@tonic-gate * Check for the special value P_MYID in either operand 1040Sstevel@tonic-gate * and replace it with the correct value. We don't check 1050Sstevel@tonic-gate * for an error return from getmyid() because the idtypes 1060Sstevel@tonic-gate * have been validated by the checkprocset() call above. 1070Sstevel@tonic-gate */ 1080Sstevel@tonic-gate mutex_enter(&pidlock); 1090Sstevel@tonic-gate if (psp->p_lid == P_MYID) { 1100Sstevel@tonic-gate psp->p_lid = getmyid(psp->p_lidtype); 1110Sstevel@tonic-gate } 1120Sstevel@tonic-gate if (psp->p_rid == P_MYID) { 1130Sstevel@tonic-gate psp->p_rid = getmyid(psp->p_ridtype); 1140Sstevel@tonic-gate } 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate /* 1170Sstevel@tonic-gate * If psp only acts on a single proc, we can reduce pidlock hold time 1180Sstevel@tonic-gate * by avoiding a needless scan of the entire proc list. Although 1190Sstevel@tonic-gate * there are many procset_t combinations which might boil down to a 1200Sstevel@tonic-gate * single proc, the most common case is an AND operation where one 1210Sstevel@tonic-gate * side is a specific pid, and the other side is P_ALL, so that is 1220Sstevel@tonic-gate * the case for which we will provide a fast path. Other cases could 1230Sstevel@tonic-gate * be added in a similar fashion if they were to become significant 1240Sstevel@tonic-gate * pidlock bottlenecks. 1250Sstevel@tonic-gate * 1260Sstevel@tonic-gate * Perform the check symmetrically: either the left or right side may 1270Sstevel@tonic-gate * specify a pid, with the opposite side being 'all'. 1280Sstevel@tonic-gate */ 1290Sstevel@tonic-gate if (psp->p_op == POP_AND) { 1300Sstevel@tonic-gate if (((psp->p_lidtype == P_PID) && (psp->p_ridtype == P_ALL)) || 1310Sstevel@tonic-gate ((psp->p_ridtype == P_PID) && (psp->p_lidtype == P_ALL))) { 1320Sstevel@tonic-gate id_t pid; 1330Sstevel@tonic-gate 1340Sstevel@tonic-gate pid = (psp->p_lidtype == P_PID) ? 1350Sstevel@tonic-gate psp->p_lid : psp->p_rid; 1360Sstevel@tonic-gate if ((prp = prfind((pid_t)pid)) == NULL) { 1370Sstevel@tonic-gate /* specified proc doesn't exist */ 1380Sstevel@tonic-gate mutex_exit(&pidlock); 1390Sstevel@tonic-gate return (ESRCH); 1400Sstevel@tonic-gate } 1410Sstevel@tonic-gate /* operate only on the specified proc */ 1420Sstevel@tonic-gate error = (*funcp)(prp, arg); 1430Sstevel@tonic-gate mutex_exit(&pidlock); 1440Sstevel@tonic-gate if (error == -1) 1450Sstevel@tonic-gate error = 0; 1460Sstevel@tonic-gate return (error); 1470Sstevel@tonic-gate } 1480Sstevel@tonic-gate } 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate nfound = 0; 1510Sstevel@tonic-gate error = 0; 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate for (prp = practive; prp != NULL; prp = prp->p_next) { 1540Sstevel@tonic-gate /* 1550Sstevel@tonic-gate * If caller is in a non-global zone, skip processes 1560Sstevel@tonic-gate * in other zones. 1570Sstevel@tonic-gate */ 1580Sstevel@tonic-gate if (!HASZONEACCESS(curproc, prp->p_zone->zone_id)) 1590Sstevel@tonic-gate continue; 1600Sstevel@tonic-gate if (prp->p_stat == SIDL || prp->p_stat == SZOMB || 1610Sstevel@tonic-gate prp->p_tlist == NULL || prp->p_flag & SSYS) 1620Sstevel@tonic-gate continue; 1630Sstevel@tonic-gate if (procinset(prp, psp)) { 1640Sstevel@tonic-gate nfound++; 1650Sstevel@tonic-gate lastprp = prp; 1660Sstevel@tonic-gate if (funcp != NULL && prp != proc_init) { 1670Sstevel@tonic-gate error = (*funcp)(prp, arg); 1680Sstevel@tonic-gate if (error == -1) { 1690Sstevel@tonic-gate mutex_exit(&pidlock); 1700Sstevel@tonic-gate return (0); 1710Sstevel@tonic-gate } else if (error) { 1720Sstevel@tonic-gate mutex_exit(&pidlock); 1730Sstevel@tonic-gate return (error); 1740Sstevel@tonic-gate } 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate } 1770Sstevel@tonic-gate } 1780Sstevel@tonic-gate if (nfound == 0) { 1790Sstevel@tonic-gate mutex_exit(&pidlock); 1800Sstevel@tonic-gate return (ESRCH); 1810Sstevel@tonic-gate } 1820Sstevel@tonic-gate if (nfound == 1 && lastprp == proc_init && funcp != NULL) 1830Sstevel@tonic-gate error = (*funcp)(lastprp, arg); 1840Sstevel@tonic-gate if (error == -1) 1850Sstevel@tonic-gate error = 0; 1860Sstevel@tonic-gate mutex_exit(&pidlock); 1870Sstevel@tonic-gate return (error); 1880Sstevel@tonic-gate } 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate /* 1910Sstevel@tonic-gate * Check if a procset_t is valid. Return zero or an errno. 1920Sstevel@tonic-gate */ 1930Sstevel@tonic-gate int 1940Sstevel@tonic-gate checkprocset(procset_t *psp) 1950Sstevel@tonic-gate { 1960Sstevel@tonic-gate switch (psp->p_lidtype) { 1970Sstevel@tonic-gate case P_LWPID: 1980Sstevel@tonic-gate case P_PID: 1990Sstevel@tonic-gate case P_PPID: 2000Sstevel@tonic-gate case P_PGID: 2010Sstevel@tonic-gate case P_SID: 2020Sstevel@tonic-gate case P_TASKID: 2030Sstevel@tonic-gate case P_CID: 2040Sstevel@tonic-gate case P_UID: 2050Sstevel@tonic-gate case P_GID: 2060Sstevel@tonic-gate case P_PROJID: 2070Sstevel@tonic-gate case P_POOLID: 2080Sstevel@tonic-gate case P_ZONEID: 2090Sstevel@tonic-gate case P_CTID: 2100Sstevel@tonic-gate case P_ALL: 2110Sstevel@tonic-gate break; 2120Sstevel@tonic-gate default: 2130Sstevel@tonic-gate return (EINVAL); 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate switch (psp->p_ridtype) { 2170Sstevel@tonic-gate case P_LWPID: 2180Sstevel@tonic-gate case P_PID: 2190Sstevel@tonic-gate case P_PPID: 2200Sstevel@tonic-gate case P_PGID: 2210Sstevel@tonic-gate case P_SID: 2220Sstevel@tonic-gate case P_TASKID: 2230Sstevel@tonic-gate case P_CID: 2240Sstevel@tonic-gate case P_UID: 2250Sstevel@tonic-gate case P_GID: 2260Sstevel@tonic-gate case P_PROJID: 2270Sstevel@tonic-gate case P_POOLID: 2280Sstevel@tonic-gate case P_ZONEID: 2290Sstevel@tonic-gate case P_CTID: 2300Sstevel@tonic-gate case P_ALL: 2310Sstevel@tonic-gate break; 2320Sstevel@tonic-gate default: 2330Sstevel@tonic-gate return (EINVAL); 2340Sstevel@tonic-gate } 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate switch (psp->p_op) { 2370Sstevel@tonic-gate case POP_DIFF: 2380Sstevel@tonic-gate case POP_AND: 2390Sstevel@tonic-gate case POP_OR: 2400Sstevel@tonic-gate case POP_XOR: 2410Sstevel@tonic-gate break; 2420Sstevel@tonic-gate default: 2430Sstevel@tonic-gate return (EINVAL); 2440Sstevel@tonic-gate } 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate return (0); 2470Sstevel@tonic-gate } 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate /* 2500Sstevel@tonic-gate * procinset returns 1 if the process pointed to 2510Sstevel@tonic-gate * by pp is in the process set specified by psp, otherwise 0 is returned. 2520Sstevel@tonic-gate * The caller should check that the process is not exiting and is not 2530Sstevel@tonic-gate * in the SYS scheduling class. 2540Sstevel@tonic-gate * 2550Sstevel@tonic-gate * This function expects to be called with a valid procset_t. 2560Sstevel@tonic-gate * The set should be checked using checkprocset() before calling 2570Sstevel@tonic-gate * this function. 2580Sstevel@tonic-gate */ 2590Sstevel@tonic-gate int 2600Sstevel@tonic-gate procinset(proc_t *pp, procset_t *psp) 2610Sstevel@tonic-gate { 2620Sstevel@tonic-gate int loperand = 0; 2630Sstevel@tonic-gate int roperand = 0; 2640Sstevel@tonic-gate int lwplinproc = 0; 2650Sstevel@tonic-gate int lwprinproc = 0; 2660Sstevel@tonic-gate kthread_t *tp = proctot(pp); 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate switch (psp->p_lidtype) { 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate case P_LWPID: 2710Sstevel@tonic-gate if (pp == ttoproc(curthread)) 2720Sstevel@tonic-gate if (getlwpptr(psp->p_lid) != NULL) 2730Sstevel@tonic-gate lwplinproc++; 2740Sstevel@tonic-gate break; 2750Sstevel@tonic-gate 2760Sstevel@tonic-gate case P_PID: 2770Sstevel@tonic-gate if (pp->p_pid == psp->p_lid) 2780Sstevel@tonic-gate loperand++; 2790Sstevel@tonic-gate break; 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate case P_PPID: 2820Sstevel@tonic-gate if (pp->p_ppid == psp->p_lid) 2830Sstevel@tonic-gate loperand++; 2840Sstevel@tonic-gate break; 2850Sstevel@tonic-gate 2860Sstevel@tonic-gate case P_PGID: 2870Sstevel@tonic-gate if (pp->p_pgrp == psp->p_lid) 2880Sstevel@tonic-gate loperand++; 2890Sstevel@tonic-gate break; 2900Sstevel@tonic-gate 2910Sstevel@tonic-gate case P_SID: 292*2712Snn35248 mutex_enter(&pp->p_splock); 2930Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_lid) 2940Sstevel@tonic-gate loperand++; 295*2712Snn35248 mutex_exit(&pp->p_splock); 2960Sstevel@tonic-gate break; 2970Sstevel@tonic-gate 2980Sstevel@tonic-gate case P_CID: 2990Sstevel@tonic-gate ASSERT(tp != NULL); 3000Sstevel@tonic-gate /* This case is broken for now. Need to be fixed XXX */ 3010Sstevel@tonic-gate if (tp->t_cid == psp->p_lid) 3020Sstevel@tonic-gate /* 3030Sstevel@tonic-gate * if (checkcid(psp->p_lid)) 3040Sstevel@tonic-gate */ 3050Sstevel@tonic-gate loperand++; 3060Sstevel@tonic-gate break; 3070Sstevel@tonic-gate 3080Sstevel@tonic-gate case P_TASKID: 3090Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_lid) 3100Sstevel@tonic-gate loperand++; 3110Sstevel@tonic-gate break; 3120Sstevel@tonic-gate 3130Sstevel@tonic-gate case P_UID: 3140Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 3150Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_lid) 3160Sstevel@tonic-gate loperand++; 3170Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 3180Sstevel@tonic-gate break; 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate case P_GID: 3210Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 3220Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_lid) 3230Sstevel@tonic-gate loperand++; 3240Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 3250Sstevel@tonic-gate break; 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate case P_PROJID: 3280Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 3290Sstevel@tonic-gate loperand++; 3300Sstevel@tonic-gate break; 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate case P_POOLID: 3330Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_lid) 3340Sstevel@tonic-gate loperand++; 3350Sstevel@tonic-gate break; 3360Sstevel@tonic-gate 3370Sstevel@tonic-gate case P_ZONEID: 3380Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_lid) 3390Sstevel@tonic-gate loperand++; 3400Sstevel@tonic-gate break; 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate case P_CTID: 3430Sstevel@tonic-gate if (PRCTID(pp) == psp->p_lid) 3440Sstevel@tonic-gate loperand++; 3450Sstevel@tonic-gate break; 3460Sstevel@tonic-gate 3470Sstevel@tonic-gate case P_ALL: 3480Sstevel@tonic-gate loperand++; 3490Sstevel@tonic-gate break; 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate default: 3520Sstevel@tonic-gate #ifdef DEBUG 3530Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 3540Sstevel@tonic-gate return (0); 3550Sstevel@tonic-gate #else 3560Sstevel@tonic-gate return (0); 3570Sstevel@tonic-gate #endif 3580Sstevel@tonic-gate } 3590Sstevel@tonic-gate 3600Sstevel@tonic-gate switch (psp->p_ridtype) { 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate case P_LWPID: 3630Sstevel@tonic-gate if (pp == ttoproc(curthread)) 3640Sstevel@tonic-gate if (getlwpptr(psp->p_rid) != NULL) 3650Sstevel@tonic-gate lwprinproc++; 3660Sstevel@tonic-gate break; 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate case P_PID: 3690Sstevel@tonic-gate if (pp->p_pid == psp->p_rid) 3700Sstevel@tonic-gate roperand++; 3710Sstevel@tonic-gate break; 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate case P_PPID: 3740Sstevel@tonic-gate if (pp->p_ppid == psp->p_rid) 3750Sstevel@tonic-gate roperand++; 3760Sstevel@tonic-gate break; 3770Sstevel@tonic-gate 3780Sstevel@tonic-gate case P_PGID: 3790Sstevel@tonic-gate if (pp->p_pgrp == psp->p_rid) 3800Sstevel@tonic-gate roperand++; 3810Sstevel@tonic-gate break; 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate case P_SID: 384*2712Snn35248 mutex_enter(&pp->p_splock); 3850Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_rid) 3860Sstevel@tonic-gate roperand++; 387*2712Snn35248 mutex_exit(&pp->p_splock); 3880Sstevel@tonic-gate break; 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate case P_TASKID: 3910Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_rid) 3920Sstevel@tonic-gate roperand++; 3930Sstevel@tonic-gate break; 3940Sstevel@tonic-gate 3950Sstevel@tonic-gate case P_CID: 3960Sstevel@tonic-gate ASSERT(tp != NULL); 3970Sstevel@tonic-gate /* This case is broken for now. Need to be fixed XXX */ 3980Sstevel@tonic-gate if (tp->t_cid == psp->p_rid) 3990Sstevel@tonic-gate /* 4000Sstevel@tonic-gate * if (checkcid(psp->p_rid)) 4010Sstevel@tonic-gate */ 4020Sstevel@tonic-gate roperand++; 4030Sstevel@tonic-gate break; 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate case P_UID: 4060Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 4070Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_rid) 4080Sstevel@tonic-gate roperand++; 4090Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 4100Sstevel@tonic-gate break; 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate case P_GID: 4130Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 4140Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_rid) 4150Sstevel@tonic-gate roperand++; 4160Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 4170Sstevel@tonic-gate break; 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate case P_PROJID: 4200Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 4210Sstevel@tonic-gate roperand++; 4220Sstevel@tonic-gate break; 4230Sstevel@tonic-gate 4240Sstevel@tonic-gate case P_POOLID: 4250Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_rid) 4260Sstevel@tonic-gate roperand++; 4270Sstevel@tonic-gate break; 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate case P_ZONEID: 4300Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_rid) 4310Sstevel@tonic-gate roperand++; 4320Sstevel@tonic-gate break; 4330Sstevel@tonic-gate 4340Sstevel@tonic-gate case P_CTID: 4350Sstevel@tonic-gate if (PRCTID(pp) == psp->p_rid) 4360Sstevel@tonic-gate roperand++; 4370Sstevel@tonic-gate break; 4380Sstevel@tonic-gate 4390Sstevel@tonic-gate case P_ALL: 4400Sstevel@tonic-gate roperand++; 4410Sstevel@tonic-gate break; 4420Sstevel@tonic-gate 4430Sstevel@tonic-gate default: 4440Sstevel@tonic-gate #ifdef DEBUG 4450Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 4460Sstevel@tonic-gate return (0); 4470Sstevel@tonic-gate #else 4480Sstevel@tonic-gate return (0); 4490Sstevel@tonic-gate #endif 4500Sstevel@tonic-gate } 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate switch (psp->p_op) { 4530Sstevel@tonic-gate 4540Sstevel@tonic-gate case POP_DIFF: 4550Sstevel@tonic-gate if (loperand && !lwprinproc && !roperand) 4560Sstevel@tonic-gate return (1); 4570Sstevel@tonic-gate else 4580Sstevel@tonic-gate return (0); 4590Sstevel@tonic-gate 4600Sstevel@tonic-gate case POP_AND: 4610Sstevel@tonic-gate if (loperand && roperand) 4620Sstevel@tonic-gate return (1); 4630Sstevel@tonic-gate else 4640Sstevel@tonic-gate return (0); 4650Sstevel@tonic-gate 4660Sstevel@tonic-gate case POP_OR: 4670Sstevel@tonic-gate if (loperand || roperand) 4680Sstevel@tonic-gate return (1); 4690Sstevel@tonic-gate else 4700Sstevel@tonic-gate return (0); 4710Sstevel@tonic-gate 4720Sstevel@tonic-gate case POP_XOR: 4730Sstevel@tonic-gate if ((loperand && !lwprinproc && !roperand) || 4740Sstevel@tonic-gate (roperand && !lwplinproc && !loperand)) 4750Sstevel@tonic-gate return (1); 4760Sstevel@tonic-gate else 4770Sstevel@tonic-gate return (0); 4780Sstevel@tonic-gate 4790Sstevel@tonic-gate default: 4800Sstevel@tonic-gate #ifdef DEBUG 4810Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 4820Sstevel@tonic-gate return (0); 4830Sstevel@tonic-gate #else 4840Sstevel@tonic-gate return (0); 4850Sstevel@tonic-gate #endif 4860Sstevel@tonic-gate } 4870Sstevel@tonic-gate /* NOTREACHED */ 4880Sstevel@tonic-gate } 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate /* 4910Sstevel@tonic-gate * lwpinset returns 1 if the thread pointed to 4920Sstevel@tonic-gate * by tp is in the process set specified by psp and is not in 4930Sstevel@tonic-gate * the sys scheduling class - otherwise 0 is returned. 4940Sstevel@tonic-gate * 4950Sstevel@tonic-gate * This function expects to be called with a valid procset_t. 4960Sstevel@tonic-gate * The set should be checked using checkprocset() before calling 4970Sstevel@tonic-gate * this function. 4980Sstevel@tonic-gate */ 4990Sstevel@tonic-gate int 5000Sstevel@tonic-gate lwpinset(proc_t *pp, procset_t *psp, kthread_t *tp, int *done) 5010Sstevel@tonic-gate { 5020Sstevel@tonic-gate int loperand = 0; 5030Sstevel@tonic-gate int roperand = 0; 5040Sstevel@tonic-gate int lwplinset = 0; 5050Sstevel@tonic-gate int lwprinset = 0; 5060Sstevel@tonic-gate 5070Sstevel@tonic-gate ASSERT(ttoproc(tp) == pp); 5080Sstevel@tonic-gate 5090Sstevel@tonic-gate /* 5100Sstevel@tonic-gate * If process is in the sys class return (0). 5110Sstevel@tonic-gate */ 5120Sstevel@tonic-gate if (proctot(pp)->t_cid == 0) { 5130Sstevel@tonic-gate return (0); 5140Sstevel@tonic-gate } 5150Sstevel@tonic-gate 5160Sstevel@tonic-gate switch (psp->p_lidtype) { 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate case P_LWPID: 5190Sstevel@tonic-gate if (tp->t_tid == psp->p_lid) 5200Sstevel@tonic-gate lwplinset ++; 5210Sstevel@tonic-gate break; 5220Sstevel@tonic-gate 5230Sstevel@tonic-gate case P_PID: 5240Sstevel@tonic-gate if (pp->p_pid == psp->p_lid) 5250Sstevel@tonic-gate loperand++; 5260Sstevel@tonic-gate break; 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate case P_PPID: 5290Sstevel@tonic-gate if (pp->p_ppid == psp->p_lid) 5300Sstevel@tonic-gate loperand++; 5310Sstevel@tonic-gate break; 5320Sstevel@tonic-gate 5330Sstevel@tonic-gate case P_PGID: 5340Sstevel@tonic-gate if (pp->p_pgrp == psp->p_lid) 5350Sstevel@tonic-gate loperand++; 5360Sstevel@tonic-gate break; 5370Sstevel@tonic-gate 5380Sstevel@tonic-gate case P_SID: 539*2712Snn35248 mutex_enter(&pp->p_splock); 5400Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_lid) 5410Sstevel@tonic-gate loperand++; 542*2712Snn35248 mutex_exit(&pp->p_splock); 5430Sstevel@tonic-gate break; 5440Sstevel@tonic-gate 5450Sstevel@tonic-gate case P_TASKID: 5460Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_lid) 5470Sstevel@tonic-gate loperand++; 5480Sstevel@tonic-gate break; 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate case P_CID: 5510Sstevel@tonic-gate if (tp->t_cid == psp->p_lid) 5520Sstevel@tonic-gate loperand++; 5530Sstevel@tonic-gate break; 5540Sstevel@tonic-gate 5550Sstevel@tonic-gate case P_UID: 5560Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 5570Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_lid) 5580Sstevel@tonic-gate loperand++; 5590Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 5600Sstevel@tonic-gate break; 5610Sstevel@tonic-gate 5620Sstevel@tonic-gate case P_GID: 5630Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 5640Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_lid) 5650Sstevel@tonic-gate loperand++; 5660Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 5670Sstevel@tonic-gate break; 5680Sstevel@tonic-gate 5690Sstevel@tonic-gate case P_PROJID: 5700Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 5710Sstevel@tonic-gate loperand++; 5720Sstevel@tonic-gate break; 5730Sstevel@tonic-gate 5740Sstevel@tonic-gate case P_POOLID: 5750Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_lid) 5760Sstevel@tonic-gate loperand++; 5770Sstevel@tonic-gate break; 5780Sstevel@tonic-gate 5790Sstevel@tonic-gate case P_ZONEID: 5800Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_lid) 5810Sstevel@tonic-gate loperand++; 5820Sstevel@tonic-gate break; 5830Sstevel@tonic-gate 5840Sstevel@tonic-gate case P_CTID: 5850Sstevel@tonic-gate if (PRCTID(pp) == psp->p_lid) 5860Sstevel@tonic-gate loperand++; 5870Sstevel@tonic-gate break; 5880Sstevel@tonic-gate 5890Sstevel@tonic-gate case P_ALL: 5900Sstevel@tonic-gate loperand++; 5910Sstevel@tonic-gate break; 5920Sstevel@tonic-gate 5930Sstevel@tonic-gate default: 5940Sstevel@tonic-gate #ifdef DEBUG 5950Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 5960Sstevel@tonic-gate return (0); 5970Sstevel@tonic-gate #else 5980Sstevel@tonic-gate return (0); 5990Sstevel@tonic-gate #endif 6000Sstevel@tonic-gate } 6010Sstevel@tonic-gate 6020Sstevel@tonic-gate switch (psp->p_ridtype) { 6030Sstevel@tonic-gate 6040Sstevel@tonic-gate case P_LWPID: 6050Sstevel@tonic-gate if (tp->t_tid == psp->p_rid) 6060Sstevel@tonic-gate lwprinset ++; 6070Sstevel@tonic-gate break; 6080Sstevel@tonic-gate 6090Sstevel@tonic-gate case P_PID: 6100Sstevel@tonic-gate if (pp->p_pid == psp->p_rid) 6110Sstevel@tonic-gate roperand++; 6120Sstevel@tonic-gate break; 6130Sstevel@tonic-gate 6140Sstevel@tonic-gate case P_PPID: 6150Sstevel@tonic-gate if (pp->p_ppid == psp->p_rid) 6160Sstevel@tonic-gate roperand++; 6170Sstevel@tonic-gate break; 6180Sstevel@tonic-gate 6190Sstevel@tonic-gate case P_PGID: 6200Sstevel@tonic-gate if (pp->p_pgrp == psp->p_rid) 6210Sstevel@tonic-gate roperand++; 6220Sstevel@tonic-gate break; 6230Sstevel@tonic-gate 6240Sstevel@tonic-gate case P_SID: 625*2712Snn35248 mutex_enter(&pp->p_splock); 6260Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_rid) 6270Sstevel@tonic-gate roperand++; 628*2712Snn35248 mutex_exit(&pp->p_splock); 6290Sstevel@tonic-gate break; 6300Sstevel@tonic-gate 6310Sstevel@tonic-gate case P_TASKID: 6320Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_rid) 6330Sstevel@tonic-gate roperand++; 6340Sstevel@tonic-gate break; 6350Sstevel@tonic-gate 6360Sstevel@tonic-gate case P_CID: 6370Sstevel@tonic-gate if (tp->t_cid == psp->p_rid) 6380Sstevel@tonic-gate roperand++; 6390Sstevel@tonic-gate break; 6400Sstevel@tonic-gate 6410Sstevel@tonic-gate case P_UID: 6420Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 6430Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_rid) 6440Sstevel@tonic-gate roperand++; 6450Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 6460Sstevel@tonic-gate break; 6470Sstevel@tonic-gate 6480Sstevel@tonic-gate case P_GID: 6490Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 6500Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_rid) 6510Sstevel@tonic-gate roperand++; 6520Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 6530Sstevel@tonic-gate break; 6540Sstevel@tonic-gate 6550Sstevel@tonic-gate case P_PROJID: 6560Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 6570Sstevel@tonic-gate roperand++; 6580Sstevel@tonic-gate break; 6590Sstevel@tonic-gate 6600Sstevel@tonic-gate case P_POOLID: 6610Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_rid) 6620Sstevel@tonic-gate roperand++; 6630Sstevel@tonic-gate break; 6640Sstevel@tonic-gate 6650Sstevel@tonic-gate case P_ZONEID: 6660Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_rid) 6670Sstevel@tonic-gate roperand++; 6680Sstevel@tonic-gate break; 6690Sstevel@tonic-gate 6700Sstevel@tonic-gate case P_CTID: 6710Sstevel@tonic-gate if (PRCTID(pp) == psp->p_rid) 6720Sstevel@tonic-gate roperand++; 6730Sstevel@tonic-gate break; 6740Sstevel@tonic-gate 6750Sstevel@tonic-gate case P_ALL: 6760Sstevel@tonic-gate roperand++; 6770Sstevel@tonic-gate break; 6780Sstevel@tonic-gate 6790Sstevel@tonic-gate default: 6800Sstevel@tonic-gate #ifdef DEBUG 6810Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 6820Sstevel@tonic-gate return (0); 6830Sstevel@tonic-gate #else 6840Sstevel@tonic-gate return (0); 6850Sstevel@tonic-gate #endif 6860Sstevel@tonic-gate } 6870Sstevel@tonic-gate 6880Sstevel@tonic-gate if (lwplinset && lwprinset) 6890Sstevel@tonic-gate *done = 1; 6900Sstevel@tonic-gate 6910Sstevel@tonic-gate switch (psp->p_op) { 6920Sstevel@tonic-gate 6930Sstevel@tonic-gate case POP_DIFF: 6940Sstevel@tonic-gate if ((loperand || lwplinset) && !(lwprinset || roperand)) 6950Sstevel@tonic-gate return (1); 6960Sstevel@tonic-gate else 6970Sstevel@tonic-gate return (0); 6980Sstevel@tonic-gate 6990Sstevel@tonic-gate case POP_AND: 7000Sstevel@tonic-gate if ((loperand || lwplinset) && (roperand || lwprinset)) 7010Sstevel@tonic-gate return (1); 7020Sstevel@tonic-gate else 7030Sstevel@tonic-gate return (0); 7040Sstevel@tonic-gate 7050Sstevel@tonic-gate case POP_OR: 7060Sstevel@tonic-gate if (loperand || roperand || lwplinset || lwprinset) 7070Sstevel@tonic-gate return (1); 7080Sstevel@tonic-gate else 7090Sstevel@tonic-gate return (0); 7100Sstevel@tonic-gate 7110Sstevel@tonic-gate case POP_XOR: 7120Sstevel@tonic-gate if (((loperand || lwplinset) && 7130Sstevel@tonic-gate !(lwprinset || roperand)) || 7140Sstevel@tonic-gate ((roperand || lwprinset) && 7150Sstevel@tonic-gate !(lwplinset || loperand))) 7160Sstevel@tonic-gate return (1); 7170Sstevel@tonic-gate else 7180Sstevel@tonic-gate return (0); 7190Sstevel@tonic-gate 7200Sstevel@tonic-gate default: 7210Sstevel@tonic-gate #ifdef DEBUG 7220Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 7230Sstevel@tonic-gate return (0); 7240Sstevel@tonic-gate #else 7250Sstevel@tonic-gate return (0); 7260Sstevel@tonic-gate #endif 7270Sstevel@tonic-gate } 7280Sstevel@tonic-gate /* NOTREACHED */ 7290Sstevel@tonic-gate } 7300Sstevel@tonic-gate /* 7310Sstevel@tonic-gate * Check for common cases of procsets which specify only the 7320Sstevel@tonic-gate * current process. cur_inset_only() returns B_TRUE when 7330Sstevel@tonic-gate * the current process is the only one in the set. B_FALSE 7340Sstevel@tonic-gate * is returned to indicate that this may not be the case. 7350Sstevel@tonic-gate */ 7360Sstevel@tonic-gate boolean_t 7370Sstevel@tonic-gate cur_inset_only(procset_t *psp) 7380Sstevel@tonic-gate { 7390Sstevel@tonic-gate if (((psp->p_lidtype == P_PID && 7400Sstevel@tonic-gate (psp->p_lid == P_MYID || 7410Sstevel@tonic-gate psp->p_lid == ttoproc(curthread)->p_pid)) || 7420Sstevel@tonic-gate ((psp->p_lidtype == P_LWPID) && 7430Sstevel@tonic-gate (psp->p_lid == P_MYID || 7440Sstevel@tonic-gate psp->p_lid == curthread->t_tid))) && 7450Sstevel@tonic-gate psp->p_op == POP_AND && psp->p_ridtype == P_ALL) 7460Sstevel@tonic-gate return (B_TRUE); 7470Sstevel@tonic-gate 7480Sstevel@tonic-gate if (((psp->p_ridtype == P_PID && 7490Sstevel@tonic-gate (psp->p_rid == P_MYID || 7500Sstevel@tonic-gate psp->p_rid == ttoproc(curthread)->p_pid)) || 7510Sstevel@tonic-gate ((psp->p_ridtype == P_LWPID) && 7520Sstevel@tonic-gate (psp->p_rid == P_MYID || 7530Sstevel@tonic-gate psp->p_rid == curthread->t_tid))) && 7540Sstevel@tonic-gate psp->p_op == POP_AND && psp->p_lidtype == P_ALL) 7550Sstevel@tonic-gate return (B_TRUE); 7560Sstevel@tonic-gate 7570Sstevel@tonic-gate return (B_FALSE); 7580Sstevel@tonic-gate } 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate id_t 7610Sstevel@tonic-gate getmyid(idtype_t idtype) 7620Sstevel@tonic-gate { 7630Sstevel@tonic-gate proc_t *pp; 7640Sstevel@tonic-gate uid_t uid; 7650Sstevel@tonic-gate gid_t gid; 766*2712Snn35248 pid_t sid; 7670Sstevel@tonic-gate 7680Sstevel@tonic-gate pp = ttoproc(curthread); 7690Sstevel@tonic-gate 7700Sstevel@tonic-gate switch (idtype) { 7710Sstevel@tonic-gate case P_LWPID: 7720Sstevel@tonic-gate return (curthread->t_tid); 7730Sstevel@tonic-gate 7740Sstevel@tonic-gate case P_PID: 7750Sstevel@tonic-gate return (pp->p_pid); 7760Sstevel@tonic-gate 7770Sstevel@tonic-gate case P_PPID: 7780Sstevel@tonic-gate return (pp->p_ppid); 7790Sstevel@tonic-gate 7800Sstevel@tonic-gate case P_PGID: 7810Sstevel@tonic-gate return (pp->p_pgrp); 7820Sstevel@tonic-gate 7830Sstevel@tonic-gate case P_SID: 784*2712Snn35248 mutex_enter(&pp->p_splock); 785*2712Snn35248 sid = pp->p_sessp->s_sid; 786*2712Snn35248 mutex_exit(&pp->p_splock); 787*2712Snn35248 return (sid); 7880Sstevel@tonic-gate 7890Sstevel@tonic-gate case P_TASKID: 7900Sstevel@tonic-gate return (pp->p_task->tk_tkid); 7910Sstevel@tonic-gate 7920Sstevel@tonic-gate case P_CID: 7930Sstevel@tonic-gate return (curthread->t_cid); 7940Sstevel@tonic-gate 7950Sstevel@tonic-gate case P_UID: 7960Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 7970Sstevel@tonic-gate uid = crgetuid(pp->p_cred); 7980Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 7990Sstevel@tonic-gate return (uid); 8000Sstevel@tonic-gate 8010Sstevel@tonic-gate case P_GID: 8020Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 8030Sstevel@tonic-gate gid = crgetgid(pp->p_cred); 8040Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 8050Sstevel@tonic-gate return (gid); 8060Sstevel@tonic-gate 8070Sstevel@tonic-gate case P_PROJID: 8080Sstevel@tonic-gate return (pp->p_task->tk_proj->kpj_id); 8090Sstevel@tonic-gate 8100Sstevel@tonic-gate case P_POOLID: 8110Sstevel@tonic-gate return (pp->p_pool->pool_id); 8120Sstevel@tonic-gate 8130Sstevel@tonic-gate case P_ZONEID: 8140Sstevel@tonic-gate return (pp->p_zone->zone_id); 8150Sstevel@tonic-gate 8160Sstevel@tonic-gate case P_CTID: 8170Sstevel@tonic-gate return (PRCTID(pp)); 8180Sstevel@tonic-gate 8190Sstevel@tonic-gate case P_ALL: 8200Sstevel@tonic-gate /* 8210Sstevel@tonic-gate * The value doesn't matter for P_ALL. 8220Sstevel@tonic-gate */ 8230Sstevel@tonic-gate return (0); 8240Sstevel@tonic-gate 8250Sstevel@tonic-gate default: 8260Sstevel@tonic-gate return (-1); 8270Sstevel@tonic-gate } 8280Sstevel@tonic-gate } 8290Sstevel@tonic-gate 8300Sstevel@tonic-gate static kthread_t * 8310Sstevel@tonic-gate getlwpptr(id_t id) 8320Sstevel@tonic-gate { 8330Sstevel@tonic-gate proc_t *p; 8340Sstevel@tonic-gate kthread_t *t; 8350Sstevel@tonic-gate 8360Sstevel@tonic-gate if (id == P_MYID) 8370Sstevel@tonic-gate t = curthread; 8380Sstevel@tonic-gate else { 8390Sstevel@tonic-gate p = ttoproc(curthread); 8400Sstevel@tonic-gate mutex_enter(&p->p_lock); 8410Sstevel@tonic-gate t = idtot(p, id); 8420Sstevel@tonic-gate mutex_exit(&p->p_lock); 8430Sstevel@tonic-gate } 8440Sstevel@tonic-gate 8450Sstevel@tonic-gate return (t); 8460Sstevel@tonic-gate } 8470Sstevel@tonic-gate 8480Sstevel@tonic-gate /* 8490Sstevel@tonic-gate * The dotolwp function locates the LWP(s) specified by the procset structure 8500Sstevel@tonic-gate * pointed to by psp. If funcp is non-NULL then it points to a function 8510Sstevel@tonic-gate * which dotolwp will call for each LWP in the specified set. 8520Sstevel@tonic-gate * LWPIDs specified in the procset structure always refer to lwps in curproc. 8530Sstevel@tonic-gate * The arguments for this function must be "char *arg", and "kthread_t *tp", 8540Sstevel@tonic-gate * where tp is a pointer to the current thread from the set. 8550Sstevel@tonic-gate * Note that these arguments are passed to the function in reversed order 8560Sstevel@tonic-gate * than the order of arguments passed by dotoprocs() to its callback function. 8570Sstevel@tonic-gate * Also note that there are two separate cases where this routine returns zero. 8580Sstevel@tonic-gate * In the first case no mutex is grabbed, in the second the p_lock mutex 8590Sstevel@tonic-gate * is NOT RELEASED. The priocntl code is expecting this behaviour. 8600Sstevel@tonic-gate */ 8610Sstevel@tonic-gate int 8620Sstevel@tonic-gate dotolwp(procset_t *psp, int (*funcp)(), char *arg) 8630Sstevel@tonic-gate { 8640Sstevel@tonic-gate int error = 0; 8650Sstevel@tonic-gate int nfound = 0; 8660Sstevel@tonic-gate kthread_t *tp; 8670Sstevel@tonic-gate proc_t *pp; 8680Sstevel@tonic-gate int done = 0; 8690Sstevel@tonic-gate 8700Sstevel@tonic-gate /* 8710Sstevel@tonic-gate * Check that the procset_t is valid. 8720Sstevel@tonic-gate */ 8730Sstevel@tonic-gate error = checkprocset(psp); 8740Sstevel@tonic-gate if (error) { 8750Sstevel@tonic-gate return (error); 8760Sstevel@tonic-gate } 8770Sstevel@tonic-gate 8780Sstevel@tonic-gate mutex_enter(&pidlock); 8790Sstevel@tonic-gate 8800Sstevel@tonic-gate /* 8810Sstevel@tonic-gate * Check for the special value P_MYID in either operand 8820Sstevel@tonic-gate * and replace it with the correct value. We don't check 8830Sstevel@tonic-gate * for an error return from getmyid() because the idtypes 8840Sstevel@tonic-gate * have been validated by the checkprocset() call above. 8850Sstevel@tonic-gate */ 8860Sstevel@tonic-gate if (psp->p_lid == P_MYID) { 8870Sstevel@tonic-gate psp->p_lid = getmyid(psp->p_lidtype); 8880Sstevel@tonic-gate } 8890Sstevel@tonic-gate if (psp->p_rid == P_MYID) { 8900Sstevel@tonic-gate psp->p_rid = getmyid(psp->p_ridtype); 8910Sstevel@tonic-gate } 8920Sstevel@tonic-gate 8930Sstevel@tonic-gate pp = ttoproc(curthread); 8940Sstevel@tonic-gate 8950Sstevel@tonic-gate if (procinset(pp, psp)) { 8960Sstevel@tonic-gate mutex_exit(&pidlock); 8970Sstevel@tonic-gate return (0); 8980Sstevel@tonic-gate } 8990Sstevel@tonic-gate mutex_enter(&pp->p_lock); 9000Sstevel@tonic-gate if ((tp = pp->p_tlist) == NULL) { 9010Sstevel@tonic-gate mutex_exit(&pp->p_lock); 9020Sstevel@tonic-gate mutex_exit(&pidlock); 9030Sstevel@tonic-gate return (0); 9040Sstevel@tonic-gate } 9050Sstevel@tonic-gate do { 9060Sstevel@tonic-gate if (lwpinset(pp, psp, tp, &done)) { 9070Sstevel@tonic-gate nfound ++; 9080Sstevel@tonic-gate error = (*funcp)(arg, tp); 9090Sstevel@tonic-gate if (error) { 9100Sstevel@tonic-gate mutex_exit(&pp->p_lock); 9110Sstevel@tonic-gate mutex_exit(&pidlock); 9120Sstevel@tonic-gate return (error); 9130Sstevel@tonic-gate } 9140Sstevel@tonic-gate } 9150Sstevel@tonic-gate } while (((tp = tp->t_forw) != pp->p_tlist) && !done); 9160Sstevel@tonic-gate 9170Sstevel@tonic-gate if (nfound == 0) { 9180Sstevel@tonic-gate mutex_exit(&pp->p_lock); 9190Sstevel@tonic-gate mutex_exit(&pidlock); 9200Sstevel@tonic-gate return (ESRCH); 9210Sstevel@tonic-gate } 9220Sstevel@tonic-gate 9230Sstevel@tonic-gate mutex_exit(&pidlock); 9240Sstevel@tonic-gate return (error); 9250Sstevel@tonic-gate } 926