summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorDavid Powell <David.Powell@sun.com>2008-09-29 03:46:02 -0700
committerDavid Powell <David.Powell@sun.com>2008-09-29 03:46:02 -0700
commitdfac3eb25a53097b94643fa6f32bb2fc1107df0c (patch)
tree71472f2c5f58bd34ffd7a7f581d6258e3478af4a /usr/src
parent23b4d00c19075d9d50f296d4437a3f48579b483d (diff)
downloadillumos-gate-dfac3eb25a53097b94643fa6f32bb2fc1107df0c.tar.gz
6751138 libc's lint library is missing definition for __assert_c99
6751161 PSARC 2008/551 coreadm configuration refinements
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/Targetdirs1
-rw-r--r--usr/src/cmd/coreadm/Makefile7
-rw-r--r--usr/src/cmd/coreadm/coreadm.c536
-rw-r--r--usr/src/cmd/coreadm/coreadm.xml89
-rw-r--r--usr/src/lib/libc/port/llib-lc2
-rw-r--r--usr/src/lib/libscf/common/mapfile-vers5
-rw-r--r--usr/src/lib/libscf/common/midlevel.c397
-rw-r--r--usr/src/lib/libscf/inc/libscf_priv.h52
-rw-r--r--usr/src/lib/libsecdb/auth_attr.txt2
-rw-r--r--usr/src/lib/libsecdb/exec_attr.txt3
-rw-r--r--usr/src/lib/libsecdb/help/auths/Makefile2
-rw-r--r--usr/src/lib/libsecdb/help/auths/SmfCoreadmStates.html37
-rw-r--r--usr/src/lib/libsecdb/help/auths/SmfValueCoreadm.html37
-rw-r--r--usr/src/lib/libsecdb/prof_attr.txt2
-rw-r--r--usr/src/pkgdefs/SUNW0on/prototype_com2
-rw-r--r--usr/src/pkgdefs/SUNWcsr/prototype_com1
-rw-r--r--usr/src/pkgdefs/SUNWcsu/prototype_com2
17 files changed, 894 insertions, 283 deletions
diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs
index 15c4693142..700e33d334 100644
--- a/usr/src/Targetdirs
+++ b/usr/src/Targetdirs
@@ -146,6 +146,7 @@ ROOT.SYS= \
/var/adm/pool \
/var/adm/sm.bin \
/var/adm/streams \
+ /var/cores \
/var/cron \
/var/db \
/var/db/ipf \
diff --git a/usr/src/cmd/coreadm/Makefile b/usr/src/cmd/coreadm/Makefile
index 9ad8b9d5e0..390212d227 100644
--- a/usr/src/cmd/coreadm/Makefile
+++ b/usr/src/cmd/coreadm/Makefile
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
PROG= coreadm
MANIFEST= coreadm.xml
@@ -35,7 +33,8 @@ ROOTMANIFESTDIR= $(ROOTSVCSYSTEM)
.KEEP_STATE:
CFLAGS += $(CCVERBOSE)
-LDLIBS += -lproc
+LDLIBS += -lproc -lscf
+C99MODE=$(C99_ENABLE)
all: $(PROG)
diff --git a/usr/src/cmd/coreadm/coreadm.c b/usr/src/cmd/coreadm/coreadm.c
index 53b162aa47..9ce0f27651 100644
--- a/usr/src/cmd/coreadm/coreadm.c
+++ b/usr/src/cmd/coreadm/coreadm.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
@@ -39,34 +36,64 @@
#include <sys/stat.h>
#include <sys/corectl.h>
#include <libproc.h>
+#include <libscf.h>
+#include <libscf_priv.h>
+#include <assert.h>
#define E_SUCCESS 0 /* Exit status for success */
#define E_ERROR 1 /* Exit status for error */
#define E_USAGE 2 /* Exit status for usage error */
static const char PATH_CONFIG[] = "/etc/coreadm.conf";
-#define CF_OWNER 0 /* Uid 0 (root) */
-#define CF_GROUP 1 /* Gid 1 (other) */
-#define CF_PERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) /* Mode 0644 */
+static const char PATH_CONFIG_OLD[] = "/etc/coreadm.conf.old";
+
+#define COREADM_INST_NAME "system/coreadm:default"
+#define COREADM_INST_FMRI \
+ SCF_FMRI_SVC_PREFIX SCF_FMRI_SERVICE_PREFIX COREADM_INST_NAME
+
+#define CONFIG_PARAMS "config_params"
+#define GLOBAL_ENABLED "global_enabled"
+#define PROCESS_ENABLED "process_enabled"
+#define GLOBAL_SETID_ENABLED "global_setid_enabled"
+#define PROCESS_SETID_ENABLED "process_setid_enabled"
+#define GLOBAL_LOG_ENABLED "global_log_enabled"
+#define GLOBAL_PATTERN "global_pattern"
+#define GLOBAL_CONTENT "global_content"
+#define INIT_PATTERN "init_pattern"
+#define INIT_CONTENT "init_content"
static char *command;
+static uint64_t options;
+static int alloptions;
static char *glob_pattern;
-static size_t glob_size;
+static char gpattern[PATH_MAX];
static core_content_t glob_content = CC_CONTENT_INVALID;
static char *init_pattern;
-static size_t init_size;
+static char ipattern[PATH_MAX];
static core_content_t init_content = CC_CONTENT_INVALID;
static char *proc_pattern;
static size_t proc_size;
static core_content_t proc_content = CC_CONTENT_INVALID;
-static int enable;
-static int disable;
static int report_settings(void);
static int do_processes(int, char **);
-static int do_modify(void);
+static int do_modify(boolean_t);
static int do_update(void);
-static int write_config(int);
+static int do_legacy(void);
+
+static scf_propvec_t prop_gpattern = { GLOBAL_PATTERN, NULL, SCF_TYPE_ASTRING };
+static scf_propvec_t prop_gcontent = { GLOBAL_CONTENT, NULL, SCF_TYPE_ASTRING };
+static scf_propvec_t prop_ipattern = { INIT_PATTERN, NULL, SCF_TYPE_ASTRING };
+static scf_propvec_t prop_icontent = { INIT_CONTENT, NULL, SCF_TYPE_ASTRING };
+static scf_propvec_t prop_option[] = {
+ { GLOBAL_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_PATH },
+ { PROCESS_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_PROCESS_PATH },
+ { GLOBAL_SETID_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_SETID },
+ { PROCESS_SETID_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_PROCESS_SETID },
+ { GLOBAL_LOG_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_LOG },
+ { NULL }
+};
+#define MAX_PROPS (4 + (sizeof (prop_option) / sizeof (scf_propvec_t)))
static void
usage(void)
@@ -75,15 +102,13 @@ usage(void)
"usage:\n"));
(void) fprintf(stderr, gettext(
" %s [ -g pattern ] [ -i pattern ] [ -G content ] [ -I content ]\n"),
- command);
+ command);
(void) fprintf(stderr, gettext(
" [ -e {global | process | global-setid | proc-setid | log} ]\n"));
(void) fprintf(stderr, gettext(
" [ -d {global | process | global-setid | proc-setid | log} ]\n"));
(void) fprintf(stderr, gettext(
" %s [ -p pattern ] [ -P content ] [ pid ... ]\n"), command);
- (void) fprintf(stderr, gettext(
-" %s -u\n"), command);
exit(E_USAGE);
}
@@ -91,10 +116,20 @@ static int
perm(void)
{
(void) fprintf(stderr, gettext("%s: insufficient privileges to "
- "exercise the -[GIgiedu] options\n"), command);
+ "exercise the -[GIgied] options\n"), command);
return (E_USAGE);
}
+static int
+parse_content(char *arg, core_content_t *content)
+{
+ if (proc_str2content(arg, content) == 0)
+ return (0);
+ (void) fprintf(stderr, gettext("%s: invalid content string '%s'\n"),
+ command, arg);
+ return (1);
+}
+
int
main(int argc, char **argv)
{
@@ -102,6 +137,7 @@ main(int argc, char **argv)
int opt;
int modify;
int update = 0;
+ int legacy_update = 0;
int error = 0;
int npids;
char **pidlist;
@@ -118,40 +154,26 @@ main(int argc, char **argv)
else
command = argv[0];
- while ((opt = getopt(argc, argv, "g:G:i:I:p:P:e:d:u?")) != EOF) {
+ while ((opt = getopt(argc, argv, "g:G:i:I:p:P:e:d:uU?")) != EOF) {
switch (opt) {
case 'g':
glob_pattern = optarg;
- glob_size = strlen(glob_pattern) + 1;
break;
case 'i':
init_pattern = optarg;
- init_size = strlen(init_pattern) + 1;
break;
case 'p':
proc_pattern = optarg;
proc_size = strlen(proc_pattern) + 1;
break;
case 'G':
- if (proc_str2content(optarg, &glob_content) != 0) {
- (void) fprintf(stderr, gettext("invalid "
- "content string '%s'\n"), optarg);
- error = 1;
- }
+ error |= parse_content(optarg, &glob_content);
break;
case 'I':
- if (proc_str2content(optarg, &init_content) != 0) {
- (void) fprintf(stderr, gettext("invalid "
- "content string '%s'\n"), optarg);
- error = 1;
- }
+ error |= parse_content(optarg, &init_content);
break;
case 'P':
- if (proc_str2content(optarg, &proc_content) != 0) {
- (void) fprintf(stderr, gettext("invalid "
- "content string '%s'\n"), optarg);
- error = 1;
- }
+ error |= parse_content(optarg, &proc_content);
break;
case 'e':
case 'd':
@@ -169,17 +191,18 @@ main(int argc, char **argv)
flag = 0;
error = 1;
}
- if (opt == 'e') {
- enable |= flag;
- disable &= ~flag;
- } else {
- disable |= flag;
- enable &= ~flag;
- }
+ if (opt == 'e')
+ options |= flag;
+ else
+ options &= ~flag;
+ alloptions |= flag;
break;
- case 'u':
+ case 'U':
update = 1;
break;
+ case 'u':
+ legacy_update = 1;
+ break;
case '?':
default:
error = 1;
@@ -198,28 +221,24 @@ main(int argc, char **argv)
* and update the configuration file with the new parameters.
*/
modify = glob_pattern != NULL || glob_content != CC_CONTENT_INVALID ||
- init_pattern != NULL || init_content != CC_CONTENT_INVALID ||
- (enable | disable) != 0;
+ init_pattern != NULL || init_content != CC_CONTENT_INVALID ||
+ alloptions != 0;
- if (update && (modify || proc_pattern != NULL ||
+ if ((update || legacy_update) && (modify || proc_pattern != NULL ||
proc_content != CC_CONTENT_INVALID || npids != 0)) {
(void) fprintf(stderr,
- gettext(
- "%s: the -u option must stand alone\n"),
- command);
+ gettext("%s: the -u option must stand alone\n"), command);
usage();
}
if (modify &&
(proc_pattern != NULL || proc_content != CC_CONTENT_INVALID)) {
- (void) fprintf(stderr,
- gettext(
+ (void) fprintf(stderr, gettext(
"%s: -[GIgied] and -[Pp] options are mutually exclusive\n"),
command);
usage();
}
if (modify && npids != 0) {
- (void) fprintf(stderr,
- gettext(
+ (void) fprintf(stderr, gettext(
"%s: -[GIgied] options cannot have a process-id list\n"),
command);
usage();
@@ -231,10 +250,12 @@ main(int argc, char **argv)
pidlist = &curpid_ptr;
}
+ if (legacy_update)
+ return (do_legacy());
if (update)
return (do_update());
if (modify)
- return (do_modify());
+ return (do_modify(B_FALSE));
if (npids != 0)
return (do_processes(npids, pidlist));
@@ -244,40 +265,39 @@ main(int argc, char **argv)
static int
report_settings(void)
{
- int options;
- char global_path[PATH_MAX];
- char init_path[PATH_MAX];
- core_content_t gcontent, icontent;
- char content_str[80];
+ char content_str[PRCONTENTBUFSZ];
if ((options = core_get_options()) == -1) {
perror("core_get_options()");
return (E_ERROR);
}
- if (core_get_global_path(global_path, sizeof (global_path)) != 0) {
+ if (core_get_global_path(gpattern, sizeof (gpattern)) != 0) {
perror("core_get_global_path()");
return (E_ERROR);
}
- if (core_get_default_path(init_path, sizeof (init_path)) != 0) {
+ if (core_get_default_path(ipattern, sizeof (ipattern)) != 0) {
perror("core_get_default_path()");
return (E_ERROR);
}
- if (core_get_global_content(&gcontent) != 0) {
+ if (core_get_global_content(&glob_content) != 0) {
perror("core_get_global_content()");
return (E_ERROR);
}
- if (core_get_default_content(&icontent) != 0) {
+ if (core_get_default_content(&init_content) != 0) {
perror("core_get_default_content()");
return (E_ERROR);
}
+
(void) printf(gettext(" global core file pattern: %s\n"),
- global_path);
- (void) proc_content2str(gcontent, content_str, sizeof (content_str));
+ gpattern);
+ (void) proc_content2str(glob_content, content_str,
+ sizeof (content_str));
(void) printf(gettext(" global core file content: %s\n"),
content_str);
(void) printf(gettext(" init core file pattern: %s\n"),
- init_path);
- (void) proc_content2str(icontent, content_str, sizeof (content_str));
+ ipattern);
+ (void) proc_content2str(init_content, content_str,
+ sizeof (content_str));
(void) printf(gettext(" init core file content: %s\n"),
content_str);
(void) printf(gettext(" global core dumps: %s\n"),
@@ -301,7 +321,7 @@ do_processes(int npids, char **pidlist)
pid_t pid;
char *next;
int rc = E_SUCCESS;
- char content_str[80];
+ char content_str[PRCONTENTBUFSZ];
if (proc_pattern == NULL && proc_content == CC_CONTENT_INVALID) {
while (npids-- > 0) {
@@ -354,52 +374,120 @@ do_processes(int npids, char **pidlist)
return (rc);
}
+static void
+addprop(scf_propvec_t *props, int size, int count, scf_propvec_t *pv, void *ptr)
+{
+ assert(count + 1 < size);
+ props[count] = *pv;
+ props[count].pv_ptr = ptr;
+}
+
+static boolean_t
+is_online(const char *fmri)
+{
+ char *state = smf_get_state(fmri);
+ boolean_t result = state != NULL &&
+ strcmp(state, SCF_STATE_STRING_ONLINE) == 0;
+
+ free(state);
+ return (result);
+}
+
+/*
+ * The user has specified the -g, -G, -i, -I, -d, or -e options to
+ * modify the given configuration parameter. Perform the modification
+ * in the smf repository and then perform a smf_refresh_instance which
+ * will cause a coreadm -u to occur which will transfer ALL coreadm
+ * configuration information from the repository to the kernel.
+ */
static int
-do_modify(void)
+do_modify(boolean_t method)
{
- int options;
+ char gcontentstr[PRCONTENTBUFSZ];
+ char icontentstr[PRCONTENTBUFSZ];
+ scf_propvec_t *prop;
+ scf_propvec_t properties[MAX_PROPS + 1];
+ int count = 0;
- if ((options = core_get_options()) == -1) {
- perror("core_get_options()");
- return (E_ERROR);
- }
- options |= enable;
- options &= ~disable;
- if (core_set_options(options) != 0) {
- if (errno == EPERM)
- return (perm());
- perror("core_set_options()");
+ if (!method && !is_online(COREADM_INST_FMRI)) {
+ (void) fprintf(stderr,
+ gettext("%s: coreadm service not online\n"), command);
return (E_ERROR);
}
- if (glob_pattern != NULL &&
- core_set_global_path(glob_pattern, glob_size) != 0) {
- if (errno == EPERM)
- return (perm());
- perror("core_set_global_path()");
- return (E_ERROR);
+
+ if (glob_pattern != NULL)
+ addprop(properties, MAX_PROPS, count++, &prop_gpattern,
+ glob_pattern);
+
+ if (glob_content != CC_CONTENT_INVALID) {
+ (void) proc_content2str(glob_content, gcontentstr,
+ sizeof (gcontentstr));
+ addprop(properties, MAX_PROPS, count++, &prop_gcontent,
+ gcontentstr);
}
- if (glob_content != CC_CONTENT_INVALID &&
- core_set_global_content(&glob_content) != 0) {
- if (errno == EPERM)
- return (perm());
- perror("core_set_global_content()");
- return (E_ERROR);
+
+ if (init_pattern != NULL)
+ addprop(properties, MAX_PROPS, count++, &prop_ipattern,
+ init_pattern);
+
+ if (init_content != CC_CONTENT_INVALID) {
+ (void) proc_content2str(init_content, icontentstr,
+ sizeof (icontentstr));
+ addprop(properties, MAX_PROPS, count++, &prop_icontent,
+ icontentstr);
}
- if (init_pattern != NULL &&
- core_set_default_path(init_pattern, init_size) != 0) {
- if (errno == EPERM)
- return (perm());
- perror("core_set_default_path()");
+
+ for (prop = prop_option; prop->pv_prop != NULL; prop++)
+ if ((alloptions & prop->pv_aux) != 0)
+ addprop(properties, MAX_PROPS, count++, prop, &options);
+
+ properties[count].pv_prop = NULL;
+
+ prop = NULL;
+ if (scf_write_propvec(COREADM_INST_FMRI, CONFIG_PARAMS, properties,
+ &prop) == SCF_FAILED) {
+ if (prop != NULL) {
+ (void) fprintf(stderr, gettext(
+ "%s: Unable to write property '%s': %s"), command,
+ prop->pv_prop, scf_strerror(scf_error()));
+ } else {
+ (void) fprintf(stderr, gettext(
+ "%s: Unable to write configuration: %s\n"),
+ command, scf_strerror(scf_error()));
+ }
return (E_ERROR);
}
- if (init_content != CC_CONTENT_INVALID &&
- core_set_default_content(&init_content) != 0) {
- if (errno == EPERM)
- return (perm());
- perror("core_set_default_content()");
+
+ if (smf_refresh_instance(COREADM_INST_FMRI) != 0) {
+ (void) fprintf(stderr,
+ gettext("%s: Unable to refresh %s: %s\n"
+ "Configuration stored but not made active.\n"),
+ command, COREADM_INST_FMRI, scf_strerror(scf_error()));
return (E_ERROR);
}
- return (write_config(0));
+
+ return (E_SUCCESS);
+}
+
+static const char *
+write_kernel(void)
+{
+ if (core_set_global_path(glob_pattern, strlen(glob_pattern) + 1) != 0)
+ return ("core_set_global_path()");
+
+ if (core_set_global_content(&glob_content) != 0)
+ return ("core_set_global_content()");
+
+ if (core_set_default_path(init_pattern, strlen(init_pattern) + 1) != 0)
+ return ("core_set_default_path()");
+
+ if (core_set_default_content(&init_content) != 0)
+ return ("core_set_init_content()");
+
+ if (core_set_options((int)options) != 0)
+ return ("core_set_options()");
+
+ return (NULL);
}
/*
@@ -414,39 +502,33 @@ yes(char *name, char *value, int line)
return (1);
if (strcmp(value, "no") == 0)
return (0);
- (void) fprintf(stderr,
- gettext(
- "\"%s\", line %d: warning: value must be yes or no: %s=%s\n"),
- PATH_CONFIG, line, name, value);
+ (void) fprintf(stderr, gettext(
+ "\"%s\", line %d: warning: value must be yes or no: %s=%s\n"),
+ PATH_CONFIG, line, name, value);
return (0);
}
static int
-do_update(void)
+read_legacy(void)
{
FILE *fp;
int line;
- int options;
- char gpattern[PATH_MAX];
- char ipattern[PATH_MAX];
- core_content_t gcontent, icontent;
char buf[BUFSIZE];
char name[BUFSIZE], value[BUFSIZE];
- int n;
- int len;
+ int n, len;
/* defaults */
+ alloptions = CC_OPTIONS;
options = CC_PROCESS_PATH;
gpattern[0] = '\0';
(void) strcpy(ipattern, "core");
- gcontent = icontent = CC_CONTENT_DEFAULT;
+ glob_content = init_content = CC_CONTENT_DEFAULT;
- if ((fp = fopen(PATH_CONFIG, "r")) == NULL) {
- /*
- * No config file, just accept the current settings.
- */
- return (write_config(1));
- }
+ glob_pattern = gpattern;
+ init_pattern = ipattern;
+
+ if ((fp = fopen(PATH_CONFIG, "r")) == NULL)
+ return (0);
for (line = 1; fgets(buf, sizeof (buf), fp) != NULL; line++) {
/*
@@ -469,7 +551,7 @@ do_update(void)
continue;
}
if (strcmp(name, "COREADM_GLOB_CONTENT") == 0) {
- (void) proc_str2content(value, &gcontent);
+ (void) proc_str2content(value, &glob_content);
continue;
}
if (strcmp(name, "COREADM_INIT_PATTERN") == 0) {
@@ -477,7 +559,7 @@ do_update(void)
continue;
}
if (strcmp(name, "COREADM_INIT_CONTENT") == 0) {
- (void) proc_str2content(value, &icontent);
+ (void) proc_str2content(value, &init_content);
continue;
}
if (strcmp(name, "COREADM_GLOB_ENABLED") == 0) {
@@ -507,143 +589,99 @@ do_update(void)
options |= CC_GLOBAL_LOG;
continue;
}
- (void) fprintf(stderr,
- gettext(
- "\"%s\", line %d: warning: invalid token: %s\n"),
- PATH_CONFIG, line, name);
+ (void) fprintf(stderr, gettext(
+ "\"%s\", line %d: warning: invalid token: %s\n"),
+ PATH_CONFIG, line, name);
} else {
(void) fprintf(stderr,
- gettext("\"%s\", line %d: syntax error\n"),
- PATH_CONFIG, line);
+ gettext("\"%s\", line %d: syntax error\n"),
+ PATH_CONFIG, line);
}
}
(void) fclose(fp);
- if (core_set_options(options) != 0) {
- if (errno == EPERM)
- return (perm());
- perror("core_set_options()");
- return (E_ERROR);
- }
- if (core_set_global_path(gpattern, strlen(gpattern) + 1) != 0) {
- if (errno == EPERM)
- return (perm());
- perror("core_set_global_path()");
- return (E_ERROR);
- }
- if (core_set_default_path(ipattern, strlen(ipattern) + 1) != 0) {
- if (errno == EPERM)
- return (perm());
- perror("core_set_default_path()");
- return (E_ERROR);
- }
- if (core_set_global_content(&gcontent) != 0) {
- if (errno == EPERM)
- return (perm());
- perror("core_set_global_content()");
- return (E_ERROR);
- }
- if (core_set_default_content(&icontent) != 0) {
- if (errno == EPERM)
- return (perm());
- perror("core_set_default_content()");
- return (E_ERROR);
- }
- return (write_config(1));
+
+ return (1);
}
+/*
+ * Loads and applies the coreadm configuration stored in the default
+ * coreadm instance. As this option is (only) used from within an SMF
+ * service method, this function must return an SMF_EXIT_* exit status
+ * to its caller.
+ */
static int
-write_config(int justtry)
+do_update(void)
{
- int fd;
- FILE *fp;
- int options;
- char global_path[PATH_MAX];
- char init_path[PATH_MAX];
- core_content_t gcontent, icontent;
- char content_str[PRCONTENTBUFSZ];
-
- if ((fd = open(PATH_CONFIG, O_WRONLY | O_CREAT | O_TRUNC,
- CF_PERM)) == -1) {
- /*
- * If we're updating the kernel settings from the contents
- * of the config file, it's not essential that we rewrite
- * that file.
- */
- if (justtry)
- return (E_SUCCESS);
-
- if (errno == EACCES) {
- (void) fprintf(stderr, gettext("%s: insufficient "
- "privileges to update %s\n"), command, PATH_CONFIG);
- return (E_SUCCESS);
+ char *gcstr, *icstr;
+ scf_propvec_t properties[MAX_PROPS + 1];
+ scf_propvec_t *prop;
+ int count = 0;
+ const char *errstr;
+
+ if (read_legacy()) {
+ if ((errstr = write_kernel()) != NULL)
+ goto error;
+
+ if (do_modify(B_TRUE) != 0 ||
+ rename(PATH_CONFIG, PATH_CONFIG_OLD) != 0) {
+ (void) fprintf(stderr, gettext(
+ "%s: failed to import legacy configuration.\n"),
+ command);
+ return (SMF_EXIT_ERR_FATAL);
}
-
- (void) fprintf(stderr, gettext("failed to open %s: %s\n"),
- PATH_CONFIG, strerror(errno));
- return (E_ERROR);
+ return (SMF_EXIT_OK);
}
- if ((options = core_get_options()) == -1) {
- perror("core_get_options()");
- goto err;
- }
- if (core_get_global_path(global_path, sizeof (global_path)) != 0) {
- perror("core_get_global_path()");
- goto err;
- }
- if (core_get_default_path(init_path, sizeof (init_path)) != 0) {
- perror("core_get_default_path()");
- goto err;
- }
- if (core_get_global_content(&gcontent) != 0) {
- perror("core_get_global_content()");
- goto err;
- }
- if (core_get_default_content(&icontent) != 0) {
- perror("core_get_default_content()");
- goto err;
+
+ addprop(properties, MAX_PROPS, count++, &prop_gpattern, &glob_pattern);
+ addprop(properties, MAX_PROPS, count++, &prop_gcontent, &gcstr);
+ addprop(properties, MAX_PROPS, count++, &prop_ipattern, &init_pattern);
+ addprop(properties, MAX_PROPS, count++, &prop_icontent, &icstr);
+ for (prop = prop_option; prop->pv_prop != NULL; prop++)
+ addprop(properties, MAX_PROPS, count++, prop, &options);
+ properties[count].pv_prop = NULL;
+
+ alloptions = CC_OPTIONS;
+ if (scf_read_propvec(COREADM_INST_FMRI, CONFIG_PARAMS, B_TRUE,
+ properties, &prop) == SCF_FAILED) {
+ if (prop != NULL) {
+ (void) fprintf(stderr, gettext(
+ "%s: configuration property '%s' not found.\n"),
+ command, prop->pv_prop);
+ } else {
+ (void) fprintf(stderr, gettext(
+ "%s: unable to read configuration: %s\n"),
+ command, scf_strerror(scf_error()));
+ }
+ return (SMF_EXIT_ERR_FATAL);
}
- if ((fp = fdopen(fd, "w")) == NULL) {
- (void) fprintf(stderr,
- gettext("failed to open stream for %s: %s\n"),
- PATH_CONFIG, strerror(errno));
- goto err;
+
+ (void) proc_str2content(gcstr, &glob_content);
+ (void) proc_str2content(icstr, &init_content);
+
+ errstr = write_kernel();
+ scf_clean_propvec(properties);
+ if (errstr == NULL)
+ return (SMF_EXIT_OK);
+
+error:
+ if (errno == EPERM) {
+ (void) perm();
+ return (SMF_EXIT_ERR_PERM);
}
- (void) fputs(
- "#\n"
- "# coreadm.conf\n"
- "#\n"
- "# Parameters for system core file configuration.\n"
- "# Do NOT edit this file by hand -- use coreadm(1) instead.\n"
- "#\n",
- fp);
-
- (void) fprintf(fp, "COREADM_GLOB_PATTERN=%s\n", global_path);
- (void) proc_content2str(gcontent, content_str, sizeof (content_str));
- (void) fprintf(fp, "COREADM_GLOB_CONTENT=%s\n", content_str);
- (void) fprintf(fp, "COREADM_INIT_PATTERN=%s\n", init_path);
- (void) proc_content2str(icontent, content_str, sizeof (content_str));
- (void) fprintf(fp, "COREADM_INIT_CONTENT=%s\n", content_str);
-
- (void) fprintf(fp, "COREADM_GLOB_ENABLED=%s\n",
- (options & CC_GLOBAL_PATH)? "yes" : "no");
- (void) fprintf(fp, "COREADM_PROC_ENABLED=%s\n",
- (options & CC_PROCESS_PATH)? "yes" : "no");
- (void) fprintf(fp, "COREADM_GLOB_SETID_ENABLED=%s\n",
- (options & CC_GLOBAL_SETID)? "yes" : "no");
- (void) fprintf(fp, "COREADM_PROC_SETID_ENABLED=%s\n",
- (options & CC_PROCESS_SETID)? "yes" : "no");
- (void) fprintf(fp, "COREADM_GLOB_LOG_ENABLED=%s\n",
- (options & CC_GLOBAL_LOG)? "yes" : "no");
-
- (void) fflush(fp);
- (void) fsync(fd);
- (void) fchmod(fd, CF_PERM);
- (void) fchown(fd, CF_OWNER, CF_GROUP);
- (void) fclose(fp);
+ perror(errstr);
+ return (SMF_EXIT_ERR_FATAL);
+}
- return (0);
+static int do_legacy()
+{
+ const char *errstr;
+
+ if (read_legacy() && (errstr = write_kernel()) != NULL) {
+ if (errno == EPERM)
+ return (perm());
+ perror(errstr);
+ return (E_ERROR);
+ }
-err:
- (void) close(fd);
- return (E_ERROR);
+ return (E_SUCCESS);
}
diff --git a/usr/src/cmd/coreadm/coreadm.xml b/usr/src/cmd/coreadm/coreadm.xml
index 0438d529b8..46a4cda17a 100644
--- a/usr/src/cmd/coreadm/coreadm.xml
+++ b/usr/src/cmd/coreadm/coreadm.xml
@@ -1,15 +1,14 @@
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<!--
- Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ Copyright 2008 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
CDDL HEADER START
The contents of this file are subject to the terms of the
- Common Development and Distribution License, Version 1.0 only
- (the "License"). You may not use this file except in compliance
- with the License.
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
or http://www.opensolaris.org/os/licensing.
@@ -24,8 +23,6 @@
CDDL HEADER END
- ident "%Z%%M% %I% %E% SMI"
-
NOTE: This service manifest is not editable; its contents will
be overwritten by package or patch operations, including
operating system upgrade. Make customizations in a different
@@ -41,8 +38,6 @@
type='service'
version='1'>
- <create_default_instance enabled='false' />
-
<single_instance />
<dependency
@@ -53,22 +48,69 @@
<service_fmri value='svc:/system/filesystem/minimal' />
</dependency>
- <exec_method
- type='method'
- name='start'
- exec='/usr/bin/coreadm -u'
- timeout_seconds='60' />
-
- <exec_method
- type='method'
- name='stop'
- exec=':true'
- timeout_seconds='60' />
+ <dependency
+ name='coreadm_manifest-import'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/manifest-import:default' />
+ </dependency>
- <property_group name='startd' type='framework'>
- <propval name='duration' type='astring'
- value='transient' />
- </property_group>
+ <instance name='default' enabled='false'>
+ <exec_method
+ type='method'
+ name='start'
+ exec='/usr/bin/coreadm -U'
+ timeout_seconds='60' />
+
+ <exec_method
+ type='method'
+ name='refresh'
+ exec='/usr/bin/coreadm -U'
+ timeout_seconds='60' />
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec=':true'
+ timeout_seconds='60' />
+
+ <property_group name='startd' type='framework'>
+ <propval name='duration' type='astring'
+ value='transient' />
+ </property_group>
+
+ <property_group name='general' type='framework'>
+ <propval name='action_authorization' type='astring'
+ value='solaris.smf.manage.coreadm' />
+ <propval name='value_authorization' type='astring'
+ value='solaris.smf.manage.coreadm' />
+ </property_group>
+
+ <property_group name='config_params' type='application'>
+ <propval name='value_authorization' type='astring'
+ value='solaris.smf.value.coreadm' />
+
+ <propval name='global_pattern'
+ type='astring' value='' />
+ <propval name='global_content'
+ type='astring' value='default' />
+ <propval name='init_pattern'
+ type='astring' value='core' />
+ <propval name='init_content'
+ type='astring' value='default' />
+ <propval name='global_enabled'
+ type='boolean' value='false' />
+ <propval name='process_enabled'
+ type='boolean' value='true' />
+ <propval name='global_setid_enabled'
+ type='boolean' value='false' />
+ <propval name='process_setid_enabled'
+ type='boolean' value='false' />
+ <propval name='global_log_enabled'
+ type='boolean' value='false' />
+ </property_group>
+ </instance>
<stability value='Unstable' />
@@ -86,6 +128,7 @@
manpath='/usr/share/man' />
</documentation>
</template>
+
</service>
</service_bundle>
diff --git a/usr/src/lib/libc/port/llib-lc b/usr/src/lib/libc/port/llib-lc
index 7bad235638..8ca3ae6d24 100644
--- a/usr/src/lib/libc/port/llib-lc
+++ b/usr/src/lib/libc/port/llib-lc
@@ -241,6 +241,8 @@ long labs(long int arg);
/* assert.c */
void _assert(const char *assertion, const char *filename, int line_num);
+void __assert_c99(const char *assertion, const char *filename, int line_num,
+ const char *funcname);
/* atexit.c */
int atexit(void(*func)());
diff --git a/usr/src/lib/libscf/common/mapfile-vers b/usr/src/lib/libscf/common/mapfile-vers
index 315e24d9e8..8c420aade1 100644
--- a/usr/src/lib/libscf/common/mapfile-vers
+++ b/usr/src/lib/libscf/common/mapfile-vers
@@ -22,8 +22,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
SUNW_1.1 {
global:
@@ -235,6 +233,9 @@ SUNWprivate_1.1 {
gen_filenms_from_fmri;
_scf_pg_is_read_protected;
_scf_repository_switch;
+ scf_read_propvec;
+ scf_write_propvec;
+ scf_clean_propvec;
local:
*;
};
diff --git a/usr/src/lib/libscf/common/midlevel.c b/usr/src/lib/libscf/common/midlevel.c
index a15fb445c7..c12cab4027 100644
--- a/usr/src/lib/libscf/common/midlevel.c
+++ b/usr/src/lib/libscf/common/midlevel.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "libscf_impl.h"
#include <libuutil.h>
@@ -36,6 +34,7 @@
#include <sys/param.h>
#include <errno.h>
#include <libgen.h>
+#include <assert.h>
#include "midlevel_impl.h"
#include "lowlevel_impl.h"
@@ -2485,3 +2484,397 @@ gen_filenms_from_fmri(const char *fmri, const char *name, char *filename,
return (0);
}
+
+static scf_type_t
+scf_true_base_type(scf_type_t type)
+{
+ scf_type_t base = type;
+
+ do {
+ type = base;
+ (void) scf_type_base_type(type, &base);
+ } while (base != type);
+
+ return (base);
+}
+
+/*
+ * Convenience routine which frees all strings and opaque data
+ * allocated by scf_read_propvec.
+ *
+ * Like free(3C), this function preserves the value of errno.
+ */
+void
+scf_clean_propvec(scf_propvec_t *propvec)
+{
+ int saved_errno = errno;
+ scf_propvec_t *prop;
+
+ for (prop = propvec; prop->pv_prop != NULL; prop++) {
+ assert(prop->pv_type != SCF_TYPE_INVALID);
+ if (prop->pv_type == SCF_TYPE_OPAQUE) {
+ scf_opaque_t *o = prop->pv_ptr;
+
+ if (o->so_addr != NULL)
+ free(o->so_addr);
+ } else if (scf_true_base_type(prop->pv_type) ==
+ SCF_TYPE_ASTRING) {
+ if (*(char **)prop->pv_ptr != NULL)
+ free(*(char **)prop->pv_ptr);
+ }
+ }
+
+ errno = saved_errno;
+}
+
+static int
+count_props(scf_propvec_t *props)
+{
+ int count = 0;
+
+ for (; props->pv_prop != NULL; props++)
+ count++;
+ return (count);
+}
+
+/*
+ * Reads a vector of properties from the specified fmri/property group.
+ * If 'running' is true, reads from the running snapshot instead of the
+ * editing snapshot.
+ *
+ * For string types, a buffer is allocated using malloc(3C) to hold the
+ * zero-terminated string, a pointer to which is stored in the
+ * caller-provided char **. It is the caller's responsbility to free
+ * this string. To simplify error handling, unread strings are
+ * initialized to NULL.
+ *
+ * For opaque types, a buffer is allocated using malloc(3C) to hold the
+ * opaque data. A pointer to this buffer and its size are stored in
+ * the caller-provided scf_opaque_t. It is the caller's responsibility
+ * to free this buffer. To simplify error handling, the address fields
+ * for unread opaque data are initialized to NULL.
+ *
+ * All other data is stored directly in caller-provided variables or
+ * structures.
+ *
+ * If this function fails to read a specific property, *badprop is set
+ * to point at that property's entry in the properties array.
+ *
+ * On all failures, all memory allocated by this function is freed.
+ */
+int
+scf_read_propvec(const char *fmri, const char *pgname, boolean_t running,
+ scf_propvec_t *properties, scf_propvec_t **badprop)
+{
+ scf_handle_t *h = handle_create();
+ scf_service_t *s = scf_service_create(h);
+ scf_instance_t *i = scf_instance_create(h);
+ scf_snapshot_t *snap = running ? scf_snapshot_create(h) : NULL;
+ scf_propertygroup_t *pg = scf_pg_create(h);
+ scf_property_t *p = scf_property_create(h);
+ scf_value_t *v = scf_value_create(h);
+ boolean_t instance = B_TRUE;
+ scf_propvec_t *prop;
+ int error = 0;
+
+ if (h == NULL || s == NULL || i == NULL || (running && snap == NULL) ||
+ pg == NULL || p == NULL || v == NULL)
+ goto scferror;
+
+ if (scf_handle_decode_fmri(h, fmri, NULL, s, i, NULL, NULL, 0) == -1)
+ goto scferror;
+
+ if (scf_instance_to_fmri(i, NULL, 0) == -1) {
+ if (scf_error() != SCF_ERROR_NOT_SET)
+ goto scferror;
+ instance = B_FALSE;
+ }
+
+ if (running) {
+ if (!instance) {
+ error = SCF_ERROR_TYPE_MISMATCH;
+ goto out;
+ }
+
+ if (scf_instance_get_snapshot(i, "running", snap) !=
+ SCF_SUCCESS)
+ goto scferror;
+ }
+
+ if ((instance ? scf_instance_get_pg_composed(i, snap, pgname, pg) :
+ scf_service_get_pg(s, pgname, pg)) == -1)
+ goto scferror;
+
+ for (prop = properties; prop->pv_prop != NULL; prop++) {
+ if (prop->pv_type == SCF_TYPE_OPAQUE)
+ ((scf_opaque_t *)prop->pv_ptr)->so_addr = NULL;
+ else if (scf_true_base_type(prop->pv_type) == SCF_TYPE_ASTRING)
+ *((char **)prop->pv_ptr) = NULL;
+ }
+
+ for (prop = properties; prop->pv_prop != NULL; prop++) {
+ int ret = 0;
+
+ if (scf_pg_get_property(pg, prop->pv_prop, p) == -1 ||
+ scf_property_get_value(p, v) == -1) {
+ *badprop = prop;
+ goto scferror;
+ }
+ switch (prop->pv_type) {
+ case SCF_TYPE_BOOLEAN: {
+ uint8_t b;
+
+ ret = scf_value_get_boolean(v, &b);
+ if (ret == -1)
+ break;
+ if (prop->pv_aux != 0) {
+ uint64_t *bits = prop->pv_ptr;
+ *bits = b ? (*bits | prop->pv_aux) :
+ (*bits & ~prop->pv_aux);
+ } else {
+ boolean_t *bool = prop->pv_ptr;
+ *bool = b ? B_TRUE : B_FALSE;
+ }
+ break;
+ }
+ case SCF_TYPE_COUNT:
+ ret = scf_value_get_count(v, prop->pv_ptr);
+ break;
+ case SCF_TYPE_INTEGER:
+ ret = scf_value_get_integer(v, prop->pv_ptr);
+ break;
+ case SCF_TYPE_TIME: {
+ scf_time_t *time = prop->pv_ptr;
+
+ ret = scf_value_get_time(v, &time->st_sec,
+ &time->st_nanosec);
+ break;
+ }
+ case SCF_TYPE_OPAQUE: {
+ scf_opaque_t *opaque = prop->pv_ptr;
+ ssize_t size = scf_value_get_opaque(v, NULL, 0);
+
+ if (size == -1) {
+ *badprop = prop;
+ goto scferror;
+ }
+ if ((opaque->so_addr = malloc(size)) == NULL) {
+ error = SCF_ERROR_NO_MEMORY;
+ goto out;
+ }
+ opaque->so_size = size;
+ ret = scf_value_get_opaque(v, opaque->so_addr, size);
+ break;
+ }
+ default: {
+ char *s;
+ ssize_t size;
+
+ assert(scf_true_base_type(prop->pv_type) ==
+ SCF_TYPE_ASTRING);
+
+ size = scf_value_get_astring(v, NULL, 0);
+ if (size == -1) {
+ *badprop = prop;
+ goto scferror;
+ }
+ if ((s = malloc(++size)) == NULL) {
+ error = SCF_ERROR_NO_MEMORY;
+ goto out;
+ }
+ ret = scf_value_get_astring(v, s, size);
+ *(char **)prop->pv_ptr = s;
+ }
+
+ if (ret == -1) {
+ *badprop = prop;
+ goto scferror;
+ }
+
+ }
+ }
+
+ goto out;
+
+scferror:
+ error = scf_error();
+ scf_clean_propvec(properties);
+
+out:
+ scf_pg_destroy(pg);
+ scf_snapshot_destroy(snap);
+ scf_instance_destroy(i);
+ scf_service_destroy(s);
+ scf_handle_destroy(h);
+
+ if (error != 0) {
+ (void) scf_set_error(error);
+ return (SCF_FAILED);
+ }
+
+ return (SCF_SUCCESS);
+}
+
+/*
+ * Writes a vector of properties to the specified fmri/property group.
+ *
+ * If this function fails to write a specific property, *badprop is set
+ * to point at that property's entry in the properties array.
+ *
+ * One significant difference between this function and the
+ * scf_read_propvec function is that for string types, pv_ptr is a
+ * char *, not a char **. This means that you can't write a propvec
+ * you just read, but makes other uses (hopefully the majority) simpler.
+ */
+int
+scf_write_propvec(const char *fmri, const char *pgname,
+ scf_propvec_t *properties, scf_propvec_t **badprop)
+{
+ scf_handle_t *h = handle_create();
+ scf_service_t *s = scf_service_create(h);
+ scf_instance_t *inst = scf_instance_create(h);
+ scf_snapshot_t *snap = scf_snapshot_create(h);
+ scf_propertygroup_t *pg = scf_pg_create(h);
+ scf_property_t *p = scf_property_create(h);
+ scf_transaction_t *tx = scf_transaction_create(h);
+ scf_value_t **v = NULL;
+ scf_transaction_entry_t **e = NULL;
+ boolean_t instance = B_TRUE;
+ int i, n;
+ scf_propvec_t *prop;
+ int error = 0, ret;
+
+ n = count_props(properties);
+ v = calloc(n, sizeof (scf_value_t *));
+ e = calloc(n, sizeof (scf_transaction_entry_t *));
+
+ if (v == NULL || e == NULL) {
+ error = SCF_ERROR_NO_MEMORY;
+ goto out;
+ }
+
+ if (h == NULL || s == NULL || inst == NULL || pg == NULL || p == NULL ||
+ tx == NULL)
+ goto scferror;
+
+ for (i = 0; i < n; i++) {
+ v[i] = scf_value_create(h);
+ e[i] = scf_entry_create(h);
+ if (v[i] == NULL || e[i] == NULL)
+ goto scferror;
+ }
+
+ if (scf_handle_decode_fmri(h, fmri, NULL, s, inst, NULL, NULL, 0)
+ != SCF_SUCCESS)
+ goto scferror;
+
+ if (scf_instance_to_fmri(inst, NULL, 0) == -1) {
+ if (scf_error() != SCF_ERROR_NOT_SET)
+ goto scferror;
+ instance = B_FALSE;
+ }
+
+ if ((instance ? scf_instance_get_pg(inst, pgname, pg) :
+ scf_service_get_pg(s, pgname, pg)) == -1)
+ goto scferror;
+
+top:
+ if (scf_transaction_start(tx, pg) == -1)
+ goto scferror;
+
+ for (prop = properties, i = 0; prop->pv_prop != NULL; prop++, i++) {
+ ret = scf_transaction_property_change(tx, e[i], prop->pv_prop,
+ prop->pv_type);
+ if (ret == -1 && scf_error() == SCF_ERROR_NOT_FOUND)
+ ret = scf_transaction_property_new(tx, e[i],
+ prop->pv_prop, prop->pv_type);
+
+ if (ret == -1) {
+ *badprop = prop;
+ goto scferror;
+ }
+
+ switch (prop->pv_type) {
+ case SCF_TYPE_BOOLEAN: {
+ boolean_t b = (prop->pv_aux != 0) ?
+ (*(uint64_t *)prop->pv_ptr & prop->pv_aux) != 0 :
+ *(boolean_t *)prop->pv_ptr;
+
+ scf_value_set_boolean(v[i], b ? 1 : 0);
+ break;
+ }
+ case SCF_TYPE_COUNT:
+ scf_value_set_count(v[i], *(uint64_t *)prop->pv_ptr);
+ break;
+ case SCF_TYPE_INTEGER:
+ scf_value_set_integer(v[i], *(int64_t *)prop->pv_ptr);
+ break;
+ case SCF_TYPE_TIME: {
+ scf_time_t *time = prop->pv_ptr;
+
+ ret = scf_value_set_time(v[i], time->st_sec,
+ time->st_nanosec);
+ break;
+ }
+ case SCF_TYPE_OPAQUE: {
+ scf_opaque_t *opaque = prop->pv_ptr;
+
+ ret = scf_value_set_opaque(v[i], opaque->so_addr,
+ opaque->so_size);
+ break;
+ }
+ case SCF_TYPE_ASTRING:
+ ret = scf_value_set_astring(v[i],
+ (const char *)prop->pv_ptr);
+ break;
+ default:
+ ret = scf_value_set_from_string(v[i], prop->pv_type,
+ (const char *)prop->pv_ptr);
+ }
+
+ if (ret == -1 || scf_entry_add_value(e[i], v[i]) == -1) {
+ *badprop = prop;
+ goto scferror;
+ }
+ }
+
+ ret = scf_transaction_commit(tx);
+ if (ret == 1)
+ goto out;
+
+ if (ret == 0 && scf_pg_update(pg) != -1) {
+ scf_transaction_reset(tx);
+ goto top;
+ }
+
+scferror:
+ error = scf_error();
+
+out:
+ if (v != NULL) {
+ for (i = 0; i < n; i++)
+ scf_value_destroy(v[i]);
+ free(v);
+ }
+
+ if (e != NULL) {
+ for (i = 0; i < n; i++)
+ scf_entry_destroy(e[i]);
+ free(e);
+ }
+
+ scf_transaction_destroy(tx);
+ scf_property_destroy(p);
+ scf_pg_destroy(pg);
+ scf_snapshot_destroy(snap);
+ scf_instance_destroy(inst);
+ scf_service_destroy(s);
+ scf_handle_destroy(h);
+
+ if (error != 0) {
+ (void) scf_set_error(error);
+ return (SCF_FAILED);
+ }
+
+ return (SCF_SUCCESS);
+}
diff --git a/usr/src/lib/libscf/inc/libscf_priv.h b/usr/src/lib/libscf/inc/libscf_priv.h
index ab4ad553c5..4c6ad80597 100644
--- a/usr/src/lib/libscf/inc/libscf_priv.h
+++ b/usr/src/lib/libscf/inc/libscf_priv.h
@@ -369,6 +369,58 @@ int scf_cmp_pattern(char *, scf_pattern_t *);
int gen_filenms_from_fmri(const char *, const char *, char *, char *);
+/*
+ * Interfaces for bulk access to SMF-stored configuration.
+ *
+ * Each scf_propvec_t represents a single property to be read (with
+ * scf_read_propvec) or written (with scf_write_propvec).
+ *
+ * The fields of a scf_propvec_t have the following meanings:
+ *
+ * pv_prop - the name of the property
+ * pv_desc - a description string (optional; to be consumed by the caller)
+ * pv_type - the type of the property
+ * pv_ptr - where to store the data read, or a pointer to the data to
+ * be written
+ * pv_aux - additional data influencing the interpretation of pv_ptr
+ *
+ * The meaning of pv_ptr and pv_aux depends on the type of property. For:
+ *
+ * boolean - if pv_aux is 0, pv_ptr is a pointer to a boolean_t
+ * if pv_aux is non-0, pv_ptr is a pointer to a uint64_t,
+ * where pv_aux indicates the bit holding the truth value.
+ * count - pv_ptr is a pointer to a uint64_t; pv_aux is unused
+ * integer - pv_ptr is a pointer to an int64_t; pv_aux is unused
+ * time - pv_ptr is a pointer to an scf_time_t; pv_aux is unused
+ * opaque - pv_ptr is a pointer to an scf_opaque_t; pv_aux is unused
+ * strings - (scf_read_propvec) pv_ptr is a pointer to a char *
+ * (scf_write_propvec) pv_ptr is a pointer to an array of char
+ * (both) pv_aux is unused
+ */
+typedef struct {
+ int64_t st_sec;
+ int32_t st_nanosec;
+} scf_time_t;
+
+typedef struct {
+ void *so_addr;
+ size_t so_size;
+} scf_opaque_t;
+
+typedef struct {
+ const char *pv_prop;
+ const char *pv_desc;
+ scf_type_t pv_type;
+ void *pv_ptr;
+ uint64_t pv_aux;
+} scf_propvec_t;
+
+void scf_clean_propvec(scf_propvec_t *);
+int scf_read_propvec(const char *, const char *, boolean_t, scf_propvec_t *,
+ scf_propvec_t **);
+int scf_write_propvec(const char *, const char *, scf_propvec_t *,
+ scf_propvec_t **);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/libsecdb/auth_attr.txt b/usr/src/lib/libsecdb/auth_attr.txt
index 42ec91a1b1..36e39c55fa 100644
--- a/usr/src/lib/libsecdb/auth_attr.txt
+++ b/usr/src/lib/libsecdb/auth_attr.txt
@@ -116,6 +116,7 @@ solaris.smf.modify.framework:::Modify Framework Type Properties::help=SmfModifyF
solaris.smf.manage.:::Manage All SMF Service States::help=SmfManageHeader.html
solaris.smf.manage.autofs:::Manage Automount Service States::help=SmfAutofsStates.html
solaris.smf.manage.bind:::Manage DNS Service States::help=BindStates.html
+solaris.smf.manage.coreadm:::Manage Coreadm Service States::help=SmfCoreadmStates.html
solaris.smf.manage.cron:::Manage Cron Service States::help=SmfCronStates.html
solaris.smf.manage.discovery.printers.snmp:::Manage Network Attached Device Discovery Service States::help=SmfNADDStates.html
solaris.smf.manage.extended-accounting.flow:::Manage Flow Extended Accounting Service States::help=SmfExAcctFlowStates.html
@@ -145,6 +146,7 @@ solaris.smf.manage.vt:::Manage Virtual Console Service States::help=SmfVtStates.
solaris.smf.manage.wpa:::Manage WPA Service States::help=SmfWpaStates.html
solaris.smf.manage.ndmp:::Manage NDMP Service States::help=SmfNDMPStates.html
solaris.smf.value.:::Change Values of SMF Service Properties::help=SmfValueHeader.html
+solaris.smf.value.coreadm:::Change Values of SMF Coreadm Properties::help=SmfValueCoreadm.html
solaris.smf.value.discovery.printers.snmp:::Manage Network Attached Device Discovery Service Properties::help=SmfValueNADD.html
solaris.smf.value.extended-accounting.flow:::Change Values of Flow Extended Accounting Service Properties::help=SmfValueExAcctFlow.html
solaris.smf.value.extended-accounting.process:::Change Values of Process Extended Accounting Service Properties::help=SmfValueExAcctProcess.html
diff --git a/usr/src/lib/libsecdb/exec_attr.txt b/usr/src/lib/libsecdb/exec_attr.txt
index a41c0ace1c..fbe2e93f75 100644
--- a/usr/src/lib/libsecdb/exec_attr.txt
+++ b/usr/src/lib/libsecdb/exec_attr.txt
@@ -130,8 +130,7 @@ Mail Management:suser:cmd:::/usr/sbin/makemap:euid=0
Mail Management:suser:cmd:::/usr/sbin/newaliases:euid=0
Maintenance and Repair:solaris:cmd:::/usr/bin/mdb:privs=all
Maintenance and Repair:suser:cmd:::/usr/bin/mdb:euid=0
-Maintenance and Repair:solaris:cmd:::/usr/bin/coreadm:euid=0;\
- privs=sys_config,proc_owner
+Maintenance and Repair:solaris:cmd:::/usr/bin/coreadm:euid=0;privs=proc_owner
Maintenance and Repair:suser:cmd:::/usr/bin/date:euid=0
Maintenance and Repair:suser:cmd:::/usr/bin/ldd:euid=0
Maintenance and Repair:suser:cmd:::/usr/bin/vmstat:euid=0
diff --git a/usr/src/lib/libsecdb/help/auths/Makefile b/usr/src/lib/libsecdb/help/auths/Makefile
index af16336769..2b73d4216f 100644
--- a/usr/src/lib/libsecdb/help/auths/Makefile
+++ b/usr/src/lib/libsecdb/help/auths/Makefile
@@ -65,6 +65,7 @@ HTMLENTS = \
DhcpmgrWrite.html \
BindStates.html \
SmfAutofsStates.html \
+ SmfCoreadmStates.html \
SmfCronStates.html \
SmfExAcctFlowStates.html \
SmfExAcctProcessStates.html \
@@ -88,6 +89,7 @@ HTMLENTS = \
SmfSendmailStates.html \
SmfSshStates.html \
SmfSyslogStates.html \
+ SmfValueCoreadm.html \
SmfValueExAcctFlow.html \
SmfValueExAcctProcess.html \
SmfValueExAcctTask.html \
diff --git a/usr/src/lib/libsecdb/help/auths/SmfCoreadmStates.html b/usr/src/lib/libsecdb/help/auths/SmfCoreadmStates.html
new file mode 100644
index 0000000000..86c2985f70
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/SmfCoreadmStates.html
@@ -0,0 +1,37 @@
+<HTML>
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+Use is subject to license terms.
+-->
+<!--
+ <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+-->
+<BODY>
+When Manage Coreadm Service States is in the Authorizations Included
+column, it grants the authorization to enable, disable, or restart the
+coreadm service.
+<p>
+If Manage Coreadm Service States is grayed, then you are not entitled to
+Add or Remove this authorization.
+<BR>&nbsp;
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/SmfValueCoreadm.html b/usr/src/lib/libsecdb/help/auths/SmfValueCoreadm.html
new file mode 100644
index 0000000000..2f75b95f8d
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/SmfValueCoreadm.html
@@ -0,0 +1,37 @@
+<HTML>
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+Use is subject to license terms.
+-->
+<!--
+ <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+-->
+<BODY>
+When Change Values of SMF Coreadm Properties is in the Authorizations Include
+column, it grants the the authorization to change coreadm service property
+values.
+<P>
+If Change Values of SMF Coreadm Properties is grayed, then you are not
+entitled to Add or Remove this authorization.
+<BR>&nbsp;
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/prof_attr.txt b/usr/src/lib/libsecdb/prof_attr.txt
index 2fb7504a67..f3d16f89fa 100644
--- a/usr/src/lib/libsecdb/prof_attr.txt
+++ b/usr/src/lib/libsecdb/prof_attr.txt
@@ -51,7 +51,7 @@ Idmap Name Mapping Management:::Manage Name-based Mapping Rules of Identity Mapp
Idmap Service Management:::Manage Identity Mapping Service:auths=solaris.smf.manage.idmap,solaris.smf.value.idmap;help=RtIdmapMngmnt.html
Inetd Management:::Manage inetd configuration parameters:auths=solaris.smf.manage.inetd,solaris.smf.value.inetd;help=RtInetdMngmnt.html
Mail Management:::Manage sendmail & queues:auths=solaris.smf.manage.sendmail;help=RtMailMngmnt.html
-Maintenance and Repair:::Maintain and repair a system:auths=solaris.smf.manage.system-log,solaris.label.range;help=RtMaintAndRepair.html
+Maintenance and Repair:::Maintain and repair a system:auths=solaris.smf.manage.system-log,solaris.label.range,solaris.smf.manage.coreadm,solaris.smf.value.coreadm;help=RtMaintAndRepair.html
Media Backup:::Backup files and file systems:profiles=NDMP Management;help=RtMediaBkup.html
Media Restore:::Restore files and file systems from backups:profiles=NDMP Management;help=RtMediaRestore.html
MMS Administrator:::MMS Media Manager Administrator:auths=solaris.smf.manage.mms,solaris.smf.modify.mms,solaris.smf.value.mms,solaris.mms.*
diff --git a/usr/src/pkgdefs/SUNW0on/prototype_com b/usr/src/pkgdefs/SUNW0on/prototype_com
index a8ec534d70..bc359aaa6d 100644
--- a/usr/src/pkgdefs/SUNW0on/prototype_com
+++ b/usr/src/pkgdefs/SUNW0on/prototype_com
@@ -237,6 +237,7 @@ f none usr/lib/help/auths/locale/DhcpmgrHeader.html 444 root bin
f none usr/lib/help/auths/locale/DhcpmgrWrite.html 444 root bin
f none usr/lib/help/auths/locale/BindStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfAutofsStates.html 444 root bin
+f none usr/lib/help/auths/locale/SmfCoreadmStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfCronStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfExAcctFlowStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfExAcctProcessStates.html 444 root bin
@@ -262,6 +263,7 @@ f none usr/lib/help/auths/locale/SmfSMBStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfSshStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfSyslogStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfVscanStates.html 444 root bin
+f none usr/lib/help/auths/locale/SmfValueCoreadm.html 444 root bin
f none usr/lib/help/auths/locale/SmfValueExAcctFlow.html 444 root bin
f none usr/lib/help/auths/locale/SmfValueExAcctProcess.html 444 root bin
f none usr/lib/help/auths/locale/SmfValueExAcctTask.html 444 root bin
diff --git a/usr/src/pkgdefs/SUNWcsr/prototype_com b/usr/src/pkgdefs/SUNWcsr/prototype_com
index a806ca1425..0d3d4c6ec9 100644
--- a/usr/src/pkgdefs/SUNWcsr/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsr/prototype_com
@@ -446,6 +446,7 @@ d none var/adm/streams 755 root sys
e preserve var/adm/utmpx 644 root bin
e preserve var/adm/wtmpx 644 adm adm
d none var/audit 755 root sys
+d none var/cores 755 root sys
d none var/cron 755 root sys
d none var/games 755 root bin
d none var/idmap 755 daemon daemon
diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_com b/usr/src/pkgdefs/SUNWcsu/prototype_com
index e01cfff87c..230a9f354c 100644
--- a/usr/src/pkgdefs/SUNWcsu/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_com
@@ -478,6 +478,7 @@ f none usr/lib/help/auths/locale/C/PriAdmin.html 444 root bin
f none usr/lib/help/auths/locale/C/ProfmgrHeader.html 444 root bin
f none usr/lib/help/auths/locale/C/RoleHeader.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfAutofsStates.html 444 root bin
+f none usr/lib/help/auths/locale/C/SmfCoreadmStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfCronStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfExAcctFlowStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfExAcctProcessStates.html 444 root bin
@@ -502,6 +503,7 @@ f none usr/lib/help/auths/locale/C/SmfSMBFSStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfSMBStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfSshStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfSyslogStates.html 444 root bin
+f none usr/lib/help/auths/locale/C/SmfValueCoreadm.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfValueExAcctFlow.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfValueExAcctProcess.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfValueExAcctTask.html 444 root bin