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 #include <sys/types.h> 31 #include <sys/param.h> 32 #include <sys/fss.h> 33 #include <sys/priocntl.h> 34 #include <sys/fsspriocntl.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <unistd.h> 39 #include <errno.h> 40 #include "dispadmin.h" 41 42 /* 43 * This file contains the class specific code implementing the fair-share 44 * scheduler dispadmin sub-command. 45 */ 46 47 #define BASENMSZ 16 48 49 extern char *basename(); 50 static void getadmin(), setadmin(); 51 52 static char usage[] = "usage: dispadmin -l\n" 53 "dispadmin -c FSS -g [-r res]\n" 54 "dispadmin -c FSS -s infile\n"; 55 56 static char basenm[BASENMSZ]; 57 static char cmdpath[256]; 58 59 int 60 main(int argc, char **argv) 61 { 62 int c; 63 int lflag, gflag, rflag, sflag; 64 ulong_t res; 65 char *infile; 66 char *endp; 67 68 (void) strcpy(cmdpath, argv[0]); 69 (void) strcpy(basenm, basename(argv[0])); 70 lflag = gflag = rflag = sflag = 0; 71 while ((c = getopt(argc, argv, "lc:gr:s:")) != -1) { 72 switch (c) { 73 74 case 'l': 75 lflag++; 76 break; 77 78 case 'c': 79 if (strcmp(optarg, "FSS") != 0) 80 fatalerr("error: %s executed for %s class, " 81 "%s is actually sub-command for FSS " 82 "class\n", cmdpath, optarg, cmdpath); 83 break; 84 85 case 'g': 86 gflag++; 87 break; 88 89 case 'r': 90 rflag++; 91 errno = 0; 92 res = strtoul(optarg, &endp, 10); 93 if (res == 0 || errno != 0 || *endp != '\0') 94 fatalerr("%s: Can't convert to requested " 95 "resolution\n", basenm); 96 break; 97 98 case 's': 99 sflag++; 100 infile = optarg; 101 break; 102 103 case '?': 104 fatalerr(usage); 105 106 default: 107 break; 108 } 109 } 110 111 if (lflag) { 112 if (gflag || rflag || sflag) 113 fatalerr(usage); 114 115 (void) printf("FSS\t(Fair Share)\n"); 116 return (0); 117 118 } else if (gflag) { 119 if (lflag || sflag) 120 fatalerr(usage); 121 122 if (rflag == 0) 123 res = 1000; 124 125 getadmin(res); 126 return (0); 127 128 } else if (sflag) { 129 if (lflag || gflag || rflag) 130 fatalerr(usage); 131 132 setadmin(infile); 133 return (0); 134 135 } else { 136 fatalerr(usage); 137 } 138 return (1); 139 } 140 141 /* 142 * Retrieve the current settings from kernel, convert the time quantum 143 * value to the resolution specified by res and print out the results. 144 */ 145 static void 146 getadmin(ulong_t res) 147 { 148 pcinfo_t pcinfo; 149 pcadmin_t pcadmin; 150 fssadmin_t fssadmin; 151 hrtimer_t hrtime; 152 long fss_quantum; 153 154 (void) strcpy(pcinfo.pc_clname, "FSS"); 155 if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 156 fatalerr("%s: Can't get FSS class ID, priocntl system call " 157 "failed (%s)\n", basenm, strerror(errno)); 158 159 pcadmin.pc_cid = pcinfo.pc_cid; 160 pcadmin.pc_cladmin = (char *)&fssadmin; 161 fssadmin.fss_cmd = FSS_GETADMIN; 162 163 if (priocntl(0, 0, PC_ADMIN, (caddr_t)&pcadmin) == -1) 164 fatalerr("%s: Can't get scheduler configuration, priocntl " 165 "system call failed (%s)\n", basenm, strerror(errno)); 166 167 hrtime.hrt_secs = 0; 168 hrtime.hrt_rem = fssadmin.fss_quantum; 169 hrtime.hrt_res = HZ; 170 if (_hrtnewres(&hrtime, res, HRT_RNDUP) == -1) 171 fatalerr("%s: Can't convert to requested resolution\n", basenm); 172 if ((fss_quantum = hrtconvert(&hrtime)) == -1) 173 fatalerr("%s: Can't express time quantum in " 174 "requested resolution,\n" 175 "try coarser resolution\n", basenm); 176 177 (void) printf("#\n# Fair Share Scheduler Configuration\n#\n"); 178 (void) printf("RES=%ld\n", res); 179 (void) printf("#\n# Time Quantum\n#\n"); 180 (void) printf("QUANTUM=%ld\n", fss_quantum); 181 } 182 183 /* 184 * Read the scheduler settings from infile, convert the time quantum values 185 * to HZ resolution, do a little sanity checking and overwrite kernel settings 186 * with the values from the file. 187 */ 188 static void 189 setadmin(char *infile) 190 { 191 int i; 192 pcinfo_t pcinfo; 193 pcadmin_t pcadmin; 194 fssadmin_t fssadmin; 195 int line; 196 ulong_t res; 197 long fss_quantum; 198 hrtimer_t hrtime; 199 FILE *fp; 200 char buf[512]; 201 char *endp; 202 int nparams = 0; 203 204 (void) strcpy(pcinfo.pc_clname, "FSS"); 205 if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 206 fatalerr("%s: Can't get FSS class ID, priocntl system call " 207 "failed (%s)\n", basenm, strerror(errno)); 208 209 if ((fp = fopen(infile, "r")) == NULL) 210 fatalerr("%s: Can't open %s for input\n", basenm, infile); 211 212 for (line = 1; fgets(buf, sizeof (buf), fp) != NULL; line++) { 213 char name[512], value[512]; 214 int len; 215 216 if (buf[0] == '#' || buf[0] == '\n') 217 continue; 218 /* 219 * Look for "name=value", with optional whitespaces on either 220 * side, terminated by a newline, and consuming the whole line. 221 */ 222 /* LINTED - unbounded string specifier */ 223 if (sscanf(buf, " %[^=]=%s \n%n", name, value, &len) == 2 && 224 name[0] != '\0' && value[0] != '\0' && len == strlen(buf)) { 225 226 if (strcmp(name, "RES") == 0) { 227 errno = 0; 228 i = (int)strtol(value, &endp, 10); 229 if (errno != 0 || endp == value || 230 i < 0 || *endp != '\0') 231 fatalerr("%s, line %d: illegal " 232 "resolution value\n", infile, line); 233 else 234 res = i; 235 nparams++; 236 } else if (strcmp(name, "QUANTUM") == 0) { 237 errno = 0; 238 i = (int)strtol(value, &endp, 10); 239 if (errno != 0 || endp == value || 240 i < 0 || *endp != '\0') 241 fatalerr("%s, line %d: illegal time " 242 "quantum value\n", infile, line); 243 else 244 fss_quantum = i; 245 nparams++; 246 } else { 247 fatalerr("%s, line %d: invalid token\n", 248 infile, line); 249 } 250 } else { 251 fatalerr("%s, line %d: syntax error\n", infile, line); 252 } 253 } 254 if (line == 1 || nparams < 2) 255 fatalerr("cannot read settings from %s\n", infile); 256 if (res != HZ) { 257 hrtime.hrt_secs = 0; 258 hrtime.hrt_rem = fss_quantum; 259 hrtime.hrt_res = res; 260 if (_hrtnewres(&hrtime, HZ, HRT_RNDUP) == -1) 261 fatalerr("%s: Can't convert specified " 262 "resolution to ticks\n", basenm); 263 if ((fssadmin.fss_quantum = hrtconvert(&hrtime)) == -1) 264 fatalerr("%s, line %d: time quantum value out of " 265 "valid range\n", infile, line); 266 } else { 267 fssadmin.fss_quantum = (short)fss_quantum; 268 } 269 270 pcadmin.pc_cid = pcinfo.pc_cid; 271 pcadmin.pc_cladmin = (char *)&fssadmin; 272 fssadmin.fss_cmd = FSS_SETADMIN; 273 274 if (priocntl(0, 0, PC_ADMIN, (caddr_t)&pcadmin) == -1) 275 fatalerr("%s: Can't set scheduler parameters, priocntl " 276 "system call failed (%s)\n", basenm, strerror(errno)); 277 } 278