summaryrefslogtreecommitdiff
path: root/usr/src/cmd/rcap/common/rcapd_conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/rcap/common/rcapd_conf.c')
-rw-r--r--usr/src/cmd/rcap/common/rcapd_conf.c244
1 files changed, 244 insertions, 0 deletions
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);
+}