xref: /illumos-gate/usr/src/cmd/coreadm/coreadm.c (revision dfac3eb2)
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