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