1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 1.25 */ 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/cred.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/file.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/errno.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 43*7c478bd9Sstevel@tonic-gate #include <sys/user.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/buf.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/var.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/conf.h> 47*7c478bd9Sstevel@tonic-gate #include <sys/debug.h> 48*7c478bd9Sstevel@tonic-gate #include <sys/proc.h> 49*7c478bd9Sstevel@tonic-gate #include <sys/signal.h> 50*7c478bd9Sstevel@tonic-gate #include <sys/siginfo.h> 51*7c478bd9Sstevel@tonic-gate #include <sys/acct.h> 52*7c478bd9Sstevel@tonic-gate #include <sys/procset.h> 53*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 54*7c478bd9Sstevel@tonic-gate #include <sys/fault.h> 55*7c478bd9Sstevel@tonic-gate #include <sys/syscall.h> 56*7c478bd9Sstevel@tonic-gate #include <sys/ucontext.h> 57*7c478bd9Sstevel@tonic-gate #include <sys/procfs.h> 58*7c478bd9Sstevel@tonic-gate #include <sys/session.h> 59*7c478bd9Sstevel@tonic-gate #include <sys/task.h> 60*7c478bd9Sstevel@tonic-gate #include <sys/project.h> 61*7c478bd9Sstevel@tonic-gate #include <sys/pool.h> 62*7c478bd9Sstevel@tonic-gate #include <sys/zone.h> 63*7c478bd9Sstevel@tonic-gate #include <sys/contract/process_impl.h> 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate id_t getmyid(idtype_t); 66*7c478bd9Sstevel@tonic-gate int checkprocset(procset_t *); 67*7c478bd9Sstevel@tonic-gate static kthread_t *getlwpptr(id_t); 68*7c478bd9Sstevel@tonic-gate int procinset(proc_t *, procset_t *); 69*7c478bd9Sstevel@tonic-gate static int lwpinset(proc_t *, procset_t *, kthread_t *, int *); 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate /* 72*7c478bd9Sstevel@tonic-gate * The dotoprocs function locates the process(es) specified 73*7c478bd9Sstevel@tonic-gate * by the procset structure pointed to by psp. If funcp 74*7c478bd9Sstevel@tonic-gate * is non-NULL then it points to a function which dotoprocs 75*7c478bd9Sstevel@tonic-gate * will call for each process in the specified set. The 76*7c478bd9Sstevel@tonic-gate * arguments to this function will be a pointer to the 77*7c478bd9Sstevel@tonic-gate * current process from the set and arg. 78*7c478bd9Sstevel@tonic-gate * If the called function returns -1, it means that processing of the 79*7c478bd9Sstevel@tonic-gate * procset should stop and a normal (non-error) return should be made 80*7c478bd9Sstevel@tonic-gate * to the caller of dotoprocs. 81*7c478bd9Sstevel@tonic-gate * If the called function returns any other non-zero value the search 82*7c478bd9Sstevel@tonic-gate * is terminated and the function's return value is returned to 83*7c478bd9Sstevel@tonic-gate * the caller of dotoprocs. This will normally be an error code. 84*7c478bd9Sstevel@tonic-gate * Otherwise, dotoprocs will return zero after processing the entire 85*7c478bd9Sstevel@tonic-gate * process set unless no processes were found in which case ESRCH will 86*7c478bd9Sstevel@tonic-gate * be returned. 87*7c478bd9Sstevel@tonic-gate */ 88*7c478bd9Sstevel@tonic-gate int 89*7c478bd9Sstevel@tonic-gate dotoprocs(procset_t *psp, int (*funcp)(), char *arg) 90*7c478bd9Sstevel@tonic-gate { 91*7c478bd9Sstevel@tonic-gate proc_t *prp; /* A process from the set */ 92*7c478bd9Sstevel@tonic-gate int error; 93*7c478bd9Sstevel@tonic-gate int nfound; /* Nbr of processes found. */ 94*7c478bd9Sstevel@tonic-gate proc_t *lastprp; /* Last proc found. */ 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate /* 97*7c478bd9Sstevel@tonic-gate * Check that the procset_t is valid. 98*7c478bd9Sstevel@tonic-gate */ 99*7c478bd9Sstevel@tonic-gate error = checkprocset(psp); 100*7c478bd9Sstevel@tonic-gate if (error) { 101*7c478bd9Sstevel@tonic-gate return (error); 102*7c478bd9Sstevel@tonic-gate } 103*7c478bd9Sstevel@tonic-gate /* 104*7c478bd9Sstevel@tonic-gate * Check for the special value P_MYID in either operand 105*7c478bd9Sstevel@tonic-gate * and replace it with the correct value. We don't check 106*7c478bd9Sstevel@tonic-gate * for an error return from getmyid() because the idtypes 107*7c478bd9Sstevel@tonic-gate * have been validated by the checkprocset() call above. 108*7c478bd9Sstevel@tonic-gate */ 109*7c478bd9Sstevel@tonic-gate mutex_enter(&pidlock); 110*7c478bd9Sstevel@tonic-gate if (psp->p_lid == P_MYID) { 111*7c478bd9Sstevel@tonic-gate psp->p_lid = getmyid(psp->p_lidtype); 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate if (psp->p_rid == P_MYID) { 114*7c478bd9Sstevel@tonic-gate psp->p_rid = getmyid(psp->p_ridtype); 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate /* 118*7c478bd9Sstevel@tonic-gate * If psp only acts on a single proc, we can reduce pidlock hold time 119*7c478bd9Sstevel@tonic-gate * by avoiding a needless scan of the entire proc list. Although 120*7c478bd9Sstevel@tonic-gate * there are many procset_t combinations which might boil down to a 121*7c478bd9Sstevel@tonic-gate * single proc, the most common case is an AND operation where one 122*7c478bd9Sstevel@tonic-gate * side is a specific pid, and the other side is P_ALL, so that is 123*7c478bd9Sstevel@tonic-gate * the case for which we will provide a fast path. Other cases could 124*7c478bd9Sstevel@tonic-gate * be added in a similar fashion if they were to become significant 125*7c478bd9Sstevel@tonic-gate * pidlock bottlenecks. 126*7c478bd9Sstevel@tonic-gate * 127*7c478bd9Sstevel@tonic-gate * Perform the check symmetrically: either the left or right side may 128*7c478bd9Sstevel@tonic-gate * specify a pid, with the opposite side being 'all'. 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate if (psp->p_op == POP_AND) { 131*7c478bd9Sstevel@tonic-gate if (((psp->p_lidtype == P_PID) && (psp->p_ridtype == P_ALL)) || 132*7c478bd9Sstevel@tonic-gate ((psp->p_ridtype == P_PID) && (psp->p_lidtype == P_ALL))) { 133*7c478bd9Sstevel@tonic-gate id_t pid; 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate pid = (psp->p_lidtype == P_PID) ? 136*7c478bd9Sstevel@tonic-gate psp->p_lid : psp->p_rid; 137*7c478bd9Sstevel@tonic-gate if ((prp = prfind((pid_t)pid)) == NULL) { 138*7c478bd9Sstevel@tonic-gate /* specified proc doesn't exist */ 139*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 140*7c478bd9Sstevel@tonic-gate return (ESRCH); 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate /* operate only on the specified proc */ 143*7c478bd9Sstevel@tonic-gate error = (*funcp)(prp, arg); 144*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 145*7c478bd9Sstevel@tonic-gate if (error == -1) 146*7c478bd9Sstevel@tonic-gate error = 0; 147*7c478bd9Sstevel@tonic-gate return (error); 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate nfound = 0; 152*7c478bd9Sstevel@tonic-gate error = 0; 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate for (prp = practive; prp != NULL; prp = prp->p_next) { 155*7c478bd9Sstevel@tonic-gate /* 156*7c478bd9Sstevel@tonic-gate * If caller is in a non-global zone, skip processes 157*7c478bd9Sstevel@tonic-gate * in other zones. 158*7c478bd9Sstevel@tonic-gate */ 159*7c478bd9Sstevel@tonic-gate if (!HASZONEACCESS(curproc, prp->p_zone->zone_id)) 160*7c478bd9Sstevel@tonic-gate continue; 161*7c478bd9Sstevel@tonic-gate if (prp->p_stat == SIDL || prp->p_stat == SZOMB || 162*7c478bd9Sstevel@tonic-gate prp->p_tlist == NULL || prp->p_flag & SSYS) 163*7c478bd9Sstevel@tonic-gate continue; 164*7c478bd9Sstevel@tonic-gate if (procinset(prp, psp)) { 165*7c478bd9Sstevel@tonic-gate nfound++; 166*7c478bd9Sstevel@tonic-gate lastprp = prp; 167*7c478bd9Sstevel@tonic-gate if (funcp != NULL && prp != proc_init) { 168*7c478bd9Sstevel@tonic-gate error = (*funcp)(prp, arg); 169*7c478bd9Sstevel@tonic-gate if (error == -1) { 170*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 171*7c478bd9Sstevel@tonic-gate return (0); 172*7c478bd9Sstevel@tonic-gate } else if (error) { 173*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 174*7c478bd9Sstevel@tonic-gate return (error); 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate } 179*7c478bd9Sstevel@tonic-gate if (nfound == 0) { 180*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 181*7c478bd9Sstevel@tonic-gate return (ESRCH); 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate if (nfound == 1 && lastprp == proc_init && funcp != NULL) 184*7c478bd9Sstevel@tonic-gate error = (*funcp)(lastprp, arg); 185*7c478bd9Sstevel@tonic-gate if (error == -1) 186*7c478bd9Sstevel@tonic-gate error = 0; 187*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 188*7c478bd9Sstevel@tonic-gate return (error); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate /* 192*7c478bd9Sstevel@tonic-gate * Check if a procset_t is valid. Return zero or an errno. 193*7c478bd9Sstevel@tonic-gate */ 194*7c478bd9Sstevel@tonic-gate int 195*7c478bd9Sstevel@tonic-gate checkprocset(procset_t *psp) 196*7c478bd9Sstevel@tonic-gate { 197*7c478bd9Sstevel@tonic-gate switch (psp->p_lidtype) { 198*7c478bd9Sstevel@tonic-gate case P_LWPID: 199*7c478bd9Sstevel@tonic-gate case P_PID: 200*7c478bd9Sstevel@tonic-gate case P_PPID: 201*7c478bd9Sstevel@tonic-gate case P_PGID: 202*7c478bd9Sstevel@tonic-gate case P_SID: 203*7c478bd9Sstevel@tonic-gate case P_TASKID: 204*7c478bd9Sstevel@tonic-gate case P_CID: 205*7c478bd9Sstevel@tonic-gate case P_UID: 206*7c478bd9Sstevel@tonic-gate case P_GID: 207*7c478bd9Sstevel@tonic-gate case P_PROJID: 208*7c478bd9Sstevel@tonic-gate case P_POOLID: 209*7c478bd9Sstevel@tonic-gate case P_ZONEID: 210*7c478bd9Sstevel@tonic-gate case P_CTID: 211*7c478bd9Sstevel@tonic-gate case P_ALL: 212*7c478bd9Sstevel@tonic-gate break; 213*7c478bd9Sstevel@tonic-gate default: 214*7c478bd9Sstevel@tonic-gate return (EINVAL); 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate switch (psp->p_ridtype) { 218*7c478bd9Sstevel@tonic-gate case P_LWPID: 219*7c478bd9Sstevel@tonic-gate case P_PID: 220*7c478bd9Sstevel@tonic-gate case P_PPID: 221*7c478bd9Sstevel@tonic-gate case P_PGID: 222*7c478bd9Sstevel@tonic-gate case P_SID: 223*7c478bd9Sstevel@tonic-gate case P_TASKID: 224*7c478bd9Sstevel@tonic-gate case P_CID: 225*7c478bd9Sstevel@tonic-gate case P_UID: 226*7c478bd9Sstevel@tonic-gate case P_GID: 227*7c478bd9Sstevel@tonic-gate case P_PROJID: 228*7c478bd9Sstevel@tonic-gate case P_POOLID: 229*7c478bd9Sstevel@tonic-gate case P_ZONEID: 230*7c478bd9Sstevel@tonic-gate case P_CTID: 231*7c478bd9Sstevel@tonic-gate case P_ALL: 232*7c478bd9Sstevel@tonic-gate break; 233*7c478bd9Sstevel@tonic-gate default: 234*7c478bd9Sstevel@tonic-gate return (EINVAL); 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate switch (psp->p_op) { 238*7c478bd9Sstevel@tonic-gate case POP_DIFF: 239*7c478bd9Sstevel@tonic-gate case POP_AND: 240*7c478bd9Sstevel@tonic-gate case POP_OR: 241*7c478bd9Sstevel@tonic-gate case POP_XOR: 242*7c478bd9Sstevel@tonic-gate break; 243*7c478bd9Sstevel@tonic-gate default: 244*7c478bd9Sstevel@tonic-gate return (EINVAL); 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate return (0); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate /* 251*7c478bd9Sstevel@tonic-gate * procinset returns 1 if the process pointed to 252*7c478bd9Sstevel@tonic-gate * by pp is in the process set specified by psp, otherwise 0 is returned. 253*7c478bd9Sstevel@tonic-gate * The caller should check that the process is not exiting and is not 254*7c478bd9Sstevel@tonic-gate * in the SYS scheduling class. 255*7c478bd9Sstevel@tonic-gate * 256*7c478bd9Sstevel@tonic-gate * This function expects to be called with a valid procset_t. 257*7c478bd9Sstevel@tonic-gate * The set should be checked using checkprocset() before calling 258*7c478bd9Sstevel@tonic-gate * this function. 259*7c478bd9Sstevel@tonic-gate */ 260*7c478bd9Sstevel@tonic-gate int 261*7c478bd9Sstevel@tonic-gate procinset(proc_t *pp, procset_t *psp) 262*7c478bd9Sstevel@tonic-gate { 263*7c478bd9Sstevel@tonic-gate int loperand = 0; 264*7c478bd9Sstevel@tonic-gate int roperand = 0; 265*7c478bd9Sstevel@tonic-gate int lwplinproc = 0; 266*7c478bd9Sstevel@tonic-gate int lwprinproc = 0; 267*7c478bd9Sstevel@tonic-gate kthread_t *tp = proctot(pp); 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate switch (psp->p_lidtype) { 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate case P_LWPID: 272*7c478bd9Sstevel@tonic-gate if (pp == ttoproc(curthread)) 273*7c478bd9Sstevel@tonic-gate if (getlwpptr(psp->p_lid) != NULL) 274*7c478bd9Sstevel@tonic-gate lwplinproc++; 275*7c478bd9Sstevel@tonic-gate break; 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate case P_PID: 278*7c478bd9Sstevel@tonic-gate if (pp->p_pid == psp->p_lid) 279*7c478bd9Sstevel@tonic-gate loperand++; 280*7c478bd9Sstevel@tonic-gate break; 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate case P_PPID: 283*7c478bd9Sstevel@tonic-gate if (pp->p_ppid == psp->p_lid) 284*7c478bd9Sstevel@tonic-gate loperand++; 285*7c478bd9Sstevel@tonic-gate break; 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate case P_PGID: 288*7c478bd9Sstevel@tonic-gate if (pp->p_pgrp == psp->p_lid) 289*7c478bd9Sstevel@tonic-gate loperand++; 290*7c478bd9Sstevel@tonic-gate break; 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate case P_SID: 293*7c478bd9Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_lid) 294*7c478bd9Sstevel@tonic-gate loperand++; 295*7c478bd9Sstevel@tonic-gate break; 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate case P_CID: 298*7c478bd9Sstevel@tonic-gate ASSERT(tp != NULL); 299*7c478bd9Sstevel@tonic-gate /* This case is broken for now. Need to be fixed XXX */ 300*7c478bd9Sstevel@tonic-gate if (tp->t_cid == psp->p_lid) 301*7c478bd9Sstevel@tonic-gate /* 302*7c478bd9Sstevel@tonic-gate * if (checkcid(psp->p_lid)) 303*7c478bd9Sstevel@tonic-gate */ 304*7c478bd9Sstevel@tonic-gate loperand++; 305*7c478bd9Sstevel@tonic-gate break; 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate case P_TASKID: 308*7c478bd9Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_lid) 309*7c478bd9Sstevel@tonic-gate loperand++; 310*7c478bd9Sstevel@tonic-gate break; 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate case P_UID: 313*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 314*7c478bd9Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_lid) 315*7c478bd9Sstevel@tonic-gate loperand++; 316*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 317*7c478bd9Sstevel@tonic-gate break; 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate case P_GID: 320*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 321*7c478bd9Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_lid) 322*7c478bd9Sstevel@tonic-gate loperand++; 323*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 324*7c478bd9Sstevel@tonic-gate break; 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate case P_PROJID: 327*7c478bd9Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 328*7c478bd9Sstevel@tonic-gate loperand++; 329*7c478bd9Sstevel@tonic-gate break; 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate case P_POOLID: 332*7c478bd9Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_lid) 333*7c478bd9Sstevel@tonic-gate loperand++; 334*7c478bd9Sstevel@tonic-gate break; 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate case P_ZONEID: 337*7c478bd9Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_lid) 338*7c478bd9Sstevel@tonic-gate loperand++; 339*7c478bd9Sstevel@tonic-gate break; 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate case P_CTID: 342*7c478bd9Sstevel@tonic-gate if (PRCTID(pp) == psp->p_lid) 343*7c478bd9Sstevel@tonic-gate loperand++; 344*7c478bd9Sstevel@tonic-gate break; 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate case P_ALL: 347*7c478bd9Sstevel@tonic-gate loperand++; 348*7c478bd9Sstevel@tonic-gate break; 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate default: 351*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 352*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 353*7c478bd9Sstevel@tonic-gate return (0); 354*7c478bd9Sstevel@tonic-gate #else 355*7c478bd9Sstevel@tonic-gate return (0); 356*7c478bd9Sstevel@tonic-gate #endif 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate switch (psp->p_ridtype) { 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate case P_LWPID: 362*7c478bd9Sstevel@tonic-gate if (pp == ttoproc(curthread)) 363*7c478bd9Sstevel@tonic-gate if (getlwpptr(psp->p_rid) != NULL) 364*7c478bd9Sstevel@tonic-gate lwprinproc++; 365*7c478bd9Sstevel@tonic-gate break; 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate case P_PID: 368*7c478bd9Sstevel@tonic-gate if (pp->p_pid == psp->p_rid) 369*7c478bd9Sstevel@tonic-gate roperand++; 370*7c478bd9Sstevel@tonic-gate break; 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate case P_PPID: 373*7c478bd9Sstevel@tonic-gate if (pp->p_ppid == psp->p_rid) 374*7c478bd9Sstevel@tonic-gate roperand++; 375*7c478bd9Sstevel@tonic-gate break; 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate case P_PGID: 378*7c478bd9Sstevel@tonic-gate if (pp->p_pgrp == psp->p_rid) 379*7c478bd9Sstevel@tonic-gate roperand++; 380*7c478bd9Sstevel@tonic-gate break; 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate case P_SID: 383*7c478bd9Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_rid) 384*7c478bd9Sstevel@tonic-gate roperand++; 385*7c478bd9Sstevel@tonic-gate break; 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate case P_TASKID: 388*7c478bd9Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_rid) 389*7c478bd9Sstevel@tonic-gate roperand++; 390*7c478bd9Sstevel@tonic-gate break; 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate case P_CID: 393*7c478bd9Sstevel@tonic-gate ASSERT(tp != NULL); 394*7c478bd9Sstevel@tonic-gate /* This case is broken for now. Need to be fixed XXX */ 395*7c478bd9Sstevel@tonic-gate if (tp->t_cid == psp->p_rid) 396*7c478bd9Sstevel@tonic-gate /* 397*7c478bd9Sstevel@tonic-gate * if (checkcid(psp->p_rid)) 398*7c478bd9Sstevel@tonic-gate */ 399*7c478bd9Sstevel@tonic-gate roperand++; 400*7c478bd9Sstevel@tonic-gate break; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate case P_UID: 403*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 404*7c478bd9Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_rid) 405*7c478bd9Sstevel@tonic-gate roperand++; 406*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 407*7c478bd9Sstevel@tonic-gate break; 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate case P_GID: 410*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 411*7c478bd9Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_rid) 412*7c478bd9Sstevel@tonic-gate roperand++; 413*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 414*7c478bd9Sstevel@tonic-gate break; 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate case P_PROJID: 417*7c478bd9Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 418*7c478bd9Sstevel@tonic-gate roperand++; 419*7c478bd9Sstevel@tonic-gate break; 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate case P_POOLID: 422*7c478bd9Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_rid) 423*7c478bd9Sstevel@tonic-gate roperand++; 424*7c478bd9Sstevel@tonic-gate break; 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate case P_ZONEID: 427*7c478bd9Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_rid) 428*7c478bd9Sstevel@tonic-gate roperand++; 429*7c478bd9Sstevel@tonic-gate break; 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate case P_CTID: 432*7c478bd9Sstevel@tonic-gate if (PRCTID(pp) == psp->p_rid) 433*7c478bd9Sstevel@tonic-gate roperand++; 434*7c478bd9Sstevel@tonic-gate break; 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate case P_ALL: 437*7c478bd9Sstevel@tonic-gate roperand++; 438*7c478bd9Sstevel@tonic-gate break; 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate default: 441*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 442*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 443*7c478bd9Sstevel@tonic-gate return (0); 444*7c478bd9Sstevel@tonic-gate #else 445*7c478bd9Sstevel@tonic-gate return (0); 446*7c478bd9Sstevel@tonic-gate #endif 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate switch (psp->p_op) { 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate case POP_DIFF: 452*7c478bd9Sstevel@tonic-gate if (loperand && !lwprinproc && !roperand) 453*7c478bd9Sstevel@tonic-gate return (1); 454*7c478bd9Sstevel@tonic-gate else 455*7c478bd9Sstevel@tonic-gate return (0); 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate case POP_AND: 458*7c478bd9Sstevel@tonic-gate if (loperand && roperand) 459*7c478bd9Sstevel@tonic-gate return (1); 460*7c478bd9Sstevel@tonic-gate else 461*7c478bd9Sstevel@tonic-gate return (0); 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate case POP_OR: 464*7c478bd9Sstevel@tonic-gate if (loperand || roperand) 465*7c478bd9Sstevel@tonic-gate return (1); 466*7c478bd9Sstevel@tonic-gate else 467*7c478bd9Sstevel@tonic-gate return (0); 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate case POP_XOR: 470*7c478bd9Sstevel@tonic-gate if ((loperand && !lwprinproc && !roperand) || 471*7c478bd9Sstevel@tonic-gate (roperand && !lwplinproc && !loperand)) 472*7c478bd9Sstevel@tonic-gate return (1); 473*7c478bd9Sstevel@tonic-gate else 474*7c478bd9Sstevel@tonic-gate return (0); 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate default: 477*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 478*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "procinset called with bad set"); 479*7c478bd9Sstevel@tonic-gate return (0); 480*7c478bd9Sstevel@tonic-gate #else 481*7c478bd9Sstevel@tonic-gate return (0); 482*7c478bd9Sstevel@tonic-gate #endif 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 485*7c478bd9Sstevel@tonic-gate } 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate /* 488*7c478bd9Sstevel@tonic-gate * lwpinset returns 1 if the thread pointed to 489*7c478bd9Sstevel@tonic-gate * by tp is in the process set specified by psp and is not in 490*7c478bd9Sstevel@tonic-gate * the sys scheduling class - otherwise 0 is returned. 491*7c478bd9Sstevel@tonic-gate * 492*7c478bd9Sstevel@tonic-gate * This function expects to be called with a valid procset_t. 493*7c478bd9Sstevel@tonic-gate * The set should be checked using checkprocset() before calling 494*7c478bd9Sstevel@tonic-gate * this function. 495*7c478bd9Sstevel@tonic-gate */ 496*7c478bd9Sstevel@tonic-gate int 497*7c478bd9Sstevel@tonic-gate lwpinset(proc_t *pp, procset_t *psp, kthread_t *tp, int *done) 498*7c478bd9Sstevel@tonic-gate { 499*7c478bd9Sstevel@tonic-gate int loperand = 0; 500*7c478bd9Sstevel@tonic-gate int roperand = 0; 501*7c478bd9Sstevel@tonic-gate int lwplinset = 0; 502*7c478bd9Sstevel@tonic-gate int lwprinset = 0; 503*7c478bd9Sstevel@tonic-gate 504*7c478bd9Sstevel@tonic-gate ASSERT(ttoproc(tp) == pp); 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate /* 507*7c478bd9Sstevel@tonic-gate * If process is in the sys class return (0). 508*7c478bd9Sstevel@tonic-gate */ 509*7c478bd9Sstevel@tonic-gate if (proctot(pp)->t_cid == 0) { 510*7c478bd9Sstevel@tonic-gate return (0); 511*7c478bd9Sstevel@tonic-gate } 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate switch (psp->p_lidtype) { 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate case P_LWPID: 516*7c478bd9Sstevel@tonic-gate if (tp->t_tid == psp->p_lid) 517*7c478bd9Sstevel@tonic-gate lwplinset ++; 518*7c478bd9Sstevel@tonic-gate break; 519*7c478bd9Sstevel@tonic-gate 520*7c478bd9Sstevel@tonic-gate case P_PID: 521*7c478bd9Sstevel@tonic-gate if (pp->p_pid == psp->p_lid) 522*7c478bd9Sstevel@tonic-gate loperand++; 523*7c478bd9Sstevel@tonic-gate break; 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate case P_PPID: 526*7c478bd9Sstevel@tonic-gate if (pp->p_ppid == psp->p_lid) 527*7c478bd9Sstevel@tonic-gate loperand++; 528*7c478bd9Sstevel@tonic-gate break; 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate case P_PGID: 531*7c478bd9Sstevel@tonic-gate if (pp->p_pgrp == psp->p_lid) 532*7c478bd9Sstevel@tonic-gate loperand++; 533*7c478bd9Sstevel@tonic-gate break; 534*7c478bd9Sstevel@tonic-gate 535*7c478bd9Sstevel@tonic-gate case P_SID: 536*7c478bd9Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_lid) 537*7c478bd9Sstevel@tonic-gate loperand++; 538*7c478bd9Sstevel@tonic-gate break; 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate case P_TASKID: 541*7c478bd9Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_lid) 542*7c478bd9Sstevel@tonic-gate loperand++; 543*7c478bd9Sstevel@tonic-gate break; 544*7c478bd9Sstevel@tonic-gate 545*7c478bd9Sstevel@tonic-gate case P_CID: 546*7c478bd9Sstevel@tonic-gate if (tp->t_cid == psp->p_lid) 547*7c478bd9Sstevel@tonic-gate loperand++; 548*7c478bd9Sstevel@tonic-gate break; 549*7c478bd9Sstevel@tonic-gate 550*7c478bd9Sstevel@tonic-gate case P_UID: 551*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 552*7c478bd9Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_lid) 553*7c478bd9Sstevel@tonic-gate loperand++; 554*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 555*7c478bd9Sstevel@tonic-gate break; 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate case P_GID: 558*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 559*7c478bd9Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_lid) 560*7c478bd9Sstevel@tonic-gate loperand++; 561*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 562*7c478bd9Sstevel@tonic-gate break; 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate case P_PROJID: 565*7c478bd9Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 566*7c478bd9Sstevel@tonic-gate loperand++; 567*7c478bd9Sstevel@tonic-gate break; 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate case P_POOLID: 570*7c478bd9Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_lid) 571*7c478bd9Sstevel@tonic-gate loperand++; 572*7c478bd9Sstevel@tonic-gate break; 573*7c478bd9Sstevel@tonic-gate 574*7c478bd9Sstevel@tonic-gate case P_ZONEID: 575*7c478bd9Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_lid) 576*7c478bd9Sstevel@tonic-gate loperand++; 577*7c478bd9Sstevel@tonic-gate break; 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate case P_CTID: 580*7c478bd9Sstevel@tonic-gate if (PRCTID(pp) == psp->p_lid) 581*7c478bd9Sstevel@tonic-gate loperand++; 582*7c478bd9Sstevel@tonic-gate break; 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate case P_ALL: 585*7c478bd9Sstevel@tonic-gate loperand++; 586*7c478bd9Sstevel@tonic-gate break; 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate default: 589*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 590*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 591*7c478bd9Sstevel@tonic-gate return (0); 592*7c478bd9Sstevel@tonic-gate #else 593*7c478bd9Sstevel@tonic-gate return (0); 594*7c478bd9Sstevel@tonic-gate #endif 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate switch (psp->p_ridtype) { 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate case P_LWPID: 600*7c478bd9Sstevel@tonic-gate if (tp->t_tid == psp->p_rid) 601*7c478bd9Sstevel@tonic-gate lwprinset ++; 602*7c478bd9Sstevel@tonic-gate break; 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate case P_PID: 605*7c478bd9Sstevel@tonic-gate if (pp->p_pid == psp->p_rid) 606*7c478bd9Sstevel@tonic-gate roperand++; 607*7c478bd9Sstevel@tonic-gate break; 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate case P_PPID: 610*7c478bd9Sstevel@tonic-gate if (pp->p_ppid == psp->p_rid) 611*7c478bd9Sstevel@tonic-gate roperand++; 612*7c478bd9Sstevel@tonic-gate break; 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate case P_PGID: 615*7c478bd9Sstevel@tonic-gate if (pp->p_pgrp == psp->p_rid) 616*7c478bd9Sstevel@tonic-gate roperand++; 617*7c478bd9Sstevel@tonic-gate break; 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate case P_SID: 620*7c478bd9Sstevel@tonic-gate if (pp->p_sessp->s_sid == psp->p_rid) 621*7c478bd9Sstevel@tonic-gate roperand++; 622*7c478bd9Sstevel@tonic-gate break; 623*7c478bd9Sstevel@tonic-gate 624*7c478bd9Sstevel@tonic-gate case P_TASKID: 625*7c478bd9Sstevel@tonic-gate if (pp->p_task->tk_tkid == psp->p_rid) 626*7c478bd9Sstevel@tonic-gate roperand++; 627*7c478bd9Sstevel@tonic-gate break; 628*7c478bd9Sstevel@tonic-gate 629*7c478bd9Sstevel@tonic-gate case P_CID: 630*7c478bd9Sstevel@tonic-gate if (tp->t_cid == psp->p_rid) 631*7c478bd9Sstevel@tonic-gate roperand++; 632*7c478bd9Sstevel@tonic-gate break; 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate case P_UID: 635*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 636*7c478bd9Sstevel@tonic-gate if (crgetuid(pp->p_cred) == psp->p_rid) 637*7c478bd9Sstevel@tonic-gate roperand++; 638*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 639*7c478bd9Sstevel@tonic-gate break; 640*7c478bd9Sstevel@tonic-gate 641*7c478bd9Sstevel@tonic-gate case P_GID: 642*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 643*7c478bd9Sstevel@tonic-gate if (crgetgid(pp->p_cred) == psp->p_rid) 644*7c478bd9Sstevel@tonic-gate roperand++; 645*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 646*7c478bd9Sstevel@tonic-gate break; 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate case P_PROJID: 649*7c478bd9Sstevel@tonic-gate if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 650*7c478bd9Sstevel@tonic-gate roperand++; 651*7c478bd9Sstevel@tonic-gate break; 652*7c478bd9Sstevel@tonic-gate 653*7c478bd9Sstevel@tonic-gate case P_POOLID: 654*7c478bd9Sstevel@tonic-gate if (pp->p_pool->pool_id == psp->p_rid) 655*7c478bd9Sstevel@tonic-gate roperand++; 656*7c478bd9Sstevel@tonic-gate break; 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate case P_ZONEID: 659*7c478bd9Sstevel@tonic-gate if (pp->p_zone->zone_id == psp->p_rid) 660*7c478bd9Sstevel@tonic-gate roperand++; 661*7c478bd9Sstevel@tonic-gate break; 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate case P_CTID: 664*7c478bd9Sstevel@tonic-gate if (PRCTID(pp) == psp->p_rid) 665*7c478bd9Sstevel@tonic-gate roperand++; 666*7c478bd9Sstevel@tonic-gate break; 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate case P_ALL: 669*7c478bd9Sstevel@tonic-gate roperand++; 670*7c478bd9Sstevel@tonic-gate break; 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate default: 673*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 674*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 675*7c478bd9Sstevel@tonic-gate return (0); 676*7c478bd9Sstevel@tonic-gate #else 677*7c478bd9Sstevel@tonic-gate return (0); 678*7c478bd9Sstevel@tonic-gate #endif 679*7c478bd9Sstevel@tonic-gate } 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate if (lwplinset && lwprinset) 682*7c478bd9Sstevel@tonic-gate *done = 1; 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate switch (psp->p_op) { 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate case POP_DIFF: 687*7c478bd9Sstevel@tonic-gate if ((loperand || lwplinset) && !(lwprinset || roperand)) 688*7c478bd9Sstevel@tonic-gate return (1); 689*7c478bd9Sstevel@tonic-gate else 690*7c478bd9Sstevel@tonic-gate return (0); 691*7c478bd9Sstevel@tonic-gate 692*7c478bd9Sstevel@tonic-gate case POP_AND: 693*7c478bd9Sstevel@tonic-gate if ((loperand || lwplinset) && (roperand || lwprinset)) 694*7c478bd9Sstevel@tonic-gate return (1); 695*7c478bd9Sstevel@tonic-gate else 696*7c478bd9Sstevel@tonic-gate return (0); 697*7c478bd9Sstevel@tonic-gate 698*7c478bd9Sstevel@tonic-gate case POP_OR: 699*7c478bd9Sstevel@tonic-gate if (loperand || roperand || lwplinset || lwprinset) 700*7c478bd9Sstevel@tonic-gate return (1); 701*7c478bd9Sstevel@tonic-gate else 702*7c478bd9Sstevel@tonic-gate return (0); 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate case POP_XOR: 705*7c478bd9Sstevel@tonic-gate if (((loperand || lwplinset) && 706*7c478bd9Sstevel@tonic-gate !(lwprinset || roperand)) || 707*7c478bd9Sstevel@tonic-gate ((roperand || lwprinset) && 708*7c478bd9Sstevel@tonic-gate !(lwplinset || loperand))) 709*7c478bd9Sstevel@tonic-gate return (1); 710*7c478bd9Sstevel@tonic-gate else 711*7c478bd9Sstevel@tonic-gate return (0); 712*7c478bd9Sstevel@tonic-gate 713*7c478bd9Sstevel@tonic-gate default: 714*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 715*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "lwpinset called with bad set"); 716*7c478bd9Sstevel@tonic-gate return (0); 717*7c478bd9Sstevel@tonic-gate #else 718*7c478bd9Sstevel@tonic-gate return (0); 719*7c478bd9Sstevel@tonic-gate #endif 720*7c478bd9Sstevel@tonic-gate } 721*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 722*7c478bd9Sstevel@tonic-gate } 723*7c478bd9Sstevel@tonic-gate /* 724*7c478bd9Sstevel@tonic-gate * Check for common cases of procsets which specify only the 725*7c478bd9Sstevel@tonic-gate * current process. cur_inset_only() returns B_TRUE when 726*7c478bd9Sstevel@tonic-gate * the current process is the only one in the set. B_FALSE 727*7c478bd9Sstevel@tonic-gate * is returned to indicate that this may not be the case. 728*7c478bd9Sstevel@tonic-gate */ 729*7c478bd9Sstevel@tonic-gate boolean_t 730*7c478bd9Sstevel@tonic-gate cur_inset_only(procset_t *psp) 731*7c478bd9Sstevel@tonic-gate { 732*7c478bd9Sstevel@tonic-gate if (((psp->p_lidtype == P_PID && 733*7c478bd9Sstevel@tonic-gate (psp->p_lid == P_MYID || 734*7c478bd9Sstevel@tonic-gate psp->p_lid == ttoproc(curthread)->p_pid)) || 735*7c478bd9Sstevel@tonic-gate ((psp->p_lidtype == P_LWPID) && 736*7c478bd9Sstevel@tonic-gate (psp->p_lid == P_MYID || 737*7c478bd9Sstevel@tonic-gate psp->p_lid == curthread->t_tid))) && 738*7c478bd9Sstevel@tonic-gate psp->p_op == POP_AND && psp->p_ridtype == P_ALL) 739*7c478bd9Sstevel@tonic-gate return (B_TRUE); 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate if (((psp->p_ridtype == P_PID && 742*7c478bd9Sstevel@tonic-gate (psp->p_rid == P_MYID || 743*7c478bd9Sstevel@tonic-gate psp->p_rid == ttoproc(curthread)->p_pid)) || 744*7c478bd9Sstevel@tonic-gate ((psp->p_ridtype == P_LWPID) && 745*7c478bd9Sstevel@tonic-gate (psp->p_rid == P_MYID || 746*7c478bd9Sstevel@tonic-gate psp->p_rid == curthread->t_tid))) && 747*7c478bd9Sstevel@tonic-gate psp->p_op == POP_AND && psp->p_lidtype == P_ALL) 748*7c478bd9Sstevel@tonic-gate return (B_TRUE); 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate return (B_FALSE); 751*7c478bd9Sstevel@tonic-gate } 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate id_t 754*7c478bd9Sstevel@tonic-gate getmyid(idtype_t idtype) 755*7c478bd9Sstevel@tonic-gate { 756*7c478bd9Sstevel@tonic-gate proc_t *pp; 757*7c478bd9Sstevel@tonic-gate uid_t uid; 758*7c478bd9Sstevel@tonic-gate gid_t gid; 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate pp = ttoproc(curthread); 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate switch (idtype) { 763*7c478bd9Sstevel@tonic-gate case P_LWPID: 764*7c478bd9Sstevel@tonic-gate return (curthread->t_tid); 765*7c478bd9Sstevel@tonic-gate 766*7c478bd9Sstevel@tonic-gate case P_PID: 767*7c478bd9Sstevel@tonic-gate return (pp->p_pid); 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate case P_PPID: 770*7c478bd9Sstevel@tonic-gate return (pp->p_ppid); 771*7c478bd9Sstevel@tonic-gate 772*7c478bd9Sstevel@tonic-gate case P_PGID: 773*7c478bd9Sstevel@tonic-gate return (pp->p_pgrp); 774*7c478bd9Sstevel@tonic-gate 775*7c478bd9Sstevel@tonic-gate case P_SID: 776*7c478bd9Sstevel@tonic-gate return (pp->p_sessp->s_sid); 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate case P_TASKID: 779*7c478bd9Sstevel@tonic-gate return (pp->p_task->tk_tkid); 780*7c478bd9Sstevel@tonic-gate 781*7c478bd9Sstevel@tonic-gate case P_CID: 782*7c478bd9Sstevel@tonic-gate return (curthread->t_cid); 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate case P_UID: 785*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 786*7c478bd9Sstevel@tonic-gate uid = crgetuid(pp->p_cred); 787*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 788*7c478bd9Sstevel@tonic-gate return (uid); 789*7c478bd9Sstevel@tonic-gate 790*7c478bd9Sstevel@tonic-gate case P_GID: 791*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_crlock); 792*7c478bd9Sstevel@tonic-gate gid = crgetgid(pp->p_cred); 793*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_crlock); 794*7c478bd9Sstevel@tonic-gate return (gid); 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate case P_PROJID: 797*7c478bd9Sstevel@tonic-gate return (pp->p_task->tk_proj->kpj_id); 798*7c478bd9Sstevel@tonic-gate 799*7c478bd9Sstevel@tonic-gate case P_POOLID: 800*7c478bd9Sstevel@tonic-gate return (pp->p_pool->pool_id); 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate case P_ZONEID: 803*7c478bd9Sstevel@tonic-gate return (pp->p_zone->zone_id); 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate case P_CTID: 806*7c478bd9Sstevel@tonic-gate return (PRCTID(pp)); 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate case P_ALL: 809*7c478bd9Sstevel@tonic-gate /* 810*7c478bd9Sstevel@tonic-gate * The value doesn't matter for P_ALL. 811*7c478bd9Sstevel@tonic-gate */ 812*7c478bd9Sstevel@tonic-gate return (0); 813*7c478bd9Sstevel@tonic-gate 814*7c478bd9Sstevel@tonic-gate default: 815*7c478bd9Sstevel@tonic-gate return (-1); 816*7c478bd9Sstevel@tonic-gate } 817*7c478bd9Sstevel@tonic-gate } 818*7c478bd9Sstevel@tonic-gate 819*7c478bd9Sstevel@tonic-gate static kthread_t * 820*7c478bd9Sstevel@tonic-gate getlwpptr(id_t id) 821*7c478bd9Sstevel@tonic-gate { 822*7c478bd9Sstevel@tonic-gate proc_t *p; 823*7c478bd9Sstevel@tonic-gate kthread_t *t; 824*7c478bd9Sstevel@tonic-gate 825*7c478bd9Sstevel@tonic-gate if (id == P_MYID) 826*7c478bd9Sstevel@tonic-gate t = curthread; 827*7c478bd9Sstevel@tonic-gate else { 828*7c478bd9Sstevel@tonic-gate p = ttoproc(curthread); 829*7c478bd9Sstevel@tonic-gate mutex_enter(&p->p_lock); 830*7c478bd9Sstevel@tonic-gate t = idtot(p, id); 831*7c478bd9Sstevel@tonic-gate mutex_exit(&p->p_lock); 832*7c478bd9Sstevel@tonic-gate } 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate return (t); 835*7c478bd9Sstevel@tonic-gate } 836*7c478bd9Sstevel@tonic-gate 837*7c478bd9Sstevel@tonic-gate /* 838*7c478bd9Sstevel@tonic-gate * The dotolwp function locates the LWP(s) specified by the procset structure 839*7c478bd9Sstevel@tonic-gate * pointed to by psp. If funcp is non-NULL then it points to a function 840*7c478bd9Sstevel@tonic-gate * which dotolwp will call for each LWP in the specified set. 841*7c478bd9Sstevel@tonic-gate * LWPIDs specified in the procset structure always refer to lwps in curproc. 842*7c478bd9Sstevel@tonic-gate * The arguments for this function must be "char *arg", and "kthread_t *tp", 843*7c478bd9Sstevel@tonic-gate * where tp is a pointer to the current thread from the set. 844*7c478bd9Sstevel@tonic-gate * Note that these arguments are passed to the function in reversed order 845*7c478bd9Sstevel@tonic-gate * than the order of arguments passed by dotoprocs() to its callback function. 846*7c478bd9Sstevel@tonic-gate * Also note that there are two separate cases where this routine returns zero. 847*7c478bd9Sstevel@tonic-gate * In the first case no mutex is grabbed, in the second the p_lock mutex 848*7c478bd9Sstevel@tonic-gate * is NOT RELEASED. The priocntl code is expecting this behaviour. 849*7c478bd9Sstevel@tonic-gate */ 850*7c478bd9Sstevel@tonic-gate int 851*7c478bd9Sstevel@tonic-gate dotolwp(procset_t *psp, int (*funcp)(), char *arg) 852*7c478bd9Sstevel@tonic-gate { 853*7c478bd9Sstevel@tonic-gate int error = 0; 854*7c478bd9Sstevel@tonic-gate int nfound = 0; 855*7c478bd9Sstevel@tonic-gate kthread_t *tp; 856*7c478bd9Sstevel@tonic-gate proc_t *pp; 857*7c478bd9Sstevel@tonic-gate int done = 0; 858*7c478bd9Sstevel@tonic-gate 859*7c478bd9Sstevel@tonic-gate /* 860*7c478bd9Sstevel@tonic-gate * Check that the procset_t is valid. 861*7c478bd9Sstevel@tonic-gate */ 862*7c478bd9Sstevel@tonic-gate error = checkprocset(psp); 863*7c478bd9Sstevel@tonic-gate if (error) { 864*7c478bd9Sstevel@tonic-gate return (error); 865*7c478bd9Sstevel@tonic-gate } 866*7c478bd9Sstevel@tonic-gate 867*7c478bd9Sstevel@tonic-gate mutex_enter(&pidlock); 868*7c478bd9Sstevel@tonic-gate 869*7c478bd9Sstevel@tonic-gate /* 870*7c478bd9Sstevel@tonic-gate * Check for the special value P_MYID in either operand 871*7c478bd9Sstevel@tonic-gate * and replace it with the correct value. We don't check 872*7c478bd9Sstevel@tonic-gate * for an error return from getmyid() because the idtypes 873*7c478bd9Sstevel@tonic-gate * have been validated by the checkprocset() call above. 874*7c478bd9Sstevel@tonic-gate */ 875*7c478bd9Sstevel@tonic-gate if (psp->p_lid == P_MYID) { 876*7c478bd9Sstevel@tonic-gate psp->p_lid = getmyid(psp->p_lidtype); 877*7c478bd9Sstevel@tonic-gate } 878*7c478bd9Sstevel@tonic-gate if (psp->p_rid == P_MYID) { 879*7c478bd9Sstevel@tonic-gate psp->p_rid = getmyid(psp->p_ridtype); 880*7c478bd9Sstevel@tonic-gate } 881*7c478bd9Sstevel@tonic-gate 882*7c478bd9Sstevel@tonic-gate pp = ttoproc(curthread); 883*7c478bd9Sstevel@tonic-gate 884*7c478bd9Sstevel@tonic-gate if (procinset(pp, psp)) { 885*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 886*7c478bd9Sstevel@tonic-gate return (0); 887*7c478bd9Sstevel@tonic-gate } 888*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->p_lock); 889*7c478bd9Sstevel@tonic-gate if ((tp = pp->p_tlist) == NULL) { 890*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_lock); 891*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 892*7c478bd9Sstevel@tonic-gate return (0); 893*7c478bd9Sstevel@tonic-gate } 894*7c478bd9Sstevel@tonic-gate do { 895*7c478bd9Sstevel@tonic-gate if (lwpinset(pp, psp, tp, &done)) { 896*7c478bd9Sstevel@tonic-gate nfound ++; 897*7c478bd9Sstevel@tonic-gate error = (*funcp)(arg, tp); 898*7c478bd9Sstevel@tonic-gate if (error) { 899*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_lock); 900*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 901*7c478bd9Sstevel@tonic-gate return (error); 902*7c478bd9Sstevel@tonic-gate } 903*7c478bd9Sstevel@tonic-gate } 904*7c478bd9Sstevel@tonic-gate } while (((tp = tp->t_forw) != pp->p_tlist) && !done); 905*7c478bd9Sstevel@tonic-gate 906*7c478bd9Sstevel@tonic-gate if (nfound == 0) { 907*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->p_lock); 908*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 909*7c478bd9Sstevel@tonic-gate return (ESRCH); 910*7c478bd9Sstevel@tonic-gate } 911*7c478bd9Sstevel@tonic-gate 912*7c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 913*7c478bd9Sstevel@tonic-gate return (error); 914*7c478bd9Sstevel@tonic-gate } 915