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*dfac3eb2SDavid Powell * Common Development and Distribution License (the "License"). 6*dfac3eb2SDavid Powell * 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 /* 22*dfac3eb2SDavid Powell * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <stdio.h> 277c478bd9Sstevel@tonic-gate #include <fcntl.h> 287c478bd9Sstevel@tonic-gate #include <ctype.h> 297c478bd9Sstevel@tonic-gate #include <string.h> 307c478bd9Sstevel@tonic-gate #include <stdlib.h> 317c478bd9Sstevel@tonic-gate #include <unistd.h> 327c478bd9Sstevel@tonic-gate #include <errno.h> 337c478bd9Sstevel@tonic-gate #include <limits.h> 347c478bd9Sstevel@tonic-gate #include <libintl.h> 357c478bd9Sstevel@tonic-gate #include <locale.h> 367c478bd9Sstevel@tonic-gate #include <sys/stat.h> 377c478bd9Sstevel@tonic-gate #include <sys/corectl.h> 387c478bd9Sstevel@tonic-gate #include <libproc.h> 39*dfac3eb2SDavid Powell #include <libscf.h> 40*dfac3eb2SDavid Powell #include <libscf_priv.h> 41*dfac3eb2SDavid Powell #include <assert.h> 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate #define E_SUCCESS 0 /* Exit status for success */ 447c478bd9Sstevel@tonic-gate #define E_ERROR 1 /* Exit status for error */ 457c478bd9Sstevel@tonic-gate #define E_USAGE 2 /* Exit status for usage error */ 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate static const char PATH_CONFIG[] = "/etc/coreadm.conf"; 48*dfac3eb2SDavid Powell static const char PATH_CONFIG_OLD[] = "/etc/coreadm.conf.old"; 49*dfac3eb2SDavid Powell 50*dfac3eb2SDavid Powell #define COREADM_INST_NAME "system/coreadm:default" 51*dfac3eb2SDavid Powell #define COREADM_INST_FMRI \ 52*dfac3eb2SDavid Powell SCF_FMRI_SVC_PREFIX SCF_FMRI_SERVICE_PREFIX COREADM_INST_NAME 53*dfac3eb2SDavid Powell 54*dfac3eb2SDavid Powell #define CONFIG_PARAMS "config_params" 55*dfac3eb2SDavid Powell #define GLOBAL_ENABLED "global_enabled" 56*dfac3eb2SDavid Powell #define PROCESS_ENABLED "process_enabled" 57*dfac3eb2SDavid Powell #define GLOBAL_SETID_ENABLED "global_setid_enabled" 58*dfac3eb2SDavid Powell #define PROCESS_SETID_ENABLED "process_setid_enabled" 59*dfac3eb2SDavid Powell #define GLOBAL_LOG_ENABLED "global_log_enabled" 60*dfac3eb2SDavid Powell #define GLOBAL_PATTERN "global_pattern" 61*dfac3eb2SDavid Powell #define GLOBAL_CONTENT "global_content" 62*dfac3eb2SDavid Powell #define INIT_PATTERN "init_pattern" 63*dfac3eb2SDavid Powell #define INIT_CONTENT "init_content" 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate static char *command; 66*dfac3eb2SDavid Powell static uint64_t options; 67*dfac3eb2SDavid Powell static int alloptions; 687c478bd9Sstevel@tonic-gate static char *glob_pattern; 69*dfac3eb2SDavid Powell static char gpattern[PATH_MAX]; 707c478bd9Sstevel@tonic-gate static core_content_t glob_content = CC_CONTENT_INVALID; 717c478bd9Sstevel@tonic-gate static char *init_pattern; 72*dfac3eb2SDavid Powell static char ipattern[PATH_MAX]; 737c478bd9Sstevel@tonic-gate static core_content_t init_content = CC_CONTENT_INVALID; 747c478bd9Sstevel@tonic-gate static char *proc_pattern; 757c478bd9Sstevel@tonic-gate static size_t proc_size; 767c478bd9Sstevel@tonic-gate static core_content_t proc_content = CC_CONTENT_INVALID; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate static int report_settings(void); 797c478bd9Sstevel@tonic-gate static int do_processes(int, char **); 80*dfac3eb2SDavid Powell static int do_modify(boolean_t); 817c478bd9Sstevel@tonic-gate static int do_update(void); 82*dfac3eb2SDavid Powell static int do_legacy(void); 83*dfac3eb2SDavid Powell 84*dfac3eb2SDavid Powell static scf_propvec_t prop_gpattern = { GLOBAL_PATTERN, NULL, SCF_TYPE_ASTRING }; 85*dfac3eb2SDavid Powell static scf_propvec_t prop_gcontent = { GLOBAL_CONTENT, NULL, SCF_TYPE_ASTRING }; 86*dfac3eb2SDavid Powell static scf_propvec_t prop_ipattern = { INIT_PATTERN, NULL, SCF_TYPE_ASTRING }; 87*dfac3eb2SDavid Powell static scf_propvec_t prop_icontent = { INIT_CONTENT, NULL, SCF_TYPE_ASTRING }; 88*dfac3eb2SDavid Powell static scf_propvec_t prop_option[] = { 89*dfac3eb2SDavid Powell { GLOBAL_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_PATH }, 90*dfac3eb2SDavid Powell { PROCESS_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_PROCESS_PATH }, 91*dfac3eb2SDavid Powell { GLOBAL_SETID_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_SETID }, 92*dfac3eb2SDavid Powell { PROCESS_SETID_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_PROCESS_SETID }, 93*dfac3eb2SDavid Powell { GLOBAL_LOG_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_LOG }, 94*dfac3eb2SDavid Powell { NULL } 95*dfac3eb2SDavid Powell }; 96*dfac3eb2SDavid Powell #define MAX_PROPS (4 + (sizeof (prop_option) / sizeof (scf_propvec_t))) 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate static void 997c478bd9Sstevel@tonic-gate usage(void) 1007c478bd9Sstevel@tonic-gate { 1017c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1027c478bd9Sstevel@tonic-gate "usage:\n")); 1037c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1047c478bd9Sstevel@tonic-gate " %s [ -g pattern ] [ -i pattern ] [ -G content ] [ -I content ]\n"), 105*dfac3eb2SDavid Powell command); 1067c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1077c478bd9Sstevel@tonic-gate " [ -e {global | process | global-setid | proc-setid | log} ]\n")); 1087c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1097c478bd9Sstevel@tonic-gate " [ -d {global | process | global-setid | proc-setid | log} ]\n")); 1107c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1117c478bd9Sstevel@tonic-gate " %s [ -p pattern ] [ -P content ] [ pid ... ]\n"), command); 1127c478bd9Sstevel@tonic-gate exit(E_USAGE); 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate static int 1167c478bd9Sstevel@tonic-gate perm(void) 1177c478bd9Sstevel@tonic-gate { 1187c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: insufficient privileges to " 119*dfac3eb2SDavid Powell "exercise the -[GIgied] options\n"), command); 1207c478bd9Sstevel@tonic-gate return (E_USAGE); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 123*dfac3eb2SDavid Powell static int 124*dfac3eb2SDavid Powell parse_content(char *arg, core_content_t *content) 125*dfac3eb2SDavid Powell { 126*dfac3eb2SDavid Powell if (proc_str2content(arg, content) == 0) 127*dfac3eb2SDavid Powell return (0); 128*dfac3eb2SDavid Powell (void) fprintf(stderr, gettext("%s: invalid content string '%s'\n"), 129*dfac3eb2SDavid Powell command, arg); 130*dfac3eb2SDavid Powell return (1); 131*dfac3eb2SDavid Powell } 132*dfac3eb2SDavid Powell 1337c478bd9Sstevel@tonic-gate int 1347c478bd9Sstevel@tonic-gate main(int argc, char **argv) 1357c478bd9Sstevel@tonic-gate { 1367c478bd9Sstevel@tonic-gate int flag; 1377c478bd9Sstevel@tonic-gate int opt; 1387c478bd9Sstevel@tonic-gate int modify; 1397c478bd9Sstevel@tonic-gate int update = 0; 140*dfac3eb2SDavid Powell int legacy_update = 0; 1417c478bd9Sstevel@tonic-gate int error = 0; 1427c478bd9Sstevel@tonic-gate int npids; 1437c478bd9Sstevel@tonic-gate char **pidlist; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate char curpid[11]; 1467c478bd9Sstevel@tonic-gate char *curpid_ptr = &curpid[0]; 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1497c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate /* command name (e.g., "coreadm") */ 1527c478bd9Sstevel@tonic-gate if ((command = strrchr(argv[0], '/')) != NULL) 1537c478bd9Sstevel@tonic-gate command++; 1547c478bd9Sstevel@tonic-gate else 1557c478bd9Sstevel@tonic-gate command = argv[0]; 1567c478bd9Sstevel@tonic-gate 157*dfac3eb2SDavid Powell while ((opt = getopt(argc, argv, "g:G:i:I:p:P:e:d:uU?")) != EOF) { 1587c478bd9Sstevel@tonic-gate switch (opt) { 1597c478bd9Sstevel@tonic-gate case 'g': 1607c478bd9Sstevel@tonic-gate glob_pattern = optarg; 1617c478bd9Sstevel@tonic-gate break; 1627c478bd9Sstevel@tonic-gate case 'i': 1637c478bd9Sstevel@tonic-gate init_pattern = optarg; 1647c478bd9Sstevel@tonic-gate break; 1657c478bd9Sstevel@tonic-gate case 'p': 1667c478bd9Sstevel@tonic-gate proc_pattern = optarg; 1677c478bd9Sstevel@tonic-gate proc_size = strlen(proc_pattern) + 1; 1687c478bd9Sstevel@tonic-gate break; 1697c478bd9Sstevel@tonic-gate case 'G': 170*dfac3eb2SDavid Powell error |= parse_content(optarg, &glob_content); 1717c478bd9Sstevel@tonic-gate break; 1727c478bd9Sstevel@tonic-gate case 'I': 173*dfac3eb2SDavid Powell error |= parse_content(optarg, &init_content); 1747c478bd9Sstevel@tonic-gate break; 1757c478bd9Sstevel@tonic-gate case 'P': 176*dfac3eb2SDavid Powell error |= parse_content(optarg, &proc_content); 1777c478bd9Sstevel@tonic-gate break; 1787c478bd9Sstevel@tonic-gate case 'e': 1797c478bd9Sstevel@tonic-gate case 'd': 1807c478bd9Sstevel@tonic-gate if (strcmp(optarg, "global") == 0) 1817c478bd9Sstevel@tonic-gate flag = CC_GLOBAL_PATH; 1827c478bd9Sstevel@tonic-gate else if (strcmp(optarg, "process") == 0) 1837c478bd9Sstevel@tonic-gate flag = CC_PROCESS_PATH; 1847c478bd9Sstevel@tonic-gate else if (strcmp(optarg, "global-setid") == 0) 1857c478bd9Sstevel@tonic-gate flag = CC_GLOBAL_SETID; 1867c478bd9Sstevel@tonic-gate else if (strcmp(optarg, "proc-setid") == 0) 1877c478bd9Sstevel@tonic-gate flag = CC_PROCESS_SETID; 1887c478bd9Sstevel@tonic-gate else if (strcmp(optarg, "log") == 0) 1897c478bd9Sstevel@tonic-gate flag = CC_GLOBAL_LOG; 1907c478bd9Sstevel@tonic-gate else { 1917c478bd9Sstevel@tonic-gate flag = 0; 1927c478bd9Sstevel@tonic-gate error = 1; 1937c478bd9Sstevel@tonic-gate } 194*dfac3eb2SDavid Powell if (opt == 'e') 195*dfac3eb2SDavid Powell options |= flag; 196*dfac3eb2SDavid Powell else 197*dfac3eb2SDavid Powell options &= ~flag; 198*dfac3eb2SDavid Powell alloptions |= flag; 1997c478bd9Sstevel@tonic-gate break; 200*dfac3eb2SDavid Powell case 'U': 2017c478bd9Sstevel@tonic-gate update = 1; 2027c478bd9Sstevel@tonic-gate break; 203*dfac3eb2SDavid Powell case 'u': 204*dfac3eb2SDavid Powell legacy_update = 1; 205*dfac3eb2SDavid Powell break; 2067c478bd9Sstevel@tonic-gate case '?': 2077c478bd9Sstevel@tonic-gate default: 2087c478bd9Sstevel@tonic-gate error = 1; 2097c478bd9Sstevel@tonic-gate break; 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate npids = argc - optind; 2147c478bd9Sstevel@tonic-gate pidlist = argv + optind; 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate if (error) 2177c478bd9Sstevel@tonic-gate usage(); 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate /* 2207c478bd9Sstevel@tonic-gate * If 'modify' is true, we must modify the system settings 2217c478bd9Sstevel@tonic-gate * and update the configuration file with the new parameters. 2227c478bd9Sstevel@tonic-gate */ 2237c478bd9Sstevel@tonic-gate modify = glob_pattern != NULL || glob_content != CC_CONTENT_INVALID || 224*dfac3eb2SDavid Powell init_pattern != NULL || init_content != CC_CONTENT_INVALID || 225*dfac3eb2SDavid Powell alloptions != 0; 2267c478bd9Sstevel@tonic-gate 227*dfac3eb2SDavid Powell if ((update || legacy_update) && (modify || proc_pattern != NULL || 2287c478bd9Sstevel@tonic-gate proc_content != CC_CONTENT_INVALID || npids != 0)) { 2297c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 230*dfac3eb2SDavid Powell gettext("%s: the -u option must stand alone\n"), command); 2317c478bd9Sstevel@tonic-gate usage(); 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate if (modify && 2347c478bd9Sstevel@tonic-gate (proc_pattern != NULL || proc_content != CC_CONTENT_INVALID)) { 235*dfac3eb2SDavid Powell (void) fprintf(stderr, gettext( 2367c478bd9Sstevel@tonic-gate "%s: -[GIgied] and -[Pp] options are mutually exclusive\n"), 2377c478bd9Sstevel@tonic-gate command); 2387c478bd9Sstevel@tonic-gate usage(); 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate if (modify && npids != 0) { 241*dfac3eb2SDavid Powell (void) fprintf(stderr, gettext( 2427c478bd9Sstevel@tonic-gate "%s: -[GIgied] options cannot have a process-id list\n"), 2437c478bd9Sstevel@tonic-gate command); 2447c478bd9Sstevel@tonic-gate usage(); 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate if ((proc_pattern != NULL || proc_content != CC_CONTENT_INVALID) && 2477c478bd9Sstevel@tonic-gate npids == 0) { 2487c478bd9Sstevel@tonic-gate (void) sprintf(curpid, "%u", (uint_t)getppid()); 2497c478bd9Sstevel@tonic-gate npids = 1; 2507c478bd9Sstevel@tonic-gate pidlist = &curpid_ptr; 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate 253*dfac3eb2SDavid Powell if (legacy_update) 254*dfac3eb2SDavid Powell return (do_legacy()); 2557c478bd9Sstevel@tonic-gate if (update) 2567c478bd9Sstevel@tonic-gate return (do_update()); 2577c478bd9Sstevel@tonic-gate if (modify) 258*dfac3eb2SDavid Powell return (do_modify(B_FALSE)); 2597c478bd9Sstevel@tonic-gate if (npids != 0) 2607c478bd9Sstevel@tonic-gate return (do_processes(npids, pidlist)); 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate return (report_settings()); 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate static int 2667c478bd9Sstevel@tonic-gate report_settings(void) 2677c478bd9Sstevel@tonic-gate { 268*dfac3eb2SDavid Powell char content_str[PRCONTENTBUFSZ]; 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate if ((options = core_get_options()) == -1) { 2717c478bd9Sstevel@tonic-gate perror("core_get_options()"); 2727c478bd9Sstevel@tonic-gate return (E_ERROR); 2737c478bd9Sstevel@tonic-gate } 274*dfac3eb2SDavid Powell if (core_get_global_path(gpattern, sizeof (gpattern)) != 0) { 2757c478bd9Sstevel@tonic-gate perror("core_get_global_path()"); 2767c478bd9Sstevel@tonic-gate return (E_ERROR); 2777c478bd9Sstevel@tonic-gate } 278*dfac3eb2SDavid Powell if (core_get_default_path(ipattern, sizeof (ipattern)) != 0) { 2797c478bd9Sstevel@tonic-gate perror("core_get_default_path()"); 2807c478bd9Sstevel@tonic-gate return (E_ERROR); 2817c478bd9Sstevel@tonic-gate } 282*dfac3eb2SDavid Powell if (core_get_global_content(&glob_content) != 0) { 2837c478bd9Sstevel@tonic-gate perror("core_get_global_content()"); 2847c478bd9Sstevel@tonic-gate return (E_ERROR); 2857c478bd9Sstevel@tonic-gate } 286*dfac3eb2SDavid Powell if (core_get_default_content(&init_content) != 0) { 2877c478bd9Sstevel@tonic-gate perror("core_get_default_content()"); 2887c478bd9Sstevel@tonic-gate return (E_ERROR); 2897c478bd9Sstevel@tonic-gate } 290*dfac3eb2SDavid Powell 2917c478bd9Sstevel@tonic-gate (void) printf(gettext(" global core file pattern: %s\n"), 292*dfac3eb2SDavid Powell gpattern); 293*dfac3eb2SDavid Powell (void) proc_content2str(glob_content, content_str, 294*dfac3eb2SDavid Powell sizeof (content_str)); 2957c478bd9Sstevel@tonic-gate (void) printf(gettext(" global core file content: %s\n"), 2967c478bd9Sstevel@tonic-gate content_str); 2977c478bd9Sstevel@tonic-gate (void) printf(gettext(" init core file pattern: %s\n"), 298*dfac3eb2SDavid Powell ipattern); 299*dfac3eb2SDavid Powell (void) proc_content2str(init_content, content_str, 300*dfac3eb2SDavid Powell sizeof (content_str)); 3017c478bd9Sstevel@tonic-gate (void) printf(gettext(" init core file content: %s\n"), 3027c478bd9Sstevel@tonic-gate content_str); 3037c478bd9Sstevel@tonic-gate (void) printf(gettext(" global core dumps: %s\n"), 3047c478bd9Sstevel@tonic-gate (options & CC_GLOBAL_PATH)? "enabled" : "disabled"); 3057c478bd9Sstevel@tonic-gate (void) printf(gettext(" per-process core dumps: %s\n"), 3067c478bd9Sstevel@tonic-gate (options & CC_PROCESS_PATH)? "enabled" : "disabled"); 3077c478bd9Sstevel@tonic-gate (void) printf(gettext(" global setid core dumps: %s\n"), 3087c478bd9Sstevel@tonic-gate (options & CC_GLOBAL_SETID)? "enabled" : "disabled"); 3097c478bd9Sstevel@tonic-gate (void) printf(gettext(" per-process setid core dumps: %s\n"), 3107c478bd9Sstevel@tonic-gate (options & CC_PROCESS_SETID)? "enabled" : "disabled"); 3117c478bd9Sstevel@tonic-gate (void) printf(gettext(" global core dump logging: %s\n"), 3127c478bd9Sstevel@tonic-gate (options & CC_GLOBAL_LOG)? "enabled" : "disabled"); 3137c478bd9Sstevel@tonic-gate return (E_SUCCESS); 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate static int 3177c478bd9Sstevel@tonic-gate do_processes(int npids, char **pidlist) 3187c478bd9Sstevel@tonic-gate { 3197c478bd9Sstevel@tonic-gate char process_path[PATH_MAX]; 3207c478bd9Sstevel@tonic-gate core_content_t content; 3217c478bd9Sstevel@tonic-gate pid_t pid; 3227c478bd9Sstevel@tonic-gate char *next; 3237c478bd9Sstevel@tonic-gate int rc = E_SUCCESS; 324*dfac3eb2SDavid Powell char content_str[PRCONTENTBUFSZ]; 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate if (proc_pattern == NULL && proc_content == CC_CONTENT_INVALID) { 3277c478bd9Sstevel@tonic-gate while (npids-- > 0) { 3287c478bd9Sstevel@tonic-gate pid = strtol(*pidlist, &next, 10); 3297c478bd9Sstevel@tonic-gate if (*next != '\0' || !isdigit(**pidlist)) { 3307c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3317c478bd9Sstevel@tonic-gate gettext("%s: invalid process-id\n"), 3327c478bd9Sstevel@tonic-gate *pidlist); 3337c478bd9Sstevel@tonic-gate rc = E_USAGE; 3347c478bd9Sstevel@tonic-gate } else if (core_get_process_path(process_path, 3357c478bd9Sstevel@tonic-gate sizeof (process_path), pid) != 0 || 3367c478bd9Sstevel@tonic-gate core_get_process_content(&content, pid) != 0) { 3377c478bd9Sstevel@tonic-gate perror(*pidlist); 3387c478bd9Sstevel@tonic-gate rc = E_USAGE; 3397c478bd9Sstevel@tonic-gate } else { 3407c478bd9Sstevel@tonic-gate (void) proc_content2str(content, content_str, 3417c478bd9Sstevel@tonic-gate sizeof (content_str)); 3427c478bd9Sstevel@tonic-gate (void) printf(gettext("%s:\t%s\t%s\n"), 3437c478bd9Sstevel@tonic-gate *pidlist, process_path, content_str); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate pidlist++; 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate } else { 3487c478bd9Sstevel@tonic-gate while (npids-- > 0) { 3497c478bd9Sstevel@tonic-gate pid = strtol(*pidlist, &next, 10); 3507c478bd9Sstevel@tonic-gate if (*next != '\0') { 3517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3527c478bd9Sstevel@tonic-gate gettext("%s: invalid process-id\n"), 3537c478bd9Sstevel@tonic-gate *pidlist); 3547c478bd9Sstevel@tonic-gate rc = E_USAGE; 3557c478bd9Sstevel@tonic-gate } else { 3567c478bd9Sstevel@tonic-gate if (proc_pattern != NULL && 3577c478bd9Sstevel@tonic-gate core_set_process_path(proc_pattern, 3587c478bd9Sstevel@tonic-gate proc_size, pid) != 0) { 3597c478bd9Sstevel@tonic-gate perror(*pidlist); 3607c478bd9Sstevel@tonic-gate rc = E_USAGE; 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate if (proc_content != CC_CONTENT_INVALID && 3647c478bd9Sstevel@tonic-gate core_set_process_content( 3657c478bd9Sstevel@tonic-gate &proc_content, pid) != 0) { 3667c478bd9Sstevel@tonic-gate perror(*pidlist); 3677c478bd9Sstevel@tonic-gate rc = E_USAGE; 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate pidlist++; 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate return (rc); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 377*dfac3eb2SDavid Powell static void 378*dfac3eb2SDavid Powell addprop(scf_propvec_t *props, int size, int count, scf_propvec_t *pv, void *ptr) 379*dfac3eb2SDavid Powell { 380*dfac3eb2SDavid Powell assert(count + 1 < size); 381*dfac3eb2SDavid Powell props[count] = *pv; 382*dfac3eb2SDavid Powell props[count].pv_ptr = ptr; 383*dfac3eb2SDavid Powell } 384*dfac3eb2SDavid Powell 385*dfac3eb2SDavid Powell static boolean_t 386*dfac3eb2SDavid Powell is_online(const char *fmri) 387*dfac3eb2SDavid Powell { 388*dfac3eb2SDavid Powell char *state = smf_get_state(fmri); 389*dfac3eb2SDavid Powell boolean_t result = state != NULL && 390*dfac3eb2SDavid Powell strcmp(state, SCF_STATE_STRING_ONLINE) == 0; 391*dfac3eb2SDavid Powell 392*dfac3eb2SDavid Powell free(state); 393*dfac3eb2SDavid Powell return (result); 394*dfac3eb2SDavid Powell } 395*dfac3eb2SDavid Powell 396*dfac3eb2SDavid Powell /* 397*dfac3eb2SDavid Powell * The user has specified the -g, -G, -i, -I, -d, or -e options to 398*dfac3eb2SDavid Powell * modify the given configuration parameter. Perform the modification 399*dfac3eb2SDavid Powell * in the smf repository and then perform a smf_refresh_instance which 400*dfac3eb2SDavid Powell * will cause a coreadm -u to occur which will transfer ALL coreadm 401*dfac3eb2SDavid Powell * configuration information from the repository to the kernel. 402*dfac3eb2SDavid Powell */ 4037c478bd9Sstevel@tonic-gate static int 404*dfac3eb2SDavid Powell do_modify(boolean_t method) 4057c478bd9Sstevel@tonic-gate { 406*dfac3eb2SDavid Powell char gcontentstr[PRCONTENTBUFSZ]; 407*dfac3eb2SDavid Powell char icontentstr[PRCONTENTBUFSZ]; 408*dfac3eb2SDavid Powell scf_propvec_t *prop; 409*dfac3eb2SDavid Powell scf_propvec_t properties[MAX_PROPS + 1]; 410*dfac3eb2SDavid Powell int count = 0; 4117c478bd9Sstevel@tonic-gate 412*dfac3eb2SDavid Powell if (!method && !is_online(COREADM_INST_FMRI)) { 413*dfac3eb2SDavid Powell (void) fprintf(stderr, 414*dfac3eb2SDavid Powell gettext("%s: coreadm service not online\n"), command); 4157c478bd9Sstevel@tonic-gate return (E_ERROR); 4167c478bd9Sstevel@tonic-gate } 417*dfac3eb2SDavid Powell 418*dfac3eb2SDavid Powell if (glob_pattern != NULL) 419*dfac3eb2SDavid Powell addprop(properties, MAX_PROPS, count++, &prop_gpattern, 420*dfac3eb2SDavid Powell glob_pattern); 421*dfac3eb2SDavid Powell 422*dfac3eb2SDavid Powell if (glob_content != CC_CONTENT_INVALID) { 423*dfac3eb2SDavid Powell (void) proc_content2str(glob_content, gcontentstr, 424*dfac3eb2SDavid Powell sizeof (gcontentstr)); 425*dfac3eb2SDavid Powell addprop(properties, MAX_PROPS, count++, &prop_gcontent, 426*dfac3eb2SDavid Powell gcontentstr); 4277c478bd9Sstevel@tonic-gate } 428*dfac3eb2SDavid Powell 429*dfac3eb2SDavid Powell if (init_pattern != NULL) 430*dfac3eb2SDavid Powell addprop(properties, MAX_PROPS, count++, &prop_ipattern, 431*dfac3eb2SDavid Powell init_pattern); 432*dfac3eb2SDavid Powell 433*dfac3eb2SDavid Powell if (init_content != CC_CONTENT_INVALID) { 434*dfac3eb2SDavid Powell (void) proc_content2str(init_content, icontentstr, 435*dfac3eb2SDavid Powell sizeof (icontentstr)); 436*dfac3eb2SDavid Powell addprop(properties, MAX_PROPS, count++, &prop_icontent, 437*dfac3eb2SDavid Powell icontentstr); 4387c478bd9Sstevel@tonic-gate } 439*dfac3eb2SDavid Powell 440*dfac3eb2SDavid Powell for (prop = prop_option; prop->pv_prop != NULL; prop++) 441*dfac3eb2SDavid Powell if ((alloptions & prop->pv_aux) != 0) 442*dfac3eb2SDavid Powell addprop(properties, MAX_PROPS, count++, prop, &options); 443*dfac3eb2SDavid Powell 444*dfac3eb2SDavid Powell properties[count].pv_prop = NULL; 445*dfac3eb2SDavid Powell 446*dfac3eb2SDavid Powell prop = NULL; 447*dfac3eb2SDavid Powell if (scf_write_propvec(COREADM_INST_FMRI, CONFIG_PARAMS, properties, 448*dfac3eb2SDavid Powell &prop) == SCF_FAILED) { 449*dfac3eb2SDavid Powell if (prop != NULL) { 450*dfac3eb2SDavid Powell (void) fprintf(stderr, gettext( 451*dfac3eb2SDavid Powell "%s: Unable to write property '%s': %s"), command, 452*dfac3eb2SDavid Powell prop->pv_prop, scf_strerror(scf_error())); 453*dfac3eb2SDavid Powell } else { 454*dfac3eb2SDavid Powell (void) fprintf(stderr, gettext( 455*dfac3eb2SDavid Powell "%s: Unable to write configuration: %s\n"), 456*dfac3eb2SDavid Powell command, scf_strerror(scf_error())); 457*dfac3eb2SDavid Powell } 4587c478bd9Sstevel@tonic-gate return (E_ERROR); 4597c478bd9Sstevel@tonic-gate } 460*dfac3eb2SDavid Powell 461*dfac3eb2SDavid Powell if (smf_refresh_instance(COREADM_INST_FMRI) != 0) { 462*dfac3eb2SDavid Powell (void) fprintf(stderr, 463*dfac3eb2SDavid Powell gettext("%s: Unable to refresh %s: %s\n" 464*dfac3eb2SDavid Powell "Configuration stored but not made active.\n"), 465*dfac3eb2SDavid Powell command, COREADM_INST_FMRI, scf_strerror(scf_error())); 4667c478bd9Sstevel@tonic-gate return (E_ERROR); 4677c478bd9Sstevel@tonic-gate } 468*dfac3eb2SDavid Powell 469*dfac3eb2SDavid Powell return (E_SUCCESS); 470*dfac3eb2SDavid Powell } 471*dfac3eb2SDavid Powell 472*dfac3eb2SDavid Powell static const char * 473*dfac3eb2SDavid Powell write_kernel(void) 474*dfac3eb2SDavid Powell { 475*dfac3eb2SDavid Powell if (core_set_global_path(glob_pattern, strlen(glob_pattern) + 1) != 0) 476*dfac3eb2SDavid Powell return ("core_set_global_path()"); 477*dfac3eb2SDavid Powell 478*dfac3eb2SDavid Powell if (core_set_global_content(&glob_content) != 0) 479*dfac3eb2SDavid Powell return ("core_set_global_content()"); 480*dfac3eb2SDavid Powell 481*dfac3eb2SDavid Powell if (core_set_default_path(init_pattern, strlen(init_pattern) + 1) != 0) 482*dfac3eb2SDavid Powell return ("core_set_default_path()"); 483*dfac3eb2SDavid Powell 484*dfac3eb2SDavid Powell if (core_set_default_content(&init_content) != 0) 485*dfac3eb2SDavid Powell return ("core_set_init_content()"); 486*dfac3eb2SDavid Powell 487*dfac3eb2SDavid Powell if (core_set_options((int)options) != 0) 488*dfac3eb2SDavid Powell return ("core_set_options()"); 489*dfac3eb2SDavid Powell 490*dfac3eb2SDavid Powell return (NULL); 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate /* 4947c478bd9Sstevel@tonic-gate * BUFSIZE must be large enough to contain the longest path plus some more. 4957c478bd9Sstevel@tonic-gate */ 4967c478bd9Sstevel@tonic-gate #define BUFSIZE (PATH_MAX + 80) 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate static int 4997c478bd9Sstevel@tonic-gate yes(char *name, char *value, int line) 5007c478bd9Sstevel@tonic-gate { 5017c478bd9Sstevel@tonic-gate if (strcmp(value, "yes") == 0) 5027c478bd9Sstevel@tonic-gate return (1); 5037c478bd9Sstevel@tonic-gate if (strcmp(value, "no") == 0) 5047c478bd9Sstevel@tonic-gate return (0); 505*dfac3eb2SDavid Powell (void) fprintf(stderr, gettext( 506*dfac3eb2SDavid Powell "\"%s\", line %d: warning: value must be yes or no: %s=%s\n"), 507*dfac3eb2SDavid Powell PATH_CONFIG, line, name, value); 5087c478bd9Sstevel@tonic-gate return (0); 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate static int 512*dfac3eb2SDavid Powell read_legacy(void) 5137c478bd9Sstevel@tonic-gate { 5147c478bd9Sstevel@tonic-gate FILE *fp; 5157c478bd9Sstevel@tonic-gate int line; 5167c478bd9Sstevel@tonic-gate char buf[BUFSIZE]; 5177c478bd9Sstevel@tonic-gate char name[BUFSIZE], value[BUFSIZE]; 518*dfac3eb2SDavid Powell int n, len; 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate /* defaults */ 521*dfac3eb2SDavid Powell alloptions = CC_OPTIONS; 5227c478bd9Sstevel@tonic-gate options = CC_PROCESS_PATH; 5237c478bd9Sstevel@tonic-gate gpattern[0] = '\0'; 5247c478bd9Sstevel@tonic-gate (void) strcpy(ipattern, "core"); 525*dfac3eb2SDavid Powell glob_content = init_content = CC_CONTENT_DEFAULT; 5267c478bd9Sstevel@tonic-gate 527*dfac3eb2SDavid Powell glob_pattern = gpattern; 528*dfac3eb2SDavid Powell init_pattern = ipattern; 529*dfac3eb2SDavid Powell 530*dfac3eb2SDavid Powell if ((fp = fopen(PATH_CONFIG, "r")) == NULL) 531*dfac3eb2SDavid Powell return (0); 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate for (line = 1; fgets(buf, sizeof (buf), fp) != NULL; line++) { 5347c478bd9Sstevel@tonic-gate /* 5357c478bd9Sstevel@tonic-gate * Skip comment lines and empty lines. 5367c478bd9Sstevel@tonic-gate */ 5377c478bd9Sstevel@tonic-gate if (buf[0] == '#' || buf[0] == '\n') 5387c478bd9Sstevel@tonic-gate continue; 5397c478bd9Sstevel@tonic-gate /* 5407c478bd9Sstevel@tonic-gate * Look for "name=value", with optional whitespace on either 5417c478bd9Sstevel@tonic-gate * side, terminated by a newline, and consuming the whole line. 5427c478bd9Sstevel@tonic-gate */ 5437c478bd9Sstevel@tonic-gate /* LINTED - unbounded string specifier */ 5447c478bd9Sstevel@tonic-gate n = sscanf(buf, " %[^=]=%s \n%n", name, value, &len); 5457c478bd9Sstevel@tonic-gate if (n >= 1 && name[0] != '\0' && 5467c478bd9Sstevel@tonic-gate (n == 1 || len == strlen(buf))) { 5477c478bd9Sstevel@tonic-gate if (n == 1) 5487c478bd9Sstevel@tonic-gate value[0] = '\0'; 5497c478bd9Sstevel@tonic-gate if (strcmp(name, "COREADM_GLOB_PATTERN") == 0) { 5507c478bd9Sstevel@tonic-gate (void) strcpy(gpattern, value); 5517c478bd9Sstevel@tonic-gate continue; 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate if (strcmp(name, "COREADM_GLOB_CONTENT") == 0) { 554*dfac3eb2SDavid Powell (void) proc_str2content(value, &glob_content); 5557c478bd9Sstevel@tonic-gate continue; 5567c478bd9Sstevel@tonic-gate } 5577c478bd9Sstevel@tonic-gate if (strcmp(name, "COREADM_INIT_PATTERN") == 0) { 5587c478bd9Sstevel@tonic-gate (void) strcpy(ipattern, value); 5597c478bd9Sstevel@tonic-gate continue; 5607c478bd9Sstevel@tonic-gate } 5617c478bd9Sstevel@tonic-gate if (strcmp(name, "COREADM_INIT_CONTENT") == 0) { 562*dfac3eb2SDavid Powell (void) proc_str2content(value, &init_content); 5637c478bd9Sstevel@tonic-gate continue; 5647c478bd9Sstevel@tonic-gate } 5657c478bd9Sstevel@tonic-gate if (strcmp(name, "COREADM_GLOB_ENABLED") == 0) { 5667c478bd9Sstevel@tonic-gate if (yes(name, value, line)) 5677c478bd9Sstevel@tonic-gate options |= CC_GLOBAL_PATH; 5687c478bd9Sstevel@tonic-gate continue; 5697c478bd9Sstevel@tonic-gate } 5707c478bd9Sstevel@tonic-gate if (strcmp(name, "COREADM_PROC_ENABLED") == 0) { 5717c478bd9Sstevel@tonic-gate if (yes(name, value, line)) 5727c478bd9Sstevel@tonic-gate options |= CC_PROCESS_PATH; 5737c478bd9Sstevel@tonic-gate else 5747c478bd9Sstevel@tonic-gate options &= ~CC_PROCESS_PATH; 5757c478bd9Sstevel@tonic-gate continue; 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate if (strcmp(name, "COREADM_GLOB_SETID_ENABLED") == 0) { 5787c478bd9Sstevel@tonic-gate if (yes(name, value, line)) 5797c478bd9Sstevel@tonic-gate options |= CC_GLOBAL_SETID; 5807c478bd9Sstevel@tonic-gate continue; 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate if (strcmp(name, "COREADM_PROC_SETID_ENABLED") == 0) { 5837c478bd9Sstevel@tonic-gate if (yes(name, value, line)) 5847c478bd9Sstevel@tonic-gate options |= CC_PROCESS_SETID; 5857c478bd9Sstevel@tonic-gate continue; 5867c478bd9Sstevel@tonic-gate } 5877c478bd9Sstevel@tonic-gate if (strcmp(name, "COREADM_GLOB_LOG_ENABLED") == 0) { 5887c478bd9Sstevel@tonic-gate if (yes(name, value, line)) 5897c478bd9Sstevel@tonic-gate options |= CC_GLOBAL_LOG; 5907c478bd9Sstevel@tonic-gate continue; 5917c478bd9Sstevel@tonic-gate } 592*dfac3eb2SDavid Powell (void) fprintf(stderr, gettext( 593*dfac3eb2SDavid Powell "\"%s\", line %d: warning: invalid token: %s\n"), 594*dfac3eb2SDavid Powell PATH_CONFIG, line, name); 5957c478bd9Sstevel@tonic-gate } else { 5967c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 597*dfac3eb2SDavid Powell gettext("\"%s\", line %d: syntax error\n"), 598*dfac3eb2SDavid Powell PATH_CONFIG, line); 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate (void) fclose(fp); 602*dfac3eb2SDavid Powell 603*dfac3eb2SDavid Powell return (1); 6047c478bd9Sstevel@tonic-gate } 6057c478bd9Sstevel@tonic-gate 606*dfac3eb2SDavid Powell /* 607*dfac3eb2SDavid Powell * Loads and applies the coreadm configuration stored in the default 608*dfac3eb2SDavid Powell * coreadm instance. As this option is (only) used from within an SMF 609*dfac3eb2SDavid Powell * service method, this function must return an SMF_EXIT_* exit status 610*dfac3eb2SDavid Powell * to its caller. 611*dfac3eb2SDavid Powell */ 6127c478bd9Sstevel@tonic-gate static int 613*dfac3eb2SDavid Powell do_update(void) 6147c478bd9Sstevel@tonic-gate { 615*dfac3eb2SDavid Powell char *gcstr, *icstr; 616*dfac3eb2SDavid Powell scf_propvec_t properties[MAX_PROPS + 1]; 617*dfac3eb2SDavid Powell scf_propvec_t *prop; 618*dfac3eb2SDavid Powell int count = 0; 619*dfac3eb2SDavid Powell const char *errstr; 620*dfac3eb2SDavid Powell 621*dfac3eb2SDavid Powell if (read_legacy()) { 622*dfac3eb2SDavid Powell if ((errstr = write_kernel()) != NULL) 623*dfac3eb2SDavid Powell goto error; 624*dfac3eb2SDavid Powell 625*dfac3eb2SDavid Powell if (do_modify(B_TRUE) != 0 || 626*dfac3eb2SDavid Powell rename(PATH_CONFIG, PATH_CONFIG_OLD) != 0) { 627*dfac3eb2SDavid Powell (void) fprintf(stderr, gettext( 628*dfac3eb2SDavid Powell "%s: failed to import legacy configuration.\n"), 629*dfac3eb2SDavid Powell command); 630*dfac3eb2SDavid Powell return (SMF_EXIT_ERR_FATAL); 6317c478bd9Sstevel@tonic-gate } 632*dfac3eb2SDavid Powell return (SMF_EXIT_OK); 6337c478bd9Sstevel@tonic-gate } 634*dfac3eb2SDavid Powell 635*dfac3eb2SDavid Powell addprop(properties, MAX_PROPS, count++, &prop_gpattern, &glob_pattern); 636*dfac3eb2SDavid Powell addprop(properties, MAX_PROPS, count++, &prop_gcontent, &gcstr); 637*dfac3eb2SDavid Powell addprop(properties, MAX_PROPS, count++, &prop_ipattern, &init_pattern); 638*dfac3eb2SDavid Powell addprop(properties, MAX_PROPS, count++, &prop_icontent, &icstr); 639*dfac3eb2SDavid Powell for (prop = prop_option; prop->pv_prop != NULL; prop++) 640*dfac3eb2SDavid Powell addprop(properties, MAX_PROPS, count++, prop, &options); 641*dfac3eb2SDavid Powell properties[count].pv_prop = NULL; 642*dfac3eb2SDavid Powell 643*dfac3eb2SDavid Powell alloptions = CC_OPTIONS; 644*dfac3eb2SDavid Powell if (scf_read_propvec(COREADM_INST_FMRI, CONFIG_PARAMS, B_TRUE, 645*dfac3eb2SDavid Powell properties, &prop) == SCF_FAILED) { 646*dfac3eb2SDavid Powell if (prop != NULL) { 647*dfac3eb2SDavid Powell (void) fprintf(stderr, gettext( 648*dfac3eb2SDavid Powell "%s: configuration property '%s' not found.\n"), 649*dfac3eb2SDavid Powell command, prop->pv_prop); 650*dfac3eb2SDavid Powell } else { 651*dfac3eb2SDavid Powell (void) fprintf(stderr, gettext( 652*dfac3eb2SDavid Powell "%s: unable to read configuration: %s\n"), 653*dfac3eb2SDavid Powell command, scf_strerror(scf_error())); 654*dfac3eb2SDavid Powell } 655*dfac3eb2SDavid Powell return (SMF_EXIT_ERR_FATAL); 6567c478bd9Sstevel@tonic-gate } 657*dfac3eb2SDavid Powell 658*dfac3eb2SDavid Powell (void) proc_str2content(gcstr, &glob_content); 659*dfac3eb2SDavid Powell (void) proc_str2content(icstr, &init_content); 660*dfac3eb2SDavid Powell 661*dfac3eb2SDavid Powell errstr = write_kernel(); 662*dfac3eb2SDavid Powell scf_clean_propvec(properties); 663*dfac3eb2SDavid Powell if (errstr == NULL) 664*dfac3eb2SDavid Powell return (SMF_EXIT_OK); 665*dfac3eb2SDavid Powell 666*dfac3eb2SDavid Powell error: 667*dfac3eb2SDavid Powell if (errno == EPERM) { 668*dfac3eb2SDavid Powell (void) perm(); 669*dfac3eb2SDavid Powell return (SMF_EXIT_ERR_PERM); 6707c478bd9Sstevel@tonic-gate } 671*dfac3eb2SDavid Powell perror(errstr); 672*dfac3eb2SDavid Powell return (SMF_EXIT_ERR_FATAL); 673*dfac3eb2SDavid Powell } 6747c478bd9Sstevel@tonic-gate 675*dfac3eb2SDavid Powell static int do_legacy() 676*dfac3eb2SDavid Powell { 677*dfac3eb2SDavid Powell const char *errstr; 678*dfac3eb2SDavid Powell 679*dfac3eb2SDavid Powell if (read_legacy() && (errstr = write_kernel()) != NULL) { 680*dfac3eb2SDavid Powell if (errno == EPERM) 681*dfac3eb2SDavid Powell return (perm()); 682*dfac3eb2SDavid Powell perror(errstr); 683*dfac3eb2SDavid Powell return (E_ERROR); 684*dfac3eb2SDavid Powell } 6857c478bd9Sstevel@tonic-gate 686*dfac3eb2SDavid Powell return (E_SUCCESS); 6877c478bd9Sstevel@tonic-gate } 688