Mercurial > illumos > onarm
comparison usr/src/cmd/dispadmin/fxdispadmin.c @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c9caec207d52 |
---|---|
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 "@(#)fxdispadmin.c 1.5 05/06/08 SMI" | |
31 | |
32 #include <stdio.h> | |
33 #include <stdlib.h> | |
34 #include <string.h> | |
35 #include <unistd.h> | |
36 #include <sys/types.h> | |
37 #include <sys/priocntl.h> | |
38 #include <sys/fxpriocntl.h> | |
39 #include <sys/param.h> | |
40 #include <errno.h> | |
41 #include <sys/fx.h> | |
42 | |
43 #include "dispadmin.h" | |
44 | |
45 /* | |
46 * This file contains the class specific code implementing | |
47 * the fixed-priority dispadmin sub-command. | |
48 */ | |
49 | |
50 #define BASENMSZ 16 | |
51 | |
52 extern char *basename(); | |
53 | |
54 static void get_fxdptbl(), set_fxdptbl(); | |
55 | |
56 static char usage[] = "usage: dispadmin -l\n" | |
57 "dispadmin -c FX -g [-r res]\n" | |
58 "dispadmin -c FX -s infile\n"; | |
59 | |
60 static char basenm[BASENMSZ]; | |
61 static char cmdpath[256]; | |
62 | |
63 | |
64 int | |
65 main(int argc, char **argv) | |
66 { | |
67 int c; | |
68 int lflag, gflag, rflag, sflag; | |
69 ulong_t res; | |
70 char *infile; | |
71 char *endp; | |
72 | |
73 (void) strcpy(cmdpath, argv[0]); | |
74 (void) strcpy(basenm, basename(argv[0])); | |
75 lflag = gflag = rflag = sflag = 0; | |
76 while ((c = getopt(argc, argv, "lc:gr:s:")) != -1) { | |
77 switch (c) { | |
78 | |
79 case 'l': | |
80 lflag++; | |
81 break; | |
82 | |
83 case 'c': | |
84 if (strcmp(optarg, "FX") != 0) | |
85 fatalerr("error: %s executed for %s class, " | |
86 "%s is actually sub-command for FX class\n", | |
87 cmdpath, optarg, cmdpath); | |
88 break; | |
89 | |
90 case 'g': | |
91 gflag++; | |
92 break; | |
93 | |
94 case 'r': | |
95 rflag++; | |
96 errno = 0; | |
97 res = strtoul(optarg, &endp, 10); | |
98 if (res == 0 || errno != 0 || *endp != '\0') | |
99 fatalerr("%s: Can't convert to requested " | |
100 "resolution\n", basenm); | |
101 break; | |
102 | |
103 case 's': | |
104 sflag++; | |
105 infile = optarg; | |
106 break; | |
107 | |
108 case '?': | |
109 fatalerr(usage); | |
110 | |
111 default: | |
112 break; | |
113 } | |
114 } | |
115 | |
116 | |
117 if (lflag) { | |
118 if (gflag || rflag || sflag) | |
119 fatalerr(usage); | |
120 | |
121 (void) printf("FX\t(Fixed Priority)\n"); | |
122 return (0); | |
123 | |
124 } else if (gflag) { | |
125 if (sflag) | |
126 fatalerr(usage); | |
127 | |
128 if (rflag == 0) | |
129 res = 1000; | |
130 | |
131 get_fxdptbl(res); | |
132 return (0); | |
133 | |
134 } else if (sflag) { | |
135 if (rflag) | |
136 fatalerr(usage); | |
137 | |
138 set_fxdptbl(infile); | |
139 return (0); | |
140 | |
141 } else { | |
142 fatalerr(usage); | |
143 } | |
144 return (1); | |
145 } | |
146 | |
147 | |
148 /* | |
149 * Retrieve the current fx_dptbl from memory, convert the time quantum | |
150 * values to the resolution specified by res and write the table to stdout. | |
151 */ | |
152 static void | |
153 get_fxdptbl(ulong_t res) | |
154 { | |
155 int i; | |
156 int fxdpsz; | |
157 pcinfo_t pcinfo; | |
158 pcadmin_t pcadmin; | |
159 fxadmin_t fxadmin; | |
160 fxdpent_t *fx_dptbl; | |
161 hrtimer_t hrtime; | |
162 | |
163 (void) strcpy(pcinfo.pc_clname, "FX"); | |
164 if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) | |
165 fatalerr("%s: Can't get FX class ID, priocntl system call " | |
166 "failed with errno %d\n", basenm, errno); | |
167 | |
168 pcadmin.pc_cid = pcinfo.pc_cid; | |
169 pcadmin.pc_cladmin = (char *)&fxadmin; | |
170 fxadmin.fx_cmd = FX_GETDPSIZE; | |
171 | |
172 if (priocntl(0, 0, PC_ADMIN, (caddr_t)&pcadmin) == -1) | |
173 fatalerr("%s: Can't get fx_dptbl size, priocntl system call " | |
174 "failed with errno %d\n", basenm, errno); | |
175 | |
176 fxdpsz = fxadmin.fx_ndpents * sizeof (fxdpent_t); | |
177 if ((fx_dptbl = (fxdpent_t *)malloc(fxdpsz)) == NULL) | |
178 fatalerr("%s: Can't allocate memory for fx_dptbl\n", basenm); | |
179 | |
180 fxadmin.fx_dpents = fx_dptbl; | |
181 | |
182 fxadmin.fx_cmd = FX_GETDPTBL; | |
183 if (priocntl(0, 0, PC_ADMIN, (caddr_t)&pcadmin) == -1) | |
184 fatalerr("%s: Can't get fx_dptbl, priocntl system call " | |
185 "failed with errno %d\n", basenm, errno); | |
186 | |
187 (void) printf("# Fixed Priority Dispatcher Configuration\n"); | |
188 (void) printf("RES=%ld\n\n", res); | |
189 (void) printf("# TIME QUANTUM PRIORITY\n"); | |
190 (void) printf("# (fx_quantum) LEVEL\n"); | |
191 | |
192 for (i = 0; i < fxadmin.fx_ndpents; i++) { | |
193 if (res != HZ && fx_dptbl[i].fx_quantum != FX_TQINF) { | |
194 hrtime.hrt_secs = 0; | |
195 hrtime.hrt_rem = fx_dptbl[i].fx_quantum; | |
196 hrtime.hrt_res = HZ; | |
197 if (_hrtnewres(&hrtime, res, HRT_RNDUP) == -1) | |
198 fatalerr("%s: Can't convert to requested " | |
199 "resolution\n", basenm); | |
200 if ((fx_dptbl[i].fx_quantum = hrtconvert(&hrtime)) | |
201 == -1) | |
202 fatalerr("%s: Can't express time quantum in " | |
203 "requested resolution,\n" | |
204 "try coarser resolution\n", basenm); | |
205 } | |
206 (void) printf("%10d # %3d\n", | |
207 fx_dptbl[i].fx_quantum, i); | |
208 } | |
209 } | |
210 | |
211 | |
212 /* | |
213 * Read the fx_dptbl values from infile, convert the time quantum values | |
214 * to HZ resolution, do a little sanity checking and overwrite the table | |
215 * in memory with the values from the file. | |
216 */ | |
217 static void | |
218 set_fxdptbl(char *infile) | |
219 { | |
220 int i; | |
221 int nfxdpents; | |
222 char *tokp; | |
223 pcinfo_t pcinfo; | |
224 pcadmin_t pcadmin; | |
225 fxadmin_t fxadmin; | |
226 fxdpent_t *fx_dptbl; | |
227 int linenum; | |
228 ulong_t res; | |
229 hrtimer_t hrtime; | |
230 FILE *fp; | |
231 char buf[512]; | |
232 int wslength; | |
233 char *endp; | |
234 char name[512], value[512]; | |
235 int len; | |
236 | |
237 (void) strcpy(pcinfo.pc_clname, "FX"); | |
238 if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) | |
239 fatalerr("%s: Can't get FX class ID, priocntl system call " | |
240 "failed with errno %d\n", basenm, errno); | |
241 | |
242 pcadmin.pc_cid = pcinfo.pc_cid; | |
243 pcadmin.pc_cladmin = (char *)&fxadmin; | |
244 fxadmin.fx_cmd = FX_GETDPSIZE; | |
245 | |
246 if (priocntl(0, 0, PC_ADMIN, (caddr_t)&pcadmin) == -1) | |
247 fatalerr("%s: Can't get fx_dptbl size, priocntl system call " | |
248 "failed with errno %d\n", basenm, errno); | |
249 | |
250 nfxdpents = fxadmin.fx_ndpents; | |
251 if ((fx_dptbl = | |
252 (fxdpent_t *)malloc(nfxdpents * sizeof (fxdpent_t))) == NULL) | |
253 fatalerr("%s: Can't allocate memory for fx_dptbl\n", basenm); | |
254 | |
255 if ((fp = fopen(infile, "r")) == NULL) | |
256 fatalerr("%s: Can't open %s for input\n", basenm, infile); | |
257 | |
258 linenum = 0; | |
259 | |
260 /* | |
261 * Find the first non-blank, non-comment line. A comment line | |
262 * is any line with '#' as the first non-white-space character. | |
263 */ | |
264 do { | |
265 if (fgets(buf, sizeof (buf), fp) == NULL) | |
266 fatalerr("%s: Too few lines in input table\n", basenm); | |
267 linenum++; | |
268 } while (buf[0] == '#' || buf[0] == '\0' || | |
269 (wslength = strspn(buf, " \t\n")) == strlen(buf) || | |
270 strchr(buf, '#') == buf + wslength); | |
271 | |
272 /* LINTED - unbounded string specifier */ | |
273 if (sscanf(buf, " %[^=]=%s \n%n", name, value, &len) == 2 && | |
274 name[0] != '\0' && value[0] != '\0' && len == strlen(buf)) { | |
275 | |
276 if (strcmp(name, "RES") == 0) { | |
277 errno = 0; | |
278 i = (int)strtol(value, &endp, 10); | |
279 if (errno != 0 || endp == value || | |
280 i < 0 || *endp != '\0') | |
281 fatalerr("%s: Bad RES specification, " | |
282 "line %d of input file\n", basenm, linenum); | |
283 else | |
284 res = i; | |
285 } else { | |
286 fatalerr("%s: Bad RES specification, " | |
287 "line %d of input file\n", basenm, linenum); | |
288 } | |
289 } | |
290 | |
291 /* | |
292 * The remainder of the input file should contain exactly enough | |
293 * non-blank, non-comment lines to fill the table (fx_ndpents lines). | |
294 * We assume that any non-blank, non-comment line is data for the | |
295 * table and fail if we find more or less than we need. | |
296 */ | |
297 for (i = 0; i < fxadmin.fx_ndpents; i++) { | |
298 | |
299 /* | |
300 * Get the next non-blank, non-comment line. | |
301 */ | |
302 do { | |
303 if (fgets(buf, sizeof (buf), fp) == NULL) | |
304 fatalerr("%s: Too few lines in input table\n", | |
305 basenm); | |
306 linenum++; | |
307 } while (buf[0] == '#' || buf[0] == '\0' || | |
308 (wslength = strspn(buf, " \t\n")) == strlen(buf) || | |
309 strchr(buf, '#') == buf + wslength); | |
310 | |
311 if ((tokp = strtok(buf, " \t")) == NULL) | |
312 fatalerr("%s: Too few values, line %d of input file\n", | |
313 basenm, linenum); | |
314 | |
315 fx_dptbl[i].fx_quantum = atol(tokp); | |
316 if (fx_dptbl[i].fx_quantum <= 0) { | |
317 fatalerr("%s: fx_quantum value out of " | |
318 "valid range; line %d of input,\n" | |
319 "table not overwritten\n", basenm, linenum); | |
320 } else if (res != HZ) { | |
321 hrtime.hrt_secs = 0; | |
322 hrtime.hrt_rem = fx_dptbl[i].fx_quantum; | |
323 hrtime.hrt_res = res; | |
324 if (_hrtnewres(&hrtime, HZ, HRT_RNDUP) == -1) | |
325 fatalerr("%s: Can't convert specified " | |
326 "resolution to ticks\n", basenm); | |
327 if ((fx_dptbl[i].fx_quantum = | |
328 hrtconvert(&hrtime)) == -1) | |
329 fatalerr("%s: fx_quantum value out of " | |
330 "valid range; line %d of input,\n" | |
331 "table not overwritten\n", basenm, linenum); | |
332 } | |
333 | |
334 if ((tokp = strtok(NULL, " \t")) != NULL && tokp[0] != '#') | |
335 fatalerr("%s: Too many values, line %d of input file\n", | |
336 basenm, linenum); | |
337 } | |
338 | |
339 /* | |
340 * We've read enough lines to fill the table. We fail | |
341 * if the input file contains any more. | |
342 */ | |
343 while (fgets(buf, sizeof (buf), fp) != NULL) { | |
344 if (buf[0] != '#' && buf[0] != '\0' && | |
345 (wslength = strspn(buf, " \t\n")) != strlen(buf) && | |
346 strchr(buf, '#') != buf + wslength) | |
347 fatalerr("%s: Too many lines in input table\n", | |
348 basenm); | |
349 } | |
350 | |
351 fxadmin.fx_dpents = fx_dptbl; | |
352 fxadmin.fx_cmd = FX_SETDPTBL; | |
353 if (priocntl(0, 0, PC_ADMIN, (caddr_t)&pcadmin) == -1) | |
354 fatalerr("%s: Can't set fx_dptbl, priocntl system call failed " | |
355 "with errno %d\n", basenm, errno); | |
356 } |