1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * Block comment which describes the contents of this file.
31*0Sstevel@tonic-gate  */
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #include <dlfcn.h>
34*0Sstevel@tonic-gate #include <meta.h>
35*0Sstevel@tonic-gate #include <metadyn.h>
36*0Sstevel@tonic-gate #include <sdssc.h>
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate #define	SDSSC_PATH SDSSC_CL_LIBDIR "/sc/libsds_sc.so"
39*0Sstevel@tonic-gate 
40*0Sstevel@tonic-gate static func_table_t dl_table[] = {
41*0Sstevel@tonic-gate 	{ "_sdssc_version",		(void **)&sdssc_version },
42*0Sstevel@tonic-gate 	{ "_sdssc_create_begin",	(void **)&sdssc_create_begin },
43*0Sstevel@tonic-gate 	{ "_sdssc_mo_create_begin",	(void **)&sdssc_mo_create_begin },
44*0Sstevel@tonic-gate 	{ "_sdssc_create_end",		(void **)&sdssc_create_end },
45*0Sstevel@tonic-gate 	{ "_sdssc_delete_begin",	(void **)&sdssc_delete_begin },
46*0Sstevel@tonic-gate 	{ "_sdssc_delete_end",		(void **)&sdssc_delete_end },
47*0Sstevel@tonic-gate 	{ "_sdssc_get_index",		(void **)&sdssc_get_index },
48*0Sstevel@tonic-gate 	{ "_sdssc_add_hosts",		(void **)&sdssc_add_hosts },
49*0Sstevel@tonic-gate 	{ "_sdssc_delete_hosts",	(void **)&sdssc_delete_hosts },
50*0Sstevel@tonic-gate 	{ "_sdssc_get_primary_host",	(void **)&sdssc_get_primary_host },
51*0Sstevel@tonic-gate 	{ "_sdssc_cmd_proxy",		(void **)&sdssc_cmd_proxy },
52*0Sstevel@tonic-gate 	{ "_sdssc_getnodelist",		(void **)&sdssc_getnodelist },
53*0Sstevel@tonic-gate 	{ "_sdssc_freenodelist",	(void **)&sdssc_freenodelist },
54*0Sstevel@tonic-gate 	{ "_sdssc_binddevs",		(void **)&sdssc_binddevs },
55*0Sstevel@tonic-gate 	{ "_sdssc_bindclusterdevs",	(void **)&sdssc_bindclusterdevs },
56*0Sstevel@tonic-gate 	{ "_sdssc_gettransportbynode",	(void **)&sdssc_gettransportbynode },
57*0Sstevel@tonic-gate 	{ "_sdssc_free_mdcerr_list",	(void **)&sdssc_free_mdcerr_list },
58*0Sstevel@tonic-gate 	{ "_sdssc_property_get",	(void **)&sdssc_property_get },
59*0Sstevel@tonic-gate 	{ "_sdssc_property_set",	(void **)&sdssc_property_set },
60*0Sstevel@tonic-gate 	{ "_sdssc_get_services",	(void **)&sdssc_get_services },
61*0Sstevel@tonic-gate 	{ "_sdssc_get_services_free",	(void **)&sdssc_get_services_free },
62*0Sstevel@tonic-gate 	{ "_sdssc_suspend",		(void **)&sdssc_suspend },
63*0Sstevel@tonic-gate 	{ "_sdssc_convert_cluster_path",
64*0Sstevel@tonic-gate 	    (void **)&sdssc_convert_cluster_path },
65*0Sstevel@tonic-gate 	{ "_sdssc_convert_ctd_path",
66*0Sstevel@tonic-gate 	    (void **)&sdssc_convert_ctd_path },
67*0Sstevel@tonic-gate 	{ "_sdssc_convert_path_free",
68*0Sstevel@tonic-gate 	    (void **)&sdssc_convert_path_free },
69*0Sstevel@tonic-gate 	{ "_sdssc_notify_service",	(void **)&sdssc_notify_service },
70*0Sstevel@tonic-gate 	{ "_sdssc_cm_nm2nid",	(void **)&sdssc_cm_nm2nid },
71*0Sstevel@tonic-gate 	{ "_sdssc_cm_sr_nm2nid",	(void **)&sdssc_cm_sr_nm2nid },
72*0Sstevel@tonic-gate 	{ "_sdssc_cm_nid2nm",	(void **)&sdssc_cm_nid2nm },
73*0Sstevel@tonic-gate 	{ "_sdssc_cm_sr_nid2nm",	(void **)&sdssc_cm_sr_nid2nm },
74*0Sstevel@tonic-gate 	{ "_sdssc_get_priv_ipaddr",	(void **)&sdssc_get_priv_ipaddr },
75*0Sstevel@tonic-gate 	{ (char *)0,			(void **)0 }
76*0Sstevel@tonic-gate };
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate static rval_e
79*0Sstevel@tonic-gate just_dup_string(const char *source, char **dest)
80*0Sstevel@tonic-gate {
81*0Sstevel@tonic-gate 	*dest = strdup(source);
82*0Sstevel@tonic-gate 	return (SDSSC_OKAY);
83*0Sstevel@tonic-gate }
84*0Sstevel@tonic-gate 
85*0Sstevel@tonic-gate static void
86*0Sstevel@tonic-gate free_dup_string(char *source)
87*0Sstevel@tonic-gate {
88*0Sstevel@tonic-gate 	free(source);
89*0Sstevel@tonic-gate }
90*0Sstevel@tonic-gate 
91*0Sstevel@tonic-gate /*
92*0Sstevel@tonic-gate  * not_bound -- routine to always return NOT_BOUND
93*0Sstevel@tonic-gate  */
94*0Sstevel@tonic-gate static rval_e
95*0Sstevel@tonic-gate not_bound(void)
96*0Sstevel@tonic-gate {
97*0Sstevel@tonic-gate 	return (SDSSC_NOT_BOUND);
98*0Sstevel@tonic-gate }
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate /*
101*0Sstevel@tonic-gate  * not_bound_error -- routine to always return SDSSC_NOT_BOUND_ERROR since
102*0Sstevel@tonic-gate  * routine is not bound.  This is used when using an older version
103*0Sstevel@tonic-gate  * of libsdssc that doesn't support MN disksets.  When an MN specific
104*0Sstevel@tonic-gate  * routine is called (such as sdssc_mo_create_set) an SDSSC_NOT_BOUND_ERROR
105*0Sstevel@tonic-gate  * will be returned.
106*0Sstevel@tonic-gate  */
107*0Sstevel@tonic-gate static rval_e
108*0Sstevel@tonic-gate not_bound_error(void)
109*0Sstevel@tonic-gate {
110*0Sstevel@tonic-gate 	return (SDSSC_NOT_BOUND_ERROR);
111*0Sstevel@tonic-gate }
112*0Sstevel@tonic-gate 
113*0Sstevel@tonic-gate 
114*0Sstevel@tonic-gate /*
115*0Sstevel@tonic-gate  * set_common_routine -- set cluster interface routines to return NOT_BOUND
116*0Sstevel@tonic-gate  */
117*0Sstevel@tonic-gate static void
118*0Sstevel@tonic-gate set_common_routine()
119*0Sstevel@tonic-gate {
120*0Sstevel@tonic-gate 	func_table_p	f;
121*0Sstevel@tonic-gate 
122*0Sstevel@tonic-gate 	for (f = dl_table; f->fptr != (void *)0; f++) {
123*0Sstevel@tonic-gate 		if (strcmp(f->fname, "_sdssc_convert_cluster_path") == 0) {
124*0Sstevel@tonic-gate 			*f->fptr = (void *)&just_dup_string;
125*0Sstevel@tonic-gate 		} else if (strcmp(f->fname, "_sdssc_free_convert_cluster_path")
126*0Sstevel@tonic-gate 		    == 0) {
127*0Sstevel@tonic-gate 			*f->fptr = (void *)&free_dup_string;
128*0Sstevel@tonic-gate 		} else {
129*0Sstevel@tonic-gate 			*f->fptr = (void *)&not_bound;
130*0Sstevel@tonic-gate 		}
131*0Sstevel@tonic-gate 	}
132*0Sstevel@tonic-gate }
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate /*
135*0Sstevel@tonic-gate  * sdssc_bind_library -- entry point which resolves all cluster interface pts.
136*0Sstevel@tonic-gate  */
137*0Sstevel@tonic-gate rval_e
138*0Sstevel@tonic-gate sdssc_bind_library(void)
139*0Sstevel@tonic-gate {
140*0Sstevel@tonic-gate 	void		*dp;
141*0Sstevel@tonic-gate 	int		(*lb)();
142*0Sstevel@tonic-gate 	func_table_p	ftp;
143*0Sstevel@tonic-gate 
144*0Sstevel@tonic-gate 	/*
145*0Sstevel@tonic-gate 	 * If already bound then just return okay so this routine
146*0Sstevel@tonic-gate 	 * becomes idempotent. If this check isn't made then we'll
147*0Sstevel@tonic-gate 	 * fail when calling the "_bind_library" function because
148*0Sstevel@tonic-gate 	 * dcs_initialize() can only be called once.
149*0Sstevel@tonic-gate 	 */
150*0Sstevel@tonic-gate 	if (sdssc_version != 0) {
151*0Sstevel@tonic-gate 		if ((void *)sdssc_version == (void *)not_bound)
152*0Sstevel@tonic-gate 			return (SDSSC_NOT_BOUND);
153*0Sstevel@tonic-gate 		else
154*0Sstevel@tonic-gate 			return (SDSSC_OKAY);
155*0Sstevel@tonic-gate 	}
156*0Sstevel@tonic-gate 
157*0Sstevel@tonic-gate 	if ((dp = dlopen(SDSSC_PATH, RTLD_LAZY)) == NULL) {
158*0Sstevel@tonic-gate 		set_common_routine();
159*0Sstevel@tonic-gate 		return (SDSSC_NOT_BOUND);
160*0Sstevel@tonic-gate 	} else {
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate 		/*
163*0Sstevel@tonic-gate 		 * Allow the binding library to initialize state if
164*0Sstevel@tonic-gate 		 * necessary. Currently this calls the DCS initialize()
165*0Sstevel@tonic-gate 		 * routine which checks to see if we're part of a cluster.
166*0Sstevel@tonic-gate 		 */
167*0Sstevel@tonic-gate 		if ((lb = (int (*)())dlsym(dp, "_bind_library")) != NULL) {
168*0Sstevel@tonic-gate 			if (lb() != 0) {
169*0Sstevel@tonic-gate 				set_common_routine();
170*0Sstevel@tonic-gate 				return (SDSSC_NOT_BOUND);
171*0Sstevel@tonic-gate 			}
172*0Sstevel@tonic-gate 		}
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate 		/*
175*0Sstevel@tonic-gate 		 * Load 'em up. Pick up the function address and store
176*0Sstevel@tonic-gate 		 * the values in the global pointers for other routines
177*0Sstevel@tonic-gate 		 * to use.
178*0Sstevel@tonic-gate 		 */
179*0Sstevel@tonic-gate 		for (ftp = dl_table; ftp->fptr != (void *)0; ftp++) {
180*0Sstevel@tonic-gate 			if ((*ftp->fptr = dlsym(dp, ftp->fname)) == NULL) {
181*0Sstevel@tonic-gate 
182*0Sstevel@tonic-gate 				/*
183*0Sstevel@tonic-gate 				 * If old libsdssc library is there, then
184*0Sstevel@tonic-gate 				 * sdssc_mo_create_begin is not yet supported.
185*0Sstevel@tonic-gate 				 */
186*0Sstevel@tonic-gate 				if (strcmp(ftp->fname,
187*0Sstevel@tonic-gate 				    "sdssc_mo_create_begin")) {
188*0Sstevel@tonic-gate 					*ftp->fptr = (void *)&not_bound_error;
189*0Sstevel@tonic-gate 					continue;
190*0Sstevel@tonic-gate 				}
191*0Sstevel@tonic-gate 				/*
192*0Sstevel@tonic-gate 				 * If this routine fails to find a single
193*0Sstevel@tonic-gate 				 * entry point that it's expecting
194*0Sstevel@tonic-gate 				 * (except sdssc_mo_create_begin) then
195*0Sstevel@tonic-gate 				 * setup non-sdssc stubs routines
196*0Sstevel@tonic-gate 				 * as function pointers.
197*0Sstevel@tonic-gate 				 */
198*0Sstevel@tonic-gate 				set_common_routine();
199*0Sstevel@tonic-gate 				return (SDSSC_ERROR);
200*0Sstevel@tonic-gate 			}
201*0Sstevel@tonic-gate 		}
202*0Sstevel@tonic-gate 
203*0Sstevel@tonic-gate 		return (SDSSC_OKAY);
204*0Sstevel@tonic-gate 	}
205*0Sstevel@tonic-gate }
206