xref: /onnv-gate/usr/src/cmd/isns/isnsd/config.c (revision 7836:4e95154b5b7a)
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