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