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 #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 30*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <stdio.h> 34*7c478bd9Sstevel@tonic-gate #include <string.h> 35*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 36*7c478bd9Sstevel@tonic-gate #include <unistd.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/procset.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/priocntl.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/iapriocntl.h> 41*7c478bd9Sstevel@tonic-gate #include <libgen.h> 42*7c478bd9Sstevel@tonic-gate #include <limits.h> 43*7c478bd9Sstevel@tonic-gate #include <errno.h> 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate #include "priocntl.h" 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate /* 48*7c478bd9Sstevel@tonic-gate * This file contains the class specific code implementing 49*7c478bd9Sstevel@tonic-gate * the interactive class priocntl sub-command. 50*7c478bd9Sstevel@tonic-gate */ 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #define ADDKEYVAL(p, k, v) { (p[0]) = (k); (p[1]) = (v); p += 2; } 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate #define IA_KEYCNT 3 /* maximal number of (key, value) pairs */ 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* 57*7c478bd9Sstevel@tonic-gate * control flags 58*7c478bd9Sstevel@tonic-gate */ 59*7c478bd9Sstevel@tonic-gate #define IA_DOUPRILIM 0x01 /* user priority limit */ 60*7c478bd9Sstevel@tonic-gate #define IA_DOUPRI 0x02 /* user priority */ 61*7c478bd9Sstevel@tonic-gate #define IA_DOMODE 0x04 /* interactive on/off */ 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate static void print_iainfo(void); 64*7c478bd9Sstevel@tonic-gate static int print_iaprocs(void); 65*7c478bd9Sstevel@tonic-gate static int ia_priocntl(idtype_t, id_t, int, char *, uintptr_t *); 66*7c478bd9Sstevel@tonic-gate static int set_iaprocs(idtype_t, int, char **, uint_t, pri_t, pri_t, int); 67*7c478bd9Sstevel@tonic-gate static void exec_iacmd(char **, uint_t, pri_t, pri_t, int); 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate static char usage[] = 70*7c478bd9Sstevel@tonic-gate "usage: priocntl -l\n\ 71*7c478bd9Sstevel@tonic-gate priocntl -d [-i idtype] [idlist]\n\ 72*7c478bd9Sstevel@tonic-gate priocntl -s [-c IA] [-m iauprilim] [-p iaupri] [-t iamode]\n\ 73*7c478bd9Sstevel@tonic-gate [-i idtype] [idlist]\n\ 74*7c478bd9Sstevel@tonic-gate priocntl -e [-c IA] [-m iauprilim] [-p iaupri] [-t iamode]\n\ 75*7c478bd9Sstevel@tonic-gate command [argument(s)]\n"; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate static char cmdpath[MAXPATHLEN]; 78*7c478bd9Sstevel@tonic-gate static char basenm[BASENMSZ]; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate int 82*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 83*7c478bd9Sstevel@tonic-gate { 84*7c478bd9Sstevel@tonic-gate int c; 85*7c478bd9Sstevel@tonic-gate int lflag, dflag, sflag, mflag, pflag, eflag, iflag, tflag; 86*7c478bd9Sstevel@tonic-gate int iamode; 87*7c478bd9Sstevel@tonic-gate pri_t iauprilim; 88*7c478bd9Sstevel@tonic-gate pri_t iaupri; 89*7c478bd9Sstevel@tonic-gate char *idtypnm; 90*7c478bd9Sstevel@tonic-gate idtype_t idtype; 91*7c478bd9Sstevel@tonic-gate int idargc; 92*7c478bd9Sstevel@tonic-gate uint_t cflags; 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate (void) strlcpy(cmdpath, argv[0], MAXPATHLEN); 95*7c478bd9Sstevel@tonic-gate (void) strlcpy(basenm, basename(argv[0]), BASENMSZ); 96*7c478bd9Sstevel@tonic-gate lflag = dflag = sflag = mflag = pflag = eflag = iflag = tflag = 0; 97*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "ldsm:p:t:ec:i:")) != -1) { 98*7c478bd9Sstevel@tonic-gate switch (c) { 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate case 'l': 101*7c478bd9Sstevel@tonic-gate lflag++; 102*7c478bd9Sstevel@tonic-gate break; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate case 'd': 105*7c478bd9Sstevel@tonic-gate dflag++; 106*7c478bd9Sstevel@tonic-gate break; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate case 's': 109*7c478bd9Sstevel@tonic-gate sflag++; 110*7c478bd9Sstevel@tonic-gate break; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate case 'm': 113*7c478bd9Sstevel@tonic-gate mflag++; 114*7c478bd9Sstevel@tonic-gate iauprilim = (pri_t)str2num(optarg, SHRT_MIN, SHRT_MAX); 115*7c478bd9Sstevel@tonic-gate if (errno) 116*7c478bd9Sstevel@tonic-gate fatalerr("%s: Specified user priority limit %s" 117*7c478bd9Sstevel@tonic-gate " out of configured range\n", 118*7c478bd9Sstevel@tonic-gate basenm, optarg); 119*7c478bd9Sstevel@tonic-gate break; 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate case 'p': 122*7c478bd9Sstevel@tonic-gate pflag++; 123*7c478bd9Sstevel@tonic-gate iaupri = (pri_t)str2num(optarg, SHRT_MIN, SHRT_MAX); 124*7c478bd9Sstevel@tonic-gate if (errno) 125*7c478bd9Sstevel@tonic-gate fatalerr("%s: Specified user priority %s out of" 126*7c478bd9Sstevel@tonic-gate " configured range\n", basenm, optarg); 127*7c478bd9Sstevel@tonic-gate break; 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate case 't': 130*7c478bd9Sstevel@tonic-gate tflag++; 131*7c478bd9Sstevel@tonic-gate iamode = (int)str2num(optarg, INT_MIN, INT_MAX); 132*7c478bd9Sstevel@tonic-gate if (errno || (iamode != IA_INTERACTIVE_OFF && 133*7c478bd9Sstevel@tonic-gate iamode != IA_SET_INTERACTIVE)) 134*7c478bd9Sstevel@tonic-gate fatalerr("%s: Specified illegal mode %s\n", 135*7c478bd9Sstevel@tonic-gate basenm, optarg); 136*7c478bd9Sstevel@tonic-gate break; 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate case 'e': 139*7c478bd9Sstevel@tonic-gate eflag++; 140*7c478bd9Sstevel@tonic-gate break; 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate case 'c': 143*7c478bd9Sstevel@tonic-gate if (strcmp(optarg, "IA") != 0) 144*7c478bd9Sstevel@tonic-gate fatalerr("error: %s executed for %s class, %s" 145*7c478bd9Sstevel@tonic-gate " is actually sub-command for IA class\n", 146*7c478bd9Sstevel@tonic-gate cmdpath, optarg, cmdpath); 147*7c478bd9Sstevel@tonic-gate break; 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate case 'i': 150*7c478bd9Sstevel@tonic-gate iflag++; 151*7c478bd9Sstevel@tonic-gate idtypnm = optarg; 152*7c478bd9Sstevel@tonic-gate break; 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate case '?': 155*7c478bd9Sstevel@tonic-gate fatalerr(usage); 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate default: 158*7c478bd9Sstevel@tonic-gate break; 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate if (lflag) { 163*7c478bd9Sstevel@tonic-gate if (dflag || sflag || mflag || pflag || tflag || eflag || iflag) 164*7c478bd9Sstevel@tonic-gate fatalerr(usage); 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate print_iainfo(); 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate } else if (dflag) { 169*7c478bd9Sstevel@tonic-gate if (lflag || sflag || mflag || pflag || tflag || eflag) 170*7c478bd9Sstevel@tonic-gate fatalerr(usage); 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate return (print_iaprocs()); 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate } else if (sflag) { 175*7c478bd9Sstevel@tonic-gate if (lflag || dflag || eflag) 176*7c478bd9Sstevel@tonic-gate fatalerr(usage); 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate if (iflag) { 179*7c478bd9Sstevel@tonic-gate if (str2idtyp(idtypnm, &idtype) == -1) 180*7c478bd9Sstevel@tonic-gate fatalerr("%s: Bad idtype %s\n", basenm, 181*7c478bd9Sstevel@tonic-gate idtypnm); 182*7c478bd9Sstevel@tonic-gate } else { 183*7c478bd9Sstevel@tonic-gate idtype = P_PID; 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate cflags = (pflag ? IA_DOUPRI : 0); 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate if (mflag) 189*7c478bd9Sstevel@tonic-gate cflags |= IA_DOUPRILIM; 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate if (tflag) 192*7c478bd9Sstevel@tonic-gate cflags |= IA_DOMODE; 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate if (optind < argc) 195*7c478bd9Sstevel@tonic-gate idargc = argc - optind; 196*7c478bd9Sstevel@tonic-gate else 197*7c478bd9Sstevel@tonic-gate idargc = 0; 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate return (set_iaprocs(idtype, idargc, &argv[optind], cflags, 200*7c478bd9Sstevel@tonic-gate iauprilim, iaupri, iamode)); 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate } else if (eflag) { 203*7c478bd9Sstevel@tonic-gate if (lflag || dflag || sflag || iflag) 204*7c478bd9Sstevel@tonic-gate fatalerr(usage); 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate cflags = (pflag ? IA_DOUPRI : 0); 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate if (mflag) 209*7c478bd9Sstevel@tonic-gate cflags |= IA_DOUPRILIM; 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate if (tflag) 212*7c478bd9Sstevel@tonic-gate cflags |= IA_DOMODE; 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate exec_iacmd(&argv[optind], cflags, iauprilim, iaupri, iamode); 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate } else { 217*7c478bd9Sstevel@tonic-gate fatalerr(usage); 218*7c478bd9Sstevel@tonic-gate } 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate return (0); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate /* 225*7c478bd9Sstevel@tonic-gate * Print our class name and the configured user priority range. 226*7c478bd9Sstevel@tonic-gate */ 227*7c478bd9Sstevel@tonic-gate static void 228*7c478bd9Sstevel@tonic-gate print_iainfo(void) 229*7c478bd9Sstevel@tonic-gate { 230*7c478bd9Sstevel@tonic-gate pcinfo_t pcinfo; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate (void) strcpy(pcinfo.pc_clname, "IA"); 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate (void) printf("IA (Interactive)\n"); 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 237*7c478bd9Sstevel@tonic-gate fatalerr("\tCan't get configured IA user priority range\n"); 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate (void) printf("\tConfigured IA User Priority Range: -%d through %d\n", 240*7c478bd9Sstevel@tonic-gate ((iainfo_t *)pcinfo.pc_clinfo)->ia_maxupri, 241*7c478bd9Sstevel@tonic-gate ((iainfo_t *)pcinfo.pc_clinfo)->ia_maxupri); 242*7c478bd9Sstevel@tonic-gate } 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate /* 246*7c478bd9Sstevel@tonic-gate * Read a list of pids from stdin and print the user priority and user 247*7c478bd9Sstevel@tonic-gate * priority limit for each of the corresponding processes. 248*7c478bd9Sstevel@tonic-gate * print their interactive mode and nice values 249*7c478bd9Sstevel@tonic-gate */ 250*7c478bd9Sstevel@tonic-gate static int 251*7c478bd9Sstevel@tonic-gate print_iaprocs(void) 252*7c478bd9Sstevel@tonic-gate { 253*7c478bd9Sstevel@tonic-gate pid_t *pidlist; 254*7c478bd9Sstevel@tonic-gate size_t numread; 255*7c478bd9Sstevel@tonic-gate int i; 256*7c478bd9Sstevel@tonic-gate char clname[PC_CLNMSZ]; 257*7c478bd9Sstevel@tonic-gate pri_t ia_uprilim; 258*7c478bd9Sstevel@tonic-gate pri_t ia_upri; 259*7c478bd9Sstevel@tonic-gate int ia_mode; 260*7c478bd9Sstevel@tonic-gate int error = 0; 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate /* 263*7c478bd9Sstevel@tonic-gate * Read a list of pids from stdin. 264*7c478bd9Sstevel@tonic-gate */ 265*7c478bd9Sstevel@tonic-gate if ((pidlist = read_pidlist(&numread, stdin)) == NULL) 266*7c478bd9Sstevel@tonic-gate fatalerr("%s: Can't read pidlist.\n", basenm); 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate (void) printf("INTERACTIVE CLASS PROCESSES:"); 269*7c478bd9Sstevel@tonic-gate (void) printf("\n PID IAUPRILIM IAUPRI IAMODE\n"); 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate if (numread == 0) 272*7c478bd9Sstevel@tonic-gate fatalerr("%s: No pids on input\n", basenm); 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate for (i = 0; i < numread; i++) { 275*7c478bd9Sstevel@tonic-gate (void) printf("%7ld", pidlist[i]); 276*7c478bd9Sstevel@tonic-gate if (priocntl(P_PID, pidlist[i], PC_GETXPARMS, "IA", 277*7c478bd9Sstevel@tonic-gate IA_KY_UPRI, &ia_upri, IA_KY_UPRILIM, &ia_uprilim, 278*7c478bd9Sstevel@tonic-gate IA_KY_MODE, &ia_mode, 0) != -1) { 279*7c478bd9Sstevel@tonic-gate (void) printf(" %5d %5d %5d\n", 280*7c478bd9Sstevel@tonic-gate ia_uprilim, ia_upri, ia_mode); 281*7c478bd9Sstevel@tonic-gate } else { 282*7c478bd9Sstevel@tonic-gate error = 1; 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate if (priocntl(P_PID, pidlist[i], PC_GETXPARMS, NULL, 285*7c478bd9Sstevel@tonic-gate PC_KY_CLNAME, clname, 0) != -1 && 286*7c478bd9Sstevel@tonic-gate strcmp(clname, "IA")) 287*7c478bd9Sstevel@tonic-gate /* 288*7c478bd9Sstevel@tonic-gate * Process from some class other than 289*7c478bd9Sstevel@tonic-gate * interactive. It has probably changed class 290*7c478bd9Sstevel@tonic-gate * while priocntl command was executing 291*7c478bd9Sstevel@tonic-gate * (otherwise we wouldn't have been passed its 292*7c478bd9Sstevel@tonic-gate * pid). Print the little we know about it. 293*7c478bd9Sstevel@tonic-gate */ 294*7c478bd9Sstevel@tonic-gate (void) printf("\tChanged to class %s while" 295*7c478bd9Sstevel@tonic-gate " priocntl command executing\n", clname); 296*7c478bd9Sstevel@tonic-gate else 297*7c478bd9Sstevel@tonic-gate (void) printf("\tCan't get IA user priority\n"); 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate free_pidlist(pidlist); 302*7c478bd9Sstevel@tonic-gate return (error); 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate /* 307*7c478bd9Sstevel@tonic-gate * Call priocntl() with command codes PC_SETXPARMS or PC_GETXPARMS. 308*7c478bd9Sstevel@tonic-gate * The first parameter behind the command code is always the class name. 309*7c478bd9Sstevel@tonic-gate * Each parameter is headed by a key, which determines the meaning of the 310*7c478bd9Sstevel@tonic-gate * following value. There are maximal IA_KEYCNT = 3 (key, value) pairs. 311*7c478bd9Sstevel@tonic-gate */ 312*7c478bd9Sstevel@tonic-gate static int 313*7c478bd9Sstevel@tonic-gate ia_priocntl(idtype_t idtype, id_t id, int cmd, char *clname, uintptr_t *argsp) 314*7c478bd9Sstevel@tonic-gate { 315*7c478bd9Sstevel@tonic-gate return (priocntl(idtype, id, cmd, clname, argsp[0], argsp[1], 316*7c478bd9Sstevel@tonic-gate argsp[2], argsp[3], argsp[4], argsp[5], 0)); 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate /* 321*7c478bd9Sstevel@tonic-gate * Set all processes in the set specified by idtype/idargv to interactive 322*7c478bd9Sstevel@tonic-gate * (if they aren't already interactive ) and set their user priority limit 323*7c478bd9Sstevel@tonic-gate * and user priority to those specified by iauprilim and iaupri. 324*7c478bd9Sstevel@tonic-gate */ 325*7c478bd9Sstevel@tonic-gate static int 326*7c478bd9Sstevel@tonic-gate set_iaprocs(idtype_t idtype, int idargc, char **idargv, uint_t cflags, 327*7c478bd9Sstevel@tonic-gate pri_t iauprilim, pri_t iaupri, int iamode) 328*7c478bd9Sstevel@tonic-gate { 329*7c478bd9Sstevel@tonic-gate pcinfo_t pcinfo; 330*7c478bd9Sstevel@tonic-gate uintptr_t args[2*IA_KEYCNT+1]; 331*7c478bd9Sstevel@tonic-gate uintptr_t *argsp = &args[0]; 332*7c478bd9Sstevel@tonic-gate int maxupri; 333*7c478bd9Sstevel@tonic-gate char idtypnm[PC_IDTYPNMSZ]; 334*7c478bd9Sstevel@tonic-gate int i; 335*7c478bd9Sstevel@tonic-gate int error = 0; 336*7c478bd9Sstevel@tonic-gate id_t id; 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate /* 339*7c478bd9Sstevel@tonic-gate * Get the interactive class ID and max configured user priority. 340*7c478bd9Sstevel@tonic-gate */ 341*7c478bd9Sstevel@tonic-gate (void) strcpy(pcinfo.pc_clname, "IA"); 342*7c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 343*7c478bd9Sstevel@tonic-gate fatalerr("%s: Can't get IA class ID, priocntl system call" 344*7c478bd9Sstevel@tonic-gate " failed with errno %d\n", basenm, errno); 345*7c478bd9Sstevel@tonic-gate maxupri = ((iainfo_t *)pcinfo.pc_clinfo)->ia_maxupri; 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate /* 348*7c478bd9Sstevel@tonic-gate * Validate the iauprilim and iaupri arguments. 349*7c478bd9Sstevel@tonic-gate */ 350*7c478bd9Sstevel@tonic-gate if ((cflags & IA_DOUPRILIM) != 0) { 351*7c478bd9Sstevel@tonic-gate if (iauprilim > maxupri || iauprilim < -maxupri) 352*7c478bd9Sstevel@tonic-gate fatalerr("%s: Specified user priority limit %d out of" 353*7c478bd9Sstevel@tonic-gate " configured range\n", basenm, iauprilim); 354*7c478bd9Sstevel@tonic-gate ADDKEYVAL(argsp, IA_KY_UPRILIM, iauprilim); 355*7c478bd9Sstevel@tonic-gate } 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate if ((cflags & IA_DOUPRI) != 0) { 358*7c478bd9Sstevel@tonic-gate if (iaupri > maxupri || iaupri < -maxupri) 359*7c478bd9Sstevel@tonic-gate fatalerr("%s: Specified user priority %d out of" 360*7c478bd9Sstevel@tonic-gate " configured range\n", basenm, iaupri); 361*7c478bd9Sstevel@tonic-gate ADDKEYVAL(argsp, IA_KY_UPRI, iaupri); 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate if ((cflags & IA_DOMODE) != 0) 365*7c478bd9Sstevel@tonic-gate ADDKEYVAL(argsp, IA_KY_MODE, iamode); 366*7c478bd9Sstevel@tonic-gate *argsp = 0; 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate if (idtype == P_ALL) { 369*7c478bd9Sstevel@tonic-gate if (ia_priocntl(P_ALL, 0, PC_SETXPARMS, "IA", args) == -1) { 370*7c478bd9Sstevel@tonic-gate if (errno == EPERM) { 371*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 372*7c478bd9Sstevel@tonic-gate "Permissions error encountered" 373*7c478bd9Sstevel@tonic-gate " on one or more processes.\n"); 374*7c478bd9Sstevel@tonic-gate error = 1; 375*7c478bd9Sstevel@tonic-gate } else { 376*7c478bd9Sstevel@tonic-gate fatalerr("%s: Can't reset interactive" 377*7c478bd9Sstevel@tonic-gate " parameters\npriocntl system call failed" 378*7c478bd9Sstevel@tonic-gate " with errno %d\n", basenm, errno); 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate } else if ((cflags & (IA_DOUPRILIM|IA_DOUPRI)) == IA_DOUPRI) { 381*7c478bd9Sstevel@tonic-gate (void) verifyupri(idtype, 0, "IA", IA_KY_UPRILIM, 382*7c478bd9Sstevel@tonic-gate iaupri, basenm); 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate } else if (idargc == 0) { 385*7c478bd9Sstevel@tonic-gate if (ia_priocntl(idtype, P_MYID, PC_SETXPARMS, "IA", 386*7c478bd9Sstevel@tonic-gate args) == -1) { 387*7c478bd9Sstevel@tonic-gate if (errno == EPERM) { 388*7c478bd9Sstevel@tonic-gate (void) idtyp2str(idtype, idtypnm); 389*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 390*7c478bd9Sstevel@tonic-gate "Permissions error encountered" 391*7c478bd9Sstevel@tonic-gate " on current %s.\n", idtypnm); 392*7c478bd9Sstevel@tonic-gate error = 1; 393*7c478bd9Sstevel@tonic-gate } else { 394*7c478bd9Sstevel@tonic-gate fatalerr("%s: Can't reset interactive" 395*7c478bd9Sstevel@tonic-gate " parameters\npriocntl system call failed" 396*7c478bd9Sstevel@tonic-gate " with errno %d\n", basenm, errno); 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate } else if ((cflags & (IA_DOUPRILIM|IA_DOUPRI)) == IA_DOUPRI && 399*7c478bd9Sstevel@tonic-gate getmyid(idtype, &id) != -1) { 400*7c478bd9Sstevel@tonic-gate (void) verifyupri(idtype, id, "IA", IA_KY_UPRILIM, 401*7c478bd9Sstevel@tonic-gate iaupri, basenm); 402*7c478bd9Sstevel@tonic-gate } 403*7c478bd9Sstevel@tonic-gate } else { 404*7c478bd9Sstevel@tonic-gate (void) idtyp2str(idtype, idtypnm); 405*7c478bd9Sstevel@tonic-gate for (i = 0; i < idargc; i++) { 406*7c478bd9Sstevel@tonic-gate if (idtype == P_CID) { 407*7c478bd9Sstevel@tonic-gate (void) strcpy(pcinfo.pc_clname, idargv[i]); 408*7c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_GETCID, 409*7c478bd9Sstevel@tonic-gate (caddr_t)&pcinfo) == -1) 410*7c478bd9Sstevel@tonic-gate fatalerr("%s: Invalid or unconfigured" 411*7c478bd9Sstevel@tonic-gate " class %s, priocntl system call" 412*7c478bd9Sstevel@tonic-gate " failed with errno %d\n", 413*7c478bd9Sstevel@tonic-gate basenm, pcinfo.pc_clname, errno); 414*7c478bd9Sstevel@tonic-gate id = pcinfo.pc_cid; 415*7c478bd9Sstevel@tonic-gate } else { 416*7c478bd9Sstevel@tonic-gate id = (id_t)str2num(idargv[i], INT_MIN, INT_MAX); 417*7c478bd9Sstevel@tonic-gate if (errno) 418*7c478bd9Sstevel@tonic-gate fatalerr("%s: Invalid id \"%s\"\n", 419*7c478bd9Sstevel@tonic-gate basenm, idargv[i]); 420*7c478bd9Sstevel@tonic-gate } 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate if (ia_priocntl(idtype, id, PC_SETXPARMS, "IA", 423*7c478bd9Sstevel@tonic-gate args) == -1) { 424*7c478bd9Sstevel@tonic-gate if (errno == EPERM) { 425*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 426*7c478bd9Sstevel@tonic-gate "Permissions error" 427*7c478bd9Sstevel@tonic-gate " encountered on %s %s.\n", 428*7c478bd9Sstevel@tonic-gate idtypnm, idargv[i]); 429*7c478bd9Sstevel@tonic-gate error = 1; 430*7c478bd9Sstevel@tonic-gate } else { 431*7c478bd9Sstevel@tonic-gate fatalerr("%s: Can't reset interactive" 432*7c478bd9Sstevel@tonic-gate " parameters\npriocntl system call" 433*7c478bd9Sstevel@tonic-gate " failed with errno %d\n", 434*7c478bd9Sstevel@tonic-gate basenm, errno); 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate } else if ((cflags & (IA_DOUPRILIM|IA_DOUPRI)) == 437*7c478bd9Sstevel@tonic-gate IA_DOUPRI) { 438*7c478bd9Sstevel@tonic-gate (void) verifyupri(idtype, id, "IA", 439*7c478bd9Sstevel@tonic-gate IA_KY_UPRILIM, iaupri, basenm); 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate } 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate return (error); 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate /* 449*7c478bd9Sstevel@tonic-gate * Execute the command pointed to by cmdargv as a interactive process 450*7c478bd9Sstevel@tonic-gate * with the user priority limit given by iauprilim and user priority iaupri. 451*7c478bd9Sstevel@tonic-gate */ 452*7c478bd9Sstevel@tonic-gate static void 453*7c478bd9Sstevel@tonic-gate exec_iacmd(char **cmdargv, uint_t cflags, pri_t iauprilim, pri_t iaupri, 454*7c478bd9Sstevel@tonic-gate int iamode) 455*7c478bd9Sstevel@tonic-gate { 456*7c478bd9Sstevel@tonic-gate pcinfo_t pcinfo; 457*7c478bd9Sstevel@tonic-gate uintptr_t args[2*IA_KEYCNT+1]; 458*7c478bd9Sstevel@tonic-gate uintptr_t *argsp = &args[0]; 459*7c478bd9Sstevel@tonic-gate pri_t maxupri; 460*7c478bd9Sstevel@tonic-gate pri_t uprilim; 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate /* 463*7c478bd9Sstevel@tonic-gate * Get the time sharing class ID and max configured user priority. 464*7c478bd9Sstevel@tonic-gate */ 465*7c478bd9Sstevel@tonic-gate (void) strcpy(pcinfo.pc_clname, "IA"); 466*7c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 467*7c478bd9Sstevel@tonic-gate fatalerr("%s: Can't get IA class ID, priocntl system call" 468*7c478bd9Sstevel@tonic-gate " failed with errno %d\n", basenm, errno); 469*7c478bd9Sstevel@tonic-gate maxupri = ((iainfo_t *)pcinfo.pc_clinfo)->ia_maxupri; 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate /* 472*7c478bd9Sstevel@tonic-gate * Validate the iauprilim and iaupri arguments. 473*7c478bd9Sstevel@tonic-gate */ 474*7c478bd9Sstevel@tonic-gate if ((cflags & IA_DOUPRILIM) != 0) { 475*7c478bd9Sstevel@tonic-gate if (iauprilim > maxupri || iauprilim < -maxupri) 476*7c478bd9Sstevel@tonic-gate fatalerr("%s: Specified user priority limit %d out of" 477*7c478bd9Sstevel@tonic-gate " configured range\n", basenm, iauprilim); 478*7c478bd9Sstevel@tonic-gate ADDKEYVAL(argsp, IA_KY_UPRILIM, iauprilim); 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate if ((cflags & IA_DOUPRI) != 0) { 482*7c478bd9Sstevel@tonic-gate if (iaupri > maxupri || iaupri < -maxupri) 483*7c478bd9Sstevel@tonic-gate fatalerr("%s: Specified user priority %d out of" 484*7c478bd9Sstevel@tonic-gate " configured range\n", basenm, iaupri); 485*7c478bd9Sstevel@tonic-gate ADDKEYVAL(argsp, IA_KY_UPRI, iaupri); 486*7c478bd9Sstevel@tonic-gate } 487*7c478bd9Sstevel@tonic-gate 488*7c478bd9Sstevel@tonic-gate if ((cflags & IA_DOMODE) != 0) 489*7c478bd9Sstevel@tonic-gate ADDKEYVAL(argsp, IA_KY_MODE, iamode); 490*7c478bd9Sstevel@tonic-gate *argsp = 0; 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate if (ia_priocntl(P_PID, P_MYID, PC_SETXPARMS, "IA", args) == -1) 493*7c478bd9Sstevel@tonic-gate fatalerr("%s: Can't reset interactive parameters\n" 494*7c478bd9Sstevel@tonic-gate "priocntl system call failed with errno %d\n", 495*7c478bd9Sstevel@tonic-gate basenm, errno); 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate if ((cflags & (IA_DOUPRILIM|IA_DOUPRI)) == IA_DOUPRI) { 498*7c478bd9Sstevel@tonic-gate if (priocntl(P_PID, P_MYID, PC_GETXPARMS, "IA", 499*7c478bd9Sstevel@tonic-gate IA_KY_UPRILIM, &uprilim, 0) != -1 && iaupri > uprilim) 500*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 501*7c478bd9Sstevel@tonic-gate "%s: Specified user priority %d exceeds" 502*7c478bd9Sstevel@tonic-gate " limit %d; set to %d (pid %d)\n", 503*7c478bd9Sstevel@tonic-gate basenm, iaupri, uprilim, uprilim, (int)getpid()); 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate (void) execvp(cmdargv[0], cmdargv); 507*7c478bd9Sstevel@tonic-gate fatalerr("%s: Can't execute %s, exec failed with errno %d\n", 508*7c478bd9Sstevel@tonic-gate basenm, cmdargv[0], errno); 509*7c478bd9Sstevel@tonic-gate } 510