corosync  2.4.1
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  active_instance->timer_problem_decrementer = 0;
1546 }
1547 
1548 
1549 /*
1550  * active replication
1551  */
1552 static void active_mcast_recv (
1553  struct totemrrp_instance *instance,
1554  unsigned int iface_no,
1555  void *context,
1556  const void *msg,
1557  unsigned int msg_len)
1558 {
1559  instance->totemrrp_deliver_fn (
1560  context,
1561  msg,
1562  msg_len);
1563 }
1564 
1565 static void active_mcast_flush_send (
1566  struct totemrrp_instance *instance,
1567  const void *msg,
1568  unsigned int msg_len)
1569 {
1570  int i;
1571  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1572 
1573  for (i = 0; i < instance->interface_count; i++) {
1574  if (rrp_algo_instance->faulty[i] == 0) {
1575  totemnet_mcast_flush_send (instance->net_handles[i], msg, msg_len);
1576  }
1577  }
1578 }
1579 
1580 static void active_mcast_noflush_send (
1581  struct totemrrp_instance *instance,
1582  const void *msg,
1583  unsigned int msg_len)
1584 {
1585  int i;
1586  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1587 
1588  for (i = 0; i < instance->interface_count; i++) {
1589  if (rrp_algo_instance->faulty[i] == 0) {
1590  totemnet_mcast_noflush_send (instance->net_handles[i], msg, msg_len);
1591  }
1592  }
1593 }
1594 
1595 static void active_token_recv (
1596  struct totemrrp_instance *rrp_instance,
1597  unsigned int iface_no,
1598  void *context,
1599  const void *msg,
1600  unsigned int msg_len,
1601  unsigned int token_seq)
1602 {
1603  int i;
1604  struct active_instance *active_instance = (struct active_instance *)rrp_instance->rrp_algo_instance;
1605 
1606  active_instance->totemrrp_context = context;
1607  if (sq_lt_compare (active_instance->last_token_seq, token_seq)) {
1608  memcpy (active_instance->token, msg, msg_len);
1609  active_instance->token_len = msg_len;
1610  for (i = 0; i < rrp_instance->interface_count; i++) {
1611  active_instance->last_token_recv[i] = 0;
1612  }
1613 
1614  active_instance->last_token_recv[iface_no] = 1;
1615  active_timer_expired_token_start (active_instance);
1616  }
1617 
1618  /*
1619  * This doesn't follow spec because the spec assumes we will know
1620  * when token resets occur.
1621  */
1622  active_instance->last_token_seq = token_seq;
1623 
1624  if (token_seq == active_instance->last_token_seq) {
1625  active_instance->last_token_recv[iface_no] = 1;
1626  for (i = 0; i < rrp_instance->interface_count; i++) {
1627  if ((active_instance->last_token_recv[i] == 0) &&
1628  active_instance->faulty[i] == 0) {
1629  return; /* don't deliver token */
1630  }
1631  }
1632  active_timer_expired_token_cancel (active_instance);
1633 
1634  rrp_instance->totemrrp_deliver_fn (
1635  context,
1636  msg,
1637  msg_len);
1638  }
1639 }
1640 
1641 static void active_token_send (
1642  struct totemrrp_instance *instance,
1643  const void *msg,
1644  unsigned int msg_len)
1645 {
1646  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1647  int i;
1648 
1649  for (i = 0; i < instance->interface_count; i++) {
1650  if (rrp_algo_instance->faulty[i] == 0) {
1652  instance->net_handles[i],
1653  msg, msg_len);
1654 
1655  }
1656  }
1657 }
1658 
1659 static void active_recv_flush (struct totemrrp_instance *instance)
1660 {
1661  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1662  unsigned int i;
1663 
1664  for (i = 0; i < instance->interface_count; i++) {
1665  if (rrp_algo_instance->faulty[i] == 0) {
1666 
1667  totemnet_recv_flush (instance->net_handles[i]);
1668  }
1669  }
1670 }
1671 
1672 static void active_send_flush (struct totemrrp_instance *instance)
1673 {
1674  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1675  unsigned int i;
1676 
1677  for (i = 0; i < instance->interface_count; i++) {
1678  if (rrp_algo_instance->faulty[i] == 0) {
1679 
1680  totemnet_send_flush (instance->net_handles[i]);
1681  }
1682  }
1683 }
1684 
1685 static int active_member_add (
1686  struct totemrrp_instance *instance,
1687  const struct totem_ip_address *member,
1688  unsigned int iface_no)
1689 {
1690  int res;
1691  res = totemnet_member_add (instance->net_handles[iface_no], member);
1692  return (res);
1693 }
1694 
1695 static int active_member_remove (
1696  struct totemrrp_instance *instance,
1697  const struct totem_ip_address *member,
1698  unsigned int iface_no)
1699 {
1700  int res;
1701  res = totemnet_member_remove (instance->net_handles[iface_no], member);
1702  return (res);
1703 }
1704 
1705 static void active_membership_changed (
1706  struct totemrrp_instance *rrp_instance,
1707  enum totem_configuration_type configuration_type,
1708  const struct srp_addr *member_list, size_t member_list_entries,
1709  const struct srp_addr *left_list, size_t left_list_entries,
1710  const struct srp_addr *joined_list, size_t joined_list_entries,
1711  const struct memb_ring_id *ring_id)
1712 {
1713  int i;
1714  int interface;
1715 
1716  for (interface = 0; interface < rrp_instance->interface_count; interface++) {
1717  for (i = 0; i < left_list_entries; i++) {
1718  if (left_list->no_addrs < interface + 1 ||
1719  (left_list[i].addr[interface].family != AF_INET &&
1720  left_list[i].addr[interface].family != AF_INET6)) {
1721  log_printf(rrp_instance->totemrrp_log_level_error,
1722  "Membership left list contains incorrect address. "
1723  "This is sign of misconfiguration between nodes!");
1724  } else {
1725  totemnet_member_set_active(rrp_instance->net_handles[interface],
1726  &left_list[i].addr[interface], 0);
1727  }
1728  }
1729 
1730  for (i = 0; i < joined_list_entries; i++) {
1731  if (joined_list->no_addrs < interface + 1 ||
1732  (joined_list[i].addr[interface].family != AF_INET &&
1733  joined_list[i].addr[interface].family != AF_INET6)) {
1734  log_printf(rrp_instance->totemrrp_log_level_error,
1735  "Membership join list contains incorrect address. "
1736  "This is sign of misconfiguration between nodes!");
1737  } else {
1738  totemnet_member_set_active(rrp_instance->net_handles[interface],
1739  &joined_list[i].addr[interface], 1);
1740  }
1741  }
1742  }
1743 }
1744 
1745 static void active_iface_check (struct totemrrp_instance *instance)
1746 {
1747  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1748  unsigned int i;
1749 
1750  for (i = 0; i < instance->interface_count; i++) {
1751  if (rrp_algo_instance->faulty[i] == 0) {
1752 
1753  totemnet_iface_check (instance->net_handles[i]);
1754  }
1755  }
1756 }
1757 
1758 static void active_processor_count_set (
1759  struct totemrrp_instance *instance,
1760  unsigned int processor_count)
1761 {
1762  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1763  unsigned int i;
1764 
1765  for (i = 0; i < instance->interface_count; i++) {
1766  if (rrp_algo_instance->faulty[i] == 0) {
1767 
1769  processor_count);
1770  }
1771  }
1772 }
1773 
1774 static void active_token_target_set (
1775  struct totemrrp_instance *instance,
1776  struct totem_ip_address *token_target,
1777  unsigned int iface_no)
1778 {
1779  totemnet_token_target_set (instance->net_handles[iface_no], token_target);
1780 }
1781 
1782 static int active_mcast_recv_empty (
1783  struct totemrrp_instance *instance)
1784 {
1785  int res;
1786  int msgs_emptied = 0;
1787  int i;
1788 
1789  for (i = 0; i < instance->interface_count; i++) {
1790  res = totemnet_recv_mcast_empty (instance->net_handles[i]);
1791  if (res == -1) {
1792  return (-1);
1793  }
1794  if (res == 1) {
1795  msgs_emptied = 1;
1796  }
1797  }
1798 
1799  return (msgs_emptied);
1800 }
1801 
1802 static void active_ring_reenable (
1803  struct totemrrp_instance *instance,
1804  unsigned int iface_no)
1805 {
1806  struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
1807  int i;
1808 
1809  if (iface_no == instance->interface_count) {
1810  memset (rrp_algo_instance->last_token_recv, 0, sizeof (unsigned int) *
1811  instance->interface_count);
1812  memset (rrp_algo_instance->faulty, 0, sizeof (unsigned int) *
1813  instance->interface_count);
1814  memset (rrp_algo_instance->counter_problems, 0, sizeof (unsigned int) *
1815  instance->interface_count);
1816 
1817  for (i = 0; i < instance->interface_count; i++) {
1818  stats_set_interface_faulty (instance, i, 0);
1819  }
1820  } else {
1821  rrp_algo_instance->last_token_recv[iface_no] = 0;
1822  rrp_algo_instance->faulty[iface_no] = 0;
1823  rrp_algo_instance->counter_problems[iface_no] = 0;
1824 
1825  stats_set_interface_faulty (instance, iface_no, 0);
1826  }
1827 }
1828 
1829 static void totemrrp_instance_initialize (struct totemrrp_instance *instance)
1830 {
1831  memset (instance, 0, sizeof (struct totemrrp_instance));
1832 }
1833 
1834 static int totemrrp_algorithm_set (
1835  struct totem_config *totem_config,
1836  struct totemrrp_instance *instance)
1837 {
1838  unsigned int res = -1;
1839  unsigned int i;
1840 
1841  for (i = 0; i < RRP_ALGOS_COUNT; i++) {
1842  if (strcmp (totem_config->rrp_mode, rrp_algos[i]->name) == 0) {
1843  instance->rrp_algo = rrp_algos[i];
1844  if (rrp_algos[i]->initialize) {
1845  instance->rrp_algo_instance = rrp_algos[i]->initialize (
1846  instance,
1847  totem_config->interface_count);
1848  }
1849  res = 0;
1850  break;
1851  }
1852  }
1853  for (i = 0; i < totem_config->interface_count; i++) {
1854  instance->status[i] = malloc (STATUS_STR_LEN+1);
1855  snprintf (instance->status[i], STATUS_STR_LEN,
1856  "ring %d active with no faults", i);
1857  }
1858  return (res);
1859 }
1860 
1862  void *context,
1863  const void *msg,
1864  unsigned int msg_len)
1865 {
1866  unsigned int token_seqid;
1867  unsigned int token_is;
1868 
1869  struct deliver_fn_context *deliver_fn_context = (struct deliver_fn_context *)context;
1870  struct totemrrp_instance *rrp_instance = deliver_fn_context->instance;
1871  const struct message_header *hdr = msg;
1872  struct message_header tmp_msg, activate_msg;
1873 
1874  memset(&tmp_msg, 0, sizeof(struct message_header));
1875  memset(&activate_msg, 0, sizeof(struct message_header));
1876 
1877  rrp_instance->totemrrp_token_seqid_get (
1878  msg,
1879  &token_seqid,
1880  &token_is);
1881 
1882  if (hdr->type == MESSAGE_TYPE_RING_TEST_ACTIVE) {
1883  log_printf (
1884  rrp_instance->totemrrp_log_level_debug,
1885  "received message requesting test of ring now active");
1886 
1887  if (hdr->endian_detector != ENDIAN_LOCAL) {
1888  test_active_msg_endian_convert(hdr, &tmp_msg);
1889  hdr = &tmp_msg;
1890  }
1891 
1892  if (hdr->nodeid_activator == rrp_instance->my_nodeid) {
1893  /*
1894  * Send an activate message
1895  */
1896  activate_msg.type = MESSAGE_TYPE_RING_TEST_ACTIVATE;
1897  activate_msg.endian_detector = ENDIAN_LOCAL;
1898  activate_msg.ring_number = hdr->ring_number;
1899  activate_msg.nodeid_activator = rrp_instance->my_nodeid;
1901  rrp_instance->net_handles[deliver_fn_context->iface_no],
1902  &activate_msg, sizeof (struct message_header));
1903  } else {
1904  /*
1905  * Send a ring test message
1906  */
1908  rrp_instance->net_handles[deliver_fn_context->iface_no],
1909  msg, msg_len);
1910  }
1911  } else
1912  if (hdr->type == MESSAGE_TYPE_RING_TEST_ACTIVATE) {
1913 
1914  if (hdr->endian_detector != ENDIAN_LOCAL) {
1915  test_active_msg_endian_convert(hdr, &tmp_msg);
1916  hdr = &tmp_msg;
1917  }
1918 
1919  log_printf (
1920  rrp_instance->totemrrp_log_level_debug,
1921  "Received ring test activate message for ring %d sent by node %u",
1922  hdr->ring_number,
1923  hdr->nodeid_activator);
1924 
1925  if (rrp_instance->stats.faulty[deliver_fn_context->iface_no]) {
1926  log_printf (rrp_instance->totemrrp_log_level_notice,
1927  "Automatically recovered ring %d", hdr->ring_number);
1928  }
1929 
1930  totemrrp_ring_reenable (rrp_instance, deliver_fn_context->iface_no);
1931  if (hdr->nodeid_activator != rrp_instance->my_nodeid) {
1933  rrp_instance->net_handles[deliver_fn_context->iface_no],
1934  msg, msg_len);
1935  }
1936  } else
1937  if (token_is) {
1938  /*
1939  * Deliver to the token receiver for this rrp algorithm
1940  */
1941  rrp_instance->rrp_algo->token_recv (
1942  rrp_instance,
1943  deliver_fn_context->iface_no,
1944  deliver_fn_context->context,
1945  msg,
1946  msg_len,
1947  token_seqid);
1948  } else {
1949  /*
1950  * Deliver to the mcast receiver for this rrp algorithm
1951  */
1952  rrp_instance->rrp_algo->mcast_recv (
1953  rrp_instance,
1954  deliver_fn_context->iface_no,
1955  deliver_fn_context->context,
1956  msg,
1957  msg_len);
1958  }
1959 }
1960 
1962  void *context,
1963  const struct totem_ip_address *iface_addr)
1964 {
1965  struct deliver_fn_context *deliver_fn_context = (struct deliver_fn_context *)context;
1966 
1967  deliver_fn_context->instance->my_nodeid = iface_addr->nodeid;
1968  deliver_fn_context->instance->totemrrp_iface_change_fn (
1969  deliver_fn_context->context,
1970  iface_addr,
1971  deliver_fn_context->iface_no);
1972 }
1973 
1975  void *rrp_context)
1976 {
1977  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
1978  int i;
1979 
1980  for (i = 0; i < instance->interface_count; i++) {
1981  totemnet_finalize (instance->net_handles[i]);
1982  }
1983  free (instance->net_handles);
1984  free (instance);
1985  return (0);
1986 }
1987 
1988 static void rrp_target_set_completed (void *context)
1989 {
1990  struct deliver_fn_context *deliver_fn_context = (struct deliver_fn_context *)context;
1991 
1992  deliver_fn_context->instance->totemrrp_target_set_completed (deliver_fn_context->context);
1993 }
1994 
1995 /*
1996  * Totem Redundant Ring interface
1997  * depends on poll abstraction, POSIX, IPV4
1998  */
1999 
2000 /*
2001  * Create an instance
2002  */
2004  qb_loop_t *poll_handle,
2005  void **rrp_context,
2006  struct totem_config *totem_config,
2007  totemsrp_stats_t *stats,
2008  void *context,
2009 
2010  void (*deliver_fn) (
2011  void *context,
2012  const void *msg,
2013  unsigned int msg_len),
2014 
2015  void (*iface_change_fn) (
2016  void *context,
2017  const struct totem_ip_address *iface_addr,
2018  unsigned int iface_no),
2019 
2020  void (*token_seqid_get) (
2021  const void *msg,
2022  unsigned int *seqid,
2023  unsigned int *token_is),
2024 
2025  unsigned int (*msgs_missing) (void),
2026 
2027  void (*target_set_completed) (void *context))
2028 {
2029  struct totemrrp_instance *instance;
2030  unsigned int res;
2031  int i;
2032 
2033  instance = malloc (sizeof (struct totemrrp_instance));
2034  if (instance == 0) {
2035  return (-1);
2036  }
2037 
2038  totemrrp_instance_initialize (instance);
2039 
2040  instance->totem_config = totem_config;
2041  stats->rrp = &instance->stats;
2042  instance->stats.interface_count = totem_config->interface_count;
2043  instance->stats.faulty = calloc(instance->stats.interface_count, sizeof(uint8_t));
2044 
2045  res = totemrrp_algorithm_set (
2046  instance->totem_config,
2047  instance);
2048  if (res == -1) {
2049  goto error_destroy;
2050  }
2051 
2052  /*
2053  * Configure logging
2054  */
2062 
2063  instance->interfaces = totem_config->interfaces;
2064 
2065  instance->poll_handle = poll_handle;
2066 
2067  instance->totemrrp_deliver_fn = deliver_fn;
2068 
2069  instance->totemrrp_iface_change_fn = iface_change_fn;
2070 
2071  instance->totemrrp_token_seqid_get = token_seqid_get;
2072 
2073  instance->totemrrp_target_set_completed = target_set_completed;
2074 
2075  instance->totemrrp_msgs_missing = msgs_missing;
2076 
2077  instance->interface_count = totem_config->interface_count;
2078 
2079  instance->net_handles = malloc (sizeof (void *) * totem_config->interface_count);
2080 
2081  instance->context = context;
2082 
2083  instance->poll_handle = poll_handle;
2084 
2085 
2086  for (i = 0; i < totem_config->interface_count; i++) {
2087  struct deliver_fn_context *deliver_fn_context;
2088 
2089  deliver_fn_context = malloc (sizeof (struct deliver_fn_context));
2090  assert (deliver_fn_context);
2091  deliver_fn_context->instance = instance;
2092  deliver_fn_context->context = context;
2093  deliver_fn_context->iface_no = i;
2094  instance->deliver_fn_context[i] = (void *)deliver_fn_context;
2095 
2097  poll_handle,
2098  &instance->net_handles[i],
2099  totem_config,
2100  stats,
2101  i,
2102  (void *)deliver_fn_context,
2105  rrp_target_set_completed);
2106 
2107  totemnet_net_mtu_adjust (instance->net_handles[i], totem_config);
2108  }
2109 
2110  *rrp_context = instance;
2111  return (0);
2112 
2113 error_destroy:
2114  free (instance);
2115  return (res);
2116 }
2117 
2118 void *totemrrp_buffer_alloc (void *rrp_context)
2119 {
2120  struct totemrrp_instance *instance = rrp_context;
2121  assert (instance != NULL);
2122  return totemnet_buffer_alloc (instance->net_handles[0]);
2123 }
2124 
2125 void totemrrp_buffer_release (void *rrp_context, void *ptr)
2126 {
2127  struct totemrrp_instance *instance = rrp_context;
2128  assert (instance != NULL);
2129  totemnet_buffer_release (instance->net_handles[0], ptr);
2130 }
2131 
2133  void *rrp_context,
2134  unsigned int processor_count)
2135 {
2136  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2137  instance->rrp_algo->processor_count_set (instance, processor_count);
2138 
2139  instance->processor_count = processor_count;
2140 
2141  return (0);
2142 }
2143 
2145  void *rrp_context,
2146  struct totem_ip_address *addr,
2147  unsigned int iface_no)
2148 {
2149  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2150  instance->rrp_algo->token_target_set (instance, addr, iface_no);
2151 
2152  return (0);
2153 }
2154 int totemrrp_recv_flush (void *rrp_context)
2155 {
2156  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2157 
2158  instance->rrp_algo->recv_flush (instance);
2159 
2160  return (0);
2161 }
2162 
2163 int totemrrp_send_flush (void *rrp_context)
2164 {
2165  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2166  instance->rrp_algo->send_flush (instance);
2167 
2168  return (0);
2169 }
2170 
2172  void *rrp_context,
2173  const void *msg,
2174  unsigned int msg_len)
2175 {
2176  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2177  instance->rrp_algo->token_send (instance, msg, msg_len);
2178 
2179  return (0);
2180 }
2181 
2183  void *rrp_context,
2184  const void *msg,
2185  unsigned int msg_len)
2186 {
2187  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2188  int res = 0;
2189 
2190 // TODO this needs to return the result
2191  instance->rrp_algo->mcast_flush_send (instance, msg, msg_len);
2192 
2193  return (res);
2194 }
2195 
2197  void *rrp_context,
2198  const void *msg,
2199  unsigned int msg_len)
2200 {
2201  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2202  /*
2203  * merge detects go out through mcast_flush_send so it is safe to
2204  * flush these messages if we are only one processor. This avoids
2205  * an encryption/hmac and decryption/hmac
2206  */
2207  if (instance->processor_count > 1) {
2208 
2209 // TODO this needs to return the result
2210  instance->rrp_algo->mcast_noflush_send (instance, msg, msg_len);
2211  }
2212 
2213  return (0);
2214 }
2215 
2216 int totemrrp_iface_check (void *rrp_context)
2217 {
2218  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2219 
2220  instance->rrp_algo->iface_check (instance);
2221 
2222  return (0);
2223 }
2224 
2226  void *rrp_context,
2227  char ***status,
2228  unsigned int *iface_count)
2229 {
2230  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2231  *status = instance->status;
2232 
2233  if (iface_count) {
2234  *iface_count = instance->interface_count;
2235  }
2236 
2237  return (0);
2238 }
2239 
2241  void *rrp_context,
2242  const char *cipher_type,
2243  const char *hash_type)
2244 {
2245  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2246  int res;
2247 
2248  res = totemnet_crypto_set(instance->net_handles[0], cipher_type, hash_type);
2249 
2250  return (res);
2251 }
2252 
2253 
2254 /*
2255  * iface_no indicates the interface number [0, ..., interface_count-1] of the
2256  * specific ring which will be reenabled. We specify iface_no == interface_count
2257  * means reenabling all the rings.
2258  */
2260  void *rrp_context,
2261  unsigned int iface_no)
2262 {
2263  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2264  int res = 0;
2265  unsigned int i;
2266 
2267  instance->rrp_algo->ring_reenable (instance, iface_no);
2268 
2269  if (iface_no == instance->interface_count) {
2270  for (i = 0; i < instance->interface_count; i++) {
2271  snprintf (instance->status[i], STATUS_STR_LEN,
2272  "ring %d active with no faults", i);
2273  }
2274  } else {
2275  snprintf (instance->status[iface_no], STATUS_STR_LEN,
2276  "ring %d active with no faults", iface_no);
2277  }
2278 
2279  return (res);
2280 }
2281 
2283  void *rrp_context)
2284 {
2285  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2286  int res;
2287 
2288  res = instance->rrp_algo->mcast_recv_empty (instance);
2289 
2290  return (res);
2291 }
2292 
2294  void *rrp_context,
2295  const struct totem_ip_address *member,
2296  int iface_no)
2297 {
2298  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2299  int res;
2300 
2301  res = instance->rrp_algo->member_add (instance, member, iface_no);
2302 
2303  return (res);
2304 }
2305 
2307  void *rrp_context,
2308  const struct totem_ip_address *member,
2309  int iface_no)
2310 {
2311  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2312  int res;
2313 
2314  res = instance->rrp_algo->member_remove (instance, member, iface_no);
2315 
2316  return (res);
2317 }
2318 
2320  void *rrp_context,
2321  enum totem_configuration_type configuration_type,
2322  const struct srp_addr *member_list, size_t member_list_entries,
2323  const struct srp_addr *left_list, size_t left_list_entries,
2324  const struct srp_addr *joined_list, size_t joined_list_entries,
2325  const struct memb_ring_id *ring_id)
2326 {
2327  struct totemrrp_instance *instance = (struct totemrrp_instance *)rrp_context;
2328 
2329  instance->rrp_algo->membership_changed (instance,
2330  configuration_type,
2331  member_list, member_list_entries,
2332  left_list, left_list_entries,
2333  joined_list, joined_list_entries,
2334  ring_id);
2335 }
uint8_t no_addrs
Definition: totemrrp.h:59
unsigned short family
Definition: coroapi.h:113
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:2216
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:1961
#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
The totem_ip_address struct.
Definition: coroapi.h:111
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
The totem_configuration_type enum.
Definition: coroapi.h:132
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:2319
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:77
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:2225
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:2118
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:88
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:1974
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:2306
int totemrrp_crypto_set(void *rrp_context, const char *cipher_type, const char *hash_type)
Definition: totemrrp.c:2240
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:112
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:2163
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:2293
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:2003
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)
The swab32 macro.
Definition: swab.h:51
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:2154
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:2125
Totem Network interface - also does encryption/decryption.
struct totem_config * totem_config
Definition: totemrrp.c:255
The memb_ring_id struct.
Definition: coroapi.h:122
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:2132
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:2196
int totemrrp_mcast_recv_empty(void *rrp_context)
Definition: totemrrp.c:2282
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:2182
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:1861
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:2259
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:2171
int totemrrp_token_target_set(void *rrp_context, struct totem_ip_address *addr, unsigned int iface_no)
Definition: totemrrp.c:2144
int totemnet_processor_count_set(void *net_context, int processor_count)
Definition: totemnet.c:339
#define STATUS_STR_LEN
Definition: totemrrp.c:190