Hi

This fixes Fedora bz506255.

I have tested with compat=none & compat=whitetank

Steve I have updated your patch to make allowance for the syncv2 case.

This depends on: "move sync_v2_init() into main_service_ready".

-Angus

Signed-off-by: Angus Salkeld <[email protected]>
---
 exec/evil.c                       |    8 +++--
 exec/main.c                       |   20 ++++++++++--
 exec/sync.c                       |   20 ++++++++++--
 exec/sync.h                       |   16 ++++++++-
 exec/syncv2.c                     |   63 ++++++++++++++++++++++++++++++------
 exec/syncv2.h                     |    5 +++
 include/corosync/engine/coroapi.h |    5 ++-
 services/cpg.c                    |   16 ++++++---
 8 files changed, 123 insertions(+), 30 deletions(-)

diff --git a/exec/evil.c b/exec/evil.c
index 6d25f9a..9d61c5b 100644
--- a/exec/evil.c
+++ b/exec/evil.c
@@ -117,16 +117,18 @@ static void deliver_fn_evt_compat (
        unsigned int endian_conversion_required);
 
 static struct sync_callbacks clm_sync_operations = {
+       .api_version            = 1,
        .name                   = "dummy CLM service",
-       .sync_init              = clm_sync_init,
+       .sync_init_api.sync_init_v1 = clm_sync_init,
        .sync_process           = clm_sync_process,
        .sync_activate          = clm_sync_activate,
        .sync_abort             = clm_sync_abort,
 };
 
 static struct sync_callbacks evt_sync_operations = {
+       .api_version            = 1,
        .name                   = "dummy EVT service",
-       .sync_init              = evt_sync_init,
+       .sync_init_api.sync_init_v1 = evt_sync_init,
        .sync_process           = evt_sync_process,
        .sync_activate          = evt_sync_activate,
        .sync_abort             = evt_sync_abort,
@@ -212,7 +214,7 @@ extern int evil_callbacks_load (int sync_id,
 
        }
        if (callbacks_init) {
-               callbacks->sync_init = sync_dummy_init;
+               callbacks->sync_init_api.sync_init_v1 = sync_dummy_init;
                callbacks->sync_process = sync_dummy_process;
                callbacks->sync_activate = sync_dummy_activate;
                callbacks->sync_abort = sync_dummy_abort;
diff --git a/exec/main.c b/exec/main.c
index 5b50086..beedc2c 100644
--- a/exec/main.c
+++ b/exec/main.c
@@ -274,7 +274,8 @@ static int corosync_sync_callbacks_retrieve (int sync_id,
                ais_service_index++) {
 
                if (ais_service[ais_service_index] != NULL
-                       && ais_service[ais_service_index]->sync_mode == 
CS_SYNC_V1) {
+                       && (ais_service[ais_service_index]->sync_mode == 
CS_SYNC_V1
+                               || ais_service[ais_service_index]->sync_mode == 
CS_SYNC_V1_APIV2)) {
                        if (ais_service_index == sync_id) {
                                break;
                        }
@@ -288,7 +289,11 @@ static int corosync_sync_callbacks_retrieve (int sync_id,
                return (res);
        }
        callbacks->name = ais_service[ais_service_index]->name;
-       callbacks->sync_init = ais_service[ais_service_index]->sync_init;
+       callbacks->sync_init_api.sync_init_v1 = 
ais_service[ais_service_index]->sync_init;
+       callbacks->api_version = 1;
+       if (ais_service[ais_service_index]->sync_mode == CS_SYNC_V1_APIV2) {
+               callbacks->api_version = 2;
+       }
        callbacks->sync_process = ais_service[ais_service_index]->sync_process;
        callbacks->sync_activate = 
ais_service[ais_service_index]->sync_activate;
        callbacks->sync_abort = ais_service[ais_service_index]->sync_abort;
@@ -317,7 +322,13 @@ static int corosync_sync_v2_callbacks_retrieve (
        }
 
        callbacks->name = ais_service[service_id]->name;
-       callbacks->sync_init = ais_service[service_id]->sync_init;
+
+       callbacks->api_version = 1;
+       if (ais_service[service_id]->sync_mode == CS_SYNC_V1_APIV2) {
+               callbacks->api_version = 2;
+       }
+
+       callbacks->sync_init_api.sync_init_v1 = 
ais_service[service_id]->sync_init;
        callbacks->sync_process = ais_service[service_id]->sync_process;
        callbacks->sync_activate = ais_service[service_id]->sync_activate;
        callbacks->sync_abort = ais_service[service_id]->sync_abort;
@@ -359,6 +370,9 @@ static void confchg_fn (
        if (abort_activate) {
                sync_v2_abort ();
        }
+       if (minimum_sync_mode == CS_SYNC_V2 && configuration_type == 
TOTEM_CONFIGURATION_TRANSITIONAL) {
+               sync_v2_save_transitional (member_list, member_list_entries, 
ring_id);
+       }
        if (minimum_sync_mode == CS_SYNC_V2 && configuration_type == 
TOTEM_CONFIGURATION_REGULAR) {
                sync_v2_start (member_list, member_list_entries, ring_id);
        }
diff --git a/exec/sync.c b/exec/sync.c
index cb3c300..ce115a3 100644
--- a/exec/sync.c
+++ b/exec/sync.c
@@ -99,8 +99,12 @@ static struct barrier_data 
barrier_data_process[PROCESSOR_COUNT_MAX];
 
 static unsigned int my_member_list[PROCESSOR_COUNT_MAX];
 
+static unsigned int my_trans_list[PROCESSOR_COUNT_MAX];
+
 static unsigned int my_member_list_entries;
 
+static unsigned int my_trans_list_entries;
+
 static int sync_barrier_send (const struct memb_ring_id *ring_id);
 
 static int sync_start_process (enum totem_callback_token_type type,
@@ -181,7 +185,14 @@ static void sync_start_init (const struct memb_ring_id 
*ring_id)
 
 static void sync_service_init (struct memb_ring_id *ring_id)
 {
-       sync_callbacks.sync_init (my_member_list, my_member_list_entries, 
ring_id);
+       if (sync_callbacks.api_version == 1) {
+               sync_callbacks.sync_init_api.sync_init_v1 (my_member_list,
+                       my_member_list_entries, ring_id);
+       } else {
+               sync_callbacks.sync_init_api.sync_init_v2 (my_trans_list,
+                       my_trans_list_entries,
+                       my_member_list, my_member_list_entries, ring_id);
+       }
        totempg_callback_token_destroy (&sync_callback_token_handle);
 
        /*
@@ -227,7 +238,7 @@ static void sync_callbacks_load (void)
                        break;
                }
                sync_recovery_index += 1;
-               if (sync_callbacks.sync_init) {
+               if (sync_callbacks.sync_init_api.sync_init_v1) {
                        break;
                }
        }
@@ -434,7 +445,7 @@ static void sync_deliver_fn (
                /*
                 * if sync service found, execute it
                 */
-               if (sync_processing && sync_callbacks.sync_init) {
+               if (sync_processing && 
sync_callbacks.sync_init_api.sync_init_v1) {
                        log_printf (LOGSYS_LEVEL_DEBUG,
                                "Synchronization actions starting for (%s)\n",
                                sync_callbacks.name);
@@ -460,6 +471,9 @@ static void sync_confchg_fn (
        sync_ring_id = ring_id;
 
        if (configuration_type != TOTEM_CONFIGURATION_REGULAR) {
+               memcpy (my_trans_list, member_list, member_list_entries *
+                       sizeof (unsigned int));
+               my_trans_list_entries = member_list_entries;
                return;
        }
        memcpy (my_member_list, member_list, member_list_entries * sizeof 
(unsigned int));
diff --git a/exec/sync.h b/exec/sync.h
index b642120..a8071d4 100644
--- a/exec/sync.h
+++ b/exec/sync.h
@@ -39,11 +39,23 @@
 #include <corosync/totem/totempg.h>
 #include "totemsrp.h"
 
-struct sync_callbacks {
-       void (*sync_init) (
+union sync_init_api {
+       void (*sync_init_v1) (
+               const unsigned int *member_list,
+               size_t member_list_entries,
+               const struct memb_ring_id *ring_id);
+
+       void (*sync_init_v2) (
+               const unsigned int *trans_list,
+               size_t trans_list_entries,
                const unsigned int *member_list,
                size_t member_list_entries,
                const struct memb_ring_id *ring_id);
+};
+
+struct sync_callbacks {
+       int api_version;
+       union sync_init_api sync_init_api;
        int (*sync_process) (void);
        void (*sync_activate) (void);
        void (*sync_abort) (void);
diff --git a/exec/syncv2.c b/exec/syncv2.c
index 3cdf52d..e0521f0 100644
--- a/exec/syncv2.c
+++ b/exec/syncv2.c
@@ -81,10 +81,8 @@ enum sync_state {
 
 struct service_entry {
        int service_id;
-       void (*sync_init) (
-               const unsigned int *member_list,
-               size_t member_list_entries,
-               const struct memb_ring_id *ring_id);
+       int api_version;
+       union sync_init_api sync_init_api;
        void (*sync_abort) (void);
        int (*sync_process) (void);
        void (*sync_activate) (void);
@@ -134,8 +132,12 @@ static struct processor_entry 
my_processor_list[PROCESSOR_COUNT_MAX];
 
 static unsigned int my_member_list[PROCESSOR_COUNT_MAX];
 
+static unsigned int my_trans_list[PROCESSOR_COUNT_MAX];
+
 static size_t my_member_list_entries = 0;
 
+static size_t my_trans_list_entries = 0;
+
 static int my_processor_list_entries = 0;
 
 static struct service_entry my_service_list[128];
@@ -202,7 +204,7 @@ int sync_v2_init (
                if (res == -1) {
                        continue;
                }
-               if (sync_callbacks.sync_init == NULL) {
+               if (sync_callbacks.sync_init_api.sync_init_v1 == NULL) {
                        continue;
                }
                my_initial_service_list[my_initial_service_list_entries].state =
@@ -210,7 +212,8 @@ int sync_v2_init (
                
my_initial_service_list[my_initial_service_list_entries].service_id = i;
                strcpy 
(my_initial_service_list[my_initial_service_list_entries].name,
                        sync_callbacks.name);
-               
my_initial_service_list[my_initial_service_list_entries].sync_init = 
sync_callbacks.sync_init;
+               
my_initial_service_list[my_initial_service_list_entries].api_version = 
sync_callbacks.api_version;
+               
my_initial_service_list[my_initial_service_list_entries].sync_init_api = 
sync_callbacks.sync_init_api;
                
my_initial_service_list[my_initial_service_list_entries].sync_process = 
sync_callbacks.sync_process;
                
my_initial_service_list[my_initial_service_list_entries].sync_abort = 
sync_callbacks.sync_abort;
                
my_initial_service_list[my_initial_service_list_entries].sync_activate = 
sync_callbacks.sync_activate;
@@ -334,7 +337,8 @@ static void sync_service_build_handler (unsigned int 
nodeid, const void *msg)
                        sprintf (my_service_list[my_service_list_entries].name,
                                "External Service (id = %d)\n",
                                
req_exec_service_build_message->service_list[i]);
-                       my_service_list[my_service_list_entries].sync_init =
+                       my_service_list[my_service_list_entries].api_version = 
1;
+                       
my_service_list[my_service_list_entries].sync_init_api.sync_init_v1 =
                                dummy_sync_init;
                        my_service_list[my_service_list_entries].sync_abort =
                                dummy_sync_abort;
@@ -510,13 +514,39 @@ static void sync_servicelist_build_enter (
 
 static int schedwrk_processor (const void *context)
 {
-       int res;
+       int res = 0;
 
        if (my_service_list[my_processing_idx].state == INIT) {
                my_service_list[my_processing_idx].state = PROCESS;
-               my_service_list[my_processing_idx].sync_init (my_member_list,
-                       my_member_list_entries,
-                       &my_ring_id);
+               if (my_service_list[my_processing_idx].api_version == 1) {
+                       
my_service_list[my_processing_idx].sync_init_api.sync_init_v1 (my_member_list,
+                               my_member_list_entries,
+                               &my_ring_id);
+               } else {
+                       unsigned int old_trans_list[PROCESSOR_COUNT_MAX];
+                       size_t old_trans_list_entries = 0;
+                       int o, m;
+
+                       memcpy (old_trans_list, my_trans_list, 
my_trans_list_entries *
+                               sizeof (unsigned int));
+                       old_trans_list_entries = my_trans_list_entries;
+
+                       my_trans_list_entries = 0;
+                       for (o = 0; o < old_trans_list_entries; o++) {
+                               for (m = 0; m < my_member_list_entries; m++) {
+                                       if (old_trans_list[o] == 
my_member_list[m]) {
+                                               
my_trans_list[my_trans_list_entries] = my_member_list[m];
+                                               my_trans_list_entries++;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       
my_service_list[my_processing_idx].sync_init_api.sync_init_v2 (my_trans_list,
+                               my_trans_list_entries, my_member_list,
+                               my_member_list_entries,
+                               &my_ring_id);
+               }
        }
        if (my_service_list[my_processing_idx].state == PROCESS) {
                my_service_list[my_processing_idx].state = PROCESS;
@@ -554,6 +584,17 @@ void sync_v2_start (
        }
 }
 
+void sync_v2_save_transitional (
+        const unsigned int *member_list,
+        size_t member_list_entries,
+        const struct memb_ring_id *ring_id)
+{
+       log_printf (LOGSYS_LEVEL_DEBUG, "saving transitional configuration\n");
+       memcpy (my_trans_list, member_list, member_list_entries *
+               sizeof (unsigned int));
+       my_trans_list_entries = member_list_entries;
+}
+
 void sync_v2_abort (void)
 {
        if (my_state == SYNC_PROCESS) {
diff --git a/exec/syncv2.h b/exec/syncv2.h
index c383636..91b9aff 100644
--- a/exec/syncv2.h
+++ b/exec/syncv2.h
@@ -48,6 +48,11 @@ extern void sync_v2_start (
         size_t member_list_entries,
         const struct memb_ring_id *ring_id);
 
+extern void sync_v2_save_transitional (
+        const unsigned int *member_list,
+        size_t member_list_entries,
+        const struct memb_ring_id *ring_id);
+
 extern void sync_v2_abort (void);
 
 extern void sync_v2_memb_list_determine (const struct memb_ring_id *ring_id);
diff --git a/include/corosync/engine/coroapi.h 
b/include/corosync/engine/coroapi.h
index 556a568..b3c9777 100644
--- a/include/corosync/engine/coroapi.h
+++ b/include/corosync/engine/coroapi.h
@@ -136,8 +136,9 @@ enum cs_flow_control_state {
 #endif /* COROSYNC_FLOW_CONTROL_STATE */
 
 enum cs_sync_mode {
-       CS_SYNC_V1      = 0,
-       CS_SYNC_V2      = 1
+       CS_SYNC_V1       = 0,
+       CS_SYNC_V2       = 1,
+       CS_SYNC_V1_APIV2 = 2
 };
 
 typedef enum {
diff --git a/services/cpg.c b/services/cpg.c
index 59d59b2..68bd1ed 100644
--- a/services/cpg.c
+++ b/services/cpg.c
@@ -240,7 +240,9 @@ static int cpg_exec_send_downlist(void);
 
 static int cpg_exec_send_joinlist(void);
 
-static void cpg_sync_init (
+static void cpg_sync_init_v2 (
+       const unsigned int *trans_list,
+       size_t trans_list_entries,
        const unsigned int *member_list,
        size_t member_list_entries,
        const struct memb_ring_id *ring_id);
@@ -329,8 +331,8 @@ struct corosync_service_engine cpg_service_engine = {
        .exec_dump_fn                           = NULL,
        .exec_engine                            = cpg_exec_engine,
        .exec_engine_count                      = sizeof (cpg_exec_engine) / 
sizeof (struct corosync_exec_handler),
-       .sync_mode                              = CS_SYNC_V1,
-       .sync_init                              = cpg_sync_init,
+       .sync_mode                              = CS_SYNC_V1_APIV2,
+       .sync_init                              = cpg_sync_init_v2,
        .sync_process                           = cpg_sync_process,
        .sync_activate                          = cpg_sync_activate,
        .sync_abort                             = cpg_sync_abort
@@ -406,7 +408,9 @@ struct req_exec_cpg_downlist {
 
 static struct req_exec_cpg_downlist g_req_exec_cpg_downlist;
 
-static void cpg_sync_init (
+static void cpg_sync_init_v2 (
+       const unsigned int *trans_list,
+       size_t trans_list_entries,
        const unsigned int *member_list,
        size_t member_list_entries,
        const struct memb_ring_id *ring_id)
@@ -435,8 +439,8 @@ static void cpg_sync_init (
                 */
                for (i = 0; i < my_old_member_list_entries; i++) {
                        found = 0;
-                       for (j = 0; j < my_member_list_entries; j++) {
-                               if (my_old_member_list[i] == my_member_list[j]) 
{
+                       for (j = 0; j < trans_list_entries; j++) {
+                               if (my_old_member_list[i] == trans_list[j]) {
                                        found = 1;
                                        break;
                                }
-- 
1.6.6


_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to