summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/rcap/Makefile.com27
-rw-r--r--usr/src/cmd/rcap/common/rcapd.h10
-rw-r--r--usr/src/cmd/rcap/common/rcapd_conf.c244
-rw-r--r--usr/src/cmd/rcap/common/rcapd_conf.h6
-rw-r--r--usr/src/cmd/rcap/common/rcapd_conf.l347
-rw-r--r--usr/src/cmd/rcap/rcapadm/Makefile4
-rw-r--r--usr/src/cmd/rcap/rcapadm/rcapadm.c87
-rw-r--r--usr/src/cmd/rcap/rcapd/Makefile.rcapd4
-rw-r--r--usr/src/cmd/rcap/rcapd/rcap.xml24
-rw-r--r--usr/src/cmd/rcap/rcapd/rcapd_main.c78
-rw-r--r--usr/src/cmd/rcap/rcapstat/Makefile4
-rw-r--r--usr/src/lib/libscf/common/mapfile-vers8
-rw-r--r--usr/src/lib/libscf/common/midlevel.c325
-rw-r--r--usr/src/lib/libscf/inc/libscf_priv.h17
-rw-r--r--usr/src/pkgdefs/SUNWrcapr/postinstall78
-rw-r--r--usr/src/tools/scripts/bfu.sh66
16 files changed, 848 insertions, 481 deletions
diff --git a/usr/src/cmd/rcap/Makefile.com b/usr/src/cmd/rcap/Makefile.com
index deb938a28e..c39ee2a6fd 100644
--- a/usr/src/cmd/rcap/Makefile.com
+++ b/usr/src/cmd/rcap/Makefile.com
@@ -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,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -31,26 +30,6 @@
# COMMON_DIR.
#
-LFLAGS= -t -v
-YFLAGS= -d -v
-
-rcapd_conf.o := CFLAGS += -erroff=E_STATEMENT_NOT_REACHED
-rcapd_conf.o := CFLAGS64 += -erroff=E_STATEMENT_NOT_REACHED
-
-rcapd_conf.c: $(COMMON_DIR)/rcapd_conf.l
- $(RM) rcapd_conf.c
- $(LEX) $(LFLAGS) $(COMMON_DIR)/rcapd_conf.l > $@
-
-rcapd_conf.o: rcapd_conf.c
-
-#
-# Switching the order of these would have the undesired effect of having
-# the .c.l rule be used to build $(COMMON_DIR)/rcapd_conf.c from
-# $(COMMON_DIR)/rcapd_conf.l, instead of building ./rcapd_conf.c.
-#
-%.o: %.c
- $(COMPILE.c) $<
-
%.o: $(COMMON_DIR)/%.c
$(COMPILE.c) $<
%.po: $(COMMON_DIR)/%.c
diff --git a/usr/src/cmd/rcap/common/rcapd.h b/usr/src/cmd/rcap/common/rcapd.h
index 7a554c213b..4dc6116adc 100644
--- a/usr/src/cmd/rcap/common/rcapd.h
+++ b/usr/src/cmd/rcap/common/rcapd.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,7 +37,13 @@ extern "C" {
#include "rcapd_conf.h"
#define LC_NAME_LEN 32
-#define RCAPD_DEFAULT_CONF_FILE "/etc/rcap.conf"
+#define RCAP_FMRI "svc:/system/rcap:default"
+#define CONFIG_PG "config"
+#define PRESSURE "pressure"
+#define RECONFIG_INT "reconfig_interval"
+#define REPORT_INT "report_interval"
+#define RSS_SAMPLE_INT "rss_sample_interval"
+#define WALK_INT "walk_interval"
#define RCAPD_IGNORED_SET_FLUSH_IVAL 10 /* number of scans between */
/* flushes of the ignored set */
diff --git a/usr/src/cmd/rcap/common/rcapd_conf.c b/usr/src/cmd/rcap/common/rcapd_conf.c
new file mode 100644
index 0000000000..63daa38564
--- /dev/null
+++ b/usr/src/cmd/rcap/common/rcapd_conf.c
@@ -0,0 +1,244 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <strings.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <libscf.h>
+#include <libscf_priv.h>
+#include <libuutil.h>
+#include "rcapd.h"
+#include "rcapd_conf.h"
+#include "rcapd_stat.h"
+#include "utils.h"
+
+/*
+ * Read configuration and set the fields of an rcfg_t correspondingly.
+ * Verify that the statistics file is writable, with the optional
+ * verify_stat_file_creation() callback.
+ */
+int
+rcfg_read(rcfg_t *_rcfg, int(*verify_stat_file_creation)(void))
+{
+ scf_simple_handle_t *simple_h;
+ uint64_t count_val;
+ int ret = E_ERROR;
+
+ rcfg_init(_rcfg);
+
+ if ((simple_h = scf_general_pg_setup(RCAP_FMRI, CONFIG_PG))
+ == NULL) {
+ warn(gettext("SMF initialization problem: %s\n"),
+ scf_strerror(scf_error()));
+ goto err;
+ }
+
+ if (scf_read_count_property(simple_h, PRESSURE, &count_val)
+ == SCF_FAILED) {
+ warn(gettext("Configuration property '%s' "
+ "not found. \n"), PRESSURE);
+ goto err;
+ } else {
+ if (count_val > 100)
+ _rcfg->rcfg_memory_cap_enforcement_pressure = 100;
+ else
+ _rcfg->rcfg_memory_cap_enforcement_pressure
+ = count_val;
+
+ debug("cap max pressure: %d%%\n",
+ _rcfg->rcfg_memory_cap_enforcement_pressure);
+ }
+
+ if (scf_read_count_property(simple_h, RECONFIG_INT, &count_val)
+ == SCF_FAILED) {
+ warn(gettext("Configuration property '%s' "
+ "not found. \n"), RECONFIG_INT);
+ goto err;
+ } else {
+ _rcfg->rcfg_reconfiguration_interval = count_val;
+ debug("reconfiguration interval: %d seconds\n",
+ _rcfg->rcfg_reconfiguration_interval);
+ }
+
+ if (scf_read_count_property(simple_h, REPORT_INT, &count_val)
+ == SCF_FAILED) {
+ warn(gettext("Configuration property '%s' "
+ "not found. \n"), REPORT_INT);
+ goto err;
+ } else {
+ _rcfg->rcfg_report_interval = count_val;
+ debug("report interval: %d seconds\n",
+ _rcfg->rcfg_report_interval);
+ }
+
+ if (scf_read_count_property(simple_h, RSS_SAMPLE_INT, &count_val)
+ == SCF_FAILED) {
+ warn(gettext("Configuration property '%s' "
+ "not found. \n"), RSS_SAMPLE_INT);
+ goto err;
+ } else {
+ _rcfg->rcfg_rss_sample_interval = count_val;
+ debug("RSS sample interval: %d seconds\n",
+ _rcfg->rcfg_rss_sample_interval);
+ }
+
+ if (scf_read_count_property(simple_h, WALK_INT, &count_val)
+ == SCF_FAILED) {
+ warn(gettext("Configuration property '%s' "
+ "not found. \n"), WALK_INT);
+ goto err;
+ } else {
+ _rcfg->rcfg_proc_walk_interval = count_val;
+ debug("proc_walk interval: %d seconds\n",
+ _rcfg->rcfg_proc_walk_interval);
+ }
+
+ if (_rcfg->rcfg_mode_name == NULL) {
+ /*
+ * Set project mode, by default.
+ */
+ _rcfg->rcfg_mode = rctype_project;
+ _rcfg->rcfg_mode_name = "project";
+ debug("mode: %s\n", _rcfg->rcfg_mode_name);
+ }
+
+ if (verify_stat_file_creation != 0 && verify_stat_file_creation()
+ != 0) {
+ warn(gettext("cannot create statistics file, " "%s"),
+ _rcfg->rcfg_stat_file);
+ goto err;
+ }
+
+ debug("done parsing\n");
+ ret = E_SUCCESS;
+ goto out;
+
+err:
+ if (scf_error() != SCF_ERROR_NONE) {
+ warn(gettext("Unexpected libscf error: %s. \n"),
+ scf_strerror(scf_error()));
+ }
+
+out:
+ scf_simple_handle_destroy(simple_h);
+ return (ret);
+}
+
+void
+rcfg_init(rcfg_t *rcfg)
+{
+ bzero(rcfg, sizeof (*rcfg));
+ (void) strcpy(rcfg->rcfg_stat_file, STAT_FILE_DEFAULT);
+}
+
+/*
+ * Modify configuration in repository given the rcfg_t structure.
+ */
+int
+modify_config(rcfg_t *conf)
+{
+ scf_simple_handle_t *simple_h;
+ scf_transaction_t *tx = NULL;
+ int rval, ret = E_ERROR;
+
+ if ((simple_h = scf_general_pg_setup(RCAP_FMRI, CONFIG_PG))
+ == NULL) {
+ warn(gettext("SMF initialization problem: %s\n"),
+ scf_strerror(scf_error()));
+ goto out;
+ }
+
+ if ((tx = scf_transaction_setup(simple_h)) == NULL) {
+ warn(gettext("SMF initialization problem: %s\n"),
+ scf_strerror(scf_error()));
+ goto out;
+ }
+
+ do {
+ if (scf_set_count_property(tx, PRESSURE,
+ conf->rcfg_memory_cap_enforcement_pressure, 0)
+ != SCF_SUCCESS) {
+ warn(gettext("Couldn't set '%s' property. \n"),
+ PRESSURE);
+ goto out;
+ }
+
+ if (scf_set_count_property(tx, RECONFIG_INT,
+ conf->rcfg_reconfiguration_interval, 0) != SCF_SUCCESS) {
+ warn(gettext("Couldn't set '%s' property. \n"),
+ RECONFIG_INT);
+ goto out;
+ }
+
+ if (scf_set_count_property(tx, RSS_SAMPLE_INT,
+ conf->rcfg_rss_sample_interval, 0) != SCF_SUCCESS) {
+ warn(gettext("Couldn't set '%s' property. \n"),
+ RSS_SAMPLE_INT);
+ goto out;
+ }
+
+ if (scf_set_count_property(tx, REPORT_INT,
+ conf->rcfg_report_interval, 0) != SCF_SUCCESS) {
+ warn(gettext("Couldn't set '%s' property. \n"),
+ REPORT_INT);
+ goto out;
+ }
+
+ if (scf_set_count_property(tx, WALK_INT,
+ conf->rcfg_proc_walk_interval, 0) != SCF_SUCCESS) {
+ warn(gettext("Couldn't set '%s' property. \n"),
+ WALK_INT);
+ goto out;
+ }
+
+ if ((rval = scf_transaction_commit(tx)) == -1)
+ goto out;
+
+ if (rval == 0) {
+ if (scf_transaction_restart(simple_h, tx)
+ != SCF_SUCCESS) {
+ warn(gettext("SMF initialization problem: "
+ "%s\n"), scf_strerror(scf_error()));
+ goto out;
+ }
+ }
+ } while (rval == 0);
+
+ ret = E_SUCCESS;
+
+out:
+ if (tx != NULL) {
+ scf_transaction_destroy_children(tx);
+ scf_transaction_destroy(tx);
+ }
+ scf_simple_handle_destroy(simple_h);
+ return (ret);
+}
diff --git a/usr/src/cmd/rcap/common/rcapd_conf.h b/usr/src/cmd/rcap/common/rcapd_conf.h
index 3b12d8cab9..f648a05782 100644
--- a/usr/src/cmd/rcap/common/rcapd_conf.h
+++ b/usr/src/cmd/rcap/common/rcapd_conf.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -85,9 +85,9 @@ typedef enum {
RCT_INVALID
} rctoken_t;
-extern int rcfg_read(char *, int, rcfg_t *, int(*)(void));
+extern int rcfg_read(rcfg_t *, int(*)(void));
extern void rcfg_init(rcfg_t *);
-extern void create_config_file(rcfg_t *);
+extern int modify_config(rcfg_t *);
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/rcap/common/rcapd_conf.l b/usr/src/cmd/rcap/common/rcapd_conf.l
deleted file mode 100644
index e990a58e19..0000000000
--- a/usr/src/cmd/rcap/common/rcapd_conf.l
+++ /dev/null
@@ -1,347 +0,0 @@
-%{
-/*
- * 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 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <strings.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "rcapd.h"
-#include "rcapd_conf.h"
-#include "rcapd_stat.h"
-#include "utils.h"
-
-#define LINELEN 256
-
-/*PRINTFLIKE1*/
-static void
-parse_err(char *filename, char *str, ...)
-{
- va_list alist;
- char buf[LINELEN];
-
- (void) snprintf(buf, LINELEN - 1, "%s: line %d: ", filename, yylineno);
- va_start(alist, str);
- (void) vsnprintf(buf + strlen(buf), LINELEN - 1 - strlen(buf), str,
- alist);
- va_end(alist);
- dprintfe(RCM_ERR, buf);
-
- exit(E_ERROR);
- /*NOTREACHED*/
-}
-
-#define CFG_EXPECT(ttype, context) { \
- if (yylex() != ttype) { \
- parse_err(name, context); \
- } \
- }
-
-#define YYSTYPE yystype_t
-
-typedef union {
- int id;
-} yystype_t;
-
-extern yystype_t yylval;
-%}
-
-%x fn
-
-%%
-
-<fn>\= { return (RCT_EQUALS); }
-<fn>[ \t] { break; }
-<fn>[^ \t\n]+ { BEGIN(INITIAL); return (RCT_FILENAME); }
-
-"RCAPD_MODE" { return (RCT_MODE_VAR); }
-"RCAPD_STATE" { return (RCT_STATE); }
-"RCAPD_PROC_WALK_INTERVAL" { return (RCT_PROC_WALK_INTERVAL_VAR); }
-
-"RCAPD_RECONFIGURATION_INTERVAL" { return
- (RCT_RECONFIGURATION_INTERVAL_VAR);
- }
-"RCAPD_REPORT_INTERVAL" \
- { return (RCT_REPORT_INTERVAL_VAR); }
-"RCAPD_RSS_SAMPLE_INTERVAL" \
- { return (RCT_RSS_SAMPLE_INTERVAL_VAR); }
-"RCAPD_MEMORY_CAP_ENFORCEMENT_PRESSURE" \
- { return (RCT_MEMORY_CAP_ENFORCEMENT_PRESSURE_VAR); }
-"RCAPD_STATISTICS_FILE" { BEGIN(fn); return (RCT_STAT_FILE_VAR); }
-\= { return (RCT_EQUALS); }
-[0-9]+ { return (RCT_NUMBER); }
-"project" { return (RCT_PROJECT); }
-"lnode" { return (RCT_LNODE); }
-"on" { return (RCT_ON); }
-"off" { return (RCT_OFF); }
-
-[ \t] { break; }
-\#.* { break; }
-\n { break; }
-[^ \t\n]* { return (RCT_INVALID); }
-
-%%
-
-/*
- * Read the supplied configuration file and set the fields of an rcfg_t
- * correspondingly. Verify that the statistics file is writable, with the
- * optional verify_stat_file_creation() callback.
- *
- * fd should be the number of a low-numbered (<256) file descriptor on 32-bit
- * processes, as stdio requires them to be in that range. The actual
- * descriptor will be recorded in rcfg and left open, and may be supplied in
- * future calls to rcfg_read(), simplifying descriptor distribution.
- */
-int
-rcfg_read(char *name, int fd, rcfg_t *_rcfg,
- int(*verify_stat_file_creation)(void))
-{
- rctoken_t l;
- FILE *f;
- struct stat stat;
-
- if (fd >= 0)
- (void) close(fd);
- if ((fd = open(name, O_RDONLY)) < 0)
- return (-1);
- if ((f = fdopen(fd, "r")) == NULL)
- return (-1);
- if (strlen(name) >= sizeof (_rcfg->rcfg_filename)) {
- errno = EINVAL;
- return (-1);
- }
-
- rcfg_init(_rcfg);
- (void) strcpy(_rcfg->rcfg_filename, name);
- _rcfg->rcfg_fd = fd;
- if (fstat(fd, &stat) == 0)
- _rcfg->rcfg_last_modification = stat.st_mtime;
-
- yyin = f;
- l = 0;
- for (; (l = yylex()) != 0; ) {
- switch (l) {
- case RCT_MODE_VAR:
- if (_rcfg->rcfg_mode_name != NULL)
- parse_err(name, "RCAPD_MODE already set\n");
- CFG_EXPECT(RCT_EQUALS, "Expecting '='\n");
- l = yylex();
- if (l == RCT_PROJECT) {
- _rcfg->rcfg_mode = rctype_project;
- _rcfg->rcfg_mode_name = "project";
- } else if (l == RCT_LNODE) {
- /*
- * Provided for compatibility with old
- * configuration files. The consumer is
- * expected to warn that the mode setting is
- * ineffective when anything other than
- * "project" is specified.
- */
- _rcfg->rcfg_mode_name = "lnode";
- } else
- parse_err(name, "RCAPD_MODE must be "
- "\"project\", and is unused.\n");
- debug("%s: mode: %s\n", name,
- _rcfg->rcfg_mode_name);
- break;
- case RCT_STATE:
- /* legacy variable is ignored */
- CFG_EXPECT(RCT_EQUALS, "Expecting '='\n");
- l = yylex();
- debug("%s: state ignored\n", name);
- break;
- case RCT_REPORT_INTERVAL_VAR:
- CFG_EXPECT(RCT_EQUALS, "Expecting '='\n");
- CFG_EXPECT(RCT_NUMBER, "Expecting time value "
- "(seconds)\n");
- _rcfg->rcfg_report_interval = atoi(yytext);
- debug("%s: report interval: %d seconds\n", name,
- _rcfg->rcfg_report_interval);
- break;
- case RCT_RSS_SAMPLE_INTERVAL_VAR:
- CFG_EXPECT(RCT_EQUALS, "Expecting '='\n");
- CFG_EXPECT(RCT_NUMBER, "Expecting time value "
- "(seconds)\n");
- _rcfg->rcfg_rss_sample_interval = atoi(yytext);
- debug("%s: RSS sample interval: %d seconds\n", name,
- _rcfg->rcfg_rss_sample_interval);
- break;
- case RCT_STAT_FILE_VAR:
- CFG_EXPECT(RCT_EQUALS, "Expecting '='\n");
- CFG_EXPECT(RCT_FILENAME, "Expecting filename\n");
- if (strlen(yytext) >= sizeof (_rcfg->rcfg_stat_file))
- parse_err(name, "Path too long");
- if (yytext[0] != '/')
- parse_err(name, "Path not absolute");
- (void) strcpy(_rcfg->rcfg_stat_file, yytext);
- debug("%s: statistics file: %s\n", name, _rcfg->rcfg_stat_file);
- break;
- case RCT_RECONFIGURATION_INTERVAL_VAR:
- CFG_EXPECT(RCT_EQUALS, "Expecting '='\n");
- CFG_EXPECT(RCT_NUMBER, "Expecting time value "
- "(seconds)\n");
- _rcfg->rcfg_reconfiguration_interval = atoi(yytext);
- debug("%s: reconfiguration interval: %d seconds\n",
- name, _rcfg->rcfg_reconfiguration_interval);
- break;
- case RCT_PROC_WALK_INTERVAL_VAR:
- CFG_EXPECT(RCT_EQUALS, "Expecting '='\n");
- CFG_EXPECT(RCT_NUMBER, "Expecting time value "
- "(seconds)\n");
- _rcfg->rcfg_proc_walk_interval = atoi(yytext);
- debug("%s: proc_walk interval: %d seconds\n",
- name, _rcfg->rcfg_proc_walk_interval);
- break;
- case RCT_MEMORY_CAP_ENFORCEMENT_PRESSURE_VAR:
- CFG_EXPECT(RCT_EQUALS, "Expecting '='\n");
- CFG_EXPECT(RCT_NUMBER, "Expecting integer value (%)\n");
- if ((_rcfg->rcfg_memory_cap_enforcement_pressure =
- atoi(yytext)) < 0)
- _rcfg->rcfg_memory_cap_enforcement_pressure = 0;
- debug("%s: cap max pressure: %d%%\n", name,
- _rcfg->rcfg_memory_cap_enforcement_pressure);
- break;
- default:
- parse_err(name, "Unexpected input: %s\n", yytext);
- }
- }
- if (_rcfg->rcfg_mode_name == NULL) {
- /*
- * Set project mode, by default.
- */
- _rcfg->rcfg_mode = rctype_project;
- _rcfg->rcfg_mode_name = "project";
- debug("%s: mode: %s\n", name, _rcfg->rcfg_mode_name);
- }
- if (verify_stat_file_creation != 0 && verify_stat_file_creation() != 0)
- die(gettext("cannot create statistics file, " "%s"),
- _rcfg->rcfg_stat_file);
- debug("%s: done parsing\n", name);
-
- return (0);
-}
-
-void
-rcfg_init(rcfg_t *rcfg)
-{
- bzero(rcfg, sizeof (*rcfg));
- rcfg->rcfg_proc_walk_interval = 15;
- rcfg->rcfg_reconfiguration_interval = 60;
- rcfg->rcfg_report_interval = 5;
- rcfg->rcfg_rss_sample_interval = 5;
- rcfg->rcfg_memory_cap_enforcement_pressure = 0;
- (void) strcpy(rcfg->rcfg_stat_file, STAT_FILE_DEFAULT);
-}
-
-/*
- * Create the configuration file given the rcfg_t structure. If a rcfg_t
- * structure is NULL, create the configuration file with default parameters.
- */
-void
-create_config_file(rcfg_t *conf)
-{
- char *fname = RCAPD_DEFAULT_CONF_FILE;
- char *template;
- FILE *fp;
- mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
- int fd, olderrno, create_default = 0;
-
- if (conf == NULL) {
- create_default = 1;
- if ((conf = malloc(sizeof (*conf))) == NULL)
- die(gettext("memory allocation failure"));
-
- /* Initialize config file with default parameters */
- rcfg_init(conf);
- conf->rcfg_mode_name = "project";
- }
-
- if ((template = malloc(strlen(fname) +
- strlen(CFG_TEMPLATE_SUFFIX) + 1)) == NULL)
- die(gettext("memory allocation failure"));
-
- (void) strcpy(template, fname);
- (void) strcat(template, CFG_TEMPLATE_SUFFIX);
-
- if ((fd = mkstemp(template)) < 0)
- die(gettext("failed to create a temporary file %s"),
- template);
-
- if ((fp = fdopen(fd, "w")) == NULL) {
- olderrno = errno;
- (void) close(fd);
- if (unlink(template) < 0)
- warn(gettext("could not unlink temp file %s"),
- template);
- errno = olderrno;
- die(gettext("Failed to open output file %s"), template);
- }
-
- (void) fputs("#\n# rcap.conf\n#\n"
- "# Configuration parameters for resource capping daemon.\n"
- "# Do NOT edit by hand -- use rcapadm(1m) instead.\n"
- "#\n", fp);
- (void) fprintf(fp, "RCAPD_MEMORY_CAP_ENFORCEMENT_PRESSURE "
- "= %d\n", conf->rcfg_memory_cap_enforcement_pressure);
- (void) fprintf(fp, "RCAPD_RECONFIGURATION_INTERVAL "
- "= %d\n", conf->rcfg_reconfiguration_interval);
- (void) fprintf(fp, "RCAPD_PROC_WALK_INTERVAL "
- "= %d\n", conf->rcfg_proc_walk_interval);
- (void) fprintf(fp, "RCAPD_REPORT_INTERVAL "
- "= %d\n", conf->rcfg_report_interval);
- (void) fprintf(fp, "RCAPD_RSS_SAMPLE_INTERVAL "
- "= %d\n", conf->rcfg_rss_sample_interval);
-
- if (fchmod(fd, mode) != 0) {
- olderrno = errno;
- (void) fclose(fp);
- if (unlink(template) < 0)
- warn(gettext("could not unlink temp file %s"),
- template);
- errno = olderrno;
- die(gettext("failed to fchmod %s to %o"), template, mode);
- }
-
- if (rename(template, fname) != 0) {
- olderrno = errno;
- (void) fclose(fp);
- if (unlink(template) < 0)
- warn(gettext("could not unlink temp file %s"),
- template);
- errno = olderrno;
- die(gettext("could not rename temporary file to %s"), fname);
- }
-
- (void) fclose(fp);
- free(template);
-
- if (create_default == 1)
- free(conf);
-}
diff --git a/usr/src/cmd/rcap/rcapadm/Makefile b/usr/src/cmd/rcap/rcapadm/Makefile
index 3b4de32953..e88a65ecdf 100644
--- a/usr/src/cmd/rcap/rcapadm/Makefile
+++ b/usr/src/cmd/rcap/rcapadm/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -40,7 +40,7 @@ LINTSRCS = $(COMMON_DIR)/utils.c \
$(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG
CPPFLAGS += -I$(COMMON_DIR)
-LDLIBS += -lumem -ll -lscf -lzonecfg
+LDLIBS += -lumem -lscf -lzonecfg
LINTFLAGS += $(LDLIBS) -mnu
diff --git a/usr/src/cmd/rcap/rcapadm/rcapadm.c b/usr/src/cmd/rcap/rcapadm/rcapadm.c
index 1951682283..f8e6269221 100644
--- a/usr/src/cmd/rcap/rcapadm/rcapadm.c
+++ b/usr/src/cmd/rcap/rcapadm/rcapadm.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,8 +47,6 @@
#include "rcapd_conf.h"
#include "rcapd_stat.h"
-#define RCAP_FMRI "system/rcap:default"
-
static void
usage()
{
@@ -78,7 +76,6 @@ static int scan_interval = -1;
static int report_interval = -1;
static int config_interval = -1;
static int sample_interval = -1;
-static char *fname = RCAPD_DEFAULT_CONF_FILE;
static char *subopt_v[] = {
"scan",
@@ -134,6 +131,17 @@ out:
"state: %s\n"), *persistent ? gettext("enabled") :
gettext("disabled"));
+ (void) printf(gettext(" memory cap enforcement"
+ " threshold: %d%%\n"), conf.rcfg_memory_cap_enforcement_pressure);
+ (void) printf(gettext(" process scan rate"
+ " (sec): %d\n"), conf.rcfg_proc_walk_interval);
+ (void) printf(gettext(" reconfiguration rate"
+ " (sec): %d\n"), conf.rcfg_reconfiguration_interval);
+ (void) printf(gettext(" report rate"
+ " (sec): %d\n"), conf.rcfg_report_interval);
+ (void) printf(gettext(" RSS sampling rate"
+ " (sec): %d\n"), conf.rcfg_rss_sample_interval);
+
scf_simple_prop_free(temporary_prop);
scf_simple_prop_free(persistent_prop);
scf_handle_destroy(h);
@@ -201,12 +209,10 @@ main(int argc, char *argv[])
case 'E':
enable = 1;
disable = 0;
- modified++;
break;
case 'D':
disable = 1;
enable = 0;
- modified++;
break;
case 'i':
subopts = optarg;
@@ -263,19 +269,37 @@ main(int argc, char *argv[])
if (refresh && (no_starting_stopping > 0 || modified))
usage();
- if (rcfg_read(fname, -1, &conf, NULL) < 0) {
- if (!(errno == ENOENT && modified)) {
- die(gettext("resource caps not configured\n"));
- return (E_ERROR);
- }
- rcfg_init(&conf);
- conf.rcfg_mode_name = "project";
- } else {
+ /*
+ * disable/enable before reading configuration from the repository
+ * which may fail and prevents the disabling/enabling to complete.
+ */
+ if (disable > 0) {
+ if (smf_disable_instance(RCAP_FMRI, no_starting_stopping > 0
+ ? SMF_AT_NEXT_BOOT : 0) != 0)
+ die(gettext("cannot disable service: %s\n"),
+ scf_strerror(scf_error()));
+ }
+
+ if (enable > 0) {
+ if (smf_enable_instance(RCAP_FMRI, no_starting_stopping > 0
+ ? SMF_AT_NEXT_BOOT : 0) != 0)
+ die(gettext("cannot enable service: %s\n"),
+ scf_strerror(scf_error()));
+ }
+
+ if (rcfg_read(&conf, NULL) != E_SUCCESS) {
/*
- * The configuration file has been read. Warn that any lnode
- * (or non-project) mode specification (by an SRM
- * 1.3 configuration file, for example) is ignored.
+ * If instance is enabled, put it in maintenance since we
+ * failed to read configuration from the repository or
+ * create statistics file.
*/
+ if (strcmp(smf_get_state(RCAP_FMRI),
+ SCF_STATE_STRING_DISABLED) != 0)
+ (void) smf_maintain_instance(RCAP_FMRI, 0);
+
+ die(gettext("resource caps not configured\n"));
+ } else {
+ /* Done reading configuration */
if (strcmp(conf.rcfg_mode_name, "project") != 0) {
warn(gettext("%s mode specification ignored -- using"
" project mode\n"), conf.rcfg_mode_name);
@@ -300,37 +324,20 @@ main(int argc, char *argv[])
conf.rcfg_rss_sample_interval = sample_interval;
/*
- * Create config file with the new parameter(s). The
- * create_config_file will exit if it fails.
+ * Modify configuration with the new parameter(s). The
+ * function will exit if it fails.
*/
- create_config_file(&conf);
+ if ((modify_config(&conf)) != 0)
+ die(gettext("Error updating repository \n"));
- if (enable > 0 && smf_enable_instance(RCAP_FMRI,
- no_starting_stopping > 0 ? SMF_AT_NEXT_BOOT : 0) != 0)
- die(gettext("cannot enable service: %s\n"),
- scf_strerror(scf_error()));
- else if (disable > 0 && smf_disable_instance(RCAP_FMRI,
- no_starting_stopping > 0 ? SMF_AT_NEXT_BOOT : 0) != 0)
- die(gettext("cannot disable service: %s\n"),
+ if (smf_refresh_instance(RCAP_FMRI) != 0)
+ die(gettext("cannot refresh service: %s\n"),
scf_strerror(scf_error()));
-
- return (E_SUCCESS);
}
/*
* Display current configuration
*/
print_state();
- (void) printf(gettext(" memory cap enforcement"
- " threshold: %d%%\n"), conf.rcfg_memory_cap_enforcement_pressure);
- (void) printf(gettext(" process scan rate"
- " (sec): %d\n"), conf.rcfg_proc_walk_interval);
- (void) printf(gettext(" reconfiguration rate"
- " (sec): %d\n"), conf.rcfg_reconfiguration_interval);
- (void) printf(gettext(" report rate"
- " (sec): %d\n"), conf.rcfg_report_interval);
- (void) printf(gettext(" RSS sampling rate"
- " (sec): %d\n"), conf.rcfg_rss_sample_interval);
-
return (E_SUCCESS);
}
diff --git a/usr/src/cmd/rcap/rcapd/Makefile.rcapd b/usr/src/cmd/rcap/rcapd/Makefile.rcapd
index 716ea41e38..f0ff0e0669 100644
--- a/usr/src/cmd/rcap/rcapd/Makefile.rcapd
+++ b/usr/src/cmd/rcap/rcapd/Makefile.rcapd
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -55,7 +55,7 @@ LINTSRCS = ../rcapd_main.c \
$(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG
CPPFLAGS += -DDEBUG_MSG
CPPFLAGS += -I$(COMMON_DIR)
-LDLIBS += -lkstat -ll -lproc -lproject -lzonecfg -lumem
+LDLIBS += -lkstat -lproc -lproject -lzonecfg -lumem -lscf
LDLIBS += $(EXTRA_LDLIBS)
LINTFLAGS += -u
diff --git a/usr/src/cmd/rcap/rcapd/rcap.xml b/usr/src/cmd/rcap/rcapd/rcap.xml
index 957643a361..41fae6decf 100644
--- a/usr/src/cmd/rcap/rcapd/rcap.xml
+++ b/usr/src/cmd/rcap/rcapd/rcap.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<!--
- Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ Copyright 2007 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
CDDL HEADER START
@@ -38,8 +38,6 @@
type='service'
version='1'>
- <create_default_instance enabled='false' />
-
<single_instance />
<dependency
@@ -50,6 +48,14 @@
<service_fmri value='svc:/system/filesystem/minimal' />
</dependency>
+ <dependency
+ name='manifest'
+ type='service'
+ grouping='optional_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/manifest-import' />
+ </dependency>
+
<dependent
name='rcap_multi-user'
grouping='optional_all'
@@ -57,6 +63,8 @@
<service_fmri value='svc:/milestone/multi-user' />
</dependent>
+ <instance name='default' enabled='false'>
+
<exec_method
type='method'
name='start'
@@ -79,6 +87,16 @@
exec=':kill'
timeout_seconds='60' />
+ <property_group name='config' type='application'>
+ <propval name='pressure' type='count' value='0' />
+ <propval name='reconfig_interval' type='count' value='60' />
+ <propval name='walk_interval' type='count' value='15' />
+ <propval name='report_interval' type='count' value='5' />
+ <propval name='rss_sample_interval' type='count' value='5' />
+ </property_group>
+
+ </instance>
+
<stability value='Unstable' />
<template>
diff --git a/usr/src/cmd/rcap/rcapd/rcapd_main.c b/usr/src/cmd/rcap/rcapd/rcapd_main.c
index 960065826e..bb0a13f129 100644
--- a/usr/src/cmd/rcap/rcapd/rcapd_main.c
+++ b/usr/src/cmd/rcap/rcapd/rcapd_main.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -56,6 +56,7 @@
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
+#include <libscf.h>
#include <strings.h>
#include <time.h>
#include <unistd.h>
@@ -937,24 +938,19 @@ finish_configuration(void)
}
/*
- * Cause the configuration file to be reread and applied.
+ * Cause the configuration to be reread and applied.
*/
static void
-reread_configuration_file(void)
+reread_configuration(void)
{
rcfg_t rcfg_new;
- struct stat st;
- if (stat(rcfg.rcfg_filename, &st) == 0 && st.st_mtime ==
- rcfg.rcfg_last_modification)
- return;
-
- if (rcfg_read(rcfg.rcfg_filename, rcfg.rcfg_fd, &rcfg_new,
- update_statistics) != 0)
- warn(gettext("can't reread configuration"));
- else {
+ if (rcfg_read(&rcfg_new, update_statistics) != E_SUCCESS) {
+ warn(gettext("can't reread configuration \n"));
+ exit(SMF_EXIT_ERR_CONFIG);
+ } else {
/*
- * The configuration file has been read. Remove existing
+ * Done reading configuration. Remove existing
* collections in case there is a change in collection type.
*/
if (rcfg.rcfg_mode != rcfg_new.rcfg_mode) {
@@ -972,8 +968,8 @@ reread_configuration_file(void)
}
/*
- * Reread the configuration filex, then examine changes, additions, and
- * deletions to cap definitions.
+ * First, examine changes, additions, and deletions to cap definitions.
+ * Then, set the next event time.
*/
static void
reconfigure(hrtime_t now, hrtime_t *next_configuration,
@@ -982,11 +978,6 @@ reconfigure(hrtime_t now, hrtime_t *next_configuration,
debug("reconfigure...\n");
/*
- * Reread the configuration data.
- */
- reread_configuration_file();
-
- /*
* Walk the lcollection, marking active collections so inactive ones
* can be freed.
*/
@@ -1021,7 +1012,7 @@ reconfigure(hrtime_t now, hrtime_t *next_configuration,
}
/*
- * Respond to SIGHUP by triggering the rereading the configuration file and cap
+ * Respond to SIGHUP by triggering the rereading the configuration and cap
* definitions.
*/
/*ARGSUSED*/
@@ -1488,6 +1479,14 @@ main(int argc, char *argv[])
}
/*
+ * Read the configuration.
+ */
+ if (rcfg_read(&rcfg, verify_statistics) != E_SUCCESS) {
+ warn(gettext("resource caps not configured\n"));
+ return (SMF_EXIT_ERR_CONFIG);
+ }
+
+ /*
* If not debugging, fork and continue operating, changing the
* destination of messages to syslog().
*/
@@ -1514,27 +1513,6 @@ main(int argc, char *argv[])
"terminal"));
}
- /*
- * Read the configuration file.
- */
- if (rcfg_read(RCAPD_DEFAULT_CONF_FILE, -1, &rcfg, verify_statistics)
- != 0) {
- /*
- * A configuration file may not exist if rcapd is started
- * by enabling the smf rcap service, so attempt to create
- * a default file.
- */
- create_config_file(NULL);
-
- /*
- * A real failure if still can't read the
- * configuration file
- */
- if (rcfg_read(RCAPD_DEFAULT_CONF_FILE, -1, &rcfg,
- verify_statistics) != 0)
- die(gettext("resource caps not configured %s"),
- RCAPD_DEFAULT_CONF_FILE);
- }
finish_configuration();
should_reconfigure = 0;
@@ -1636,14 +1614,20 @@ main(int argc, char *argv[])
now = gethrtime();
/*
- * Detect configuration and cap changes at every
- * reconfiguration_interval, or when SIGHUP has been received.
+ * Detect configuration and cap changes only when SIGHUP
+ * is received. Call reconfigure to apply new configuration
+ * parameters.
*/
- if (EVENT_TIME(now, next_configuration) ||
- should_reconfigure == 1) {
+ if (should_reconfigure == 1) {
+ reread_configuration();
+ should_reconfigure = 0;
+ reconfigure(now, &next_configuration, &next_proc_walk,
+ &next_rss_sample);
+ }
+
+ if (EVENT_TIME(now, next_configuration)) {
reconfigure(now, &next_configuration, &next_proc_walk,
&next_rss_sample);
- should_reconfigure = 0;
}
/*
diff --git a/usr/src/cmd/rcap/rcapstat/Makefile b/usr/src/cmd/rcap/rcapstat/Makefile
index fb436f5684..e9959c4ef7 100644
--- a/usr/src/cmd/rcap/rcapstat/Makefile
+++ b/usr/src/cmd/rcap/rcapstat/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -38,7 +38,7 @@ LINTSRCS = $(COMMON_DIR)/utils.c \
$(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG
CPPFLAGS += -I$(COMMON_DIR)
-LDLIBS += -lumem -ll -lzonecfg
+LDLIBS += -lumem -lzonecfg -lscf
LINTFLAGS += $(LDLIBS) -mnu
diff --git a/usr/src/lib/libscf/common/mapfile-vers b/usr/src/lib/libscf/common/mapfile-vers
index 9de9678dd5..7ce168681a 100644
--- a/usr/src/lib/libscf/common/mapfile-vers
+++ b/usr/src/lib/libscf/common/mapfile-vers
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -225,6 +225,12 @@ SUNWprivate_1.1 {
scf_type_to_string;
scf_walk_fmri;
_smf_refresh_instance_i;
+ scf_general_pg_setup;
+ scf_transaction_setup;
+ scf_transaction_restart;
+ scf_read_count_property;
+ scf_set_count_property;
+ scf_simple_handle_destroy;
gen_filenms_from_fmri;
local:
*;
diff --git a/usr/src/lib/libscf/common/midlevel.c b/usr/src/lib/libscf/common/midlevel.c
index 2629abfdd8..a9cc196816 100644
--- a/usr/src/lib/libscf/common/midlevel.c
+++ b/usr/src/lib/libscf/common/midlevel.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,6 +36,7 @@
#include <errno.h>
#include <libgen.h>
#include "midlevel_impl.h"
+#include "lowlevel_impl.h"
#ifndef NDEBUG
#define bad_error(func, err) { \
@@ -69,6 +70,20 @@ handle_create(void)
return (h);
}
+void
+scf_simple_handle_destroy(scf_simple_handle_t *simple_h)
+{
+ if (simple_h == NULL)
+ return;
+
+ scf_pg_destroy(simple_h->running_pg);
+ scf_pg_destroy(simple_h->editing_pg);
+ scf_snapshot_destroy(simple_h->snap);
+ scf_instance_destroy(simple_h->inst);
+ scf_handle_destroy(simple_h->h);
+ uu_free(simple_h);
+}
+
/*
* Given a base service FMRI and the names of a property group and property,
* assemble_fmri() merges them into a property FMRI. Note that if the base
@@ -1075,6 +1090,52 @@ out:
return (ret);
}
+/*
+ * Create and return a pg from the instance associated with the given handle.
+ * This function is only called in scf_transaction_setup and
+ * scf_transaction_restart where the h->rh_instance pointer is properly filled
+ * in by scf_general_setup_pg().
+ */
+static scf_propertygroup_t *
+get_instance_pg(scf_simple_handle_t *simple_h)
+{
+ scf_propertygroup_t *ret_pg = scf_pg_create(simple_h->h);
+ char *pg_name;
+ ssize_t namelen;
+
+ if (ret_pg == NULL) {
+ return (NULL);
+ }
+
+ if ((namelen = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH)) == -1) {
+ if (scf_error() == SCF_ERROR_NOT_SET) {
+ (void) scf_set_error(SCF_ERROR_INTERNAL);
+ }
+ return (NULL);
+ }
+
+ if ((pg_name = malloc(namelen)) == NULL) {
+ if (scf_error() == SCF_ERROR_NOT_SET) {
+ (void) scf_set_error(SCF_ERROR_NO_MEMORY);
+ }
+ return (NULL);
+ }
+
+ if (scf_pg_get_name(simple_h->running_pg, pg_name, namelen) < 0) {
+ if (scf_error() == SCF_ERROR_NOT_SET) {
+ (void) scf_set_error(SCF_ERROR_INTERNAL);
+ }
+ return (NULL);
+ }
+
+ /* Get pg from instance */
+ if (scf_instance_get_pg(simple_h->inst, pg_name, ret_pg) == -1) {
+ return (NULL);
+ }
+
+ return (ret_pg);
+}
+
int
smf_enable_instance(const char *fmri, int flags)
{
@@ -1199,6 +1260,268 @@ smf_get_state(const char *instance)
return (ret);
}
+/*
+ * scf_general_pg_setup(fmri, pg_name)
+ * Create a scf_simple_handle_t and fill in the instance, snapshot, and
+ * property group fields associated with the given fmri and property group
+ * name.
+ * Returns:
+ * Handle on success
+ * Null on error with scf_error set to:
+ * SCF_ERROR_HANDLE_MISMATCH,
+ * SCF_ERROR_INVALID_ARGUMENT,
+ * SCF_ERROR_CONSTRAINT_VIOLATED,
+ * SCF_ERROR_NOT_FOUND,
+ * SCF_ERROR_NOT_SET,
+ * SCF_ERROR_DELETED,
+ * SCF_ERROR_NOT_BOUND,
+ * SCF_ERROR_CONNECTION_BROKEN,
+ * SCF_ERROR_INTERNAL,
+ * SCF_ERROR_NO_RESOURCES,
+ * SCF_ERROR_BACKEND_ACCESS
+ */
+scf_simple_handle_t *
+scf_general_pg_setup(const char *fmri, const char *pg_name)
+{
+ scf_simple_handle_t *ret;
+
+ ret = uu_zalloc(sizeof (*ret));
+ if (ret == NULL) {
+ (void) scf_set_error(SCF_ERROR_NO_MEMORY);
+ return (NULL);
+ } else {
+
+ ret->h = handle_create();
+ ret->inst = scf_instance_create(ret->h);
+ ret->snap = scf_snapshot_create(ret->h);
+ ret->running_pg = scf_pg_create(ret->h);
+ }
+
+ if ((ret->h == NULL) || (ret->inst == NULL) ||
+ (ret->snap == NULL) || (ret->running_pg == NULL)) {
+ goto out;
+ }
+
+ if (scf_handle_decode_fmri(ret->h, fmri, NULL, NULL, ret->inst,
+ NULL, NULL, NULL) == -1) {
+ goto out;
+ }
+
+ if ((scf_instance_get_snapshot(ret->inst, "running", ret->snap))
+ != 0) {
+ goto out;
+ }
+
+ if (scf_instance_get_pg_composed(ret->inst, ret->snap, pg_name,
+ ret->running_pg) != 0) {
+ goto out;
+ }
+
+ return (ret);
+
+out:
+ scf_simple_handle_destroy(ret);
+ return (NULL);
+}
+
+/*
+ * scf_transaction_setup(h)
+ * creates and starts the transaction
+ * Returns:
+ * transaction on success
+ * NULL on failure with scf_error set to:
+ * SCF_ERROR_NO_MEMORY,
+ * SCF_ERROR_INVALID_ARGUMENT,
+ * SCF_ERROR_HANDLE_DESTROYED,
+ * SCF_ERROR_INTERNAL,
+ * SCF_ERROR_NO_RESOURCES,
+ * SCF_ERROR_NOT_BOUND,
+ * SCF_ERROR_CONNECTION_BROKEN,
+ * SCF_ERROR_NOT_SET,
+ * SCF_ERROR_DELETED,
+ * SCF_ERROR_CONSTRAINT_VIOLATED,
+ * SCF_ERROR_HANDLE_MISMATCH,
+ * SCF_ERROR_BACKEND_ACCESS,
+ * SCF_ERROR_IN_USE
+ */
+scf_transaction_t *
+scf_transaction_setup(scf_simple_handle_t *simple_h)
+{
+ scf_transaction_t *tx = NULL;
+
+ if ((tx = scf_transaction_create(simple_h->h)) == NULL) {
+ return (NULL);
+ }
+
+ if ((simple_h->editing_pg = get_instance_pg(simple_h)) == NULL) {
+ return (NULL);
+ }
+
+ if (scf_transaction_start(tx, simple_h->editing_pg) == -1) {
+ scf_pg_destroy(simple_h->editing_pg);
+ simple_h->editing_pg = NULL;
+ return (NULL);
+ }
+
+ return (tx);
+}
+
+int
+scf_transaction_restart(scf_simple_handle_t *simple_h, scf_transaction_t *tx)
+{
+ scf_transaction_reset(tx);
+
+ if (scf_pg_update(simple_h->editing_pg) == -1) {
+ return (SCF_FAILED);
+ }
+
+ if (scf_transaction_start(tx, simple_h->editing_pg) == -1) {
+ return (SCF_FAILED);
+ }
+
+ return (SCF_SUCCESS);
+}
+
+/*
+ * scf_read_count_property(scf_simple_handle_t *simple_h, char *prop_name,
+ * uint64_t *ret_count)
+ *
+ * For the given property name, return the count value.
+ * RETURNS:
+ * SCF_SUCCESS
+ * SCF_FAILED on failure with scf_error() set to:
+ * SCF_ERROR_HANDLE_DESTROYED
+ * SCF_ERROR_INTERNAL
+ * SCF_ERROR_NO_RESOURCES
+ * SCF_ERROR_NO_MEMORY
+ * SCF_ERROR_HANDLE_MISMATCH
+ * SCF_ERROR_INVALID_ARGUMENT
+ * SCF_ERROR_NOT_BOUND
+ * SCF_ERROR_CONNECTION_BROKEN
+ * SCF_ERROR_NOT_SET
+ * SCF_ERROR_DELETED
+ * SCF_ERROR_BACKEND_ACCESS
+ * SCF_ERROR_CONSTRAINT_VIOLATED
+ * SCF_ERROR_TYPE_MISMATCH
+ */
+int
+scf_read_count_property(
+ scf_simple_handle_t *simple_h,
+ char *prop_name,
+ uint64_t *ret_count)
+{
+ scf_property_t *prop = scf_property_create(simple_h->h);
+ scf_value_t *val = scf_value_create(simple_h->h);
+ int ret = SCF_FAILED;
+
+ if ((val == NULL) || (prop == NULL)) {
+ goto out;
+ }
+
+ /*
+ * Get the property struct that goes with this property group and
+ * property name.
+ */
+ if (scf_pg_get_property(simple_h->running_pg, prop_name, prop) != 0) {
+ goto out;
+ }
+
+ /* Get the value structure */
+ if (scf_property_get_value(prop, val) == -1) {
+ goto out;
+ }
+
+ /*
+ * Now get the count value.
+ */
+ if (scf_value_get_count(val, ret_count) == -1) {
+ goto out;
+ }
+
+ ret = SCF_SUCCESS;
+
+out:
+ scf_property_destroy(prop);
+ scf_value_destroy(val);
+ return (ret);
+}
+
+/*
+ * scf_trans_add_count_property(trans, propname, count, create_flag)
+ *
+ * Set a count property transaction entry into the pending SMF transaction.
+ * The transaction is created and committed outside of this function.
+ * Returns:
+ * SCF_SUCCESS
+ * SCF_FAILED on failure with scf_error() set to:
+ * SCF_ERROR_HANDLE_DESTROYED,
+ * SCF_ERROR_INVALID_ARGUMENT,
+ * SCF_ERROR_NO_MEMORY,
+ * SCF_ERROR_HANDLE_MISMATCH,
+ * SCF_ERROR_NOT_SET,
+ * SCF_ERROR_IN_USE,
+ * SCF_ERROR_NOT_FOUND,
+ * SCF_ERROR_EXISTS,
+ * SCF_ERROR_TYPE_MISMATCH,
+ * SCF_ERROR_NOT_BOUND,
+ * SCF_ERROR_CONNECTION_BROKEN,
+ * SCF_ERROR_INTERNAL,
+ * SCF_ERROR_DELETED,
+ * SCF_ERROR_NO_RESOURCES,
+ * SCF_ERROR_BACKEND_ACCESS
+ */
+int
+scf_set_count_property(
+ scf_transaction_t *trans,
+ char *propname,
+ uint64_t count,
+ boolean_t create_flag)
+{
+ scf_handle_t *handle = scf_transaction_handle(trans);
+ scf_value_t *value = scf_value_create(handle);
+ scf_transaction_entry_t *entry = scf_entry_create(handle);
+
+ if ((value == NULL) || (entry == NULL)) {
+ return (SCF_FAILED);
+ }
+
+ /*
+ * Property must be set in transaction and won't take
+ * effect until the transaction is committed.
+ *
+ * Attempt to change the current value. However, create new property
+ * if it doesn't exist and the create flag is set.
+ */
+ if (scf_transaction_property_change(trans, entry, propname,
+ SCF_TYPE_COUNT) == 0) {
+ scf_value_set_count(value, count);
+ if (scf_entry_add_value(entry, value) == 0) {
+ return (SCF_SUCCESS);
+ }
+ } else {
+ if ((create_flag == B_TRUE) &&
+ (scf_error() == SCF_ERROR_NOT_FOUND)) {
+ if (scf_transaction_property_new(trans, entry, propname,
+ SCF_TYPE_COUNT) == 0) {
+ scf_value_set_count(value, count);
+ if (scf_entry_add_value(entry, value) == 0) {
+ return (SCF_SUCCESS);
+ }
+ }
+ }
+ }
+
+ /*
+ * cleanup if there were any errors that didn't leave these
+ * values where they would be cleaned up later.
+ */
+ if (value != NULL)
+ scf_value_destroy(value);
+ if (entry != NULL)
+ scf_entry_destroy(entry);
+ return (SCF_FAILED);
+}
+
int
scf_simple_walk_instances(uint_t state_flags, void *private,
int (*inst_callback)(scf_handle_t *, scf_instance_t *, void *))
diff --git a/usr/src/lib/libscf/inc/libscf_priv.h b/usr/src/lib/libscf/inc/libscf_priv.h
index f4d01f0324..a9b3e273f5 100644
--- a/usr/src/lib/libscf/inc/libscf_priv.h
+++ b/usr/src/lib/libscf/inc/libscf_priv.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -193,6 +193,21 @@ scf_type_t scf_string_to_type(const char *);
int _smf_refresh_instance_i(scf_instance_t *);
+typedef struct scf_simple_handle {
+ scf_handle_t *h;
+ scf_snapshot_t *snap;
+ scf_instance_t *inst;
+ scf_propertygroup_t *running_pg;
+ scf_propertygroup_t *editing_pg;
+} scf_simple_handle_t;
+
+void scf_simple_handle_destroy(scf_simple_handle_t *);
+scf_simple_handle_t *scf_general_pg_setup(const char *, const char *);
+scf_transaction_t *scf_transaction_setup(scf_simple_handle_t *);
+int scf_transaction_restart(scf_simple_handle_t *, scf_transaction_t *);
+int scf_read_count_property(scf_simple_handle_t *, char *, uint64_t *);
+int scf_set_count_property(scf_transaction_t *, char *, uint64_t, boolean_t);
+
/*
* Walks all the instances matching a given fmri list. Each fmri in the array
* can be one of the following:
diff --git a/usr/src/pkgdefs/SUNWrcapr/postinstall b/usr/src/pkgdefs/SUNWrcapr/postinstall
index 0b4d1d3faa..89507280f8 100644
--- a/usr/src/pkgdefs/SUNWrcapr/postinstall
+++ b/usr/src/pkgdefs/SUNWrcapr/postinstall
@@ -19,21 +19,89 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
#
+SVCADM="/usr/sbin/svcadm"
+SVCCFG="/usr/sbin/svccfg"
+SVCPROP="/bin/svcprop"
+PG="config"
+RCAP_CONF="${PKG_INSTALL_ROOT}/etc/rcap.conf"
+RCAP_FMRI="svc:/system/rcap:default"
+PROFILE_UPGRADE="${PKG_INSTALL_ROOT}/var/svc/profile/upgrade"
+
#
-# If appropriate, enable this service. We know the service should be
-# enabled if the TMPFILE created by preinstall exists.
+# If appropriate, enable this service. If /etc/rcap.conf exists,
+# migrate the existing configuration values regardless of whether
+# or not rcapd was enabled.
#
BASEPREFIX=`echo $BASEDIR | tr '/' '_'`
FILENAME=`echo sunwrcapr"$BASEPREFIX" | cut -c 1-256`
TMPFILE=/tmp/$FILENAME
if [ -f $TMPFILE ]; then
- echo "/usr/sbin/svcadm enable system/rcap" >> \
- ${PKG_INSTALL_ROOT}/var/svc/profile/upgrade
+ echo "$SVCADM enable $RCAP_FMRI" >> $PROFILE_UPGRADE
+
rm $TMPFILE
fi
+
+#
+# Reads existing configuration values in /etc/rcap.conf and puts
+# them in repository upon reboot(via /var/svc/profile/upgrade).
+#
+migrate_rcap_conf()
+{
+ pressure=`awk '$1 == "RCAPD_MEMORY_CAP_ENFORCEMENT_PRESSURE" \
+ && NF == 3 {print $3}' $RCAP_CONF`
+
+ reconfig_int=`awk '$1 == "RCAPD_RECONFIGURATION_INTERVAL" \
+ && NF == 3 {print $3}' $RCAP_CONF`
+
+ walk_int=`awk '$1 == "RCAPD_PROC_WALK_INTERVAL" && \
+ NF == 3 {print $3}' $RCAP_CONF`
+
+ report_int=`awk '$1 == "RCAPD_REPORT_INTERVAL" && \
+ NF == 3 {print $3}' $RCAP_CONF`
+
+ rss_sample_int=`awk '$1 == "RCAPD_RSS_SAMPLE_INTERVAL" && \
+ NF == 3 {print $3}' $RCAP_CONF`
+
+ # Update default configuration values with
+ # pre-existing values
+ #
+ echo "# Migrating pre-existing rcap configuration" >> $PROFILE_UPGRADE
+
+ if [ -n "$pressure" ]; then
+ echo "$SVCCFG -s $RCAP_FMRI setprop ${PG}/pressure = " \
+ "$pressure" >> $PROFILE_UPGRADE
+ fi
+
+ if [ -n "$reconfig_int" ]; then
+ echo "$SVCCFG -s $RCAP_FMRI setprop ${PG}/reconfig_interval = " \
+ "$reconfig_int" >> $PROFILE_UPGRADE
+ fi
+
+ if [ -n "$walk_int" ]; then
+ echo "$SVCCFG -s $RCAP_FMRI setprop ${PG}/walk_interval = " \
+ "$walk_int" >> $PROFILE_UPGRADE
+ fi
+
+ if [ -n "$report_int" ]; then
+ echo "$SVCCFG -s $RCAP_FMRI setprop ${PG}/report_interval = " \
+ "$report_int" >> $PROFILE_UPGRADE
+ fi
+
+ if [ -n "$rss_sample_int" ]; then
+ echo "$SVCCFG -s $RCAP_FMRI setprop ${PG}/rss_sample_interval = " \
+ "$rss_sample_int" >> $PROFILE_UPGRADE
+ fi
+
+ echo "$SVCADM refresh $RCAP_FMRI" >> $PROFILE_UPGRADE
+ echo "rm /etc/rcap.conf" >> $PROFILE_UPGRADE
+}
+
+if [ -f $RCAP_CONF ]; then
+ migrate_rcap_conf
+fi
diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh
index 069b00606f..f44cd08721 100644
--- a/usr/src/tools/scripts/bfu.sh
+++ b/usr/src/tools/scripts/bfu.sh
@@ -840,6 +840,64 @@ add_devid_destroy() {
}
#
+# Reads existing configuration values in /etc/rcap.conf and puts
+# them in repository upon reboot(via /var/svc/profile/upgrade).
+#
+migrate_rcap_conf() {
+ RCAP_CONF="${rootprefix}/etc/rcap.conf"
+ PROFILE_UPGRADE="${rootprefix}/var/svc/profile/upgrade"
+ SVCCFG="/usr/sbin/svccfg"
+ RCAP_FMRI="svc:/system/rcap:default"
+ PG="config"
+
+ pressure=`awk '$1 == "RCAPD_MEMORY_CAP_ENFORCEMENT_PRESSURE" \
+ && NF == 3 {print $3}' $RCAP_CONF`
+
+ reconfig_int=`awk '$1 == "RCAPD_RECONFIGURATION_INTERVAL" \
+ && NF == 3 {print $3}' $RCAP_CONF`
+
+ walk_int=`awk '$1 == "RCAPD_PROC_WALK_INTERVAL" && \
+ NF == 3 {print $3}' $RCAP_CONF`
+
+ report_int=`awk '$1 == "RCAPD_REPORT_INTERVAL" && \
+ NF == 3 {print $3}' $RCAP_CONF`
+
+ rss_sample_int=`awk '$1 == "RCAPD_RSS_SAMPLE_INTERVAL" && \
+ NF == 3 {print $3}' $RCAP_CONF`
+
+ # Blindly update default configuration values with
+ # pre-existing values
+ #
+ echo "# Migrating pre-existing rcap configuration" >> \
+ $PROFILE_UPGRADE
+
+ echo "$SVCCFG -s $RCAP_FMRI setprop ${PG}/pressure = " \
+ "$pressure" >> $PROFILE_UPGRADE
+
+ echo "$SVCCFG -s $RCAP_FMRI " \
+ "setprop ${PG}/reconfig_interval = $reconfig_int" >> \
+ $PROFILE_UPGRADE
+
+ echo "$SVCCFG -s $RCAP_FMRI " \
+ "setprop ${PG}/walk_interval = $walk_int" >> \
+ $PROFILE_UPGRADE
+
+ echo "$SVCCFG -s $RCAP_FMRI " \
+ "setprop ${PG}/report_interval = $report_int" >> \
+ $PROFILE_UPGRADE
+
+ echo "$SVCCFG -s $RCAP_FMRI " \
+ "setprop ${PG}/rss_sample_interval = $rss_sample_int" >> \
+ $PROFILE_UPGRADE
+
+ echo "/usr/sbin/svcadm refresh $RCAP_FMRI" >> \
+ $PROFILE_UPGRADE
+
+ echo "rm /etc/rcap.conf" >> \
+ $PROFILE_UPGRADE
+}
+
+#
# smf(5) "Greenline" doesn't install the init.d or rc*.d scripts for
# converted services. Clean up previous scripts for such services.
#
@@ -1525,10 +1583,16 @@ smf_apply_conf () {
print "Marking converted services as enabled ..."
[ -f $rootprefix/etc/resolv.conf ] && smf_enable network/dns/client
- [ -f $rootprefix/etc/rcap.conf ] && smf_enable system/rcap
[ -f $rootprefix/etc/inet/dhcpsvc.conf ] && \
smf_enable network/dhcp-server
+ # Not concerned about enabling/disabling rcap but will migrate
+ # configuration parameters if rcap.conf exists
+ #
+ if [ -f $rootprefix/etc/rcap.conf ]; then
+ migrate_rcap_conf
+ fi
+
if [ $zone = global ]; then
if [ -f $rootprefix/etc/dfs/dfstab ] &&
grep '^[ ]*[^# ]' $rootprefix/etc/dfs/dfstab \