diff --git a/exec/Makefile.am b/exec/Makefile.am index 754dfe81..e1fd810c 100644 --- a/exec/Makefile.am +++ b/exec/Makefile.am @@ -53,7 +53,7 @@ libcoroipcs_a_SOURCES = $(COROIPCS_SRC) corosync_SOURCES = main.c util.c sync.c apidef.c service.c \ timer.c totemconfig.c mainconfig.c quorum.c schedwrk.c \ - ../lcr/lcr_ifact.c evil.c + ../lcr/lcr_ifact.c evil.c syncv2.c corosync_LDADD = -ltotem_pg -llogsys -lcoroipcs corosync_DEPENDENCIES = libtotem_pg.so.$(SONAME) liblogsys.so.$(SONAME) libcoroipcs.so.$(SONAME) corosync_LDFLAGS = $(OS_DYFLAGS) -L./ @@ -69,7 +69,7 @@ SHARED_LIBS_SO_TWO = $(SHARED_LIBS:%.so.$(SONAME)=%.so.$(SOMAJOR)) noinst_HEADERS = apidef.h crypto.h mainconfig.h main.h \ quorum.h service.h sync.h timer.h tlist.h totemconfig.h \ totemmrp.h totemnet.h totemrrp.h totemsrp.h util.h \ - version.h vsf.h wthread.h schedwrk.h evil.h + version.h vsf.h wthread.h schedwrk.h evil.h syncv2.h EXTRA_DIST = $(LCRSO_SRC) diff --git a/exec/main.c b/exec/main.c index bc9c1e01..022f4298 100644 --- a/exec/main.c +++ b/exec/main.c @@ -76,6 +76,7 @@ #include "totemconfig.h" #include "main.h" #include "sync.h" +#include "syncv2.h" #include "tlist.h" #include "timer.h" #include "util.h" @@ -123,6 +124,8 @@ static enum cs_sync_mode minimum_sync_mode; static enum cs_sync_mode minimum_sync_mode; +static int sync_in_process = 1; + unsigned long long *(*main_clm_get_by_nodeid) (unsigned int node_id); hdb_handle_t corosync_poll_handle; @@ -226,6 +229,9 @@ static void serialize_unlock (void) static void corosync_sync_completed (void) { + log_printf (LOGSYS_LEVEL_NOTICE, + "Completed service synchronization, ready to provide service.\n"); + sync_in_process = 0; } static int corosync_sync_callbacks_retrieve (int sync_id, @@ -238,7 +244,8 @@ static int corosync_sync_callbacks_retrieve (int sync_id, ais_service_index < SERVICE_HANDLER_MAXIMUM_COUNT; ais_service_index++) { - if (ais_service[ais_service_index] != NULL) { + if (ais_service[ais_service_index] != NULL + && ais_service[ais_service_index]->sync_mode == CS_SYNC_V1) { if (ais_service_index == sync_id) { break; } @@ -259,6 +266,33 @@ static int corosync_sync_callbacks_retrieve (int sync_id, return (0); } +static int corosync_sync_v2_callbacks_retrieve ( + int service_id, + struct sync_callbacks *callbacks) +{ + int res; + + if (service_id == CLM_SERVICE && ais_service[CLM_SERVICE] == NULL) { + res = evil_callbacks_load (service_id, callbacks); + return (res); + } + if (ais_service[service_id] == NULL) { + return (-1); + } + if (minimum_sync_mode == CS_SYNC_V1 && ais_service[service_id]->sync_mode != CS_SYNC_V2) { +printf ("returning -1 %d\n", service_id); + return (-1); + } + + callbacks->name = ais_service[service_id]->name; + callbacks->sync_init = ais_service[service_id]->sync_init; + callbacks->sync_process = ais_service[service_id]->sync_process; +printf ("process %p\n", ais_service[service_id]->sync_process); + callbacks->sync_activate = ais_service[service_id]->sync_activate; + callbacks->sync_abort = ais_service[service_id]->sync_abort; + return (0); +} + static struct memb_ring_id corosync_ring_id; static void confchg_fn ( @@ -269,7 +303,12 @@ static void confchg_fn ( const struct memb_ring_id *ring_id) { int i; + int abort_activate = 0; + if (sync_in_process == 1) { + abort_activate = 1; + } + sync_in_process = 1; serialize_lock (); memcpy (&corosync_ring_id, ring_id, sizeof (struct memb_ring_id)); @@ -285,6 +324,13 @@ static void confchg_fn ( } } serialize_unlock (); + + if (abort_activate) { + sync_v2_abort (); + } + if (minimum_sync_mode == CS_SYNC_V2 && configuration_type == TOTEM_CONFIGURATION_REGULAR) { + sync_v2_start (member_list, member_list_entries, ring_id); + } } static void priv_drop (void) @@ -522,7 +568,7 @@ static int corosync_sending_allowed ( ((ais_service[service]->lib_engine[id].flow_control == CS_LIB_FLOW_CONTROL_NOT_REQUIRED) || ((ais_service[service]->lib_engine[id].flow_control == CS_LIB_FLOW_CONTROL_REQUIRED) && (pd->reserved_msgs) && - (sync_in_process() == 0))); + (sync_in_process == 0))); return (sending_allowed); } @@ -924,13 +970,6 @@ int main (int argc, char **argv) &corosync_group, 1); - if (minimum_sync_mode == 1) { - log_printf (LOGSYS_LEVEL_NOTICE, "Compatibility mode set to none. Using V2 of the synchronization engine.\n"); - } else - if (minimum_sync_mode == 0) { - log_printf (LOGSYS_LEVEL_NOTICE, "Compatibility mode set to whitetank. Using V1 and V2 of the synchronization engine.\n"); - } - /* * This must occur after totempg is initialized because "this_ip" must be set */ @@ -941,7 +980,23 @@ int main (int argc, char **argv) } evil_init (api); - sync_register (corosync_sync_callbacks_retrieve, corosync_sync_completed); + if (minimum_sync_mode == 1) { + log_printf (LOGSYS_LEVEL_NOTICE, "Compatibility mode set to none. Using V2 of the synchronization engine.\n"); + sync_v2_init ( + corosync_sync_v2_callbacks_retrieve, + corosync_sync_completed); + } else + if (minimum_sync_mode == 0) { + log_printf (LOGSYS_LEVEL_NOTICE, "Compatibility mode set to whitetank. Using V1 and V2 of the synchronization engine.\n"); + sync_register ( + corosync_sync_callbacks_retrieve, + sync_v2_start); + + sync_v2_init ( + corosync_sync_v2_callbacks_retrieve, + corosync_sync_completed); + } + /* * Drop root privleges to user 'ais' diff --git a/exec/service.h b/exec/service.h index d68fcd2b..7e331b05 100644 --- a/exec/service.h +++ b/exec/service.h @@ -38,6 +38,8 @@ /* * Link and initialize a service */ +struct corosync_api_v1; + extern unsigned int corosync_service_link_and_init ( struct corosync_api_v1 *objdb, const char *service_name, diff --git a/exec/sync.c b/exec/sync.c index 4edc053a..805badbf 100644 --- a/exec/sync.c +++ b/exec/sync.c @@ -77,7 +77,10 @@ static struct sync_callbacks sync_callbacks; static int sync_processing = 0; -static void (*sync_synchronization_completed) (void); +static void (*sync_next_start) ( + unsigned int *member_list, + size_t member_list_entries, + const struct memb_ring_id *ring_id); static int sync_recovery_index = 0; @@ -89,6 +92,10 @@ static size_t barrier_data_confchg_entries; static struct barrier_data barrier_data_process[PROCESSOR_COUNT_MAX]; +static unsigned int my_member_list[PROCESSOR_COUNT_MAX]; + +static unsigned int my_member_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, @@ -107,9 +114,12 @@ static void sync_deliver_fn ( static void sync_confchg_fn ( enum totem_configuration_type configuration_type, - const unsigned int *member_list, size_t member_list_entries, - const unsigned int *left_list, size_t left_list_entries, - const unsigned int *joined_list, size_t joined_list_entries, + const unsigned int *member_list, + size_t member_list_entries, + const unsigned int *left_list, + size_t left_list_entries, + const unsigned int *joined_list, + size_t joined_list_entries, const struct memb_ring_id *ring_id); static void sync_primary_callback_fn ( @@ -249,8 +259,14 @@ static int sync_service_process (enum totem_callback_token_type type, } int sync_register ( - int (*callbacks_retrieve) (int sync_id, struct sync_callbacks *callack), - void (*synchronization_completed) (void)) + int (*callbacks_retrieve) ( + int sync_id, + struct sync_callbacks *callbacks), + + void (*next_start) ( + unsigned int *member_list, + size_t member_list_entries, + const struct memb_ring_id *ring_id)) { unsigned int res; @@ -274,7 +290,7 @@ int sync_register ( } sync_callbacks_retrieve = callbacks_retrieve; - sync_synchronization_completed = synchronization_completed; + sync_next_start = next_start; return (0); } @@ -412,15 +428,21 @@ static void sync_deliver_fn ( sync_callbacks.name); sync_service_init (&deliver_ring_id); } + if (sync_processing == 0) { + sync_next_start (my_member_list, my_member_list_entries, sync_ring_id); + } } return; } static void sync_confchg_fn ( enum totem_configuration_type configuration_type, - const unsigned int *member_list, size_t member_list_entries, - const unsigned int *left_list, size_t left_list_entries, - const unsigned int *joined_list, size_t joined_list_entries, + const unsigned int *member_list, + size_t member_list_entries, + const unsigned int *left_list, + size_t left_list_entries, + const unsigned int *joined_list, + size_t joined_list_entries, const struct memb_ring_id *ring_id) { sync_ring_id = ring_id; @@ -428,6 +450,9 @@ static void sync_confchg_fn ( if (configuration_type != TOTEM_CONFIGURATION_REGULAR) { return; } + memcpy (my_member_list, member_list, member_list_entries * sizeof (unsigned int)); + my_member_list_entries = member_list_entries; + if (sync_processing && sync_callbacks.sync_abort != NULL) { sync_callbacks.sync_abort (); sync_callbacks.sync_activate = NULL; @@ -439,13 +464,3 @@ static void sync_confchg_fn ( 1, ring_id); } - -int sync_in_process (void) -{ - return (sync_processing); -} - -int sync_primary_designated (void) -{ - return (1); -} diff --git a/exec/sync.h b/exec/sync.h index cb6f44b1..c57b8694 100644 --- a/exec/sync.h +++ b/exec/sync.h @@ -47,21 +47,15 @@ struct sync_callbacks { const char *name; }; -struct corosync_api_v1; int sync_register ( - int (*sync_callbacks_retrieve) (int sync_id, struct sync_callbacks *callbacks), - void (*synchronization_completed) (void)); + int (*sync_callbacks_retrieve) ( + int sync_id, + struct sync_callbacks *callbacks), -int sync_in_process (void); + void (*next_start) ( + unsigned int *member_list, + size_t member_list_entries, + const struct memb_ring_id *ring_id)); -int sync_primary_designated (void); - -/** - * Execute synchronization upon request for the named service - * @param name service handler name to synchronize - * - * @return int 0 OK, error code otherwise - */ -extern int sync_request (const char *name); #endif /* SYNC_H_DEFINED */ diff --git a/exec/syncv2.c b/exec/syncv2.c new file mode 100644 index 00000000..211a53a9 --- /dev/null +++ b/exec/syncv2.c @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2009 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Steven Dake (sdake@redhat.com) + * + * This software licensed under BSD license, the text of which follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the MontaVista Software, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "schedwrk.h" +#include "quorum.h" +#include "sync.h" +#include "syncv2.h" + +LOGSYS_DECLARE_SUBSYS ("SYNCV2"); + +#define MESSAGE_REQ_SYNC_BARRIER 0 +#define MESSAGE_REQ_SYNC_SERVICE_BUILD 1 + +enum sync_process_state { + INIT, + PROCESS, + ACTIVATE +}; + +enum sync_state { + SYNC_SERVICELIST_BUILD, + SYNC_PROCESS, + SYNC_BARRIER +}; + +struct service_entry { + int service_id; + void (*sync_init) (void); + void (*sync_abort) (void); + int (*sync_process) (void); + void (*sync_activate) (void); + enum sync_process_state state; + char name[128]; +}; + +struct processor_entry { + int nodeid; + int received; +}; + +struct req_exec_service_build_message { + coroipc_request_header_t header; + struct memb_ring_id ring_id; + int service_list[128]; + int service_list_entries; +}; + +struct req_exec_barrier_message { + coroipc_request_header_t header; + struct memb_ring_id ring_id; +}; + +static enum sync_state my_state = SYNC_BARRIER; + +static struct memb_ring_id my_ring_id; + +static int my_processing_idx = 0; + +static hdb_handle_t my_schedwrk_handle; + +static struct processor_entry my_processor_list[128]; + +static int my_processor_list_entries = 0; + +static struct service_entry my_service_list[128]; + +static int my_service_list_entries = 0; + +static const struct memb_ring_id sync_ring_id; + +static struct service_entry my_initial_service_list[128]; + +static int my_initial_service_list_entries; + +static void (*sync_synchronization_completed) (void); + +static void sync_deliver_fn ( + unsigned int nodeid, + const void *msg, + unsigned int msg_len, + int endian_conversion_required); + +static int schedwrk_processor (const void *context); + +static void sync_process_enter (void); + +static struct totempg_group sync_group = { + .group = "syncv2", + .group_len = 6 +}; + +static hdb_handle_t sync_group_handle; + +int sync_v2_init ( + int (*sync_callbacks_retrieve) ( + int service_id, + struct sync_callbacks *callbacks), + void (*synchronization_completed) (void)) +{ + unsigned int res; + int i; + struct sync_callbacks sync_callbacks; + + res = totempg_groups_initialize ( + &sync_group_handle, + sync_deliver_fn, + NULL); + if (res == -1) { + log_printf (LOGSYS_LEVEL_ERROR, + "Couldn't initialize groups interface.\n"); + return (-1); + } + + res = totempg_groups_join ( + sync_group_handle, + &sync_group, + 1); + if (res == -1) { + log_printf (LOGSYS_LEVEL_ERROR, "Couldn't join group.\n"); + return (-1); + } + + sync_synchronization_completed = synchronization_completed; + for (i = 0; i < 64; i++) { + res = sync_callbacks_retrieve (i, &sync_callbacks); + if (res == -1) { + continue; + } + if (sync_callbacks.sync_init == NULL) { + continue; + } + my_initial_service_list[my_initial_service_list_entries].state = + 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].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; + my_initial_service_list_entries += 1; + } + return (0); +} + +static void sync_barrier_handler (unsigned int nodeid, const void *msg) +{ + const struct req_exec_barrier_message *req_exec_barrier_message = msg; + int i; + int barrier_reached = 1; + + if (memcmp (&my_ring_id, &req_exec_barrier_message->ring_id, + sizeof (struct memb_ring_id)) != 0) { + + return; + } + for (i = 0; i < my_processor_list_entries; i++) { + if (my_processor_list[i].nodeid == nodeid) { + my_processor_list[i].received = 1; + } + } + for (i = 0; i < my_processor_list_entries; i++) { + if (my_processor_list[i].received == 0) { + barrier_reached = 0; + } + } + if (barrier_reached) { + my_processing_idx += 1; + if (my_service_list_entries == my_processing_idx) { + sync_synchronization_completed (); + } else { + sync_process_enter (); + } + } +} + +static void dummy_sync_init (void) +{ +} + +static void dummy_sync_abort (void) +{ +} + +static int dummy_sync_process (void) +{ + return (0); +} + +static void dummy_sync_activate (void) +{ +} + +static int service_entry_compare (const void *a, const void *b) +{ + const struct service_entry *service_entry_a = a; + const struct service_entry *service_entry_b = b; + + return (service_entry_a->service_id > service_entry_b->service_id); +} + +static void sync_service_build_handler (unsigned int nodeid, const void *msg) +{ + const struct req_exec_service_build_message *req_exec_service_build_message = msg; + int i, j; + int barrier_reached = 1; + int found; + int qsort_trigger = 0; + + if (memcmp (&my_ring_id, &req_exec_service_build_message->ring_id, + sizeof (struct memb_ring_id)) != 0) { + + return; + } + for (i = 0; i < req_exec_service_build_message->service_list_entries; i++) { + + found = 0; + for (j = 0; j < my_service_list_entries; j++) { + if (req_exec_service_build_message->service_list[i] == + my_service_list[j].service_id) { + found = 1; + break; + } + } + if (found == 0) { + my_service_list[my_service_list_entries].state = + INIT; + my_service_list[my_service_list_entries].service_id = + req_exec_service_build_message->service_list[i]; + 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 = + dummy_sync_init; + my_service_list[my_service_list_entries].sync_abort = + dummy_sync_abort; + my_service_list[my_service_list_entries].sync_process = + dummy_sync_process; + my_service_list[my_service_list_entries].sync_activate = + dummy_sync_activate; + my_service_list_entries += 1; + + qsort_trigger = 1; + } + } + if (qsort_trigger) { + qsort (my_service_list, my_service_list_entries, + sizeof (struct service_entry), service_entry_compare); + } + for (i = 0; i < my_processor_list_entries; i++) { + if (my_processor_list[i].nodeid == nodeid) { + my_processor_list[i].received = 1; + } + } + for (i = 0; i < my_processor_list_entries; i++) { + if (my_processor_list[i].received == 0) { + barrier_reached = 0; + } + } + if (barrier_reached) { + sync_process_enter (); + } +} + +static void sync_deliver_fn ( + unsigned int nodeid, + const void *msg, + unsigned int msg_len, + int endian_conversion_required) +{ + coroipc_request_header_t *header = (coroipc_request_header_t *)msg; + + switch (header->id) { + case MESSAGE_REQ_SYNC_BARRIER: + sync_barrier_handler (nodeid, msg); + break; + case MESSAGE_REQ_SYNC_SERVICE_BUILD: + sync_service_build_handler (nodeid, msg); + break; + } +} + +static void barrier_message_transmit (void) +{ + struct iovec iovec; + struct req_exec_barrier_message req_exec_barrier_message; + int res; + + req_exec_barrier_message.header.size = sizeof (struct req_exec_barrier_message); + req_exec_barrier_message.header.id = MESSAGE_REQ_SYNC_BARRIER; + + memcpy (&req_exec_barrier_message.ring_id, &my_ring_id, + sizeof (struct memb_ring_id)); + + iovec.iov_base = (char *)&req_exec_barrier_message; + iovec.iov_len = sizeof (req_exec_barrier_message); + + res = totempg_groups_mcast_joined (sync_group_handle, + &iovec, 1, TOTEMPG_AGREED); +} + +static void service_build_message_transmit (struct req_exec_service_build_message *service_build_message) +{ + struct iovec iovec; + int res; + + service_build_message->header.size = sizeof (struct req_exec_service_build_message); + service_build_message->header.id = MESSAGE_REQ_SYNC_SERVICE_BUILD; + + memcpy (&service_build_message->ring_id, &my_ring_id, + sizeof (struct memb_ring_id)); + + iovec.iov_base = (void *)service_build_message; + iovec.iov_len = sizeof (struct req_exec_service_build_message); + + res = totempg_groups_mcast_joined (sync_group_handle, + &iovec, 1, TOTEMPG_AGREED); +} + +static void sync_barrier_enter (void) +{ + my_state = SYNC_BARRIER; + barrier_message_transmit (); +} + +static void sync_process_enter (void) +{ + int i; + + my_state = SYNC_PROCESS; + + /* + * No syncv2 services + */ +assert (my_service_list_entries); + if (my_service_list_entries == 0) { + my_state = SYNC_SERVICELIST_BUILD; + sync_synchronization_completed (); + return; + } + for (i = 0; i < my_processor_list_entries; i++) { + my_processor_list[i].received = 0; + } + schedwrk_create (&my_schedwrk_handle, + schedwrk_processor, + NULL); +} + +static void sync_servicelist_build_enter ( + const unsigned int *member_list, + size_t member_list_entries, + const struct memb_ring_id *ring_id) +{ + struct req_exec_service_build_message service_build; + int i; + + my_state = SYNC_SERVICELIST_BUILD; + for (i = 0; i < member_list_entries; i++) { + my_processor_list[i].nodeid = member_list[i]; + my_processor_list[i].received = 0; + } + my_processor_list_entries = member_list_entries; + + my_processing_idx = 0; + + memcpy (my_service_list, my_initial_service_list, + sizeof (struct service_entry) * + my_initial_service_list_entries); + my_service_list_entries = my_initial_service_list_entries; + + for (i = 0; i < my_initial_service_list[i].service_id; i++) { + service_build.service_list[i] = + my_initial_service_list[i].service_id; + } + service_build.service_list_entries = i; + + service_build_message_transmit (&service_build); +} + +static int schedwrk_processor (const void *context) +{ + int res; + + 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 (); + } + if (my_service_list[my_processing_idx].state == PROCESS) { + my_service_list[my_processing_idx].state = PROCESS; + res = my_service_list[my_processing_idx].sync_process (); + if (res != -1) { + my_service_list[my_processing_idx].state = ACTIVATE; + } else { + return (-1); + } + } + if (my_service_list[my_processing_idx].state == ACTIVATE) { + my_service_list[my_processing_idx].state = ACTIVATE; + my_service_list[my_processing_idx].sync_activate (); + log_printf (LOGSYS_LEVEL_DEBUG, "Committing synchronization for %s\n", + my_service_list[my_processing_idx].name); + sync_barrier_enter(); + } + return (0); +} + +void sync_v2_start ( + const unsigned int *member_list, + size_t member_list_entries, + const struct memb_ring_id *ring_id) +{ + memcpy (&my_ring_id, ring_id, sizeof (struct memb_ring_id)); + + sync_servicelist_build_enter (member_list, member_list_entries, ring_id); +} + +void sync_v2_abort (void) +{ + if (my_state == SYNC_PROCESS) { + schedwrk_destroy (my_schedwrk_handle); + my_service_list[my_processing_idx].sync_abort (); + } +} diff --git a/exec/syncv2.h b/exec/syncv2.h new file mode 100644 index 00000000..13427229 --- /dev/null +++ b/exec/syncv2.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2009 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Steven Dake (sdake@redhat.com) + * + * This software licensed under BSD license, the text of which follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the MontaVista Software, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SYNCV2_H_DEFINED +#define SYNCV2_H_DEFINED + +#include "sync.h" + +extern int sync_v2_init ( + int (*sync_callbacks_retrieve) ( + int service_id, + struct sync_callbacks *callbacks), + void (*synchronization_completed) (void)); + +extern void sync_v2_start ( + const unsigned int *member_list, + size_t member_list_entries, + const struct memb_ring_id *ring_id); + +extern void sync_v2_abort (void); + +#endif /* SYNC_H_DEFINED */