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
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.
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]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 #pragma ident "%Z%%M% %I% %E% SMI"
38 #include <sys/types.h>
39 #include <sys/priocntl.h>
40 #include <sys/tspriocntl.h>
41 #include <sys/param.h>
44 #include "dispadmin.h"
47 * This file contains the class specific code implementing
48 * the time-sharing dispadmin sub-command.
53 extern char *basename();
55 static void get_tsdptbl(), set_tsdptbl();
58 "usage: dispadmin -l\n\
59 dispadmin -c TS -g [-r res]\n\
60 dispadmin -c TS -s infile\n";
62 static char basenm
[BASENMSZ
];
63 static char cmdpath
[256];
67 main(int argc
, char **argv
)
72 int lflag
, gflag
, rflag
, sflag
;
76 (void) strcpy(cmdpath
, argv
[0]);
77 (void) strcpy(basenm
, basename(argv
[0]));
78 lflag
= gflag
= rflag
= sflag
= 0;
79 while ((c
= getopt(argc
, argv
, "lc:gr:s:")) != -1) {
87 if (strcmp(optarg
, "TS") != 0)
88 fatalerr("error: %s executed for %s class, \
89 %s is actually sub-command for TS class\n", cmdpath
, optarg
, cmdpath
);
98 res
= strtoul(optarg
, (char **)NULL
, 10);
115 if (gflag
|| rflag
|| sflag
)
118 (void) printf("TS\t(Time Sharing)\n");
132 if (lflag
|| gflag
|| rflag
)
146 * Retrieve the current ts_dptbl from memory, convert the time quantum
147 * values to the resolution specified by res and write the table to stdout.
150 get_tsdptbl(ulong_t res
)
160 (void) strcpy(pcinfo
.pc_clname
, "TS");
161 if (priocntl(0, 0, PC_GETCID
, (caddr_t
)&pcinfo
) == -1)
162 fatalerr("%s: Can't get TS class ID, priocntl system \
163 call failed with errno %d\n", basenm
, errno
);
165 pcadmin
.pc_cid
= pcinfo
.pc_cid
;
166 pcadmin
.pc_cladmin
= (char *)&tsadmin
;
167 tsadmin
.ts_cmd
= TS_GETDPSIZE
;
169 if (priocntl(0, 0, PC_ADMIN
, (caddr_t
)&pcadmin
) == -1)
170 fatalerr("%s: Can't get ts_dptbl size, priocntl system \
171 call failed with errno %d\n", basenm
, errno
);
173 tsdpsz
= tsadmin
.ts_ndpents
* sizeof (tsdpent_t
);
174 if ((ts_dptbl
= (tsdpent_t
*)malloc(tsdpsz
)) == NULL
)
175 fatalerr("%s: Can't allocate memory for ts_dptbl\n", basenm
);
177 tsadmin
.ts_dpents
= ts_dptbl
;
179 tsadmin
.ts_cmd
= TS_GETDPTBL
;
180 if (priocntl(0, 0, PC_ADMIN
, (caddr_t
)&pcadmin
) == -1)
181 fatalerr("%s: Can't get ts_dptbl, priocntl system call \
182 call failed with errno %d\n", basenm
, errno
);
184 (void) printf("# Time Sharing Dispatcher Configuration\n");
185 (void) printf("RES=%ld\n\n", res
);
186 (void) printf("# ts_quantum ts_tqexp ts_slpret ts_maxwait ts_lwait \
189 for (i
= 0; i
< tsadmin
.ts_ndpents
; i
++) {
192 hrtime
.hrt_rem
= ts_dptbl
[i
].ts_quantum
;
194 if (_hrtnewres(&hrtime
, res
, HRT_RNDUP
) == -1)
195 fatalerr("%s: Can't convert to requested \
196 resolution\n", basenm
);
197 if ((ts_dptbl
[i
].ts_quantum
= hrtconvert(&hrtime
))
199 fatalerr("%s: Can't express time quantum in "
200 "requested resolution,\n"
201 "try coarser resolution\n", basenm
);
203 (void) printf("%10d%10d%10d%12d%10d # %3d\n",
204 ts_dptbl
[i
].ts_quantum
, ts_dptbl
[i
].ts_tqexp
,
205 ts_dptbl
[i
].ts_slpret
, ts_dptbl
[i
].ts_maxwait
,
206 ts_dptbl
[i
].ts_lwait
, i
);
212 * Read the ts_dptbl values from infile, convert the time quantum values
213 * to HZ resolution, do a little sanity checking and overwrite the table
214 * in memory with the values from the file.
234 (void) strcpy(pcinfo
.pc_clname
, "TS");
235 if (priocntl(0, 0, PC_GETCID
, (caddr_t
)&pcinfo
) == -1)
236 fatalerr("%s: Can't get TS class ID, priocntl system \
237 call failed with errno %d\n", basenm
, errno
);
239 pcadmin
.pc_cid
= pcinfo
.pc_cid
;
240 pcadmin
.pc_cladmin
= (char *)&tsadmin
;
241 tsadmin
.ts_cmd
= TS_GETDPSIZE
;
243 if (priocntl(0, 0, PC_ADMIN
, (caddr_t
)&pcadmin
) == -1)
244 fatalerr("%s: Can't get ts_dptbl size, priocntl system \
245 call failed with errno %d\n", basenm
, errno
);
247 ntsdpents
= tsadmin
.ts_ndpents
;
249 (tsdpent_t
*)malloc(ntsdpents
* sizeof (tsdpent_t
))) == NULL
)
250 fatalerr("%s: Can't allocate memory for ts_dptbl\n", basenm
);
252 if ((fp
= fopen(infile
, "r")) == NULL
)
253 fatalerr("%s: Can't open %s for input\n", basenm
, infile
);
258 * Find the first non-blank, non-comment line. A comment line
259 * is any line with '#' as the first non-white-space character.
262 if (fgets(buf
, sizeof (buf
), fp
) == NULL
)
263 fatalerr("%s: Too few lines in input table\n", basenm
);
265 } while (buf
[0] == '#' || buf
[0] == '\0' ||
266 (wslength
= strspn(buf
, " \t\n")) == strlen(buf
) ||
267 strchr(buf
, '#') == buf
+ wslength
);
269 if ((tokp
= strtok(buf
, " \t")) == NULL
)
270 fatalerr("%s: Bad RES specification, line %d of input file\n",
272 if ((int)strlen(tokp
) > 4) {
273 if (strncmp(tokp
, "RES=", 4) != 0)
274 fatalerr("%s: Bad RES specification, \
275 line %d of input file\n", basenm
, linenum
);
277 fatalerr("%s: Bad RES specification, \
278 line %d of input file\n", basenm
, linenum
);
279 res
= strtoul(&tokp
[4], (char **)NULL
, 10);
280 } else if (strlen(tokp
) == 4) {
281 if (strcmp(tokp
, "RES=") != 0)
282 fatalerr("%s: Bad RES specification, \
283 line %d of input file\n", basenm
, linenum
);
284 if ((tokp
= strtok(NULL
, " \t")) == NULL
)
285 fatalerr("%s: Bad RES specification, \
286 line %d of input file\n", basenm
, linenum
);
288 fatalerr("%s: Bad RES specification, \
289 line %d of input file\n", basenm
, linenum
);
290 res
= strtoul(tokp
, (char **)NULL
, 10);
291 } else if (strlen(tokp
) == 3) {
292 if (strcmp(tokp
, "RES") != 0)
293 fatalerr("%s: Bad RES specification, \
294 line %d of input file\n", basenm
, linenum
);
295 if ((tokp
= strtok(NULL
, " \t")) == NULL
)
296 fatalerr("%s: Bad RES specification, \
297 line %d of input file\n", basenm
, linenum
);
298 if ((int)strlen(tokp
) > 1) {
299 if (strncmp(tokp
, "=", 1) != 0)
300 fatalerr("%s: Bad RES specification, \
301 line %d of input file\n", basenm
, linenum
);
303 fatalerr("%s: Bad RES specification, \
304 line %d of input file\n", basenm
, linenum
);
305 res
= strtoul(&tokp
[1], (char **)NULL
, 10);
306 } else if (strlen(tokp
) == 1) {
307 if ((tokp
= strtok(NULL
, " \t")) == NULL
)
308 fatalerr("%s: Bad RES specification, \
309 line %d of input file\n", basenm
, linenum
);
311 fatalerr("%s: Bad RES specification, \
312 line %d of input file\n", basenm
, linenum
);
313 res
= strtoul(tokp
, (char **)NULL
, 10);
316 fatalerr("%s: Bad RES specification, line %d of input file\n",
321 * The remainder of the input file should contain exactly enough
322 * non-blank, non-comment lines to fill the table (ts_ndpents lines).
323 * We assume that any non-blank, non-comment line is data for the
324 * table and fail if we find more or less than we need.
326 for (i
= 0; i
< tsadmin
.ts_ndpents
; i
++) {
329 * Get the next non-blank, non-comment line.
332 if (fgets(buf
, sizeof (buf
), fp
) == NULL
)
333 fatalerr("%s: Too few lines in input table\n",
336 } while (buf
[0] == '#' || buf
[0] == '\0' ||
337 (wslength
= strspn(buf
, " \t\n")) == strlen(buf
) ||
338 strchr(buf
, '#') == buf
+ wslength
);
340 if ((tokp
= strtok(buf
, " \t")) == NULL
)
341 fatalerr("%s: Too few values, line %d of input file\n",
346 hrtime
.hrt_rem
= atol(tokp
);
347 hrtime
.hrt_res
= res
;
348 if (_hrtnewres(&hrtime
, HZ
, HRT_RNDUP
) == -1)
349 fatalerr("%s: Can't convert specified "
350 "resolution to ticks\n", basenm
);
351 if ((ts_dptbl
[i
].ts_quantum
= hrtconvert(&hrtime
))
353 fatalerr("%s: ts_quantum value out of "
354 "valid range; line %d of input,\n"
355 "table not overwritten\n",
358 ts_dptbl
[i
].ts_quantum
= atol(tokp
);
360 if (ts_dptbl
[i
].ts_quantum
<= 0)
361 fatalerr("%s: ts_quantum value out of valid range; "
362 "line %d of input,\ntable not overwritten\n",
365 if ((tokp
= strtok(NULL
, " \t")) == NULL
|| tokp
[0] == '#')
366 fatalerr("%s: Too few values, line %d of input file\n",
368 ts_dptbl
[i
].ts_tqexp
= (short)atoi(tokp
);
369 if (ts_dptbl
[i
].ts_tqexp
< 0 ||
370 ts_dptbl
[i
].ts_tqexp
> tsadmin
.ts_ndpents
)
371 fatalerr("%s: ts_tqexp value out of valid range; "
372 "line %d of input,\ntable not overwritten\n",
375 if ((tokp
= strtok(NULL
, " \t")) == NULL
|| tokp
[0] == '#')
376 fatalerr("%s: Too few values, line %d of input file\n",
378 ts_dptbl
[i
].ts_slpret
= (short)atoi(tokp
);
379 if (ts_dptbl
[i
].ts_slpret
< 0 ||
380 ts_dptbl
[i
].ts_slpret
> tsadmin
.ts_ndpents
)
381 fatalerr("%s: ts_slpret value out of valid range; "
382 "line %d of input,\ntable not overwritten\n",
385 if ((tokp
= strtok(NULL
, " \t")) == NULL
|| tokp
[0] == '#')
386 fatalerr("%s: Too few values, line %d of input file\n",
388 ts_dptbl
[i
].ts_maxwait
= (short)atoi(tokp
);
389 if (ts_dptbl
[i
].ts_maxwait
< 0)
390 fatalerr("%s: ts_maxwait value out of valid range; "
391 "line %d of input,\ntable not overwritten\n",
394 if ((tokp
= strtok(NULL
, " \t")) == NULL
|| tokp
[0] == '#')
395 fatalerr("%s: Too few values, line %d of input file\n",
397 ts_dptbl
[i
].ts_lwait
= (short)atoi(tokp
);
398 if (ts_dptbl
[i
].ts_lwait
< 0 ||
399 ts_dptbl
[i
].ts_lwait
> tsadmin
.ts_ndpents
)
400 fatalerr("%s: ts_lwait value out of valid range; "
401 "line %d of input,\ntable not overwritten\n",
404 if ((tokp
= strtok(NULL
, " \t")) != NULL
&& tokp
[0] != '#')
405 fatalerr("%s: Too many values, line %d of input file\n",
410 * We've read enough lines to fill the table. We fail
411 * if the input file contains any more.
413 while (fgets(buf
, sizeof (buf
), fp
) != NULL
) {
414 if (buf
[0] != '#' && buf
[0] != '\0' &&
415 (wslength
= strspn(buf
, " \t\n")) != strlen(buf
) &&
416 strchr(buf
, '#') != buf
+ wslength
)
417 fatalerr("%s: Too many lines in input table\n",
421 tsadmin
.ts_dpents
= ts_dptbl
;
422 tsadmin
.ts_cmd
= TS_SETDPTBL
;
423 if (priocntl(0, 0, PC_ADMIN
, (caddr_t
)&pcadmin
) == -1)
424 fatalerr("%s: Can't set ts_dptbl, priocntl system call \
425 failed with errno %d\n", basenm
, errno
);