corosync  2.3.4
totemrrp.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 #include <pthread.h>
40 #include <sys/mman.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <sys/socket.h>
44 #include <netdb.h>
45 #include <sys/un.h>
46 #include <sys/ioctl.h>
47 #include <sys/param.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h>
50 #include <unistd.h>
51 #include <fcntl.h>
52 #include <stdlib.h>
53 #include <stdio.h>
54 #include <errno.h>
55 #include <sched.h>
56 #include <time.h>
57 #include <sys/time.h>
58 #include <sys/poll.h>
59 #include <limits.h>
60 
61 #include <corosync/sq.h>
62 #include <corosync/list.h>
63 #include <corosync/swab.h>
64 #include <qb/qbdefs.h>
65 #include <qb/qbloop.h>
66 #define LOGSYS_UTILS_ONLY 1
67 #include <corosync/logsys.h>
68 
69 #include "totemnet.h"
70 #include "totemrrp.h"
71 
72 void rrp_deliver_fn (
73  void *context,
74  const void *msg,
75  unsigned int msg_len);
76 
78  void *context,
79  const struct totem_ip_address *iface_addr);
80 
81 struct totemrrp_instance;
84  unsigned int *faulty;
85  unsigned int *token_recv_count;
86  unsigned int *mcast_recv_count;
87  unsigned char token[15000];
88  unsigned int token_len;
89  qb_loop_timer_handle timer_expired_token;
90  qb_loop_timer_handle timer_problem_decrementer;
92  unsigned int token_xmit_iface;
93  unsigned int msg_xmit_iface;
94 };
95 
98  unsigned int *faulty;
99  unsigned int *last_token_recv;
100  unsigned int *counter_problems;
101  unsigned char token[15000];
102  unsigned int token_len;
103  unsigned int last_token_seq;
104  qb_loop_timer_handle timer_expired_token;
105  qb_loop_timer_handle timer_problem_decrementer;
107 };
108 
109 struct rrp_algo {
110  const char *name;
111 
112  void * (*initialize) (
113  struct totemrrp_instance *rrp_instance,
114  int interface_count);
115 
116  void (*mcast_recv) (
117  struct totemrrp_instance *instance,
118  unsigned int iface_no,
119  void *context,
120  const void *msg,
121  unsigned int msg_len);
122 
124  struct totemrrp_instance *instance,
125  const void *msg,
126  unsigned int msg_len);
127 
129  struct totemrrp_instance *instance,
130  const void *msg,
131  unsigned int msg_len);
132 
133  void (*token_recv) (
134  struct totemrrp_instance *instance,
135  unsigned int iface_no,
136  void *context,
137  const void *msg,
138  unsigned int msg_len,
139  unsigned int token_seqid);
140 
141  void (*token_send) (
142  struct totemrrp_instance *instance,
143  const void *msg,
144  unsigned int msg_len);
145 
146  void (*recv_flush) (
147  struct totemrrp_instance *instance);
148 
149  void (*send_flush) (
150  struct totemrrp_instance *instance);
151 
152  void (*iface_check) (
153  struct totemrrp_instance *instance);
154 
156  struct totemrrp_instance *instance,
157  unsigned int processor_count);
158 
160  struct totemrrp_instance *instance,
161  struct totem_ip_address *token_target,
162  unsigned int iface_no);
163 
164  void (*ring_reenable) (
165  struct totemrrp_instance *instance,
166  unsigned int iface_no);
167 
169  struct totemrrp_instance *instance);
170 
171  int (*member_add) (
172  struct totemrrp_instance *instance,
173  const struct totem_ip_address *member,
174  unsigned int iface_no);
175 
176  int (*member_remove) (
177  struct totemrrp_instance *instance,
178  const struct totem_ip_address *member,
179  unsigned int iface_no);
180 
182  struct totemrrp_instance *instance,
183  enum totem_configuration_type configuration_type,
184  const struct srp_addr *member_list, size_t member_list_entries,
185  const struct srp_addr *left_list, size_t left_list_entries,
186  const struct srp_addr *joined_list, size_t joined_list_entries,
187  const struct memb_ring_id *ring_id);
188 };
189 
190 #define STATUS_STR_LEN 512
192  qb_loop_t *poll_handle;
193 
195 
197 
198  void *context;
199 
201 
203  void *context,
204  const void *msg,
205  unsigned int msg_len);
206 
208  void *context,
209  const struct totem_ip_address *iface_addr,
210  unsigned int iface_no);
211 
213  const void *msg,
214  unsigned int *seqid,
215  unsigned int *token_is);
216 
218  void *context);
219 
220  unsigned int (*totemrrp_msgs_missing) (void);
221 
222  /*
223  * Function and data used to log messages
224  */
226 
228 
230 
232 
234 
236 
238  int level,
239  int subsys,
240  const char *function,
241  const char *file,
242  int line,
243  const char *format, ...)__attribute__((format(printf, 6, 7)));
244 
245  void **net_handles;
246 
248 
250 
252 
254 
256 
258 
260 
262 };
263 
264 static void stats_set_interface_faulty(struct totemrrp_instance *rrp_instance,
265  unsigned int iface_no, int is_faulty);
266 
267 /*
268  * None Replication Forward Declerations
269  */
270 static void none_mcast_recv (
271  struct totemrrp_instance *instance,
272  unsigned int iface_no,
273  void *context,
274  const void *msg,
275  unsigned int msg_len);
276 
277 static void none_mcast_noflush_send (
278  struct totemrrp_instance *instance,
279  const void *msg,
280  unsigned int msg_len);
281 
282 static void none_mcast_flush_send (
283  struct totemrrp_instance *instance,
284  const void *msg,
285  unsigned int msg_len);
286 
287 static void none_token_recv (
288  struct totemrrp_instance *instance,
289  unsigned int iface_no,
290  void *context,
291  const void *msg,
292  unsigned int msg_len,
293  unsigned int token_seqid);
294 
295 static void none_token_send (
296  struct totemrrp_instance *instance,
297  const void *msg,
298  unsigned int msg_len);
299 
300 static void none_recv_flush (
301  struct totemrrp_instance *instance);
302 
303 static void none_send_flush (
304  struct totemrrp_instance *instance);
305 
306 static void none_iface_check (
307  struct totemrrp_instance *instance);
308 
309 static void none_processor_count_set (
310  struct totemrrp_instance *instance,
311  unsigned int processor_count_set);
312 
313 static void none_token_target_set (
314  struct totemrrp_instance *instance,
315  struct totem_ip_address *token_target,
316  unsigned int iface_no);
317 
318 static void none_ring_reenable (
319  struct totemrrp_instance *instance,
320  unsigned int iface_no);
321 
322 static int none_mcast_recv_empty (
323  struct totemrrp_instance *instance);
324 
325 static int none_member_add (
326  struct totemrrp_instance *instance,
327  const struct totem_ip_address *member,
328  unsigned int iface_no);
329 
330 static int none_member_remove (
331  struct totemrrp_instance *instance,
332  const struct totem_ip_address *member,
333  unsigned int iface_no);
334 
335 static void none_membership_changed (
336  struct totemrrp_instance *instance,
337  enum totem_configuration_type configuration_type,
338  const struct srp_addr *member_list, size_t member_list_entries,
339  const struct srp_addr *left_list, size_t left_list_entries,
340  const struct srp_addr *joined_list, size_t joined_list_entries,
341  const struct memb_ring_id *ring_id);
342 
343 /*
344  * Passive Replication Forward Declerations
345  */
346 static void *passive_instance_initialize (
347  struct totemrrp_instance *rrp_instance,
348  int interface_count);
349 
350 static void passive_mcast_recv (
351  struct totemrrp_instance *instance,
352  unsigned int iface_no,
353  void *context,
354  const void *msg,
355  unsigned int msg_len);
356 
357 static void passive_mcast_noflush_send (
358  struct totemrrp_instance *instance,
359  const void *msg,
360  unsigned int msg_len);
361 
362 static void passive_mcast_flush_send (
363  struct totemrrp_instance *instance,
364  const void *msg,
365  unsigned int msg_len);
366 
367 static void passive_monitor (
368  struct totemrrp_instance *rrp_instance,
369  unsigned int iface_no,
370  int is_token_recv_count);
371 
372 static void passive_token_recv (
373  struct totemrrp_instance *instance,
374  unsigned int iface_no,
375  void *context,
376  const void *msg,
377  unsigned int msg_len,
378  unsigned int token_seqid);
379 
380 static void passive_token_send (
381  struct totemrrp_instance *instance,
382  const void *msg,
383  unsigned int msg_len);
384 
385 static void passive_recv_flush (
386  struct totemrrp_instance *instance);
387 
388 static void passive_send_flush (
389  struct totemrrp_instance *instance);
390 
391 static void passive_iface_check (
392  struct totemrrp_instance *instance);
393 
394 static void passive_processor_count_set (
395  struct totemrrp_instance *instance,
396  unsigned int processor_count_set);
397 
398 static void passive_token_target_set (
399  struct totemrrp_instance *instance,
400  struct totem_ip_address *token_target,
401  unsigned int iface_no);
402 
403 static void passive_ring_reenable (
404  struct totemrrp_instance *instance,
405  unsigned int iface_no);
406 
407 static int passive_mcast_recv_empty (
408  struct totemrrp_instance *instance);
409 
410 static int passive_member_add (
411  struct totemrrp_instance *instance,
412  const struct totem_ip_address *member,
413  unsigned int iface_no);
414 
415 static int passive_member_remove (
416  struct totemrrp_instance *instance,
417  const struct totem_ip_address *member,
418  unsigned int iface_no);
419 
420 static void passive_membership_changed (
421  struct totemrrp_instance *instance,
422  enum totem_configuration_type configuration_type,
423  const struct srp_addr *member_list, size_t member_list_entries,
424  const struct srp_addr *left_list, size_t left_list_entries,
425  const struct srp_addr *joined_list, size_t joined_list_entries,
426  const struct memb_ring_id *ring_id);
427 
428 /*
429  * Active Replication Forward Definitions
430  */
431 static void *active_instance_initialize (
432  struct totemrrp_instance *rrp_instance,
433  int interface_count);
434 
435 static void active_mcast_recv (
436  struct totemrrp_instance *instance,
437  unsigned int iface_no,
438  void *context,
439  const void *msg,
440  unsigned int msg_len);
441 
442 static void active_mcast_noflush_send (
443  struct totemrrp_instance *instance,
444  const void *msg,
445  unsigned int msg_len);
446 
447 static void active_mcast_flush_send (
448  struct totemrrp_instance *instance,
449  const void *msg,
450  unsigned int msg_len);
451 
452 static void active_token_recv (
453  struct totemrrp_instance *instance,
454  unsigned int iface_no,
455  void *context,
456  const void *msg,
457  unsigned int msg_len,
458  unsigned int token_seqid);
459 
460 static void active_token_send (
461  struct totemrrp_instance *instance,
462  const void *msg,
463  unsigned int msg_len);
464 
465 static void active_recv_flush (
466  struct totemrrp_instance *instance);
467 
468 static void active_send_flush (
469  struct totemrrp_instance *instance);
470 
471 static void active_iface_check (
472  struct totemrrp_instance *instance);
473 
474 static void active_processor_count_set (
475  struct totemrrp_instance *instance,
476  unsigned int processor_count_set);
477 
478 static void active_token_target_set (
479  struct totemrrp_instance *instance,
480  struct totem_ip_address *token_target,
481  unsigned int iface_no);
482 
483 static void active_ring_reenable (
484  struct totemrrp_instance *instance,
485  unsigned int iface_no);
486 
487 static int active_mcast_recv_empty (
488  struct totemrrp_instance *instance);
489 
490 static int active_member_add (
491  struct totemrrp_instance *instance,
492  const struct totem_ip_address *member,
493  unsigned int iface_no);
494 
495 static int active_member_remove (
496  struct totemrrp_instance *instance,
497  const struct totem_ip_address *member,
498  unsigned int iface_no);
499 
500 static void active_membership_changed (
501  struct totemrrp_instance *instance,
502  enum totem_configuration_type configuration_type,
503  const struct srp_addr *member_list, size_t member_list_entries,
504  const struct srp_addr *left_list, size_t left_list_entries,
505  const struct srp_addr *joined_list, size_t joined_list_entries,
506  const struct memb_ring_id *ring_id);
507 
508 static void active_timer_expired_token_start (
510 
511 static void active_timer_expired_token_cancel (
513 
514 static void active_timer_problem_decrementer_start (
516 
517 static void active_timer_problem_decrementer_cancel (
520 /*
521  * 0-5 reserved for totemsrp.c
522  */
523 #define MESSAGE_TYPE_RING_TEST_ACTIVE 6
524 #define MESSAGE_TYPE_RING_TEST_ACTIVATE 7
525 
526 #define ENDIAN_LOCAL 0xff22
527 
528 /*
529  * Rollover handling:
530  *
531  * ARR_SEQNO_START_TOKEN is the starting sequence number of last seen sequence
532  * for a token for active redundand ring. This should remain zero, unless testing
533  * overflow in which case 07fffff00 or 0xffffff00 are good starting values.
534  * It should be same as on defined in totemsrp.c
535  */
536 
537 #define ARR_SEQNO_START_TOKEN 0x0
538 
539 /*
540  * These can be used ot test different rollover points
541  * #define ARR_SEQNO_START_MSG 0xfffffe00
542  */
543 
544 /*
545  * Threshold value when recv_count for passive rrp should be adjusted.
546  * Set this value to some smaller for testing of adjusting proper
547  * functionality. Also keep in mind that this value must be smaller
548  * then rrp_problem_count_threshold
549  */
550 #define PASSIVE_RECV_COUNT_THRESHOLD (INT_MAX / 2)
551 
553  char type;
555  unsigned short endian_detector;
558 } __attribute__((packed));
559 
562  void *context;
563  int iface_no;
564 };
565 
566 struct rrp_algo none_algo = {
567  .name = "none",
568  .initialize = NULL,
569  .mcast_recv = none_mcast_recv,
570  .mcast_noflush_send = none_mcast_noflush_send,
571  .mcast_flush_send = none_mcast_flush_send,
572  .token_recv = none_token_recv,
573  .token_send = none_token_send,
574  .recv_flush = none_recv_flush,
575  .send_flush = none_send_flush,
576  .iface_check = none_iface_check,
577  .processor_count_set = none_processor_count_set,
578  .token_target_set = none_token_target_set,
579  .ring_reenable = none_ring_reenable,
580  .mcast_recv_empty = none_mcast_recv_empty,
581  .member_add = none_member_add,
582  .member_remove = none_member_remove,
583  .membership_changed = none_membership_changed
584 };
585 
586 struct rrp_algo passive_algo = {
587  .name = "passive",
588  .initialize = passive_instance_initialize,
589  .mcast_recv = passive_mcast_recv,
590  .mcast_noflush_send = passive_mcast_noflush_send,
591  .mcast_flush_send = passive_mcast_flush_send,
592  .token_recv = passive_token_recv,
593  .token_send = passive_token_send,
594  .recv_flush = passive_recv_flush,
595  .send_flush = passive_send_flush,
596  .iface_check = passive_iface_check,
597  .processor_count_set = passive_processor_count_set,
598  .token_target_set = passive_token_target_set,
599  .ring_reenable = passive_ring_reenable,
600  .mcast_recv_empty = passive_mcast_recv_empty,
601  .member_add = passive_member_add,
602  .member_remove = passive_member_remove,
603  .membership_changed = passive_membership_changed
604 };
605 
606 struct rrp_algo active_algo = {
607  .name = "active",
608  .initialize = active_instance_initialize,
609  .mcast_recv = active_mcast_recv,
610  .mcast_noflush_send = active_mcast_noflush_send,
611  .mcast_flush_send = active_mcast_flush_send,
612  .token_recv = active_token_recv,
613  .token_send = active_token_send,
614  .recv_flush = active_recv_flush,
615  .send_flush = active_send_flush,
616  .iface_check = active_iface_check,
617  .processor_count_set = active_processor_count_set,
618  .token_target_set = active_token_target_set,
619  .ring_reenable = active_ring_reenable,
620  .mcast_recv_empty = active_mcast_recv_empty,
621  .member_add = active_member_add,
622  .member_remove = active_member_remove,
623  .membership_changed = active_membership_changed
624 };
625 
626 struct rrp_algo *rrp_algos[] = {
627  &none_algo,
628  &passive_algo,
629  &active_algo
630 };
631 
632 #define RRP_ALGOS_COUNT 3
633 
634 #define log_printf(level, format, args...) \
635 do { \
636  rrp_instance->totemrrp_log_printf ( \
637  level, rrp_instance->totemrrp_subsys_id, \
638  __FUNCTION__, __FILE__, __LINE__, \
639  format, ##args); \
640 } while (0);
641 
642 static void stats_set_interface_faulty(struct totemrrp_instance *rrp_instance,
643  unsigned int iface_no, int is_faulty)
644 {
645  rrp_instance->stats.faulty[iface_no] = (is_faulty ? 1 : 0);
646 }
647 
648 static void test_active_msg_endian_convert(const struct message_header *in, struct message_header *out)
649 {
650  out->type = in->type;
651  out->encapsulated = in->encapsulated;
653  out->ring_number = swab32 (in->ring_number);
655 }
656 
657 static void timer_function_test_ring_timeout (void *context)
658 {
659  struct deliver_fn_context *deliver_fn_context = (struct deliver_fn_context *)context;
660  struct totemrrp_instance *rrp_instance = deliver_fn_context->instance;
661  unsigned int *faulty = NULL;
662  int iface_no = deliver_fn_context->iface_no;
663  struct message_header msg = {
665  .endian_detector = ENDIAN_LOCAL,
666  };
667 
668  if (strcmp(rrp_instance->totem_config->rrp_mode, "active") == 0)
669  faulty = ((struct active_instance *)(rrp_instance->rrp_algo_instance))->faulty;
670  if (strcmp(rrp_instance->totem_config->rrp_mode, "passive") == 0)
671  faulty = ((struct passive_instance *)(rrp_instance->rrp_algo_instance))->faulty;
672 
673  assert (faulty != NULL);
674 
675  if (faulty[iface_no] == 1) {
676  msg.ring_number = iface_no;
677  msg.nodeid_activator = rrp_instance->my_nodeid;
679  rrp_instance->net_handles[iface_no],
680  &msg, sizeof (struct message_header));
681  qb_loop_timer_add (rrp_instance->poll_handle,
682  QB_LOOP_MED,
683  rrp_instance->totem_config->rrp_autorecovery_check_timeout*QB_TIME_NS_IN_MSEC,
684  (void *)deliver_fn_context,
685  timer_function_test_ring_timeout,
686  &rrp_instance->timer_active_test_ring_timeout[iface_no]);
687  }
688 }
689 
690 /*
691  * None Replication Implementation
692  */
693 
694 static void none_mcast_recv (
695  struct totemrrp_instance *rrp_instance,
696  unsigned int iface_no,
697  void *context,
698  const void *msg,
699  unsigned int msg_len)
700 {
701  rrp_instance->totemrrp_deliver_fn (
702  context,
703  msg,
704  msg_len);
705 }
706 
707 static void none_mcast_flush_send (
708  struct totemrrp_instance *instance,
709  const void *msg,
710  unsigned int msg_len)
711 {
712  totemnet_mcast_flush_send (instance->net_handles[0], msg, msg_len);
713 }
714 
715 static void none_mcast_noflush_send (
716  struct totemrrp_instance *instance,
717  const void *msg,
718  unsigned int msg_len)
719 {
720  totemnet_mcast_noflush_send (instance->net_handles[0], msg, msg_len);
721 }
722 
723 static void none_token_recv (
724  struct totemrrp_instance *rrp_instance,
725  unsigned int iface_no,
726  void *context,
727  const void *msg,
728  unsigned int msg_len,
729  unsigned int token_seq)
730 {
731  rrp_instance->totemrrp_deliver_fn (
732  context,
733  msg,
734  msg_len);
735 }
736 
737 static void none_token_send (
738  struct totemrrp_instance *instance,
739  const void *msg,
740  unsigned int msg_len)
741 {
743  instance->net_handles[0],
744  msg, msg_len);
745 }
746 
747 static void none_recv_flush (struct totemrrp_instance *instance)
748 {
749  totemnet_recv_flush (instance->net_handles[0]);
750 }
751 
752 static void none_send_flush (struct totemrrp_instance *instance)
753 {
754  totemnet_send_flush (instance->net_handles[0]);
755 }
756 
757 static void none_iface_check (struct totemrrp_instance *instance)
758 {
759  totemnet_iface_check (instance->net_handles[0]);
760 }
761 
762 static void none_processor_count_set (
763  struct totemrrp_instance *instance,
764  unsigned int processor_count)
765 {
767  processor_count);
768 }
769 
770 static void none_token_target_set (
771  struct totemrrp_instance *instance,
772  struct totem_ip_address *token_target,
773  unsigned int iface_no)
774 {
775  totemnet_token_target_set (instance->net_handles[0], token_target);
776 }
777 
778 static void none_ring_reenable (
779  struct totemrrp_instance *instance,
780  unsigned int iface_no)
781 {
782  /*
783  * No operation
784  */
785 }
786 
787 static int none_mcast_recv_empty (
788  struct totemrrp_instance *instance)
789 {
790  int res;
791 
792  res = totemnet_recv_mcast_empty (instance->net_handles[0]);
793 
794  return (res);
795 }
796 
797 static int none_member_add (
798  struct totemrrp_instance *instance,
799  const struct totem_ip_address *member,
800  unsigned int iface_no)
801 {
802  int res;
803  res = totemnet_member_add (instance->net_handles[0], member);
804  return (res);
805 }
806 
807 static int none_member_remove (
808  struct totemrrp_instance *instance,
809  const struct totem_ip_address *member,
810  unsigned int iface_no)
811 {
812  int res;
813  res = totemnet_member_remove (instance->net_handles[0], member);
814  return (res);
815 }
816 
817 static void none_membership_changed (
818  struct totemrrp_instance *rrp_instance,
819  enum totem_configuration_type configuration_type,
820  const struct srp_addr *member_list, size_t member_list_entries,
821  const struct srp_addr *left_list, size_t left_list_entries,
822  const struct srp_addr *joined_list, size_t joined_list_entries,
823  const struct memb_ring_id *ring_id)
824 {
825  int i;
826 
827  for (i = 0; i < left_list_entries; i++) {
828  if (left_list->no_addrs < 1 ||
829  (left_list[i].addr[0].family != AF_INET && left_list[i].addr[0].family != AF_INET6)) {
830  log_printf(rrp_instance->totemrrp_log_level_error,
831  "Membership left list contains incorrect address. "
832  "This is sign of misconfiguration between nodes!");
833  } else {
834  totemnet_member_set_active(rrp_instance->net_handles[0],
835  &left_list[i].addr[0], 0);
836  }
837  }
838 
839  for (i = 0; i < joined_list_entries; i++) {
840  if (joined_list->no_addrs < 1 ||
841  (joined_list[i].addr[0].family != AF_INET && joined_list[i].addr[0].family != AF_INET6)) {
842  log_printf(rrp_instance->totemrrp_log_level_error,
843  "Membership join list contains incorrect address. "
844  "This is sign of misconfiguration between nodes!");
845  } else {
846  totemnet_member_set_active(rrp_instance->net_handles[0],
847  &joined_list[i].addr[0], 1);
848  }
849  }
850 }
851 
852 /*
853  * Passive Replication Implementation
854  */
855 void *passive_instance_initialize (
856  struct totemrrp_instance *rrp_instance,
857  int interface_count)
858 {
859  struct passive_instance *instance;
860  int i;
861 
862  instance = malloc (sizeof (struct passive_instance));
863  if (instance == 0) {
864  goto error_exit;
865  }
866  memset (instance, 0, sizeof (struct passive_instance));
867 
868  instance->faulty = malloc (sizeof (int) * interface_count);
869  if (instance->faulty == 0) {
870  free (instance);
871  instance = 0;
872  goto error_exit;
873  }
874  memset (instance->faulty, 0, sizeof (int) * interface_count);
875 
876  for (i = 0; i < interface_count; i++) {
877  stats_set_interface_faulty (rrp_instance, i, 0);
878  }
879 
880  instance->token_recv_count = malloc (sizeof (int) * interface_count);
881  if (instance->token_recv_count == 0) {
882  free (instance->faulty);
883  free (instance);
884  instance = 0;
885  goto error_exit;
886  }
887  memset (instance->token_recv_count, 0, sizeof (int) * interface_count);
888 
889  instance->mcast_recv_count = malloc (sizeof (int) * interface_count);
890  if (instance->mcast_recv_count == 0) {
891  free (instance->token_recv_count);
892  free (instance->faulty);
893  free (instance);
894  instance = 0;
895  goto error_exit;
896  }
897  memset (instance->mcast_recv_count, 0, sizeof (int) * interface_count);
898 
899 error_exit:
900  return ((void *)instance);
901 }
902 
903 static void timer_function_passive_token_expired (void *context)
904 {
905  struct passive_instance *passive_instance = (struct passive_instance *)context;
906  struct totemrrp_instance *rrp_instance = passive_instance->rrp_instance;
907 
908  rrp_instance->totemrrp_deliver_fn (
909  passive_instance->totemrrp_context,
910  passive_instance->token,
911  passive_instance->token_len);
912 }
913 
914 /* TODO
915 static void timer_function_passive_problem_decrementer (void *context)
916 {
917 // struct passive_instance *passive_instance = (struct passive_instance *)context;
918 // struct totemrrp_instance *rrp_instance = passive_instance->rrp_instance;
919 
920 }
921 */
922 
923 
924 static void passive_timer_expired_token_start (
925  struct passive_instance *passive_instance)
926 {
927  qb_loop_timer_add (
928  passive_instance->rrp_instance->poll_handle,
929  QB_LOOP_MED,
930  passive_instance->rrp_instance->totem_config->rrp_token_expired_timeout*QB_TIME_NS_IN_MSEC,
931  (void *)passive_instance,
932  timer_function_passive_token_expired,
933  &passive_instance->timer_expired_token);
934 }
935 
936 static void passive_timer_expired_token_cancel (
937  struct passive_instance *passive_instance)
938 {
939  qb_loop_timer_del (
940  passive_instance->rrp_instance->poll_handle,
941  passive_instance->timer_expired_token);
942 }
943 
944 /*
945 static void passive_timer_problem_decrementer_start (
946  struct passive_instance *passive_instance)
947 {
948  qb_loop_timer_add (
949  QB_LOOP_MED,
950  passive_instance->rrp_instance->poll_handle,
951  passive_instance->rrp_instance->totem_config->rrp_problem_count_timeout*QB_TIME_NS_IN_MSEC,
952  (void *)passive_instance,
953  timer_function_passive_problem_decrementer,
954  &passive_instance->timer_problem_decrementer);
955 }
956 
957 static void passive_timer_problem_decrementer_cancel (
958  struct passive_instance *passive_instance)
959 {
960  qb_loop_timer_del (
961  passive_instance->rrp_instance->poll_handle,
962  passive_instance->timer_problem_decrementer);
963 }
964 */
965 
966 /*
967  * Monitor function implementation from rrp paper.
968  * rrp_instance is passive rrp instance, iface_no is interface with received messgae/token and
969  * is_token_recv_count is boolean variable which donates if message is token (>1) or regular
970  * message (= 0)
971  */
972 static void passive_monitor (
973  struct totemrrp_instance *rrp_instance,
974  unsigned int iface_no,
975  int is_token_recv_count)
976 {
977  struct passive_instance *passive_instance = (struct passive_instance *)rrp_instance->rrp_algo_instance;
978  unsigned int *recv_count;
979  unsigned int max;
980  unsigned int i;
981  unsigned int min_all, min_active;
982  unsigned int threshold;
983 
984  /*
985  * Monitor for failures
986  */
987  if (is_token_recv_count) {
988  recv_count = passive_instance->token_recv_count;
989  threshold = rrp_instance->totem_config->rrp_problem_count_threshold;
990  } else {
991  recv_count = passive_instance->mcast_recv_count;
992  threshold = rrp_instance->totem_config->rrp_problem_count_mcast_threshold;
993  }
994 
995  recv_count[iface_no] += 1;
996 
997  max = 0;
998  for (i = 0; i < rrp_instance->interface_count; i++) {
999  if (max < recv_count[i]) {
1000  max = recv_count[i];
1001  }
1002  }
1003 
1004  /*
1005  * Max is larger then threshold -> start adjusting process
1006  */
1008  min_all = min_active = recv_count[iface_no];
1009 
1010  for (i = 0; i < rrp_instance->interface_count; i++) {
1011  if (recv_count[i] < min_all) {
1012  min_all = recv_count[i];
1013  }
1014 
1015  if (passive_instance->faulty[i] == 0 &&
1016  recv_count[i] < min_active) {
1017  min_active = recv_count[i];
1018  }
1019  }
1020 
1021  if (min_all > 0) {
1022  /*
1023  * There is one or more faulty device with recv_count > 0
1024  */
1025  for (i = 0; i < rrp_instance->interface_count; i++) {
1026  recv_count[i] -= min_all;
1027  }
1028  } else {
1029  /*
1030  * No faulty device with recv_count > 0, adjust only active
1031  * devices
1032  */
1033  for (i = 0; i < rrp_instance->interface_count; i++) {
1034  if (passive_instance->faulty[i] == 0) {
1035  recv_count[i] -= min_active;
1036  }
1037  }
1038  }
1039 
1040  /*
1041  * Find again max
1042  */
1043  max = 0;
1044 
1045  for (i = 0; i < rrp_instance->interface_count; i++) {
1046  if (max < recv_count[i]) {
1047  max = recv_count[i];
1048  }
1049  }
1050  }
1051 
1052  for (i = 0; i < rrp_instance->interface_count; i++) {
1053  if ((passive_instance->faulty[i] == 0) &&
1054  (max - recv_count[i] > threshold)) {
1055  passive_instance->faulty[i] = 1;
1056 
1057  qb_loop_timer_add (rrp_instance->poll_handle,
1058  QB_LOOP_MED,
1059  rrp_instance->totem_config->rrp_autorecovery_check_timeout*QB_TIME_NS_IN_MSEC,
1060  rrp_instance->deliver_fn_context[i],
1061  timer_function_test_ring_timeout,
1062  &rrp_instance->timer_active_test_ring_timeout[i]);
1063 
1064  stats_set_interface_faulty (rrp_instance, i, passive_instance->faulty[i]);
1065 
1066  snprintf (rrp_instance->status[i], STATUS_STR_LEN,
1067  "Marking ringid %u interface %s FAULTY",
1068  i,
1069  totemnet_iface_print (rrp_instance->net_handles[i]));
1070  log_printf (
1071  rrp_instance->totemrrp_log_level_error,
1072  "%s",
1073  rrp_instance->status[i]);
1074  }
1075  }
1076 }
1077 
1078 static void passive_mcast_recv (
1079  struct totemrrp_instance *rrp_instance,
1080  unsigned int iface_no,
1081  void *context,
1082  const void *msg,
1083  unsigned int msg_len)
1084 {
1085  struct passive_instance *passive_instance = (struct passive_instance *)rrp_instance->rrp_algo_instance;
1086 
1087  rrp_instance->totemrrp_deliver_fn (
1088  context,
1089  msg,
1090  msg_len);
1091 
1092  if (rrp_instance->totemrrp_msgs_missing() == 0 &&
1093  passive_instance->timer_expired_token) {
1094  /*
1095  * Delivers the last token
1096  */
1097  rrp_instance->totemrrp_deliver_fn (
1098  passive_instance->totemrrp_context,
1099  passive_instance->token,
1100  passive_instance->token_len);
1101  passive_timer_expired_token_cancel (passive_instance);
1102  }
1103 
1104  passive_monitor (rrp_instance, iface_no, 0);
1105 }
1106 
1107 static void passive_mcast_flush_send (
1108  struct totemrrp_instance *instance,
1109  const void *msg,
1110  unsigned int msg_len)
1111 {
1112  struct passive_instance *passive_instance = (struct passive_instance *)instance->rrp_algo_instance;
1113  int i = 0;
1114 
1115  do {
1116  passive_instance->msg_xmit_iface = (passive_instance->msg_xmit_iface + 1) % instance->interface_count;
1117  i++;
1118  } while ((i <= instance->interface_count) && (passive_instance->faulty[passive_instance->msg_xmit_iface] == 1));
1119 
1120  if (i <= instance->interface_count) {
1121  totemnet_mcast_flush_send (instance->net_handles[passive_instance->msg_xmit_iface], msg, msg_len);
1122  }
1123 }
1124 
1125 static void passive_mcast_noflush_send (
1126  struct totemrrp_instance *instance,
1127  const void *msg,
1128  unsigned int msg_len)
1129 {
1130  struct passive_instance *passive_instance = (struct passive_instance *)instance->rrp_algo_instance;
1131  int i = 0;
1132 
1133  do {
1134  passive_instance->msg_xmit_iface = (passive_instance->msg_xmit_iface + 1) % instance->interface_count;
1135  i++;
1136  } while ((i <= instance->interface_count) && (passive_instance->faulty[passive_instance->msg_xmit_iface] == 1));
1137 
1138  if (i <= instance->interface_count) {
1139  totemnet_mcast_noflush_send (instance->net_handles[passive_instance->msg_xmit_iface], msg, msg_len);
1140  }
1141 }
1142 
1143 static void passive_token_recv (
1144  struct totemrrp_instance *rrp_instance,
1145  unsigned int iface_no,
1146  void *context,
1147  const void *msg,
1148  unsigned int msg_len,
1149  unsigned int token_seq)
1150 {
1151  struct passive_instance *passive_instance = (struct passive_instance *)rrp_instance->rrp_algo_instance;
1152 
1153  passive_instance->totemrrp_context = context; // this should be in totemrrp_instance ? TODO
1154 
1155  if (rrp_instance->totemrrp_msgs_missing() == 0) {
1156  rrp_instance->totemrrp_deliver_fn (
1157  context,
1158  msg,
1159  msg_len);
1160  } else {
1161  memcpy (passive_instance->token, msg, msg_len);
1162  passive_timer_expired_token_start (passive_instance);
1163 
1164  }
1165 
1166  passive_monitor (rrp_instance, iface_no, 1);
1167 }
1168 
1169 static void passive_token_send (
1170  struct totemrrp_instance *instance,
1171  const void *msg,
1172  unsigned int msg_len)
1173 {
1174  struct passive_instance *passive_instance = (struct passive_instance *)instance->rrp_algo_instance;
1175  int i = 0;
1176 
1177  do {
1178  passive_instance->token_xmit_iface = (passive_instance->token_xmit_iface + 1) % instance->interface_count;
1179  i++;
1180  } while ((i <= instance->interface_count) && (passive_instance->faulty[passive_instance->token_xmit_iface] == 1));
1181 
1182  if (i <= instance->interface_count) {
1184  instance->net_handles[passive_instance->token_xmit_iface],
1185  msg, msg_len);
1186  }
1187 
1188 }
1189 
1190 static void passive_recv_flush (struct totemrrp_instance *instance)
1191 {
1192  struct passive_instance *rrp_algo_instance = (struct passive_instance *)instance->rrp_algo_instance;
1193  unsigned int i;
1194 
1195  for (i = 0; i < instance->interface_count; i++) {
1196  if (rrp_algo_instance->faulty[i] == 0) {
1197 
1198  totemnet_recv_flush (instance->net_handles[i]);
1199  }
1200  }
1201 }
1202 
1203 static void passive_send_flush (struct totemrrp_instance *instance)
1204 {
1205  struct passive_instance *rrp_algo_instance = (struct passive_instance *)instance->rrp_algo_instance;
1206  unsigned int i;
1207 
1208  for (i = 0; i < instance->interface_count; i++) {
1209  if (rrp_algo_instance->faulty[i] == 0) {
1210 
1211  totemnet_send_flush (instance->net_handles[i]);
1212  }
1213  }
1214 }
1215 
1216 static void passive_iface_check (struct totemrrp_instance *instance)
1217 {
1218  struct passive_instance *rrp_algo_instance = (struct passive_instance *)instance->rrp_algo_instance;
1219  unsigned int i;
1220 
1221  for (i = 0; i < instance->interface_count; i++) {
1222  if (rrp_algo_instance->faulty[i] == 0) {
1223 
1224  totemnet_iface_check (instance->net_handles[i]);
1225  }
1226  }
1227 }
1228 
1229 static void passive_processor_count_set (
1230  struct totemrrp_instance *instance,
1231  unsigned int processor_count)
1232 {
1233  struct passive_instance *rrp_algo_instance = (struct passive_instance *)instance->rrp_algo_instance;
1234  unsigned int i;
1235 
1236  for (i = 0; i < instance->interface_count; i++) {
1237  if (rrp_algo_instance->faulty[i] == 0) {
1238 
1240  processor_count);
1241  }
1242  }
1243 }
1244 
1245 static void passive_token_target_set (
1246  struct totemrrp_instance *instance,
1247  struct totem_ip_address *token_target,
1248  unsigned int iface_no)
1249 {
1250  totemnet_token_target_set (instance->net_handles[iface_no], token_target);
1251 }
1252 
1253 static int passive_mcast_recv_empty (
1254  struct totemrrp_instance *instance)
1255 {
1256  int res;
1257  int msgs_emptied = 0;
1258  int i;
1259 
1260  for (i = 0; i < instance->interface_count; i++) {
1261  res = totemnet_recv_mcast_empty (instance->net_handles[i]);
1262  if (res == -1) {
1263  return (-1);
1264  }
1265  if (res == 1) {
1266  msgs_emptied = 1;
1267  }
1268  }
1269 
1270  return (msgs_emptied);
1271 }
1272 
1273 static int passive_member_add (
1274  struct totemrrp_instance *instance,
1275  const struct totem_ip_address *member,
1276  unsigned int iface_no)
1277 {
1278  int res;
1279  res = totemnet_member_add (instance->net_handles[iface_no], member);
1280  return (res);
1281 }
1282 
1283 static int passive_member_remove (
1284  struct totemrrp_instance *instance,
1285  const struct totem_ip_address *member,
1286  unsigned int iface_no)
1287 {
1288  int res;
1289  res = totemnet_member_remove (instance->net_handles[iface_no], member);
1290  return (res);
1291 }
1292 
1293 static void passive_membership_changed (
1294  struct totemrrp_instance *rrp_instance,
1295  enum totem_configuration_type configuration_type,
1296  const struct srp_addr *member_list, size_t member_list_entries,
1297  const struct srp_addr *left_list, size_t left_list_entries,
1298  const struct srp_addr *joined_list, size_t joined_list_entries,
1299  const struct memb_ring_id *ring_id)
1300 {
1301  int i;
1302  int interface;
1303 
1304  for (interface = 0; interface < rrp_instance->interface_count; interface++) {
1305  for (i = 0; i < left_list_entries; i++) {
1306  if (left_list->no_addrs < interface + 1 ||
1307  (left_list[i].addr[interface].family != AF_INET &&
1308  left_list[i].addr[interface].family != AF_INET6)) {
1309  log_printf(rrp_instance->totemrrp_log_level_error,
1310  "Membership left list contains incorrect address. "
1311  "This is sign of misconfiguration between nodes!");
1312  } else {
1313  totemnet_member_set_active(rrp_instance->net_handles[interface],
1314  &left_list[i].addr[interface], 0);
1315  }
1316  }
1317 
1318  for (i = 0; i < joined_list_entries; i++) {
1319  if (joined_list->no_addrs < interface + 1 ||
1320  (joined_list[i].addr[interface].family != AF_INET &&
1321  joined_list[i].addr[interface].family != AF_INET6)) {
1322  log_printf(rrp_instance->totemrrp_log_level_error,
1323  "Membership join list contains incorrect address. "
1324  "This is sign of misconfiguration between nodes!");
1325  } else {
1326  totemnet_member_set_active(rrp_instance->net_handles[interface],
1327  &joined_list[i].addr[interface], 1);
1328  }
1329  }
1330  }
1331 }
1332 
1333 static void passive_ring_reenable (
1334  struct totemrrp_instance *instance,
1335  unsigned int iface_no)
1336 {
1337  struct passive_instance *rrp_algo_instance = (struct passive_instance *)instance->rrp_algo_instance;
1338  int i;
1339 
1340  memset (rrp_algo_instance->mcast_recv_count, 0, sizeof (unsigned int) *
1341  instance->interface_count);
1342  memset (rrp_algo_instance->token_recv_count, 0, sizeof (unsigned int) *
1343  instance->interface_count);
1344 
1345  if (iface_no == instance->interface_count) {
1346  memset (rrp_algo_instance->faulty, 0, sizeof (unsigned int) *
1347  instance->interface_count);
1348  for (i = 0; i < instance->interface_count; i++) {
1349  stats_set_interface_faulty (instance, i, 0);
1350  }
1351  } else {
1352  rrp_algo_instance->faulty[iface_no] = 0;
1353  stats_set_interface_faulty (instance, iface_no, 0);
1354  }
1355 }
1356 
1357 /*
1358  * Active Replication Implementation
1359  */
1360 void *active_instance_initialize (
1361  struct totemrrp_instance *rrp_instance,
1362  int interface_count)
1363 {
1364  struct active_instance *instance;
1365  int i;
1366 
1367  instance = malloc (sizeof (struct active_instance));
1368  if (instance == 0) {
1369  goto error_exit;
1370  }
1371  memset (instance, 0, sizeof (struct active_instance));
1372 
1373  instance->faulty = malloc (sizeof (int) * interface_count);
1374  if (instance->faulty == 0) {
1375  free (instance);
1376  instance = 0;
1377  goto error_exit;
1378  }
1379  memset (instance->faulty, 0, sizeof (unsigned int) * interface_count);
1380 
1381  for (i = 0; i < interface_count; i++) {
1382  stats_set_interface_faulty (rrp_instance, i, 0);
1383  }
1384 
1385  instance->last_token_recv = malloc (sizeof (int) * interface_count);
1386  if (instance->last_token_recv == 0) {
1387  free (instance->faulty);
1388  free (instance);
1389  instance = 0;
1390  goto error_exit;
1391  }
1392  memset (instance->last_token_recv, 0, sizeof (unsigned int) * interface_count);
1393 
1394  instance->counter_problems = malloc (sizeof (int) * interface_count);
1395  if (instance->counter_problems == 0) {
1396  free (instance->last_token_recv);
1397  free (instance->faulty);
1398  free (instance);
1399  instance = 0;
1400  goto error_exit;
1401  }
1402  memset (instance->counter_problems, 0, sizeof (unsigned int) * interface_count);
1403 
1404  instance->timer_expired_token = 0;
1405 
1406  instance->timer_problem_decrementer = 0;
1407 
1408  instance->rrp_instance = rrp_instance;
1409 
1410  instance->last_token_seq = ARR_SEQNO_START_TOKEN - 1;
1411 
1412 error_exit:
1413  return ((void *)instance);
1414 }
1415 static void timer_function_active_problem_decrementer (void *context)
1416 {
1417  struct active_instance *active_instance = (struct active_instance *)context;
1418  struct totemrrp_instance *rrp_instance = active_instance->rrp_instance;
1419  unsigned int problem_found = 0;
1420  unsigned int i;
1421 
1422  for (i = 0; i < rrp_instance->interface_count; i++) {
1423  if (active_instance->counter_problems[i] > 0) {
1424  problem_found = 1;
1425  active_instance->counter_problems[i] -= 1;
1426  if (active_instance->counter_problems[i] == 0) {
1427  snprintf (rrp_instance->status[i], STATUS_STR_LEN,
1428  "ring %d active with no faults", i);
1429  } else {
1430  snprintf (rrp_instance->status[i], STATUS_STR_LEN,
1431  "Decrementing problem counter for iface %s to [%d of %d]",
1432  totemnet_iface_print (rrp_instance->net_handles[i]),
1433  active_instance->counter_problems[i],
1434  rrp_instance->totem_config->rrp_problem_count_threshold);
1435  }
1436  log_printf (
1437  rrp_instance->totemrrp_log_level_warning,
1438  "%s",
1439  rrp_instance->status[i]);
1440  }
1441  }
1442  if (problem_found) {
1443  active_timer_problem_decrementer_start (active_instance);
1444  } else {
1445  active_instance->timer_problem_decrementer = 0;
1446  }
1447 }
1448 
1449 static void timer_function_active_token_expired (void *context)
1450 {
1451  struct active_instance *active_instance = (struct active_instance *)context;
1452  struct totemrrp_instance *rrp_instance = active_instance->rrp_instance;
1453  unsigned int i;
1454 
1455  for (i = 0; i < rrp_instance->interface_count; i++) {
1456  if (active_instance->last_token_recv[i] == 0) {
1457  active_instance->counter_problems[i] += 1;
1458 
1459  if (active_instance->timer_problem_decrementer == 0) {
1460  active_timer_problem_decrementer_start (active_instance);
1461  }
1462  snprintf (rrp_instance->status[i], STATUS_STR_LEN,
1463  "Incrementing problem counter for seqid %d iface %s to [%d of %d]",
1464  active_instance->last_token_seq,
1465  totemnet_iface_print (rrp_instance->net_handles[i]),
1466  active_instance->counter_problems[i],
1467  rrp_instance->totem_config->rrp_problem_count_threshold);
1468  log_printf (
1469  rrp_instance->totemrrp_log_level_warning,
1470  "%s",
1471  rrp_instance->status[i]);
1472  }
1473  }
1474  for (i = 0; i < rrp_instance->interface_count; i++) {
1475  if (active_instance->counter_problems[i] >= rrp_instance->totem_config->rrp_problem_count_threshold &&
1476  active_instance->faulty[i] == 0) {
1477  active_instance->faulty[i] = 1;
1478 
1479  qb_loop_timer_add (rrp_instance->poll_handle,
1480  QB_LOOP_MED,
1481  rrp_instance->totem_config->rrp_autorecovery_check_timeout*QB_TIME_NS_IN_MSEC,
1482  rrp_instance->deliver_fn_context[i],
1483  timer_function_test_ring_timeout,
1484  &rrp_instance->timer_active_test_ring_timeout[i]);
1485 
1486  stats_set_interface_faulty (rrp_instance, i, active_instance->faulty[i]);
1487 
1488  snprintf (rrp_instance->status[i], STATUS_STR_LEN,
1489  "Marking seqid %d ringid %u interface %s FAULTY",
1490  active_instance->last_token_seq,
1491  i,
1492  totemnet_iface_print (rrp_instance->net_handles[i]));
1493  log_printf (
1494  rrp_instance->totemrrp_log_level_error,
1495  "%s",
1496  rrp_instance->status[i]);
1497  active_timer_problem_decrementer_cancel (active_instance);
1498  }
1499  }
1500 
1501  rrp_instance->totemrrp_deliver_fn (
1502  active_instance->totemrrp_context,
1503  active_instance->token,
1504  active_instance->token_len);
1505 }
1506 
1507 static void active_timer_expired_token_start (
1508  struct active_instance *active_instance)
1509 {
1510  qb_loop_timer_add (
1511  active_instance->rrp_instance->poll_handle,
1512  QB_LOOP_MED,
1513  active_instance->rrp_instance->totem_config->rrp_token_expired_timeout*QB_TIME_NS_IN_MSEC,
1514  (void *)active_instance,
1515  timer_function_active_token_expired,
1516  &active_instance->timer_expired_token);
1517 }
1518 
1519 static void active_timer_expired_token_cancel (
1520  struct active_instance *active_instance)
1521 {
1522  qb_loop_timer_del (
1523  active_instance->rrp_instance->poll_handle,
1524  active_instance->timer_expired_token);
1525 }
1526 
1527 static void active_timer_problem_decrementer_start (
1528  struct active_instance *active_instance)
1529 {
1530  qb_loop_timer_add (
1531  active_instance->rrp_instance->poll_handle,
1532  QB_LOOP_MED,
1533  active_instance->rrp_instance->totem_config->rrp_problem_count_timeout*QB_TIME_NS_IN_MSEC,
1534  (void *)active_instance,
1535  timer_function_active_problem_decrementer,
1536  &active_instance->timer_problem_decrementer);
1537 }
1538 
1539 static void active_timer_problem_decrementer_cancel (
1540  struct active_instance *active_instance)
1541 {
1542  qb_loop_timer_del (
1543  active_instance->rrp_instance->poll_handle,
1544  active_instance->timer_problem_decrementer);
1545 }
1546 
1547 
1548 /*
1549  * active replication
1550  */
1551 static void active_mcast_recv (
1552  struct totemrrp_instance *instance,
1553  unsigned int iface_no,
1554  void *context,
1555  const void *msg,
1556  unsigned int msg_len)
1557 {
1558  instance->totemrrp_deliver_fn (
1559  context,
1560  msg,
1561  msg_len);
1562 }
1563 
1564 static void active_mcast_flush_send (
1565  struct totemrrp_instance *instance,
1566  const void *msg,
1567  unsigned int msg_len)
1568 {
1569  int i;
1570  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1571 
1572  for (i = 0; i < instance->interface_count; i++) {
1573  if (rrp_algo_instance->faulty[i] == 0) {
1574  totemnet_mcast_flush_send (instance->net_handles[i], msg, msg_len);
1575  }
1576  }
1577 }
1578 
1579 static void active_mcast_noflush_send (
1580  struct totemrrp_instance *instance,
1581  const void *msg,
1582  unsigned int msg_len)
1583 {
1584  int i;
1585  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1586 
1587  for (i = 0; i < instance->interface_count; i++) {
1588  if (rrp_algo_instance->faulty[i] == 0) {
1589  totemnet_mcast_noflush_send (instance->net_handles[i], msg, msg_len);
1590  }
1591  }
1592 }
1593 
1594 static void active_token_recv (
1595  struct totemrrp_instance *rrp_instance,
1596  unsigned int iface_no,
1597  void *context,
1598  const void *msg,
1599  unsigned int msg_len,
1600  unsigned int token_seq)
1601 {
1602  int i;
1603  struct active_instance *active_instance = (struct active_instance *)rrp_instance->rrp_algo_instance;
1604 
1605  active_instance->totemrrp_context = context;
1606  if (sq_lt_compare (active_instance->last_token_seq, token_seq)) {
1607  memcpy (active_instance->token, msg, msg_len);
1608  active_instance->token_len = msg_len;
1609  for (i = 0; i < rrp_instance->interface_count; i++) {
1610  active_instance->last_token_recv[i] = 0;
1611  }
1612 
1613  active_instance->last_token_recv[iface_no] = 1;
1614  active_timer_expired_token_start (active_instance);
1615  }
1616 
1617  /*
1618  * This doesn't follow spec because the spec assumes we will know
1619  * when token resets occur.
1620  */
1621  active_instance->last_token_seq = token_seq;
1622 
1623  if (token_seq == active_instance->last_token_seq) {
1624  active_instance->last_token_recv[iface_no] = 1;
1625  for (i = 0; i < rrp_instance->interface_count; i++) {
1626  if ((active_instance->last_token_recv[i] == 0) &&
1627  active_instance->faulty[i] == 0) {
1628  return; /* don't deliver token */
1629  }
1630  }
1631  active_timer_expired_token_cancel (active_instance);
1632 
1633  rrp_instance->totemrrp_deliver_fn (
1634  context,
1635  msg,
1636  msg_len);
1637  }
1638 }
1639 
1640 static void active_token_send (
1641  struct totemrrp_instance *instance,
1642  const void *msg,
1643  unsigned int msg_len)
1644 {
1645  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1646  int i;
1647 
1648  for (i = 0; i < instance->interface_count; i++) {
1649  if (rrp_algo_instance->faulty[i] == 0) {
1651  instance->net_handles[i],
1652  msg, msg_len);
1653 
1654  }
1655  }
1656 }
1657 
1658 static void active_recv_flush (struct totemrrp_instance *instance)
1659 {
1660  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1661  unsigned int i;
1662 
1663  for (i = 0; i < instance->interface_count; i++) {
1664  if (rrp_algo_instance->faulty[i] == 0) {
1665 
1666  totemnet_recv_flush (instance->net_handles[i]);
1667  }
1668  }
1669 }
1670 
1671 static void active_send_flush (struct totemrrp_instance *instance)
1672 {
1673  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1674  unsigned int i;
1675 
1676  for (i = 0; i < instance->interface_count; i++) {
1677  if (rrp_algo_instance->faulty[i] == 0) {
1678 
1679  totemnet_send_flush (instance->net_handles[i]);
1680  }
1681  }
1682 }
1683 
1684 static int active_member_add (
1685  struct totemrrp_instance *instance,
1686  const struct totem_ip_address *member,
1687  unsigned int iface_no)
1688 {
1689  int res;
1690  res = totemnet_member_add (instance->net_handles[iface_no], member);
1691  return (res);
1692 }
1693 
1694 static int active_member_remove (
1695  struct totemrrp_instance *instance,
1696  const struct totem_ip_address *member,
1697  unsigned int iface_no)
1698 {
1699  int res;
1700  res = totemnet_member_remove (instance->net_handles[iface_no], member);
1701  return (res);
1702 }
1703 
1704 static void active_membership_changed (
1705  struct totemrrp_instance *rrp_instance,
1706  enum totem_configuration_type configuration_type,
1707  const struct srp_addr *member_list, size_t member_list_entries,
1708  const struct srp_addr *left_list, size_t left_list_entries,
1709  const struct srp_addr *joined_list, size_t joined_list_entries,
1710  const struct memb_ring_id *ring_id)
1711 {
1712  int i;
1713  int interface;
1714 
1715  for (interface = 0; interface < rrp_instance->interface_count; interface++) {
1716  for (i = 0; i < left_list_entries; i++) {
1717  if (left_list->no_addrs < interface + 1 ||
1718  (left_list[i].addr[interface].family != AF_INET &&
1719  left_list[i].addr[interface].family != AF_INET6)) {
1720  log_printf(rrp_instance->totemrrp_log_level_error,
1721  "Membership left list contains incorrect address. "
1722  "This is sign of misconfiguration between nodes!");
1723  } else {
1724  totemnet_member_set_active(rrp_instance->net_handles[interface],
1725  &left_list[i].addr[interface], 0);
1726  }
1727  }
1728 
1729  for (i = 0; i < joined_list_entries; i++) {
1730  if (joined_list->no_addrs < interface + 1 ||
1731  (joined_list[i].addr[interface].family != AF_INET &&
1732  joined_list[i].addr[interface].family != AF_INET6)) {
1733  log_printf(rrp_instance->totemrrp_log_level_error,
1734  "Membership join list contains incorrect address. "
1735  "This is sign of misconfiguration between nodes!");
1736  } else {
1737  totemnet_member_set_active(rrp_instance->net_handles[interface],
1738  &joined_list[i].addr[interface], 1);
1739  }
1740  }
1741  }
1742 }
1743 
1744 static void active_iface_check (struct totemrrp_instance *instance)
1745 {
1746  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1747  unsigned int i;
1748 
1749  for (i = 0; i < instance->interface_count; i++) {
1750  if (rrp_algo_instance->faulty[i] == 0) {
1751 
1752  totemnet_iface_check (instance->net_handles[i]);
1753  }
1754  }
1755 }
1756 
1757 static void active_processor_count_set (
1758  struct totemrrp_instance *instance,
1759  unsigned int processor_count)
1760 {
1761  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1762  unsigned int i;
1763 
1764  for (i = 0; i < instance->interface_count; i++) {
1765  if (rrp_algo_instance->faulty[i] == 0) {
1766 
1768  processor_count);
1769  }
1770  }
1771 }
1772 
1773 static void active_token_target_set (
1774  struct totemrrp_instance *instance,
1775  struct totem_ip_address *token_target,
1776  unsigned int iface_no)
1777 {
1778  totemnet_token_target_set (instance->net_handles[iface_no], token_target);
1779 }
1780 
1781 static int active_mcast_recv_empty (
1782  struct totemrrp_instance *instance)
1783 {
1784  int res;
1785  int msgs_emptied = 0;
1786  int i;
1787 
1788  for (i = 0; i < instance->interface_count; i++) {
1789  res = totemnet_recv_mcast_empty (instance->net_handles[i]);
1790  if (res == -1) {
1791  return (-1);
1792  }
1793  if (res == 1) {
1794  msgs_emptied = 1;
1795  }
1796  }
1797 
1798  return (msgs_emptied);
1799 }
1800 
1801 static void active_ring_reenable (
1802  struct totemrrp_instance *instance,
1803  unsigned int iface_no)
1804 {
1805  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1806  int i;
1807 
1808  if (iface_no == instance->interface_count) {
1809  memset (rrp_algo_instance->last_token_recv, 0, sizeof (unsigned int) *
1810  instance->interface_count);
1811  memset (rrp_algo_instance->faulty, 0, sizeof (unsigned int) *
1812  instance->interface_count);
1813  memset (rrp_algo_instance->counter_problems, 0, sizeof (unsigned int) *
1814  instance->interface_count);
1815 
1816  for (i = 0; i < instance->interface_count; i++) {
1817  stats_set_interface_faulty (instance, i, 0);
1818  }
1819  } else {
1820  rrp_algo_instance->last_token_recv[iface_no] = 0;
1821  rrp_algo_instance->faulty[iface_no] = 0;
1822  rrp_algo_instance->counter_problems[iface_no] = 0;
1823 
1824  stats_set_interface_faulty (instance, iface_no, 0);
1825  }
1826 }
1827 
1828 static void totemrrp_instance_initialize (struct totemrrp_instance *instance)
1829 {
1830  memset (instance, 0, sizeof (struct totemrrp_instance));
1831 }
1832 
1833 static int totemrrp_algorithm_set (
1834  struct totem_config *totem_config,
1835  struct totemrrp_instance *instance)
1836 {
1837  unsigned int res = -1;
1838  unsigned int i;
1839 
1840  for (i = 0; i < RRP_ALGOS_COUNT; i++) {
1841  if (strcmp (totem_config->rrp_mode, rrp_algos[i]->name) == 0) {
1842  instance->rrp_algo = rrp_algos[i];
1843  if (rrp_algos[i]->initialize) {
1844  instance->rrp_algo_instance = rrp_algos[i]->initialize (
1845  instance,
1846  totem_config->interface_count);
1847  }
1848  res = 0;
1849  break;
1850  }
1851  }
1852  for (i = 0; i < totem_config->interface_count; i++) {
1853  instance->status[i] = malloc (STATUS_STR_LEN+1);
1854  snprintf (instance->status[i], STATUS_STR_LEN,
1855  "ring %d active with no faults", i);
1856  }
1857  return (res);
1858 }
1859 
1861  void *context,
1862  const void *msg,
1863  unsigned int msg_len)
1864 {
1865  unsigned int token_seqid;
1866  unsigned int token_is;
1867 
1868  struct deliver_fn_context *deliver_fn_context = (struct deliver_fn_context *)context;
1869  struct totemrrp_instance *rrp_instance = deliver_fn_context->instance;
1870  const struct message_header *hdr = msg;
1871  struct message_header tmp_msg, activate_msg;
1872 
1873  memset(&tmp_msg, 0, sizeof(struct message_header));
1874  memset(&activate_msg, 0, sizeof(struct message_header));
1875 
1876  rrp_instance->totemrrp_token_seqid_get (
1877  msg,
1878  &token_seqid,
1879  &token_is);
1880 
1881  if (hdr->type == MESSAGE_TYPE_RING_TEST_ACTIVE) {
1882  log_printf (
1883  rrp_instance->totemrrp_log_level_debug,
1884  "received message requesting test of ring now active");
1885 
1886  if (hdr->endian_detector != ENDIAN_LOCAL) {
1887  test_active_msg_endian_convert(hdr, &tmp_msg);
1888  hdr = &tmp_msg;
1889  }
1890 
1891  if (hdr->nodeid_activator == rrp_instance->my_nodeid) {
1892  /*
1893  * Send an activate message
1894  */
1895  activate_msg.type = MESSAGE_TYPE_RING_TEST_ACTIVATE;
1896  activate_msg.endian_detector = ENDIAN_LOCAL;
1897  activate_msg.ring_number = hdr->ring_number;
1898  activate_msg.nodeid_activator = rrp_instance->my_nodeid;
1900  rrp_instance->net_handles[deliver_fn_context->iface_no],
1901  &activate_msg, sizeof (struct message_header));
1902  } else {
1903  /*
1904  * Send a ring test message
1905  */
1907  rrp_instance->net_handles[deliver_fn_context->iface_no],
1908  msg, msg_len);
1909  }
1910  } else
1911  if (hdr->type == MESSAGE_TYPE_RING_TEST_ACTIVATE) {
1912  log_printf (
1913  rrp_instance->totemrrp_log_level_notice,
1914  "Automatically recovered ring %d", hdr->ring_number);
1915 
1916  if (hdr->endian_detector != ENDIAN_LOCAL) {
1917  test_active_msg_endian_convert(hdr, &tmp_msg);
1918  hdr = &tmp_msg;
1919  }
1920 
1921  totemrrp_ring_reenable (rrp_instance, deliver_fn_context->iface_no);
1922  if (hdr->nodeid_activator != rrp_instance->my_nodeid) {
1924  rrp_instance->net_handles[deliver_fn_context->iface_no],
1925  msg, msg_len);
1926  }
1927  } else
1928  if (token_is) {
1929  /*
1930  * Deliver to the token receiver for this rrp algorithm
1931  */
1932  rrp_instance->rrp_algo->token_recv (
1933  rrp_instance,
1934  deliver_fn_context->iface_no,
1935  deliver_fn_context->context,
1936  msg,
1937  msg_len,
1938  token_seqid);
1939  } else {
1940  /*
1941  * Deliver to the mcast receiver for this rrp algorithm
1942  */
1943  rrp_instance->rrp_algo->mcast_recv (
1944  rrp_instance,
1945  deliver_fn_context->iface_no,
1946  deliver_fn_context->context,
1947  msg,
1948  msg_len);
1949  }
1950 }
1951 
1953  void *context,
1954  const struct totem_ip_address *iface_addr)
1955 {
1956  struct deliver_fn_context *deliver_fn_context = (struct deliver_fn_context *)context;
1957 
1958  deliver_fn_context->instance->my_nodeid = iface_addr->nodeid;
1959  deliver_fn_context->instance->totemrrp_iface_change_fn (
1960  deliver_fn_context->context,
1961  iface_addr,
1962  deliver_fn_context->iface_no);
1963 }
1964 
1966  void *rrp_context)
1967 {
1968  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
1969  int i;
1970 
1971  for (i = 0; i < instance->interface_count; i++) {
1972  totemnet_finalize (instance->net_handles[i]);
1973  }
1974  free (instance->net_handles);
1975  free (instance);
1976  return (0);
1977 }
1978 
1979 static void rrp_target_set_completed (void *context)
1980 {
1981  struct deliver_fn_context *deliver_fn_context = (struct deliver_fn_context *)context;
1982 
1983  deliver_fn_context->instance->totemrrp_target_set_completed (deliver_fn_context->context);
1984 }
1985 
1986 /*
1987  * Totem Redundant Ring interface
1988  * depends on poll abstraction, POSIX, IPV4
1989  */
1990 
1991 /*
1992  * Create an instance
1993  */
1995  qb_loop_t *poll_handle,
1996  void **rrp_context,
1997  struct totem_config *totem_config,
1998  totemsrp_stats_t *stats,
1999  void *context,
2000 
2001  void (*deliver_fn) (
2002  void *context,
2003  const void *msg,
2004  unsigned int msg_len),
2005 
2006  void (*iface_change_fn) (
2007  void *context,
2008  const struct totem_ip_address *iface_addr,
2009  unsigned int iface_no),
2010 
2011  void (*token_seqid_get) (
2012  const void *msg,
2013  unsigned int *seqid,
2014  unsigned int *token_is),
2015 
2016  unsigned int (*msgs_missing) (void),
2017 
2018  void (*target_set_completed) (void *context))
2019 {
2020  struct totemrrp_instance *instance;
2021  unsigned int res;
2022  int i;
2023 
2024  instance = malloc (sizeof (struct totemrrp_instance));
2025  if (instance == 0) {
2026  return (-1);
2027  }
2028 
2029  totemrrp_instance_initialize (instance);
2030 
2031  instance->totem_config = totem_config;
2032  stats->rrp = &instance->stats;
2033  instance->stats.interface_count = totem_config->interface_count;
2034  instance->stats.faulty = calloc(instance->stats.interface_count, sizeof(uint8_t));
2035 
2036  res = totemrrp_algorithm_set (
2037  instance->totem_config,
2038  instance);
2039  if (res == -1) {
2040  goto error_destroy;
2041  }
2042 
2043  /*
2044  * Configure logging
2045  */
2053 
2054  instance->interfaces = totem_config->interfaces;
2055 
2056  instance->poll_handle = poll_handle;
2057 
2058  instance->totemrrp_deliver_fn = deliver_fn;
2059 
2060  instance->totemrrp_iface_change_fn = iface_change_fn;
2061 
2062  instance->totemrrp_token_seqid_get = token_seqid_get;
2063 
2064  instance->totemrrp_target_set_completed = target_set_completed;
2065 
2066  instance->totemrrp_msgs_missing = msgs_missing;
2067 
2068  instance->interface_count = totem_config->interface_count;
2069 
2070  instance->net_handles = malloc (sizeof (void *) * totem_config->interface_count);
2071 
2072  instance->context = context;
2073 
2074  instance->poll_handle = poll_handle;
2075 
2076 
2077  for (i = 0; i < totem_config->interface_count; i++) {
2078  struct deliver_fn_context *deliver_fn_context;
2079 
2080  deliver_fn_context = malloc (sizeof (struct deliver_fn_context));
2081  assert (deliver_fn_context);
2082  deliver_fn_context->instance = instance;
2083  deliver_fn_context->context = context;
2084  deliver_fn_context->iface_no = i;
2085  instance->deliver_fn_context[i] = (void *)deliver_fn_context;
2086 
2088  poll_handle,
2089  &instance->net_handles[i],
2090  totem_config,
2091  stats,
2092  i,
2093  (void *)deliver_fn_context,
2096  rrp_target_set_completed);
2097 
2098  totemnet_net_mtu_adjust (instance->net_handles[i], totem_config);
2099  }
2100 
2101  *rrp_context = instance;
2102  return (0);
2103 
2104 error_destroy:
2105  free (instance);
2106  return (res);
2107 }
2108 
2109 void *totemrrp_buffer_alloc (void *rrp_context)
2110 {
2111  struct totemrrp_instance *instance = rrp_context;
2112  assert (instance != NULL);
2113  return totemnet_buffer_alloc (instance->net_handles[0]);
2114 }
2115 
2116 void totemrrp_buffer_release (void *rrp_context, void *ptr)
2117 {
2118  struct totemrrp_instance *instance = rrp_context;
2119  assert (instance != NULL);
2120  totemnet_buffer_release (instance->net_handles[0], ptr);
2121 }
2122 
2124  void *rrp_context,
2125  unsigned int processor_count)
2126 {
2127  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2128  instance->rrp_algo->processor_count_set (instance, processor_count);
2129 
2130  instance->processor_count = processor_count;
2131 
2132  return (0);
2133 }
2134 
2136  void *rrp_context,
2137  struct totem_ip_address *addr,
2138  unsigned int iface_no)
2139 {
2140  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2141  instance->rrp_algo->token_target_set (instance, addr, iface_no);
2142 
2143  return (0);
2144 }
2145 int totemrrp_recv_flush (void *rrp_context)
2146 {
2147  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2148 
2149  instance->rrp_algo->recv_flush (instance);
2150 
2151  return (0);
2152 }
2153 
2154 int totemrrp_send_flush (void *rrp_context)
2155 {
2156  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2157  instance->rrp_algo->send_flush (instance);
2158 
2159  return (0);
2160 }
2161 
2163  void *rrp_context,
2164  const void *msg,
2165  unsigned int msg_len)
2166 {
2167  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2168  instance->rrp_algo->token_send (instance, msg, msg_len);
2169 
2170  return (0);
2171 }
2172 
2174  void *rrp_context,
2175  const void *msg,
2176  unsigned int msg_len)
2177 {
2178  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2179  int res = 0;
2180 
2181 // TODO this needs to return the result
2182  instance->rrp_algo->mcast_flush_send (instance, msg, msg_len);
2183 
2184  return (res);
2185 }
2186 
2188  void *rrp_context,
2189  const void *msg,
2190  unsigned int msg_len)
2191 {
2192  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2193  /*
2194  * merge detects go out through mcast_flush_send so it is safe to
2195  * flush these messages if we are only one processor. This avoids
2196  * an encryption/hmac and decryption/hmac
2197  */
2198  if (instance->processor_count > 1) {
2199 
2200 // TODO this needs to return the result
2201  instance->rrp_algo->mcast_noflush_send (instance, msg, msg_len);
2202  }
2203 
2204  return (0);
2205 }
2206 
2207 int totemrrp_iface_check (void *rrp_context)
2208 {
2209  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2210 
2211  instance->rrp_algo->iface_check (instance);
2212 
2213  return (0);
2214 }
2215 
2217  void *rrp_context,
2218  char ***status,
2219  unsigned int *iface_count)
2220 {
2221  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2222  *status = instance->status;
2223 
2224  if (iface_count) {
2225  *iface_count = instance->interface_count;
2226  }
2227 
2228  return (0);
2229 }
2230 
2232  void *rrp_context,
2233  const char *cipher_type,
2234  const char *hash_type)
2235 {
2236  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2237  int res;
2238 
2239  res = totemnet_crypto_set(instance->net_handles[0], cipher_type, hash_type);
2240 
2241  return (res);
2242 }
2243 
2244 
2245 /*
2246  * iface_no indicates the interface number [0, ..., interface_count-1] of the
2247  * specific ring which will be reenabled. We specify iface_no == interface_count
2248  * means reenabling all the rings.
2249  */
2251  void *rrp_context,
2252  unsigned int iface_no)
2253 {
2254  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2255  int res = 0;
2256  unsigned int i;
2257 
2258  instance->rrp_algo->ring_reenable (instance, iface_no);
2259 
2260  if (iface_no == instance->interface_count) {
2261  for (i = 0; i < instance->interface_count; i++) {
2262  snprintf (instance->status[i], STATUS_STR_LEN,
2263  "ring %d active with no faults", i);
2264  }
2265  } else {
2266  snprintf (instance->status[iface_no], STATUS_STR_LEN,
2267  "ring %d active with no faults", iface_no);
2268  }
2269 
2270  return (res);
2271 }
2272 
2274  void *rrp_context)
2275 {
2276  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2277  int res;
2278 
2279  res = instance->rrp_algo->mcast_recv_empty (instance);
2280 
2281  return (res);
2282 }
2283 
2285  void *rrp_context,
2286  const struct totem_ip_address *member,
2287  int iface_no)
2288 {
2289  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2290  int res;
2291 
2292  res = instance->rrp_algo->member_add (instance, member, iface_no);
2293 
2294  return (res);
2295 }
2296 
2298  void *rrp_context,
2299  const struct totem_ip_address *member,
2300  int iface_no)
2301 {
2302  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2303  int res;
2304 
2305  res = instance->rrp_algo->member_remove (instance, member, iface_no);
2306 
2307  return (res);
2308 }
2309 
2311  void *rrp_context,
2312  enum totem_configuration_type configuration_type,
2313  const struct srp_addr *member_list, size_t member_list_entries,
2314  const struct srp_addr *left_list, size_t left_list_entries,
2315  const struct srp_addr *joined_list, size_t joined_list_entries,
2316  const struct memb_ring_id *ring_id)
2317 {
2318  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2319 
2320  instance->rrp_algo->membership_changed (instance,
2321  configuration_type,
2322  member_list, member_list_entries,
2323  left_list, left_list_entries,
2324  joined_list, joined_list_entries,
2325  ring_id);
2326 }
uint8_t no_addrs
Definition: totemrrp.h:59
unsigned short family
Definition: coroapi.h:97
void(* processor_count_set)(struct totemrrp_instance *instance, unsigned int processor_count)
Definition: totemrrp.c:155
unsigned int(* totemrrp_msgs_missing)(void)
Definition: totemrrp.c:220
int(* mcast_recv_empty)(struct totemrrp_instance *instance)
Definition: totemrrp.c:168
int totemrrp_iface_check(void *rrp_context)
Definition: totemrrp.c:2207
void(*) in log_level_security)
Definition: totem.h:82
unsigned int * faulty
Definition: totemrrp.c:98
void rrp_iface_change_fn(void *context, const struct totem_ip_address *iface_addr)
Definition: totemrrp.c:1952
#define RRP_ALGOS_COUNT
Definition: totemrrp.c:632
void(* totemrrp_target_set_completed)(void *context)
Definition: totemrrp.c:217
int nodeid_activator
Definition: totemrrp.c:557
int totemnet_mcast_flush_send(void *net_context, const void *msg, unsigned int msg_len)
Definition: totemnet.c:382
qb_loop_timer_handle timer_expired_token
Definition: totemrrp.c:104
struct totem_interface * interfaces
Definition: totem.h:114
unsigned int interface_count
Definition: totem.h:115
void(* token_target_set)(struct totemrrp_instance *instance, struct totem_ip_address *token_target, unsigned int iface_no)
Definition: totemrrp.c:159
int totemrrp_log_level_error
Definition: totemrrp.c:227
qb_loop_timer_handle timer_problem_decrementer
Definition: totemrrp.c:90
#define ENDIAN_LOCAL
Definition: totemrrp.c:526
void(* membership_changed)(struct totemrrp_instance *instance, enum totem_configuration_type configuration_type, const struct srp_addr *member_list, size_t member_list_entries, const struct srp_addr *left_list, size_t left_list_entries, const struct srp_addr *joined_list, size_t joined_list_entries, const struct memb_ring_id *ring_id)
Definition: totemrrp.c:181
int totemnet_member_remove(void *net_context, const struct totem_ip_address *member)
Definition: totemnet.c:486
#define max(a, b)
struct totemrrp_instance * instance
Definition: totemrrp.c:561
unsigned int last_token_seq
Definition: totemrrp.c:103
void(* send_flush)(struct totemrrp_instance *instance)
Definition: totemrrp.c:149
totem_configuration_type
Definition: coroapi.h:110
char rrp_mode[TOTEM_RRP_MODE_BYTES]
Definition: totem.h:161
void totemrrp_membership_changed(void *rrp_context, enum totem_configuration_type configuration_type, const struct srp_addr *member_list, size_t member_list_entries, const struct srp_addr *left_list, size_t left_list_entries, const struct srp_addr *joined_list, size_t joined_list_entries, const struct memb_ring_id *ring_id)
Definition: totemrrp.c:2310
const char * totemnet_iface_print(void *net_context)
Definition: totemnet.c:427
#define PASSIVE_RECV_COUNT_THRESHOLD
Definition: totemrrp.c:550
void(* token_recv)(struct totemrrp_instance *instance, unsigned int iface_no, void *context, const void *msg, unsigned int msg_len, unsigned int token_seqid)
Definition: totemrrp.c:133
unsigned char addr[TOTEMIP_ADDRLEN]
Definition: coroapi.h:67
unsigned int rrp_problem_count_timeout
Definition: totem.h:153
struct rrp_algo active_algo
Definition: totemrrp.c:606
unsigned int * token_recv_count
Definition: totemrrp.c:85
struct rrp_algo passive_algo
Definition: totemrrp.c:586
int totemnet_member_add(void *net_context, const struct totem_ip_address *member)
Definition: totemnet.c:470
int totemrrp_ifaces_get(void *rrp_context, char ***status, unsigned int *iface_count)
Definition: totemrrp.c:2216
int(* member_remove)(struct totemrrp_instance *instance, const struct totem_ip_address *member, unsigned int iface_no)
Definition: totemrrp.c:176
void * totemrrp_buffer_alloc(void *rrp_context)
Definition: totemrrp.c:2109
unsigned int token_len
Definition: totemrrp.c:88
unsigned int * counter_problems
Definition: totemrrp.c:100
void(* mcast_flush_send)(struct totemrrp_instance *instance, const void *msg, unsigned int msg_len)
Definition: totemrrp.c:128
qb_loop_timer_handle timer_expired_token
Definition: totemrrp.c:89
unsigned int * mcast_recv_count
Definition: totemrrp.c:86
unsigned int token_xmit_iface
Definition: totemrrp.c:92
void(* totemrrp_log_printf)(int level, int subsys, const char *function, const char *file, int line, const char *format,...) __attribute__((format(printf
Definition: totemrrp.c:237
unsigned int rrp_problem_count_threshold
Definition: totem.h:155
unsigned int * faulty
Definition: totemrrp.c:84
void(* totemrrp_token_seqid_get)(const void *msg, unsigned int *seqid, unsigned int *token_is)
Definition: totemrrp.c:212
struct totemrrp_instance * rrp_instance
Definition: totemrrp.c:97
void * totemrrp_context
Definition: totemrrp.c:91
#define INTERFACE_MAX
Definition: coroapi.h:75
void(* iface_check)(struct totemrrp_instance *instance)
Definition: totemrrp.c:152
Totem Network interface - also does encryption/decryption.
int totemnet_recv_flush(void *net_context)
Definition: totemnet.c:350
#define MESSAGE_TYPE_RING_TEST_ACTIVATE
Definition: totemrrp.c:524
unsigned char token[15000]
Definition: totemrrp.c:87
#define ARR_SEQNO_START_TOKEN
Definition: totemrrp.c:537
int totemrrp_finalize(void *rrp_context)
Definition: totemrrp.c:1965
int totemnet_net_mtu_adjust(void *net_context, struct totem_config *totem_config)
Definition: totemnet.c:418
int totemrrp_member_remove(void *rrp_context, const struct totem_ip_address *member, int iface_no)
Definition: totemrrp.c:2297
int totemrrp_crypto_set(void *rrp_context, const char *cipher_type, const char *hash_type)
Definition: totemrrp.c:2231
int totemnet_crypto_set(void *net_context, const char *cipher_type, const char *hash_type)
Definition: totemnet.c:253
void * totemnet_buffer_alloc(void *net_context)
Definition: totemnet.c:323
unsigned int nodeid
Definition: coroapi.h:96
void * deliver_fn_context[INTERFACE_MAX]
Definition: totemrrp.c:257
int totemrrp_log_level_debug
Definition: totemrrp.c:233
int totemnet_member_set_active(void *net_context, const struct totem_ip_address *member, int active)
Definition: totemnet.c:502
int totemrrp_send_flush(void *rrp_context)
Definition: totemrrp.c:2154
unsigned int msg_xmit_iface
Definition: totemrrp.c:93
void * rrp_algo_instance
Definition: totemrrp.c:247
char encapsulated
Definition: totemrrp.c:554
int totemnet_recv_mcast_empty(void *net_context)
Definition: totemnet.c:459
int totemrrp_member_add(void *rrp_context, const struct totem_ip_address *member, int iface_no)
Definition: totemrrp.c:2284
Linked list API.
unsigned int rrp_autorecovery_check_timeout
Definition: totem.h:159
qb_loop_t * poll_handle
Definition: totemrrp.c:192
void(* log_printf)(int level, int subsys, const char *function_name, const char *file_name, int file_line, const char *format,...) __attribute__((format(printf
Definition: totem.h:75
void *(* initialize)(struct totemrrp_instance *rrp_instance, int interface_count)
Definition: totemrrp.c:112
int totemnet_send_flush(void *net_context)
Definition: totemnet.c:360
void(* token_send)(struct totemrrp_instance *instance, const void *msg, unsigned int msg_len)
Definition: totemrrp.c:141
const char * name
Definition: totemrrp.c:110
int totemnet_mcast_noflush_send(void *net_context, const void *msg, unsigned int msg_len)
Definition: totemnet.c:395
struct totem_interface * interfaces
Definition: totemrrp.c:194
void(* ring_reenable)(struct totemrrp_instance *instance, unsigned int iface_no)
Definition: totemrrp.c:164
int totemrrp_initialize(qb_loop_t *poll_handle, void **rrp_context, struct totem_config *totem_config, totemsrp_stats_t *stats, void *context, void(*deliver_fn)(void *context, const void *msg, unsigned int msg_len), void(*iface_change_fn)(void *context, const struct totem_ip_address *iface_addr, unsigned int iface_no), void(*token_seqid_get)(const void *msg, unsigned int *seqid, unsigned int *token_is), unsigned int(*msgs_missing)(void), void(*target_set_completed)(void *context))
Create an instance.
Definition: totemrrp.c:1994
int totemnet_finalize(void *net_context)
Definition: totemnet.c:267
unsigned int * last_token_recv
Definition: totemrrp.c:99
int totemrrp_log_level_warning
Definition: totemrrp.c:229
#define swab32(x)
Definition: swab.h:43
totemrrp_stats_t * rrp
Definition: totem.h:244
int totemnet_token_send(void *net_context, const void *msg, unsigned int msg_len)
Definition: totemnet.c:370
void(*) void * net_handles)
Definition: totemrrp.c:243
int totemrrp_recv_flush(void *rrp_context)
Definition: totemrrp.c:2145
void(* totemrrp_deliver_fn)(void *context, const void *msg, unsigned int msg_len)
Definition: totemrrp.c:202
struct deliver_fn_context __attribute__
unsigned char token[15000]
Definition: totemrrp.c:101
unsigned int token_seq
Definition: totemsrp.c:62
void totemrrp_buffer_release(void *rrp_context, void *ptr)
Definition: totemrrp.c:2116
Totem Network interface - also does encryption/decryption.
struct totem_config * totem_config
Definition: totemrrp.c:255
void(* totemrrp_iface_change_fn)(void *context, const struct totem_ip_address *iface_addr, unsigned int iface_no)
Definition: totemrrp.c:207
int totemrrp_subsys_id
Definition: totemrrp.c:235
totemrrp_stats_t stats
Definition: totemrrp.c:261
int totemnet_initialize(qb_loop_t *loop_pt, void **net_context, struct totem_config *totem_config, totemsrp_stats_t *stats, int interface_no, void *context, void(*deliver_fn)(void *context, const void *msg, unsigned int msg_len), void(*iface_change_fn)(void *context, const struct totem_ip_address *iface_address), void(*target_set_completed)(void *context))
Create an instance.
Definition: totemnet.c:278
void(* recv_flush)(struct totemrrp_instance *instance)
Definition: totemrrp.c:146
void(* mcast_recv)(struct totemrrp_instance *instance, unsigned int iface_no, void *context, const void *msg, unsigned int msg_len)
Definition: totemrrp.c:116
char * status[INTERFACE_MAX]
Definition: totemrrp.c:200
unsigned int rrp_problem_count_mcast_threshold
Definition: totem.h:157
int totemrrp_processor_count_set(void *rrp_context, unsigned int processor_count)
Definition: totemrrp.c:2123
int totemrrp_log_level_security
Definition: totemrrp.c:225
int totemrrp_mcast_noflush_send(void *rrp_context, const void *msg, unsigned int msg_len)
Definition: totemrrp.c:2187
int totemrrp_mcast_recv_empty(void *rrp_context)
Definition: totemrrp.c:2273
struct rrp_algo * rrp_algo
Definition: totemrrp.c:196
struct rrp_algo * rrp_algos[]
Definition: totemrrp.c:626
struct totem_logging_configuration totem_logging_configuration
Definition: totem.h:163
unsigned short endian_detector
Definition: totemrrp.c:555
int totemrrp_mcast_flush_send(void *rrp_context, const void *msg, unsigned int msg_len)
Definition: totemrrp.c:2173
unsigned int token_len
Definition: totemrrp.c:102
qb_loop_timer_handle timer_problem_decrementer
Definition: totemrrp.c:105
void totemnet_buffer_release(void *net_context, void *ptr)
Definition: totemnet.c:331
int totemrrp_log_level_notice
Definition: totemrrp.c:231
void rrp_deliver_fn(void *context, const void *msg, unsigned int msg_len)
Definition: totemrrp.c:1860
void(* mcast_noflush_send)(struct totemrrp_instance *instance, const void *msg, unsigned int msg_len)
Definition: totemrrp.c:123
#define MESSAGE_TYPE_RING_TEST_ACTIVE
Definition: totemrrp.c:523
uint32_t interface_count
Definition: totem.h:232
int totemnet_iface_check(void *net_context)
Definition: totemnet.c:408
#define log_printf(level, format, args...)
Definition: totemrrp.c:634
uint8_t * faulty
Definition: totem.h:231
struct memb_ring_id ring_id
Definition: totemsrp.c:64
int totemrrp_ring_reenable(void *rrp_context, unsigned int iface_no)
Definition: totemrrp.c:2250
struct totemrrp_instance * rrp_instance
Definition: totemrrp.c:83
qb_loop_timer_handle timer_active_test_ring_timeout[INTERFACE_MAX]
Definition: totemrrp.c:259
void * totemrrp_context
Definition: totemrrp.c:106
int totemnet_token_target_set(void *net_context, const struct totem_ip_address *token_target)
Definition: totemnet.c:447
struct rrp_algo none_algo
Definition: totemrrp.c:566
int(* member_add)(struct totemrrp_instance *instance, const struct totem_ip_address *member, unsigned int iface_no)
Definition: totemrrp.c:171
struct totem_ip_address addr[INTERFACE_MAX]
Definition: totemrrp.h:60
unsigned int rrp_token_expired_timeout
Definition: totem.h:151
int totemrrp_token_send(void *rrp_context, const void *msg, unsigned int msg_len)
Definition: totemrrp.c:2162
int totemrrp_token_target_set(void *rrp_context, struct totem_ip_address *addr, unsigned int iface_no)
Definition: totemrrp.c:2135
int totemnet_processor_count_set(void *net_context, int processor_count)
Definition: totemnet.c:339
#define STATUS_STR_LEN
Definition: totemrrp.c:190