17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*ae0476dbSJayakara Kini * Common Development and Distribution License (the "License"). 6*ae0476dbSJayakara Kini * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate 227c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 237c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate /* 26*ae0476dbSJayakara Kini * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 277c478bd9Sstevel@tonic-gate * Use is subject to license terms. 287c478bd9Sstevel@tonic-gate */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #include <stdio.h> 317c478bd9Sstevel@tonic-gate #include <stdlib.h> 327c478bd9Sstevel@tonic-gate #include <string.h> 337c478bd9Sstevel@tonic-gate #include <unistd.h> 347c478bd9Sstevel@tonic-gate #include <fcntl.h> 357c478bd9Sstevel@tonic-gate #include <errno.h> 367c478bd9Sstevel@tonic-gate #include <string.h> 377c478bd9Sstevel@tonic-gate #include <limits.h> 387c478bd9Sstevel@tonic-gate #include <wait.h> 397c478bd9Sstevel@tonic-gate #include <zone.h> 407c478bd9Sstevel@tonic-gate #include <sys/types.h> 417c478bd9Sstevel@tonic-gate #include <sys/stat.h> 427c478bd9Sstevel@tonic-gate #include <sys/priocntl.h> 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #include "dispadmin.h" 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* 477c478bd9Sstevel@tonic-gate * This file contains the code implementing the class independent part 487c478bd9Sstevel@tonic-gate * of the dispadmin command. Most of the functionality of the dispadmin 497c478bd9Sstevel@tonic-gate * command is provided by the class specific sub-commands, the code for 507c478bd9Sstevel@tonic-gate * which is elsewhere. The class independent part of the command is 517c478bd9Sstevel@tonic-gate * responsible for switching out to the appropriate class specific 527c478bd9Sstevel@tonic-gate * sub-command based on the user supplied class argument. 537c478bd9Sstevel@tonic-gate * Code in this file should never assume any knowledge of any specific 547c478bd9Sstevel@tonic-gate * scheduler class (other than the SYS class). 557c478bd9Sstevel@tonic-gate */ 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate #define BASENMSZ 16 587c478bd9Sstevel@tonic-gate #define BUFSZ (PATH_MAX + 80) 597c478bd9Sstevel@tonic-gate #define CLASSPATH "/usr/lib/class" 607c478bd9Sstevel@tonic-gate #define CONFIGPATH "/etc/dispadmin.conf" 617c478bd9Sstevel@tonic-gate #define CONFIGOWNER 0 /* uid 0 (root) */ 627c478bd9Sstevel@tonic-gate #define CONFIGGROUP 1 /* gid 1 (other) */ 637c478bd9Sstevel@tonic-gate #define CONFIGPERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) /* 0644 */ 647c478bd9Sstevel@tonic-gate #define TOKENNAME "DEFAULT_SCHEDULER" 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate extern char *basename(); 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate static char usage[] = 697c478bd9Sstevel@tonic-gate "usage: dispadmin -l\n\ 707c478bd9Sstevel@tonic-gate dispadmin -c class [class-specific options]\n\ 71*ae0476dbSJayakara Kini dispadmin -d [class]\n"; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate static char basenm[BASENMSZ]; 747c478bd9Sstevel@tonic-gate static char cmdpath[PATH_MAX]; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate static void print_classlist(); 777c478bd9Sstevel@tonic-gate static void exec_cscmd(char *, char **); 787c478bd9Sstevel@tonic-gate static void set_scheduler(char *); 797c478bd9Sstevel@tonic-gate static void class_info(pcinfo_t *); 807c478bd9Sstevel@tonic-gate static void set_default_class(); 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate int 837c478bd9Sstevel@tonic-gate main(int argc, char **argv) 847c478bd9Sstevel@tonic-gate { 857c478bd9Sstevel@tonic-gate extern char *optarg; 867c478bd9Sstevel@tonic-gate extern int optind, opterr; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate int c; 897c478bd9Sstevel@tonic-gate int uflag, cflag, dflag, lflag, csoptsflag; 907c478bd9Sstevel@tonic-gate char *clname; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate (void) strncpy(cmdpath, argv[0], PATH_MAX); 937c478bd9Sstevel@tonic-gate (void) strncpy(basenm, basename(argv[0]), BASENMSZ); 947c478bd9Sstevel@tonic-gate cflag = dflag = lflag = uflag = csoptsflag = 0; 957c478bd9Sstevel@tonic-gate opterr = 0; 967c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "c:dlu")) != -1) { 977c478bd9Sstevel@tonic-gate switch (c) { 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate case 'c': 1007c478bd9Sstevel@tonic-gate cflag++; 1017c478bd9Sstevel@tonic-gate clname = optarg; 1027c478bd9Sstevel@tonic-gate break; 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate case 'd': 1057c478bd9Sstevel@tonic-gate dflag++; 1067c478bd9Sstevel@tonic-gate clname = argv[optind]; 1077c478bd9Sstevel@tonic-gate break; 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate case 'l': 1107c478bd9Sstevel@tonic-gate lflag++; 1117c478bd9Sstevel@tonic-gate break; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate case 'u': 1147c478bd9Sstevel@tonic-gate uflag++; 1157c478bd9Sstevel@tonic-gate break; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate case '?': 1197c478bd9Sstevel@tonic-gate /* 1207c478bd9Sstevel@tonic-gate * We assume for now that any option that 1217c478bd9Sstevel@tonic-gate * getopt() doesn't recognize is intended for a 1227c478bd9Sstevel@tonic-gate * class specific subcommand. 1237c478bd9Sstevel@tonic-gate */ 1247c478bd9Sstevel@tonic-gate csoptsflag++; 1257c478bd9Sstevel@tonic-gate if (argv[optind] && argv[optind][0] != '-') { 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate /* 1297c478bd9Sstevel@tonic-gate * Class specific option takes an 1307c478bd9Sstevel@tonic-gate * argument which we skip over for now. 1317c478bd9Sstevel@tonic-gate */ 1327c478bd9Sstevel@tonic-gate optind++; 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate break; 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate default: 1377c478bd9Sstevel@tonic-gate break; 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate if (lflag) { 1427c478bd9Sstevel@tonic-gate if (uflag || cflag || dflag || csoptsflag) 1437c478bd9Sstevel@tonic-gate fatalerr(usage); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate print_classlist(); 1467c478bd9Sstevel@tonic-gate exit(0); 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate } else if (uflag) { 1497c478bd9Sstevel@tonic-gate if (lflag || dflag || csoptsflag) 1507c478bd9Sstevel@tonic-gate fatalerr(usage); 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate set_default_class(); 1537c478bd9Sstevel@tonic-gate } else if (cflag) { 1547c478bd9Sstevel@tonic-gate if (lflag || dflag) 1557c478bd9Sstevel@tonic-gate fatalerr(usage); 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate exec_cscmd(clname, argv); 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate } else if (dflag) { 1607c478bd9Sstevel@tonic-gate if (cflag || lflag || csoptsflag) 1617c478bd9Sstevel@tonic-gate fatalerr(usage); 1627c478bd9Sstevel@tonic-gate set_scheduler(clname); 1637c478bd9Sstevel@tonic-gate exit(0); 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate } else { 1667c478bd9Sstevel@tonic-gate fatalerr(usage); 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate return (1); 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate /* 1737c478bd9Sstevel@tonic-gate * Print the heading for the class list and execute the 1747c478bd9Sstevel@tonic-gate * class specific sub-command with the -l option for each 1757c478bd9Sstevel@tonic-gate * configured class. 1767c478bd9Sstevel@tonic-gate */ 1777c478bd9Sstevel@tonic-gate static void 1787c478bd9Sstevel@tonic-gate print_classlist() 1797c478bd9Sstevel@tonic-gate { 1807c478bd9Sstevel@tonic-gate id_t cid; 1817c478bd9Sstevel@tonic-gate int nclass; 1827c478bd9Sstevel@tonic-gate pcinfo_t pcinfo; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if ((nclass = priocntl(0, 0, PC_GETCLINFO, NULL)) == -1) 1857c478bd9Sstevel@tonic-gate fatalerr("%s: Can't get number of configured classes\n", 1867c478bd9Sstevel@tonic-gate cmdpath); 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate (void) printf("CONFIGURED CLASSES\n==================\n\n"); 1897c478bd9Sstevel@tonic-gate (void) printf("SYS\t(System Class)\n"); 1907c478bd9Sstevel@tonic-gate (void) fflush(stdout); 1917c478bd9Sstevel@tonic-gate for (cid = 1; cid < nclass; cid++) { 1927c478bd9Sstevel@tonic-gate pcinfo.pc_cid = cid; 1937c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_GETCLINFO, (caddr_t)&pcinfo) == -1) 1947c478bd9Sstevel@tonic-gate fatalerr("%s: Can't get class name (class ID = %d)\n", 1957c478bd9Sstevel@tonic-gate cmdpath, cid); 1967c478bd9Sstevel@tonic-gate class_info(&pcinfo); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate /* 2027c478bd9Sstevel@tonic-gate * Execute the appropriate class specific sub-command for the class 2037c478bd9Sstevel@tonic-gate * specified by clname, passing it the arguments in subcmdargv. 2047c478bd9Sstevel@tonic-gate */ 2057c478bd9Sstevel@tonic-gate static void 2067c478bd9Sstevel@tonic-gate exec_cscmd(char *clname, char **subcmdargv) 2077c478bd9Sstevel@tonic-gate { 2087c478bd9Sstevel@tonic-gate pcinfo_t pcinfo; 2097c478bd9Sstevel@tonic-gate char subcmdpath[PATH_MAX]; 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate /* 2127c478bd9Sstevel@tonic-gate * Do a quick check to make sure clname is valid. 2137c478bd9Sstevel@tonic-gate * We could just wait and see if the exec below 2147c478bd9Sstevel@tonic-gate * succeeds but we wouldn't know much about the reason. 2157c478bd9Sstevel@tonic-gate * This way we can give the user a more meaningful error 2167c478bd9Sstevel@tonic-gate * message. 2177c478bd9Sstevel@tonic-gate */ 2187c478bd9Sstevel@tonic-gate (void) strncpy(pcinfo.pc_clname, clname, PC_CLNMSZ); 2197c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 2207c478bd9Sstevel@tonic-gate fatalerr("%s: Invalid or unconfigured class %s\n", cmdpath, 2217c478bd9Sstevel@tonic-gate clname); 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate (void) snprintf(subcmdpath, PATH_MAX, "%s/%s/%s%s", CLASSPATH, 2247c478bd9Sstevel@tonic-gate clname, clname, basenm); 2257c478bd9Sstevel@tonic-gate subcmdargv[0] = subcmdpath; 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate (void) execv(subcmdpath, subcmdargv); 2287c478bd9Sstevel@tonic-gate fatalerr("%s: Can't execute %s sub-command\n", cmdpath, clname); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate static void 2327c478bd9Sstevel@tonic-gate class_info(pcinfo_t *pcinfo) 2337c478bd9Sstevel@tonic-gate { 2347c478bd9Sstevel@tonic-gate int pid; 2357c478bd9Sstevel@tonic-gate char subcmdpath[PATH_MAX]; 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate (void) snprintf(subcmdpath, PATH_MAX, "%s/%s/%s%s", CLASSPATH, 2387c478bd9Sstevel@tonic-gate pcinfo->pc_clname, pcinfo->pc_clname, basenm); 2397c478bd9Sstevel@tonic-gate if ((pid = fork()) == 0) { 2407c478bd9Sstevel@tonic-gate (void) execl(subcmdpath, subcmdpath, "-l", (char *)0); 2417c478bd9Sstevel@tonic-gate fatalerr("%s\n\tCan't execute %s specific subcommand\n", 2427c478bd9Sstevel@tonic-gate pcinfo->pc_clname, pcinfo->pc_clname); 2437c478bd9Sstevel@tonic-gate } else if (pid == (pid_t)-1) { 2447c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2457c478bd9Sstevel@tonic-gate "%s\nCan't execute %s specific subcommand)\n", 2467c478bd9Sstevel@tonic-gate pcinfo->pc_clname, pcinfo->pc_clname); 2477c478bd9Sstevel@tonic-gate } else { 2487c478bd9Sstevel@tonic-gate (void) wait(NULL); 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate /* 2537c478bd9Sstevel@tonic-gate * Return the current default scheduling class as specified in 2547c478bd9Sstevel@tonic-gate * /etc/dispadmin.conf. 2557c478bd9Sstevel@tonic-gate */ 2567c478bd9Sstevel@tonic-gate static char * 2577c478bd9Sstevel@tonic-gate read_default_file(FILE *fp) 2587c478bd9Sstevel@tonic-gate { 2597c478bd9Sstevel@tonic-gate char buf[BUFSZ]; 2607c478bd9Sstevel@tonic-gate int line; 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate for (line = 1; fgets(buf, BUFSZ, fp) != NULL; line++) { 2637c478bd9Sstevel@tonic-gate char name[BUFSZ], value[BUFSZ]; 2647c478bd9Sstevel@tonic-gate int len; 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate if (buf[0] == '#' || buf[0] == '\n') 2677c478bd9Sstevel@tonic-gate continue; 2687c478bd9Sstevel@tonic-gate /* LINTED - unbounded string specifier */ 2697c478bd9Sstevel@tonic-gate if (sscanf(buf, " %[^=]=%s \n%n", name, value, &len) == 2 && 2707c478bd9Sstevel@tonic-gate name[0] != '\0' && value[0] != '\0' && len == strlen(buf)) { 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate if (strcmp(name, TOKENNAME) != 0) 2737c478bd9Sstevel@tonic-gate fatalerr("\"%s\", line %d: invalid " 2747c478bd9Sstevel@tonic-gate "token: %s\n", CONFIGPATH, line, name); 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate (void) fclose(fp); 2777c478bd9Sstevel@tonic-gate return (strdup(value)); 2787c478bd9Sstevel@tonic-gate } else { 2797c478bd9Sstevel@tonic-gate fatalerr("\"%s\", line %d: syntax error\n", CONFIGPATH, 2807c478bd9Sstevel@tonic-gate line); 2817c478bd9Sstevel@tonic-gate (void) fclose(fp); 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate if (line == 1) 2857c478bd9Sstevel@tonic-gate fatalerr("%s: %s is empty\n", cmdpath, CONFIGPATH); 2867c478bd9Sstevel@tonic-gate return (NULL); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate /* 2907c478bd9Sstevel@tonic-gate * Set the default scheduling class for the system. 2917c478bd9Sstevel@tonic-gate * Update /etc/dispadmin.conf if necessary. 2927c478bd9Sstevel@tonic-gate */ 2937c478bd9Sstevel@tonic-gate static void 2947c478bd9Sstevel@tonic-gate set_scheduler(char *clname) 2957c478bd9Sstevel@tonic-gate { 2967c478bd9Sstevel@tonic-gate pcinfo_t pcinfo; 2977c478bd9Sstevel@tonic-gate FILE *fp; 2987c478bd9Sstevel@tonic-gate int fd; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate if (getzoneid() != GLOBAL_ZONEID) 3017c478bd9Sstevel@tonic-gate fatalerr("%s: Operation not supported in non-global zones\n", 3027c478bd9Sstevel@tonic-gate cmdpath); 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate if (clname == NULL) { 3057c478bd9Sstevel@tonic-gate if ((fd = open(CONFIGPATH, O_RDONLY, CONFIGPERM)) == -1) { 3067c478bd9Sstevel@tonic-gate if (errno == ENOENT) 3077c478bd9Sstevel@tonic-gate fatalerr("%s: Default scheduling class " 3087c478bd9Sstevel@tonic-gate "is not set\n", cmdpath); 3097c478bd9Sstevel@tonic-gate else 3107c478bd9Sstevel@tonic-gate fatalerr("%s: Failed to open %s (%s)\n", 3117c478bd9Sstevel@tonic-gate cmdpath, CONFIGPATH, strerror(errno)); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate if ((fp = fdopen(fd, "r")) == NULL) 3157c478bd9Sstevel@tonic-gate fatalerr("%s: Failed to open stream for %s (%s)\n", 3167c478bd9Sstevel@tonic-gate cmdpath, CONFIGPATH, strerror(errno)); 3177c478bd9Sstevel@tonic-gate clname = read_default_file(fp); 3187c478bd9Sstevel@tonic-gate (void) strncpy(pcinfo.pc_clname, clname, PC_CLNMSZ); 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 3217c478bd9Sstevel@tonic-gate fatalerr("\"%s\", scheduling class %s is not " 3227c478bd9Sstevel@tonic-gate "available\n", CONFIGPATH, clname); 3237c478bd9Sstevel@tonic-gate else 3247c478bd9Sstevel@tonic-gate class_info(&pcinfo); 3257c478bd9Sstevel@tonic-gate return; 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate /* 3297c478bd9Sstevel@tonic-gate * Do a quick check to make sure clname is valid class name. 3307c478bd9Sstevel@tonic-gate */ 3317c478bd9Sstevel@tonic-gate (void) strncpy(pcinfo.pc_clname, clname, PC_CLNMSZ); 3327c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 3337c478bd9Sstevel@tonic-gate fatalerr("%s: Invalid or unconfigured class %s\n", cmdpath, 3347c478bd9Sstevel@tonic-gate clname); 3357c478bd9Sstevel@tonic-gate if ((fd = open(CONFIGPATH, O_RDWR | O_CREAT, CONFIGPERM)) == -1) 3367c478bd9Sstevel@tonic-gate fatalerr("%s: Failed to open %s (%s)\n", cmdpath, CONFIGPATH, 3377c478bd9Sstevel@tonic-gate strerror(errno)); 3387c478bd9Sstevel@tonic-gate if ((fp = fdopen(fd, "w")) == NULL) 3397c478bd9Sstevel@tonic-gate fatalerr("%s: Failed to open stream for %s\n", CONFIGPATH); 3407c478bd9Sstevel@tonic-gate if (ftruncate(fd, (off_t)0) == -1) 3417c478bd9Sstevel@tonic-gate fatalerr("%s: Failed to truncate %s\n", cmdpath, CONFIGPATH); 3427c478bd9Sstevel@tonic-gate (void) fputs("#\n# /etc/dispadmin.conf\n#\n" 3437c478bd9Sstevel@tonic-gate "# Do NOT edit this file by hand -- use dispadmin(1m) instead.\n" 3447c478bd9Sstevel@tonic-gate "#\n", fp); 3457c478bd9Sstevel@tonic-gate if ((fprintf(fp, "%s=%s\n", TOKENNAME, clname)) == -1) 3467c478bd9Sstevel@tonic-gate fatalerr("%s: Failed to write to %s\n", cmdpath, CONFIGPATH); 3477c478bd9Sstevel@tonic-gate if (fflush(fp) != 0) 3487c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3497c478bd9Sstevel@tonic-gate "%s: warning: failed to flush config file\n", 3507c478bd9Sstevel@tonic-gate cmdpath); 3517c478bd9Sstevel@tonic-gate if (fsync(fd) == -1) 3527c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3537c478bd9Sstevel@tonic-gate "%s: warning: failed to sync config file to disk\n", 3547c478bd9Sstevel@tonic-gate cmdpath); 3557c478bd9Sstevel@tonic-gate if (fchmod(fd, CONFIGPERM) == -1) 3567c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3577c478bd9Sstevel@tonic-gate "%s: warning: failed to reset config file mode\n", 3587c478bd9Sstevel@tonic-gate cmdpath); 3597c478bd9Sstevel@tonic-gate if (fchown(fd, CONFIGOWNER, CONFIGGROUP) == -1) 3607c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3617c478bd9Sstevel@tonic-gate "%s: warning: failed to reset config file owner\n", 3627c478bd9Sstevel@tonic-gate cmdpath); 3637c478bd9Sstevel@tonic-gate (void) fclose(fp); 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_SETDFLCL, clname) == -1) 3667c478bd9Sstevel@tonic-gate fatalerr("%s: failed to set default class %s in kernel: %s\n", 3677c478bd9Sstevel@tonic-gate cmdpath, clname, strerror(errno)); 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate static void 3717c478bd9Sstevel@tonic-gate set_default_class() 3727c478bd9Sstevel@tonic-gate { 3737c478bd9Sstevel@tonic-gate char *clname; 3747c478bd9Sstevel@tonic-gate FILE *fp; 3757c478bd9Sstevel@tonic-gate int fd; 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate if ((fd = open(CONFIGPATH, O_RDONLY, CONFIGPERM)) == -1) { 3787c478bd9Sstevel@tonic-gate /* silently succeed, there is nothing to do */ 3797c478bd9Sstevel@tonic-gate if (errno == ENOENT) 3807c478bd9Sstevel@tonic-gate return; 3817c478bd9Sstevel@tonic-gate else 3827c478bd9Sstevel@tonic-gate fatalerr("%s: Failed to open %s (%s)\n", 3837c478bd9Sstevel@tonic-gate cmdpath, CONFIGPATH, strerror(errno)); 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate if ((fp = fdopen(fd, "r")) == NULL) 3877c478bd9Sstevel@tonic-gate fatalerr("%s: Failed to open stream for %s (%s)\n", 3887c478bd9Sstevel@tonic-gate cmdpath, CONFIGPATH, strerror(errno)); 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate if ((clname = read_default_file(fp)) != NULL) { 3917c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_SETDFLCL, clname) == -1) 3927c478bd9Sstevel@tonic-gate fatalerr("%s: failed to set default class %s in " 3937c478bd9Sstevel@tonic-gate "kernel: %s\n", cmdpath, clname, strerror(errno)); 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate } 396