xref: /illumos-gate/usr/src/cmd/isns/isnsd/config.c (revision 2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1f)
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