Add syncv2.

git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2302 fd59a12c-fef9-0310-b244-a6a79926bd2f
This commit is contained in:
Steven Dake 2009-06-26 21:15:19 +00:00
parent 9bf201420c
commit 621511d336
7 changed files with 642 additions and 45 deletions

View File

@ -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)

View File

@ -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'

View File

@ -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,

View File

@ -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);
}

View File

@ -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 */

478
exec/syncv2.c Normal file
View File

@ -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 <config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <corosync/corotypes.h>
#include <corosync/swab.h>
#include <corosync/totem/totempg.h>
#include <corosync/totem/totem.h>
#include <corosync/lcr/lcr_ifact.h>
#include <corosync/engine/logsys.h>
#include <corosync/coroipc_types.h>
#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 ();
}
}

53
exec/syncv2.h Normal file
View File

@ -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 */