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