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