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 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <errno.h>
30 #include <strings.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <libscf.h>
34 #include <libscf_priv.h>
35 #include <libuutil.h>
36 #include "rcapd.h"
37 #include "rcapd_conf.h"
38 #include "rcapd_stat.h"
39 #include "utils.h"
40
41 /*
42 * Read configuration and set the fields of an rcfg_t correspondingly.
43 * Verify that the statistics file is writable, with the optional
44 * verify_stat_file_creation() callback.
45 */
46 int
rcfg_read(rcfg_t * _rcfg,int (* verify_stat_file_creation)(void))47 rcfg_read(rcfg_t *_rcfg, int(*verify_stat_file_creation)(void))
48 {
49 scf_simple_handle_t *simple_h;
50 uint64_t count_val;
51 int ret = E_ERROR;
52
53 rcfg_init(_rcfg);
54
55 if ((simple_h = scf_general_pg_setup(RCAP_FMRI, CONFIG_PG))
56 == NULL) {
57 warn(gettext("SMF initialization problem: %s\n"),
58 scf_strerror(scf_error()));
59 goto err;
60 }
61
62 if (scf_read_count_property(simple_h, PRESSURE, &count_val)
63 == SCF_FAILED) {
64 warn(gettext("Configuration property '%s' "
65 "not found. \n"), PRESSURE);
66 goto err;
67 } else {
68 if (count_val > 100)
69 _rcfg->rcfg_memory_cap_enforcement_pressure = 100;
70 else
71 _rcfg->rcfg_memory_cap_enforcement_pressure
72 = count_val;
73
74 debug("cap max pressure: %d%%\n",
75 _rcfg->rcfg_memory_cap_enforcement_pressure);
76 }
77
78 if (scf_read_count_property(simple_h, RECONFIG_INT, &count_val)
79 == SCF_FAILED) {
80 warn(gettext("Configuration property '%s' "
81 "not found. \n"), RECONFIG_INT);
82 goto err;
83 } else {
84 _rcfg->rcfg_reconfiguration_interval = count_val;
85 debug("reconfiguration interval: %d seconds\n",
86 _rcfg->rcfg_reconfiguration_interval);
87 }
88
89 if (scf_read_count_property(simple_h, REPORT_INT, &count_val)
90 == SCF_FAILED) {
91 warn(gettext("Configuration property '%s' "
92 "not found. \n"), REPORT_INT);
93 goto err;
94 } else {
95 _rcfg->rcfg_report_interval = count_val;
96 debug("report interval: %d seconds\n",
97 _rcfg->rcfg_report_interval);
98 }
99
100 if (scf_read_count_property(simple_h, RSS_SAMPLE_INT, &count_val)
101 == SCF_FAILED) {
102 warn(gettext("Configuration property '%s' "
103 "not found. \n"), RSS_SAMPLE_INT);
104 goto err;
105 } else {
106 _rcfg->rcfg_rss_sample_interval = count_val;
107 debug("RSS sample interval: %d seconds\n",
108 _rcfg->rcfg_rss_sample_interval);
109 }
110
111 if (scf_read_count_property(simple_h, WALK_INT, &count_val)
112 == SCF_FAILED) {
113 warn(gettext("Configuration property '%s' "
114 "not found. \n"), WALK_INT);
115 goto err;
116 } else {
117 _rcfg->rcfg_proc_walk_interval = count_val;
118 debug("proc_walk interval: %d seconds\n",
119 _rcfg->rcfg_proc_walk_interval);
120 }
121
122 if (_rcfg->rcfg_mode_name == NULL) {
123 /*
124 * Set project mode, by default.
125 */
126 _rcfg->rcfg_mode = rctype_project;
127 _rcfg->rcfg_mode_name = "project";
128 debug("mode: %s\n", _rcfg->rcfg_mode_name);
129 }
130
131 if (verify_stat_file_creation != 0 && verify_stat_file_creation()
132 != 0) {
133 warn(gettext("cannot create statistics file, " "%s"),
134 _rcfg->rcfg_stat_file);
135 goto err;
136 }
137
138 debug("done parsing\n");
139 ret = E_SUCCESS;
140 goto out;
141
142 err:
143 if (scf_error() != SCF_ERROR_NONE) {
144 warn(gettext("Unexpected libscf error: %s. \n"),
145 scf_strerror(scf_error()));
146 }
147
148 out:
149 scf_simple_handle_destroy(simple_h);
150 return (ret);
151 }
152
153 void
rcfg_init(rcfg_t * rcfg)154 rcfg_init(rcfg_t *rcfg)
155 {
156 bzero(rcfg, sizeof (*rcfg));
157 (void) strcpy(rcfg->rcfg_stat_file, STAT_FILE_DEFAULT);
158 }
159
160 /*
161 * Modify configuration in repository given the rcfg_t structure.
162 */
163 int
modify_config(rcfg_t * conf)164 modify_config(rcfg_t *conf)
165 {
166 scf_simple_handle_t *simple_h;
167 scf_transaction_t *tx = NULL;
168 int rval, ret = E_ERROR;
169
170 if ((simple_h = scf_general_pg_setup(RCAP_FMRI, CONFIG_PG))
171 == NULL) {
172 warn(gettext("SMF initialization problem: %s\n"),
173 scf_strerror(scf_error()));
174 goto out;
175 }
176
177 if ((tx = scf_transaction_setup(simple_h)) == NULL) {
178 warn(gettext("SMF initialization problem: %s\n"),
179 scf_strerror(scf_error()));
180 goto out;
181 }
182
183 do {
184 if (scf_set_count_property(tx, PRESSURE,
185 conf->rcfg_memory_cap_enforcement_pressure, 0)
186 != SCF_SUCCESS) {
187 warn(gettext("Couldn't set '%s' property. \n"),
188 PRESSURE);
189 goto out;
190 }
191
192 if (scf_set_count_property(tx, RECONFIG_INT,
193 conf->rcfg_reconfiguration_interval, 0) != SCF_SUCCESS) {
194 warn(gettext("Couldn't set '%s' property. \n"),
195 RECONFIG_INT);
196 goto out;
197 }
198
199 if (scf_set_count_property(tx, RSS_SAMPLE_INT,
200 conf->rcfg_rss_sample_interval, 0) != SCF_SUCCESS) {
201 warn(gettext("Couldn't set '%s' property. \n"),
202 RSS_SAMPLE_INT);
203 goto out;
204 }
205
206 if (scf_set_count_property(tx, REPORT_INT,
207 conf->rcfg_report_interval, 0) != SCF_SUCCESS) {
208 warn(gettext("Couldn't set '%s' property. \n"),
209 REPORT_INT);
210 goto out;
211 }
212
213 if (scf_set_count_property(tx, WALK_INT,
214 conf->rcfg_proc_walk_interval, 0) != SCF_SUCCESS) {
215 warn(gettext("Couldn't set '%s' property. \n"),
216 WALK_INT);
217 goto out;
218 }
219
220 if ((rval = scf_transaction_commit(tx)) == -1)
221 goto out;
222
223 if (rval == 0) {
224 if (scf_transaction_restart(simple_h, tx)
225 != SCF_SUCCESS) {
226 warn(gettext("SMF initialization problem: "
227 "%s\n"), scf_strerror(scf_error()));
228 goto out;
229 }
230 }
231 } while (rval == 0);
232
233 ret = E_SUCCESS;
234
235 out:
236 if (tx != NULL) {
237 scf_transaction_destroy_children(tx);
238 scf_transaction_destroy(tx);
239 }
240 scf_simple_handle_destroy(simple_h);
241 return (ret);
242 }
243