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