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 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <stdlib.h> 28 #include <string.h> 29 #include <libscf.h> 30 #include <pthread.h> 31 32 #include "isns_server.h" 33 #include "isns_log.h" 34 #include "isns_cfg.h" 35 36 /* 37 * external variables 38 */ 39 extern uint64_t esi_threshold; 40 extern uint8_t mgmt_scn; 41 extern ctrl_node_t *control_nodes; 42 extern pthread_mutex_t ctrl_node_mtx; 43 extern char data_store[MAXPATHLEN]; 44 45 #define DEFAULT_ESI_THRESHOLD 3 46 #define MAX_ESI_THRESHOLD 10 47 48 /* 49 * load_config loads config data through SMF. 50 * arg DATA_STORE_UPDATE indicates whether the data store location 51 * can be updated or not. 52 */ 53 int 54 load_config(boolean_t DATA_STORE_UPDATE) 55 { 56 57 int retval = -1; 58 59 scf_handle_t *handle = NULL; 60 scf_scope_t *sc = NULL; 61 scf_service_t *svc = NULL; 62 scf_propertygroup_t *pg = NULL; 63 scf_property_t *prop = NULL; 64 scf_value_t *value = NULL; 65 scf_iter_t *value_iter = NULL; 66 67 ctrl_node_t *ctrl_node_p; 68 char scf_name[MAXNAMELEN]; 69 char *name; 70 71 /* connect to the current SMF global repository */ 72 handle = scf_handle_create(SCF_VERSION); 73 74 /* allocate scf resources */ 75 sc = scf_scope_create(handle); 76 svc = scf_service_create(handle); 77 pg = scf_pg_create(handle); 78 prop = scf_property_create(handle); 79 value = scf_value_create(handle); 80 value_iter = scf_iter_create(handle); 81 82 /* if failed to allocate resources, exit */ 83 if (handle == NULL || sc == NULL || svc == NULL || pg == NULL || 84 prop == NULL || value == NULL || value_iter == NULL) { 85 isnslog(LOG_DEBUG, "load_config", 86 "scf handles allocation failed."); 87 goto out; 88 } 89 90 /* bind scf handle to the running svc.configd daemon */ 91 if (scf_handle_bind(handle) == -1) { 92 isnslog(LOG_DEBUG, "load_config", "scf binding failed."); 93 goto out; 94 } 95 96 /* get the scope of the localhost in the current repository */ 97 if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, sc) == -1) { 98 isnslog(LOG_DEBUG, "load_config", "Getting scf scope failed."); 99 goto out; 100 } 101 102 /* get the service "network/isns_server" within the scope */ 103 if (scf_scope_get_service(sc, ISNS_SERVER_SVC_NAME, svc) == -1) { 104 isnslog(LOG_DEBUG, "load_config", "Getting %s service failed.", 105 ISNS_SERVER_SVC_NAME); 106 goto out; 107 } 108 109 /* get the property group "config" within the given service */ 110 if (scf_service_get_pg(svc, ISNS_SERVER_CONFIG, pg) == -1) { 111 isnslog(LOG_DEBUG, "load_config", 112 "Getting property group %s failed.", 113 ISNS_SERVER_CONFIG); 114 goto out; 115 } 116 117 /* 118 * Now get the properties. 119 */ 120 if (scf_pg_get_property(pg, CONFIG_ESI_THRESHOLD, prop) == -1) { 121 isnslog(LOG_DEBUG, "load_config", "Getting property %s failed", 122 CONFIG_ESI_THRESHOLD); 123 goto out; 124 } 125 126 if (scf_property_get_value(prop, value) == -1) { 127 isnslog(LOG_DEBUG, "load_config", 128 "Getting property value for %s failed.", 129 CONFIG_ESI_THRESHOLD); 130 goto out; 131 } 132 133 if (scf_value_get_count(value, &esi_threshold) == -1) { 134 isnslog(LOG_DEBUG, "load_config", 135 "Getting property integer value for %s failed.", 136 CONFIG_ESI_THRESHOLD); 137 goto out; 138 } 139 140 /* the range of ESI Threshold is [1, 10] */ 141 if (esi_threshold < 1) { 142 esi_threshold = DEFAULT_ESI_THRESHOLD; /* 3 */ 143 } else if (esi_threshold > MAX_ESI_THRESHOLD) { 144 esi_threshold = MAX_ESI_THRESHOLD; /* 10 */ 145 } 146 147 isnslog(LOG_DEBUG, "load_config", 148 "%s set to %d", CONFIG_ESI_THRESHOLD, esi_threshold); 149 150 if (scf_pg_get_property(pg, CONFIG_MGMT_SCN, prop) == -1) { 151 isnslog(LOG_DEBUG, "load_config", 152 "Getting scf property %s failed.", CONFIG_MGMT_SCN); 153 goto out; 154 } 155 156 if (scf_property_get_value(prop, value) == -1) { 157 isnslog(LOG_DEBUG, "load_config", 158 "Getting property value for %s failed.", 159 CONFIG_MGMT_SCN); 160 goto out; 161 } 162 163 if (scf_value_get_boolean(value, &mgmt_scn) == -1) { 164 isnslog(LOG_DEBUG, "load_config", 165 "Getting boolean value for property %s failed", 166 CONFIG_MGMT_SCN); 167 goto out; 168 } 169 isnslog(LOG_DEBUG, "load_config", 170 "%s set to %s", CONFIG_MGMT_SCN, 171 mgmt_scn ? "true" : "false"); 172 173 if (DATA_STORE_UPDATE) { 174 if (scf_pg_get_property(pg, CONFIG_DATA_STORE, prop) == -1) { 175 isnslog(LOG_DEBUG, "load_config", "Getting property %s failed", 176 CONFIG_DATA_STORE); 177 goto out; 178 } 179 180 if (scf_property_get_value(prop, value) == -1) { 181 isnslog(LOG_DEBUG, "load_config", 182 "Getting property value for %s failed", 183 CONFIG_DATA_STORE); 184 goto out; 185 } 186 187 data_store[0] = 0; 188 if (scf_value_get_astring(value, data_store, MAXPATHLEN) == -1) { 189 isnslog(LOG_DEBUG, "load_config", 190 "Getting property string value for %s failed", 191 CONFIG_DATA_STORE); 192 goto out; 193 } 194 isnslog(LOG_DEBUG, "load_config", 195 "%s set to %s", CONFIG_DATA_STORE, data_store); 196 } 197 198 if (scf_pg_get_property(pg, CONFIG_CONTROL_NODES, prop) == -1) { 199 isnslog(LOG_DEBUG, "load_config", "Getting property %s failed", 200 CONFIG_CONTROL_NODES); 201 goto out; 202 } 203 204 if (scf_iter_property_values(value_iter, prop) == -1) { 205 isnslog(LOG_DEBUG, "load_config", 206 "Getting iteration property %s failed", 207 CONFIG_CONTROL_NODES); 208 goto out; 209 } 210 211 /* remove any old control node first. */ 212 (void) pthread_mutex_lock(&ctrl_node_mtx); 213 while (control_nodes != NULL) { 214 ctrl_node_p = control_nodes->next; 215 free(control_nodes->name); 216 free(control_nodes); 217 control_nodes = ctrl_node_p; 218 } 219 220 while (scf_iter_next_value(value_iter, value) != 0) { 221 if (scf_value_get_ustring(value, scf_name, MAXNAMELEN) == -1) { 222 isnslog(LOG_DEBUG, "load_config", 223 "Getting property string value for %s failed", 224 CONFIG_CONTROL_NODES); 225 (void) pthread_mutex_unlock(&ctrl_node_mtx); 226 goto out; 227 } 228 ctrl_node_p = (ctrl_node_t *)malloc(sizeof (ctrl_node_t)); 229 if (ctrl_node_p == NULL) { 230 isnslog(LOG_DEBUG, "load_config", "malloc() failed."); 231 (void) pthread_mutex_unlock(&ctrl_node_mtx); 232 goto out; 233 } 234 if (strlen(scf_name) != 0) { 235 name = (char *)malloc(strlen(scf_name) + 1); 236 if (name == NULL) { 237 free(ctrl_node_p); 238 isnslog(LOG_DEBUG, "load_config", "malloc() failed."); 239 (void) pthread_mutex_unlock(&ctrl_node_mtx); 240 goto out; 241 } else { 242 (void) strcpy(name, scf_name); 243 ctrl_node_p->name = (uchar_t *)name; 244 ctrl_node_p->next = control_nodes; 245 control_nodes = ctrl_node_p; 246 } 247 isnslog(LOG_DEBUG, "load_config", 248 "%s set to %s", CONFIG_CONTROL_NODES, scf_name); 249 } else { 250 free(ctrl_node_p); 251 } 252 } 253 (void) pthread_mutex_unlock(&ctrl_node_mtx); 254 255 isnslog(LOG_DEBUG, "load_config", "loading server settings ok."); 256 257 retval = 0; /* ok */ 258 259 out: 260 /* destroy scf pointers */ 261 if (value != NULL) { 262 scf_value_destroy(value); 263 } 264 if (value_iter != NULL) { 265 scf_iter_destroy(value_iter); 266 } 267 if (prop != NULL) { 268 scf_property_destroy(prop); 269 } 270 if (pg != NULL) { 271 scf_pg_destroy(pg); 272 } 273 if (svc != NULL) { 274 scf_service_destroy(svc); 275 } 276 if (sc != NULL) { 277 scf_scope_destroy(sc); 278 } 279 if (handle != NULL) { 280 scf_handle_destroy(handle); 281 } 282 283 return (retval); 284 } 285 286 /* 287 * is_control_node checks the given name to see if it is a control node. 288 */ 289 int 290 is_control_node( 291 uchar_t *name 292 ) 293 { 294 ctrl_node_t *p; 295 296 (void) pthread_mutex_lock(&ctrl_node_mtx); 297 p = control_nodes; 298 while (p != NULL) { 299 if (strcmp((char *)p->name, (char *)name) == 0) { 300 (void) pthread_mutex_unlock(&ctrl_node_mtx); 301 return (1); 302 } 303 p = p->next; 304 } 305 (void) pthread_mutex_unlock(&ctrl_node_mtx); 306 307 return (0); 308 } 309