summaryrefslogtreecommitdiff
path: root/usr/src/cmd/rcap
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/rcap')
-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
11 files changed, 363 insertions, 472 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