rcapd_conf.c revision 4119:293019c5ea1f
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
22 * Use is subject to license terms.
23 */
24
25#pragma ident	"%Z%%M%	%I%	%E% SMI"
26
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <errno.h>
32#include <strings.h>
33#include <fcntl.h>
34#include <unistd.h>
35#include <libscf.h>
36#include <libscf_priv.h>
37#include <libuutil.h>
38#include "rcapd.h"
39#include "rcapd_conf.h"
40#include "rcapd_stat.h"
41#include "utils.h"
42
43/*
44 * Read configuration and set the fields of an rcfg_t correspondingly.
45 * Verify that the statistics file is writable, with the optional
46 * verify_stat_file_creation() callback.
47 */
48int
49rcfg_read(rcfg_t *_rcfg, int(*verify_stat_file_creation)(void))
50{
51	scf_simple_handle_t	*simple_h;
52	uint64_t		count_val;
53	int			ret = E_ERROR;
54
55	rcfg_init(_rcfg);
56
57	if ((simple_h = scf_general_pg_setup(RCAP_FMRI, CONFIG_PG))
58	    == NULL) {
59		warn(gettext("SMF initialization problem: %s\n"),
60		    scf_strerror(scf_error()));
61		goto err;
62	}
63
64	if (scf_read_count_property(simple_h, PRESSURE, &count_val)
65	    == SCF_FAILED) {
66		warn(gettext("Configuration property '%s' "
67		    "not found. \n"), PRESSURE);
68		goto err;
69	} else {
70		if (count_val > 100)
71			_rcfg->rcfg_memory_cap_enforcement_pressure = 100;
72		else
73			_rcfg->rcfg_memory_cap_enforcement_pressure
74			    = count_val;
75
76		debug("cap max pressure: %d%%\n",
77		    _rcfg->rcfg_memory_cap_enforcement_pressure);
78	}
79
80	if (scf_read_count_property(simple_h, RECONFIG_INT, &count_val)
81	    == SCF_FAILED) {
82		warn(gettext("Configuration property '%s' "
83		    "not found. \n"), RECONFIG_INT);
84		goto err;
85	} else {
86		_rcfg->rcfg_reconfiguration_interval = count_val;
87		debug("reconfiguration interval: %d seconds\n",
88		    _rcfg->rcfg_reconfiguration_interval);
89	}
90
91	if (scf_read_count_property(simple_h, REPORT_INT, &count_val)
92	    == SCF_FAILED) {
93		warn(gettext("Configuration property '%s' "
94		    "not found. \n"), REPORT_INT);
95		goto err;
96	} else {
97		_rcfg->rcfg_report_interval = count_val;
98		debug("report interval: %d seconds\n",
99		    _rcfg->rcfg_report_interval);
100	}
101
102	if (scf_read_count_property(simple_h, RSS_SAMPLE_INT, &count_val)
103	    == SCF_FAILED) {
104		warn(gettext("Configuration property '%s' "
105		    "not found. \n"), RSS_SAMPLE_INT);
106		goto err;
107	} else {
108		_rcfg->rcfg_rss_sample_interval = count_val;
109		debug("RSS sample interval: %d seconds\n",
110		    _rcfg->rcfg_rss_sample_interval);
111	}
112
113	if (scf_read_count_property(simple_h, WALK_INT, &count_val)
114	    == SCF_FAILED) {
115		warn(gettext("Configuration property '%s' "
116		    "not found. \n"), WALK_INT);
117		goto err;
118	} else {
119		_rcfg->rcfg_proc_walk_interval = count_val;
120		debug("proc_walk interval: %d seconds\n",
121		    _rcfg->rcfg_proc_walk_interval);
122	}
123
124	if (_rcfg->rcfg_mode_name == NULL) {
125		/*
126		 * Set project mode, by default.
127		 */
128		_rcfg->rcfg_mode = rctype_project;
129		_rcfg->rcfg_mode_name = "project";
130		debug("mode: %s\n", _rcfg->rcfg_mode_name);
131	}
132
133	if (verify_stat_file_creation != 0 && verify_stat_file_creation()
134	    != 0) {
135		warn(gettext("cannot create statistics file, " "%s"),
136		    _rcfg->rcfg_stat_file);
137		goto err;
138	}
139
140	debug("done parsing\n");
141	ret = E_SUCCESS;
142	goto out;
143
144err:
145	if (scf_error() != SCF_ERROR_NONE) {
146		warn(gettext("Unexpected libscf error: %s. \n"),
147		    scf_strerror(scf_error()));
148	}
149
150out:
151	scf_simple_handle_destroy(simple_h);
152	return (ret);
153}
154
155void
156rcfg_init(rcfg_t *rcfg)
157{
158	bzero(rcfg, sizeof (*rcfg));
159	(void) strcpy(rcfg->rcfg_stat_file, STAT_FILE_DEFAULT);
160}
161
162/*
163 * Modify configuration in repository given the rcfg_t structure.
164 */
165int
166modify_config(rcfg_t *conf)
167{
168	scf_simple_handle_t	*simple_h;
169	scf_transaction_t	*tx = NULL;
170	int			rval, ret = E_ERROR;
171
172	if ((simple_h = scf_general_pg_setup(RCAP_FMRI, CONFIG_PG))
173	    == NULL) {
174		warn(gettext("SMF initialization problem: %s\n"),
175		    scf_strerror(scf_error()));
176		goto out;
177	}
178
179	if ((tx = scf_transaction_setup(simple_h)) == NULL) {
180		warn(gettext("SMF initialization problem: %s\n"),
181		    scf_strerror(scf_error()));
182		goto out;
183	}
184
185	do {
186		if (scf_set_count_property(tx, PRESSURE,
187		    conf->rcfg_memory_cap_enforcement_pressure, 0)
188		    != SCF_SUCCESS) {
189			warn(gettext("Couldn't set '%s' property. \n"),
190			    PRESSURE);
191			goto out;
192		}
193
194		if (scf_set_count_property(tx, RECONFIG_INT,
195		    conf->rcfg_reconfiguration_interval, 0) != SCF_SUCCESS) {
196			warn(gettext("Couldn't set '%s' property. \n"),
197			    RECONFIG_INT);
198			goto out;
199		}
200
201		if (scf_set_count_property(tx, RSS_SAMPLE_INT,
202		    conf->rcfg_rss_sample_interval, 0) != SCF_SUCCESS) {
203			warn(gettext("Couldn't set '%s' property. \n"),
204			    RSS_SAMPLE_INT);
205			goto out;
206		}
207
208		if (scf_set_count_property(tx, REPORT_INT,
209		    conf->rcfg_report_interval, 0) != SCF_SUCCESS) {
210			warn(gettext("Couldn't set '%s' property. \n"),
211			    REPORT_INT);
212			goto out;
213		}
214
215		if (scf_set_count_property(tx, WALK_INT,
216		    conf->rcfg_proc_walk_interval, 0) != SCF_SUCCESS) {
217			warn(gettext("Couldn't set '%s' property. \n"),
218			    WALK_INT);
219			goto out;
220		}
221
222		if ((rval = scf_transaction_commit(tx)) == -1)
223			goto out;
224
225		if (rval == 0) {
226			if (scf_transaction_restart(simple_h, tx)
227			    != SCF_SUCCESS) {
228				warn(gettext("SMF initialization problem: "
229				    "%s\n"), scf_strerror(scf_error()));
230				goto out;
231			}
232		}
233	} while (rval == 0);
234
235	ret = E_SUCCESS;
236
237out:
238	if (tx != NULL) {
239		scf_transaction_destroy_children(tx);
240		scf_transaction_destroy(tx);
241	}
242	scf_simple_handle_destroy(simple_h);
243	return (ret);
244}
245