1 /*
2  * Copyright (c) 2005 MontaVista Software, Inc.
3  * Copyright (c) 2006-2007, 2009 Red Hat, Inc.
4  *
5  * All rights reserved.
6  *
7  * Author: Steven Dake (sdake@redhat.com)
8  *
9  * This software licensed under BSD license, the text of which follows:
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are met:
13  *
14  * - Redistributions of source code must retain the above copyright notice,
15  *   this list of conditions and the following disclaimer.
16  * - Redistributions in binary form must reproduce the above copyright notice,
17  *   this list of conditions and the following disclaimer in the documentation
18  *   and/or other materials provided with the distribution.
19  * - Neither the name of the MontaVista Software, Inc. nor the names of its
20  *   contributors may be used to endorse or promote products derived from this
21  *   software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33  * THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include <config.h>
37 
38 #include <sys/mman.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/socket.h>
42 #include <netdb.h>
43 #include <sys/un.h>
44 #include <sys/ioctl.h>
45 #include <sys/param.h>
46 #include <netinet/in.h>
47 #include <arpa/inet.h>
48 #include <unistd.h>
49 #include <fcntl.h>
50 #include <stdlib.h>
51 #include <stdio.h>
52 #include <errno.h>
53 #include <sched.h>
54 #include <time.h>
55 #include <sys/time.h>
56 #include <sys/poll.h>
57 
58 #include <corosync/totem/totem.h>
59 #include <qb/qbloop.h>
60 
61 #include "totemmrp.h"
62 #include "totemsrp.h"
63 
64 void *totemsrp_context;
65 
66 void totemmrp_deliver_fn (
67 	unsigned int nodeid,
68 	const void *msg,
69 	unsigned int msg_len,
70 	int endian_conversion_required);
71 
72 void totemmrp_confchg_fn (
73 	enum totem_configuration_type configuration_type,
74 	const unsigned int *member_list, size_t member_list_entries,
75 	const unsigned int *left_list, size_t left_list_entries,
76 	const unsigned int *joined_list, size_t joined_list_entries,
77 	const struct memb_ring_id *ring_id);
78 
79 void (*pg_deliver_fn) (
80 	unsigned int nodeid,
81 	const void *msg,
82 	unsigned int msg_len,
83 	int endian_conversion_required) = 0;
84 
85 void (*pg_confchg_fn) (
86 	enum totem_configuration_type configuration_type,
87 	const unsigned int *member_list, size_t member_list_entries,
88 	const unsigned int *left_list, size_t left_list_entries,
89 	const unsigned int *joined_list, size_t joined_list_entries,
90 	const struct memb_ring_id *ring_id) = 0;
91 
totemmrp_deliver_fn(unsigned int nodeid,const void * msg,unsigned int msg_len,int endian_conversion_required)92 void totemmrp_deliver_fn (
93 	unsigned int nodeid,
94 	const void *msg,
95 	unsigned int msg_len,
96 	int endian_conversion_required)
97 {
98 	pg_deliver_fn (nodeid, msg, msg_len, endian_conversion_required);
99 }
100 
totemmrp_confchg_fn(enum totem_configuration_type configuration_type,const unsigned int * member_list,size_t member_list_entries,const unsigned int * left_list,size_t left_list_entries,const unsigned int * joined_list,size_t joined_list_entries,const struct memb_ring_id * ring_id)101 void totemmrp_confchg_fn (
102 	enum totem_configuration_type configuration_type,
103 	const unsigned int *member_list, size_t member_list_entries,
104 	const unsigned int *left_list, size_t left_list_entries,
105 	const unsigned int *joined_list, size_t joined_list_entries,
106 	const struct memb_ring_id *ring_id)
107 {
108 	pg_confchg_fn (configuration_type,
109 		member_list, member_list_entries,
110 		left_list, left_list_entries,
111 		joined_list, joined_list_entries,
112 		ring_id);
113 }
114 
115 /*
116  * Initialize the totem multiple ring protocol
117  */
totemmrp_initialize(qb_loop_t * poll_handle,struct totem_config * totem_config,totempg_stats_t * stats,void (* deliver_fn)(unsigned int nodeid,const void * msg,unsigned int msg_len,int endian_conversion_required),void (* confchg_fn)(enum totem_configuration_type configuration_type,const unsigned int * member_list,size_t member_list_entries,const unsigned int * left_list,size_t left_list_entries,const unsigned int * joined_list,size_t joined_list_entries,const struct memb_ring_id * ring_id),void (* waiting_trans_ack_cb_fn)(int waiting_trans_ack))118 int totemmrp_initialize (
119 	qb_loop_t *poll_handle,
120 	struct totem_config *totem_config,
121 	totempg_stats_t *stats,
122 
123 	void (*deliver_fn) (
124 		unsigned int nodeid,
125 		const void *msg,
126 		unsigned int msg_len,
127 		int endian_conversion_required),
128 	void (*confchg_fn) (
129 		enum totem_configuration_type configuration_type,
130 		const unsigned int *member_list, size_t member_list_entries,
131 		const unsigned int *left_list, size_t left_list_entries,
132 		const unsigned int *joined_list, size_t joined_list_entries,
133 		const struct memb_ring_id *ring_id),
134 	void (*waiting_trans_ack_cb_fn) (
135 		int waiting_trans_ack))
136 {
137 	int result;
138 	pg_deliver_fn = deliver_fn;
139 	pg_confchg_fn = confchg_fn;
140 
141 	stats->mrp = calloc (sizeof(totemmrp_stats_t), 1);
142 	result = totemsrp_initialize (
143 		poll_handle,
144 		&totemsrp_context,
145 		totem_config,
146 		stats->mrp,
147 		totemmrp_deliver_fn,
148 		totemmrp_confchg_fn,
149 		waiting_trans_ack_cb_fn);
150 
151 	return (result);
152 }
153 
totemmrp_finalize(void)154 void totemmrp_finalize (void)
155 {
156 	totemsrp_finalize (totemsrp_context);
157 }
158 
159 /*
160  * Multicast a message
161  */
totemmrp_mcast(struct iovec * iovec,unsigned int iov_len,int priority)162 int totemmrp_mcast (
163 	struct iovec *iovec,
164 	unsigned int iov_len,
165 	int priority)
166 {
167 	return totemsrp_mcast (totemsrp_context, iovec, iov_len, priority);
168 }
169 
170 /*
171  * Return number of available messages that can be queued
172  */
totemmrp_avail(void)173 int totemmrp_avail (void)
174 {
175 	return (totemsrp_avail (totemsrp_context));
176 }
177 
totemmrp_callback_token_create(void ** handle_out,enum totem_callback_token_type type,int delete,int (* callback_fn)(enum totem_callback_token_type type,const void *),const void * data)178 int totemmrp_callback_token_create (
179 	void **handle_out,
180 	enum totem_callback_token_type type,
181 	int delete,
182 	int (*callback_fn) (enum totem_callback_token_type type, const void *),
183 	const void *data)
184 {
185 	return totemsrp_callback_token_create (totemsrp_context, handle_out, type, delete, callback_fn, data);
186 }
187 
totemmrp_callback_token_destroy(void * handle_out)188 void totemmrp_callback_token_destroy (
189 	void *handle_out)
190 {
191 	totemsrp_callback_token_destroy (totemsrp_context, handle_out);
192 }
193 
totemmrp_event_signal(enum totem_event_type type,int value)194 void totemmrp_event_signal (enum totem_event_type type, int value)
195 {
196 	totemsrp_event_signal (totemsrp_context, type, value);
197 }
198 
totemmrp_ifaces_get(unsigned int nodeid,struct totem_ip_address * interfaces,unsigned int interfaces_size,char *** status,unsigned int * iface_count)199 int totemmrp_ifaces_get (
200 	unsigned int nodeid,
201 	struct totem_ip_address *interfaces,
202 	unsigned int interfaces_size,
203 	char ***status,
204 	unsigned int *iface_count)
205 {
206 	int res;
207 
208 	res = totemsrp_ifaces_get (
209 		totemsrp_context,
210 		nodeid,
211 		interfaces,
212 		interfaces_size,
213 		status,
214 		iface_count);
215 
216 	return (res);
217 }
218 
totemmrp_crypto_set(const char * cipher_type,const char * hash_type)219 int totemmrp_crypto_set (
220 	const char *cipher_type,
221 	const char *hash_type)
222 {
223 	return totemsrp_crypto_set (totemsrp_context,
224 				    cipher_type,
225 				    hash_type);
226 }
227 
totemmrp_my_nodeid_get(void)228 unsigned int totemmrp_my_nodeid_get (void)
229 {
230 	return (totemsrp_my_nodeid_get (totemsrp_context));
231 }
232 
totemmrp_my_family_get(void)233 int totemmrp_my_family_get (void)
234 {
235 	return (totemsrp_my_family_get (totemsrp_context));
236 }
237 
totemmrp_ring_reenable(void)238 extern int totemmrp_ring_reenable (void)
239 {
240 	int res;
241 
242 	res = totemsrp_ring_reenable (
243 		totemsrp_context);
244 
245 	return (res);
246 }
247 
totemmrp_service_ready_register(void (* totem_service_ready)(void))248 extern void totemmrp_service_ready_register (
249         void (*totem_service_ready) (void))
250 {
251 	totemsrp_service_ready_register (
252 		totemsrp_context,
253 		totem_service_ready);
254 }
255 
totemmrp_member_add(const struct totem_ip_address * member,int ring_no)256 int totemmrp_member_add (
257         const struct totem_ip_address *member,
258         int ring_no)
259 {
260 	int res;
261 
262 	res = totemsrp_member_add (totemsrp_context, member, ring_no);
263 
264 	return (res);
265 }
266 
totemmrp_member_remove(const struct totem_ip_address * member,int ring_no)267 int totemmrp_member_remove (
268        const struct totem_ip_address *member,
269         int ring_no)
270 {
271 	int res;
272 
273 	res = totemsrp_member_remove (totemsrp_context, member, ring_no);
274 
275 	return (res);
276 }
277 
totemmrp_threaded_mode_enable(void)278 void totemmrp_threaded_mode_enable (void)
279 {
280 	totemsrp_threaded_mode_enable (totemsrp_context);
281 }
282 
totemmrp_trans_ack(void)283 void totemmrp_trans_ack (void)
284 {
285 	totemsrp_trans_ack (totemsrp_context);
286 }
287