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 */
48 int
rcfg_read(rcfg_t * _rcfg,int (* verify_stat_file_creation)(void))49 rcfg_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
144 err:
145 if (scf_error() != SCF_ERROR_NONE) {
146 warn(gettext("Unexpected libscf error: %s. \n"),
147 scf_strerror(scf_error()));
148 }
149
150 out:
151 scf_simple_handle_destroy(simple_h);
152 return (ret);
153 }
154
155 void
rcfg_init(rcfg_t * rcfg)156 rcfg_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 */
165 int
modify_config(rcfg_t * conf)166 modify_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
237 out:
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