1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/fss.h> 35 #include <sys/priocntl.h> 36 #include <sys/fsspriocntl.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <unistd.h> 41 #include <errno.h> 42 #include "dispadmin.h" 43 44 /* 45 * This file contains the class specific code implementing the fair-share 46 * scheduler dispadmin sub-command. 47 */ 48 49 #define BASENMSZ 16 50 51 extern char *basename(); 52 static void getadmin(), setadmin(); 53 54 static char usage[] = "usage: dispadmin -l\n" 55 "dispadmin -c FSS -g [-r res]\n" 56 "dispadmin -c FSS -s infile\n"; 57 58 static char basenm[BASENMSZ]; 59 static char cmdpath[256]; 60 61 int 62 main(int argc, char **argv) 63 { 64 int c; 65 int lflag, gflag, rflag, sflag; 66 ulong_t res; 67 char *infile; 68 char *endp; 69 70 (void) strcpy(cmdpath, argv[0]); 71 (void) strcpy(basenm, basename(argv[0])); 72 lflag = gflag = rflag = sflag = 0; 73 while ((c = getopt(argc, argv, "lc:gr:s:")) != -1) { 74 switch (c) { 75 76 case 'l': 77 lflag++; 78 break; 79 80 case 'c': 81 if (strcmp(optarg, "FSS") != 0) 82 fatalerr("error: %s executed for %s class, " 83 "%s is actually sub-command for FSS " 84 "class\n", cmdpath, optarg, cmdpath); 85 break; 86 87 case 'g': 88 gflag++; 89 break; 90 91 case 'r': 92 rflag++; 93 errno = 0; 94 res = strtoul(optarg, &endp, 10); 95 if (res == 0 || errno != 0 || *endp != '\0') 96 fatalerr("%s: Can't convert to requested " 97 "resolution\n", basenm); 98 break; 99 100 case 's': 101 sflag++; 102 infile = optarg; 103 break; 104 105 case '?': 106 fatalerr(usage); 107 108 default: 109 break; 110 } 111 } 112 113 if (lflag) { 114 if (gflag || rflag || sflag) 115 fatalerr(usage); 116 117 (void) printf("FSS\t(Fair Share)\n"); 118 return (0); 119 120 } else if (gflag) { 121 if (lflag || sflag) 122 fatalerr(usage); 123 124 if (rflag == 0) 125 res = 1000; 126 127 getadmin(res); 128 return (0); 129 130 } else if (sflag) { 131 if (lflag || gflag || rflag) 132 fatalerr(usage); 133 134 setadmin(infile); 135 return (0); 136 137 } else { 138 fatalerr(usage); 139 } 140 return (1); 141 } 142 143 /* 144 * Retrieve the current settings from kernel, convert the time quantum 145 * value to the resolution specified by res and print out the results. 146 */ 147 static void 148 getadmin(ulong_t res) 149 { 150 pcinfo_t pcinfo; 151 pcadmin_t pcadmin; 152 fssadmin_t fssadmin; 153 hrtimer_t hrtime; 154 long fss_quantum; 155 156 (void) strcpy(pcinfo.pc_clname, "FSS"); 157 if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 158 fatalerr("%s: Can't get FSS class ID, priocntl system call " 159 "failed (%s)\n", basenm, strerror(errno)); 160 161 pcadmin.pc_cid = pcinfo.pc_cid; 162 pcadmin.pc_cladmin = (char *)&fssadmin; 163 fssadmin.fss_cmd = FSS_GETADMIN; 164 165 if (priocntl(0, 0, PC_ADMIN, (caddr_t)&pcadmin) == -1) 166 fatalerr("%s: Can't get scheduler configuration, priocntl " 167 "system call failed (%s)\n", basenm, strerror(errno)); 168 169 hrtime.hrt_secs = 0; 170 hrtime.hrt_rem = fssadmin.fss_quantum; 171 hrtime.hrt_res = HZ; 172 if (_hrtnewres(&hrtime, res, HRT_RNDUP) == -1) 173 fatalerr("%s: Can't convert to requested resolution\n", basenm); 174 if ((fss_quantum = hrtconvert(&hrtime)) == -1) 175 fatalerr("%s: Can't express time quantum in " 176 "requested resolution,\n" 177 "try coarser resolution\n", basenm); 178 179 (void) printf("#\n# Fair Share Scheduler Configuration\n#\n"); 180 (void) printf("RES=%ld\n", res); 181 (void) printf("#\n# Time Quantum\n#\n"); 182 (void) printf("QUANTUM=%ld\n", fss_quantum); 183 } 184 185 /* 186 * Read the scheduler settings from infile, convert the time quantum values 187 * to HZ resolution, do a little sanity checking and overwrite kernel settings 188 * with the values from the file. 189 */ 190 static void 191 setadmin(char *infile) 192 { 193 int i; 194 pcinfo_t pcinfo; 195 pcadmin_t pcadmin; 196 fssadmin_t fssadmin; 197 int line; 198 ulong_t res; 199 long fss_quantum; 200 hrtimer_t hrtime; 201 FILE *fp; 202 char buf[512]; 203 char *endp; 204 int nparams = 0; 205 206 (void) strcpy(pcinfo.pc_clname, "FSS"); 207 if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 208 fatalerr("%s: Can't get FSS class ID, priocntl system call " 209 "failed (%s)\n", basenm, strerror(errno)); 210 211 if ((fp = fopen(infile, "r")) == NULL) 212 fatalerr("%s: Can't open %s for input\n", basenm, infile); 213 214 for (line = 1; fgets(buf, sizeof (buf), fp) != NULL; line++) { 215 char name[512], value[512]; 216 int len; 217 218 if (buf[0] == '#' || buf[0] == '\n') 219 continue; 220 /* 221 * Look for "name=value", with optional whitespaces on either 222 * side, terminated by a newline, and consuming the whole line. 223 */ 224 /* LINTED - unbounded string specifier */ 225 if (sscanf(buf, " %[^=]=%s \n%n", name, value, &len) == 2 && 226 name[0] != '\0' && value[0] != '\0' && len == strlen(buf)) { 227 228 if (strcmp(name, "RES") == 0) { 229 errno = 0; 230 i = (int)strtol(value, &endp, 10); 231 if (errno != 0 || endp == value || 232 i < 0 || *endp != '\0') 233 fatalerr("%s, line %d: illegal " 234 "resolution value\n", infile, line); 235 else 236 res = i; 237 nparams++; 238 } else if (strcmp(name, "QUANTUM") == 0) { 239 errno = 0; 240 i = (int)strtol(value, &endp, 10); 241 if (errno != 0 || endp == value || 242 i < 0 || *endp != '\0') 243 fatalerr("%s, line %d: illegal time " 244 "quantum value\n", infile, line); 245 else 246 fss_quantum = i; 247 nparams++; 248 } else { 249 fatalerr("%s, line %d: invalid token\n", 250 infile, line); 251 } 252 } else { 253 fatalerr("%s, line %d: syntax error\n", infile, line); 254 } 255 } 256 if (line == 1 || nparams < 2) 257 fatalerr("cannot read settings from %s\n", infile); 258 if (res != HZ) { 259 hrtime.hrt_secs = 0; 260 hrtime.hrt_rem = fss_quantum; 261 hrtime.hrt_res = res; 262 if (_hrtnewres(&hrtime, HZ, HRT_RNDUP) == -1) 263 fatalerr("%s: Can't convert specified " 264 "resolution to ticks\n", basenm); 265 if ((fssadmin.fss_quantum = hrtconvert(&hrtime)) == -1) 266 fatalerr("%s, line %d: time quantum value out of " 267 "valid range\n", infile, line); 268 } else { 269 fssadmin.fss_quantum = (short)fss_quantum; 270 } 271 272 pcadmin.pc_cid = pcinfo.pc_cid; 273 pcadmin.pc_cladmin = (char *)&fssadmin; 274 fssadmin.fss_cmd = FSS_SETADMIN; 275 276 if (priocntl(0, 0, PC_ADMIN, (caddr_t)&pcadmin) == -1) 277 fatalerr("%s: Can't set scheduler parameters, priocntl " 278 "system call failed (%s)\n", basenm, strerror(errno)); 279 } 280