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 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 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 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