corosync  2.3.2
totemnet.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005 MontaVista Software, Inc.
3  * Copyright (c) 2006-2012 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 <assert.h>
39 
40 #ifdef HAVE_RDMA
41 #include <totemiba.h>
42 #endif
43 #include <totemudp.h>
44 #include <totemudpu.h>
45 #include <totemnet.h>
46 #include <qb/qbloop.h>
47 
48 #define LOGSYS_UTILS_ONLY 1
49 #include <corosync/logsys.h>
50 
51 struct transport {
52  const char *name;
53 
54  int (*initialize) (
55  qb_loop_t *loop_pt,
56  void **transport_instance,
57  struct totem_config *totem_config,
58  totemsrp_stats_t *stats,
59  int interface_no,
60  void *context,
61 
62  void (*deliver_fn) (
63  void *context,
64  const void *msg,
65  unsigned int msg_len),
66 
67  void (*iface_change_fn) (
68  void *context,
69  const struct totem_ip_address *iface_address),
70 
71  void (*target_set_completed) (
72  void *context));
73 
74  void *(*buffer_alloc) (void);
75 
76  void (*buffer_release) (void *ptr);
77 
79  void *transport_context,
80  int processor_count);
81 
82  int (*token_send) (
83  void *transport_context,
84  const void *msg,
85  unsigned int msg_len);
86 
88  void *transport_context,
89  const void *msg,
90  unsigned int msg_len);
91 
92 
94  void *transport_context,
95  const void *msg,
96  unsigned int msg_len);
97 
98  int (*recv_flush) (void *transport_context);
99 
100  int (*send_flush) (void *transport_context);
101 
102  int (*iface_check) (void *transport_context);
103 
104  int (*finalize) (void *transport_context);
105 
106  void (*net_mtu_adjust) (void *transport_context, struct totem_config *totem_config);
107 
108  const char *(*iface_print) (void *transport_context);
109 
110  int (*iface_get) (
111  void *transport_context,
112  struct totem_ip_address *addr);
113 
115  void *transport_context,
116  const struct totem_ip_address *token_target);
117 
118  int (*crypto_set) (
119  void *transport_context,
120  const char *cipher_type,
121  const char *hash_type);
122 
124  void *transport_context);
125 
126  int (*member_add) (
127  void *transport_context,
128  const struct totem_ip_address *member);
129 
130  int (*member_remove) (
131  void *transport_context,
132  const struct totem_ip_address *member);
133 };
134 
136  {
137  .name = "UDP/IP Multicast",
138  .initialize = totemudp_initialize,
139  .buffer_alloc = totemudp_buffer_alloc,
140  .buffer_release = totemudp_buffer_release,
141  .processor_count_set = totemudp_processor_count_set,
142  .token_send = totemudp_token_send,
143  .mcast_flush_send = totemudp_mcast_flush_send,
144  .mcast_noflush_send = totemudp_mcast_noflush_send,
145  .recv_flush = totemudp_recv_flush,
146  .send_flush = totemudp_send_flush,
147  .iface_check = totemudp_iface_check,
148  .finalize = totemudp_finalize,
149  .net_mtu_adjust = totemudp_net_mtu_adjust,
150  .iface_print = totemudp_iface_print,
151  .iface_get = totemudp_iface_get,
152  .token_target_set = totemudp_token_target_set,
153  .crypto_set = totemudp_crypto_set,
154  .recv_mcast_empty = totemudp_recv_mcast_empty
155  },
156  {
157  .name = "UDP/IP Unicast",
158  .initialize = totemudpu_initialize,
159  .buffer_alloc = totemudpu_buffer_alloc,
160  .buffer_release = totemudpu_buffer_release,
161  .processor_count_set = totemudpu_processor_count_set,
162  .token_send = totemudpu_token_send,
163  .mcast_flush_send = totemudpu_mcast_flush_send,
164  .mcast_noflush_send = totemudpu_mcast_noflush_send,
165  .recv_flush = totemudpu_recv_flush,
166  .send_flush = totemudpu_send_flush,
167  .iface_check = totemudpu_iface_check,
168  .finalize = totemudpu_finalize,
169  .net_mtu_adjust = totemudpu_net_mtu_adjust,
170  .iface_print = totemudpu_iface_print,
171  .iface_get = totemudpu_iface_get,
172  .token_target_set = totemudpu_token_target_set,
173  .crypto_set = totemudpu_crypto_set,
174  .recv_mcast_empty = totemudpu_recv_mcast_empty,
175  .member_add = totemudpu_member_add,
176  .member_remove = totemudpu_member_remove
177  },
178 #ifdef HAVE_RDMA
179  {
180  .name = "Infiniband/IP",
181  .initialize = totemiba_initialize,
182  .buffer_alloc = totemiba_buffer_alloc,
183  .buffer_release = totemiba_buffer_release,
184  .processor_count_set = totemiba_processor_count_set,
185  .token_send = totemiba_token_send,
186  .mcast_flush_send = totemiba_mcast_flush_send,
187  .mcast_noflush_send = totemiba_mcast_noflush_send,
188  .recv_flush = totemiba_recv_flush,
189  .send_flush = totemiba_send_flush,
190  .iface_check = totemiba_iface_check,
191  .finalize = totemiba_finalize,
192  .net_mtu_adjust = totemiba_net_mtu_adjust,
193  .iface_print = totemiba_iface_print,
194  .iface_get = totemiba_iface_get,
195  .token_target_set = totemiba_token_target_set,
196  .crypto_set = totemiba_crypto_set,
197  .recv_mcast_empty = totemiba_recv_mcast_empty
198 
199  }
200 #endif
201 };
202 
205 
207 
209  int level,
210  int subsys,
211  const char *function,
212  const char *file,
213  int line,
214  const char *format,
215  ...)__attribute__((format(printf, 6, 7)));
216 
217  int totemnet_subsys_id;
218 };
219 
220 #define log_printf(level, format, args...) \
221 do { \
222  instance->totemnet_log_printf ( \
223  level, \
224  instance->totemnet_subsys_id, \
225  __FUNCTION__, __FILE__, __LINE__, \
226  (const char *)format, ##args); \
227 } while (0);
228 
229 static void totemnet_instance_initialize (
230  struct totemnet_instance *instance,
231  struct totem_config *config)
232 {
233  int transport;
234 
237 
238 
239  transport = config->transport_number;
240 
242  "Initializing transport (%s).", transport_entries[transport].name);
243 
244  instance->transport = &transport_entries[transport];
245 }
246 
248  void *net_context,
249  const char *cipher_type,
250  const char *hash_type)
251 {
252  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
253  int res = 0;
254 
255  res = instance->transport->crypto_set (instance->transport_context,
256  cipher_type, hash_type);
257 
258  return res;
259 }
260 
262  void *net_context)
263 {
264  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
265  int res = 0;
266 
267  res = instance->transport->finalize (instance->transport_context);
268 
269  return (res);
270 }
271 
273  qb_loop_t *loop_pt,
274  void **net_context,
275  struct totem_config *totem_config,
276  totemsrp_stats_t *stats,
277  int interface_no,
278  void *context,
279 
280  void (*deliver_fn) (
281  void *context,
282  const void *msg,
283  unsigned int msg_len),
284 
285  void (*iface_change_fn) (
286  void *context,
287  const struct totem_ip_address *iface_address),
288 
289  void (*target_set_completed) (
290  void *context))
291 {
292  struct totemnet_instance *instance;
293  unsigned int res;
294 
295  instance = malloc (sizeof (struct totemnet_instance));
296  if (instance == NULL) {
297  return (-1);
298  }
299  totemnet_instance_initialize (instance, totem_config);
300 
301  res = instance->transport->initialize (loop_pt,
302  &instance->transport_context, totem_config, stats,
303  interface_no, context, deliver_fn, iface_change_fn, target_set_completed);
304 
305  if (res == -1) {
306  goto error_destroy;
307  }
308 
309  *net_context = instance;
310  return (0);
311 
312 error_destroy:
313  free (instance);
314  return (-1);
315 }
316 
317 void *totemnet_buffer_alloc (void *net_context)
318 {
319  struct totemnet_instance *instance = net_context;
320  assert (instance != NULL);
321  assert (instance->transport != NULL);
322  return instance->transport->buffer_alloc();
323 }
324 
325 void totemnet_buffer_release (void *net_context, void *ptr)
326 {
327  struct totemnet_instance *instance = net_context;
328  assert (instance != NULL);
329  assert (instance->transport != NULL);
330  instance->transport->buffer_release (ptr);
331 }
332 
334  void *net_context,
335  int processor_count)
336 {
337  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
338  int res = 0;
339 
340  res = instance->transport->processor_count_set (instance->transport_context, processor_count);
341  return (res);
342 }
343 
344 int totemnet_recv_flush (void *net_context)
345 {
346  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
347  int res = 0;
348 
349  res = instance->transport->recv_flush (instance->transport_context);
350 
351  return (res);
352 }
353 
354 int totemnet_send_flush (void *net_context)
355 {
356  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
357  int res = 0;
358 
359  res = instance->transport->send_flush (instance->transport_context);
360 
361  return (res);
362 }
363 
365  void *net_context,
366  const void *msg,
367  unsigned int msg_len)
368 {
369  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
370  int res = 0;
371 
372  res = instance->transport->token_send (instance->transport_context, msg, msg_len);
373 
374  return (res);
375 }
377  void *net_context,
378  const void *msg,
379  unsigned int msg_len)
380 {
381  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
382  int res = 0;
383 
384  res = instance->transport->mcast_flush_send (instance->transport_context, msg, msg_len);
385 
386  return (res);
387 }
388 
390  void *net_context,
391  const void *msg,
392  unsigned int msg_len)
393 {
394  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
395  int res = 0;
396 
397  res = instance->transport->mcast_noflush_send (instance->transport_context, msg, msg_len);
398 
399  return (res);
400 }
401 
402 extern int totemnet_iface_check (void *net_context)
403 {
404  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
405  int res = 0;
406 
407  res = instance->transport->iface_check (instance->transport_context);
408 
409  return (res);
410 }
411 
412 extern int totemnet_net_mtu_adjust (void *net_context, struct totem_config *totem_config)
413 {
414  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
415  int res = 0;
416 
417  instance->transport->net_mtu_adjust (instance->transport_context, totem_config);
418  return (res);
419 }
420 
421 const char *totemnet_iface_print (void *net_context) {
422  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
423  const char *ret_char;
424 
425  ret_char = instance->transport->iface_print (instance->transport_context);
426  return (ret_char);
427 }
428 
430  void *net_context,
431  struct totem_ip_address *addr)
432 {
433  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
434  unsigned int res;
435 
436  res = instance->transport->iface_get (instance->transport_context, addr);
437 
438  return (res);
439 }
440 
442  void *net_context,
443  const struct totem_ip_address *token_target)
444 {
445  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
446  unsigned int res;
447 
448  res = instance->transport->token_target_set (instance->transport_context, token_target);
449 
450  return (res);
451 }
452 
454  void *net_context)
455 {
456  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
457  unsigned int res;
458 
459  res = instance->transport->recv_mcast_empty (instance->transport_context);
460 
461  return (res);
462 }
463 
465  void *net_context,
466  const struct totem_ip_address *member)
467 {
468  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
469  unsigned int res = 0;
470 
471  if (instance->transport->member_add) {
472  res = instance->transport->member_add (
473  instance->transport_context,
474  member);
475  }
476 
477  return (res);
478 }
479 
481  void *net_context,
482  const struct totem_ip_address *member)
483 {
484  struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
485  unsigned int res = 0;
486 
487  if (instance->transport->member_remove) {
488  res = instance->transport->member_remove (
489  instance->transport_context,
490  member);
491  }
492 
493  return (res);
494 }