diff --git a/corosync-trunk-1750.diff b/corosync-trunk-1750.diff deleted file mode 100644 index a37d6c4..0000000 --- a/corosync-trunk-1750.diff +++ /dev/null @@ -1,22525 +0,0 @@ -diff -Naurd corosync-0.92/exec/apidef.c corosync-trunk/exec/apidef.c ---- corosync-0.92/exec/apidef.c 2008-09-17 21:15:00.000000000 +0200 -+++ corosync-trunk/exec/apidef.c 2008-12-08 16:55:41.000000000 +0100 -@@ -46,6 +46,7 @@ - #include "main.h" - #include "ipc.h" - #include "sync.h" -+#include "quorum.h" - #include - #include "service.h" - #include -@@ -55,11 +56,16 @@ - /* - * Remove compile warnings about type name changes - */ --typedef int (*typedef_tpg_join) (corosync_tpg_handle, struct corosync_tpg_group *, int); --typedef int (*typedef_tpg_leave) (corosync_tpg_handle, struct corosync_tpg_group *, int); --typedef int (*typedef_tpg_groups_mcast) (corosync_tpg_handle, int, struct corosync_tpg_group *, int groups_cnt, struct iovec *, int); --typedef int (*typedef_tpg_groups_send_ok) (corosync_tpg_handle, struct corosync_tpg_group *, int groups_cnt, struct iovec *, int); -+typedef int (*typedef_tpg_join) (cs_tpg_handle, struct corosync_tpg_group *, int); -+typedef int (*typedef_tpg_leave) (cs_tpg_handle, struct corosync_tpg_group *, int); -+typedef int (*typedef_tpg_groups_mcast) (cs_tpg_handle, int, struct corosync_tpg_group *, int groups_cnt, struct iovec *, int); -+typedef int (*typedef_tpg_groups_send_ok) (cs_tpg_handle, struct corosync_tpg_group *, int groups_cnt, struct iovec *, int); - -+static inline void _corosync_public_exit_error ( -+ cs_fatal_error_t err, const char *file, unsigned int line) -+{ -+ _corosync_exit_error (err, file, line); -+} - - static struct corosync_api_v1 apidef_corosync_api_v1 = { - .timer_add_duration = corosync_timer_add_duration, -@@ -68,16 +74,16 @@ - .timer_time_get = NULL, - .ipc_source_set = message_source_set, - .ipc_source_is_local = message_source_is_local, -- .ipc_private_data_get = corosync_conn_private_data_get, -+ .ipc_private_data_get = cs_conn_private_data_get, - .ipc_response_send = NULL, -- .ipc_response_no_fcc = corosync_conn_send_response_no_fcc, -+ .ipc_response_no_fcc = cs_conn_send_response_no_fcc, - .ipc_dispatch_send = NULL, -- .ipc_conn_send_response = corosync_conn_send_response, -- .ipc_conn_partner_get = corosync_conn_partner_get, -- .ipc_refcnt_inc = corosync_ipc_flow_control_local_increment, -- .ipc_refcnt_dec = corosync_ipc_flow_control_local_decrement, -- .ipc_fc_create = corosync_ipc_flow_control_create, -- .ipc_fc_destroy = corosync_ipc_flow_control_destroy, -+ .ipc_conn_send_response = cs_conn_send_response, -+ .ipc_conn_partner_get = cs_conn_partner_get, -+ .ipc_refcnt_inc = cs_ipc_flow_control_local_increment, -+ .ipc_refcnt_dec = cs_ipc_flow_control_local_decrement, -+ .ipc_fc_create = cs_ipc_flow_control_create, -+ .ipc_fc_destroy = cs_ipc_flow_control_destroy, - .totem_nodeid_get = totempg_my_nodeid_get, - .totem_family_get = totempg_my_family_get, - .totem_ring_reenable = totempg_ring_reenable, -@@ -86,6 +92,7 @@ - .totem_ifaces_get = totempg_ifaces_get, - .totem_ifaces_print = totempg_ifaces_print, - .totem_ip_print = totemip_print, -+ .totem_callback_token_create = totempg_callback_token_create, - .tpg_init = totempg_groups_initialize, - .tpg_exit = NULL, /* missing from totempg api */ - .tpg_join = (typedef_tpg_join)totempg_groups_join, -@@ -95,12 +102,16 @@ - .tpg_groups_mcast = (typedef_tpg_groups_mcast)totempg_groups_mcast_groups, - .tpg_groups_send_ok = (typedef_tpg_groups_send_ok)totempg_groups_send_ok_groups, - .sync_request = sync_request, -+ .quorum_is_quorate = corosync_quorum_is_quorate, -+ .quorum_register_callback = corosync_quorum_register_callback, -+ .quorum_unregister_callback = corosync_quorum_unregister_callback, -+ .quorum_initialize = corosync_quorum_initialize, - .service_link_and_init = corosync_service_link_and_init, - .service_unlink_and_exit = corosync_service_unlink_and_exit, - .plugin_interface_reference = lcr_ifact_reference, - .plugin_interface_release = lcr_ifact_release, - .error_memory_failure = _corosync_out_of_memory_error, -- .fatal_error = _corosync_exit_error -+ .fatal_error = _corosync_public_exit_error - }; - - void apidef_init (struct objdb_iface_ver0 *objdb) { -diff -Naurd corosync-0.92/exec/coropoll.c corosync-trunk/exec/coropoll.c ---- corosync-0.92/exec/coropoll.c 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/exec/coropoll.c 2009-01-20 18:59:10.000000000 +0100 -@@ -59,6 +59,7 @@ - struct timerlist timerlist; - void (*serialize_lock_fn) (void); - void (*serialize_unlock_fn) (void); -+ int stop_requested; - }; - - /* -@@ -92,6 +93,7 @@ - poll_instance->poll_entries = 0; - poll_instance->ufds = 0; - poll_instance->poll_entry_count = 0; -+ poll_instance->stop_requested = 0; - poll_instance->serialize_lock_fn = serialize_lock_fn; - poll_instance->serialize_unlock_fn = serialize_unlock_fn; - timerlist_init (&poll_instance->timerlist); -@@ -291,18 +293,18 @@ - struct poll_instance *poll_instance; - int res = 0; - -+ if (timer_handle_out == NULL) { -+ res -ENOENT; -+ goto error_exit; -+ } -+ - res = hdb_handle_get (&poll_instance_database, handle, - (void *)&poll_instance); - if (res != 0) { - res = -ENOENT; -- - goto error_exit; - } - -- if (timer_handle_out == 0) { -- res = -ENOENT; -- } -- - timerlist_add_duration (&poll_instance->timerlist, - timer_fn, data, ((unsigned long long)msec_duration) * 1000000ULL, timer_handle_out); - -@@ -336,6 +338,27 @@ - return (res); - } - -+int poll_stop ( -+ poll_handle handle) -+{ -+ struct poll_instance *poll_instance; -+ unsigned int res; -+ -+ res = hdb_handle_get (&poll_instance_database, handle, -+ (void *)&poll_instance); -+ if (res != 0) { -+ res = -ENOENT; -+ goto error_exit; -+ } -+ -+ poll_instance->stop_requested = 1; -+ -+ hdb_handle_put (&poll_instance_database, handle); -+error_exit: -+ return (res); -+} -+ -+ - int poll_run ( - poll_handle handle) - { -@@ -366,6 +389,10 @@ - retry_poll: - res = poll (poll_instance->ufds, - poll_instance->poll_entry_count, expire_timeout_msec); -+ if (poll_instance->stop_requested) { -+ printf ("poll should stop\n"); -+ return (0); -+ } - if (errno == EINTR && res == -1) { - goto retry_poll; - } else -@@ -403,9 +430,6 @@ - return (-1); - } - --int poll_stop ( -- poll_handle handle); -- - #ifdef COMPILE_OUT - void poll_print_state ( - poll_handle handle, -diff -Naurd corosync-0.92/exec/crypto.c corosync-trunk/exec/crypto.c ---- corosync-0.92/exec/crypto.c 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/exec/crypto.c 2009-01-26 21:22:28.000000000 +0100 -@@ -20,13 +20,14 @@ - #endif - #include - #include -+#include - - #include "crypto.h" - - #define CONST64(n) n ## ULL - --typedef unsigned long ulong32; --typedef unsigned long long ulong64; -+typedef uint32_t ulong32; -+typedef uint64_t ulong64; - - #if __BYTE_ORDER == __LITTLE_ENDIAN - #define ENDIAN_LITTLE -@@ -41,10 +42,10 @@ - #endif - - #if defined(COROSYNC_LINUX) --#if __WORDIZE == 64 -+#if __WORDSIZE == 64 - #define ENDIAN_64BITWORD - #endif --#if __WORDIZE == 32 -+#if __WORDSIZE == 32 - #define ENDIAN_32BITWORD - #endif - #else -@@ -844,7 +845,7 @@ - assert ((len & 3) == 0); - - for (i = 0; i < len; i += 4) { -- k = BYTE2WORD((unsigned char *)&buf[i]); -+ k = BYTE2WORD((unsigned char*)&buf[i]); - ADDKEY(k); - cycle(c->R); - XORNL(nltap(c)); -@@ -1250,11 +1251,11 @@ - void (*callback)(void)) - { - int fd; -- int rb; -+ unsigned long rb; - - fd = open ("/dev/urandom", O_RDONLY); - -- rb = read (fd, buf, len); -+ rb = (unsigned long)read (fd, buf, len); - - close (fd); - -diff -Naurd corosync-0.92/exec/crypto.h corosync-trunk/exec/crypto.h ---- corosync-0.92/exec/crypto.h 2004-09-15 22:20:07.000000000 +0200 -+++ corosync-trunk/exec/crypto.h 2009-01-26 21:22:28.000000000 +0100 -@@ -1,6 +1,8 @@ - #ifndef CRYPTO_H_DEFINED - #define CRYPTO_H_DEFINED - -+#include -+ - #define DIGEST_SHA1 0 - #define PRNG_SOBER 0 - -@@ -88,7 +90,7 @@ - unsigned char *dst, unsigned long *dstlen); - - struct sober128_prng { -- unsigned long R[17], /* Working storage for the shift register */ -+ uint32_t R[17], /* Working storage for the shift register */ - initR[17], /* saved register contents */ - konst, /* key dependent constant */ - sbuf; /* partial word encryption buffer */ -diff -Naurd corosync-0.92/exec/flow.c corosync-trunk/exec/flow.c ---- corosync-0.92/exec/flow.c 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/exec/flow.c 2008-11-06 22:49:07.000000000 +0100 -@@ -34,9 +34,9 @@ - - /* - * New messages are allowed from the library ONLY when the processor has not -- * received a COROSYNC_FLOW_CONTROL_STATE_ENABLED from any processor. If a -- * COROSYNC_FLOW_CONTROL_STATE_ENABLED message is sent, it must later be -- * cancelled by a COROSYNC_FLOW_CONTROL_STATE_DISABLED message. A configuration -+ * received a CS_FLOW_CONTROL_STATE_ENABLED from any processor. If a -+ * CS_FLOW_CONTROL_STATE_ENABLED message is sent, it must later be -+ * cancelled by a CS_FLOW_CONTROL_STATE_DISABLED message. A configuration - * change with the flow controlled processor leaving the configuration will - * also cancel flow control. - */ -@@ -68,12 +68,12 @@ - unsigned int service __attribute__((aligned(8))); - char id[1024] __attribute__((aligned(8))); - unsigned int id_len __attribute__((aligned(8))); -- enum corosync_flow_control_state flow_control_state __attribute__((aligned(8))); -+ enum cs_flow_control_state flow_control_state __attribute__((aligned(8))); - }; - - struct flow_control_node_state { - unsigned int nodeid; -- enum corosync_flow_control_state flow_control_state; -+ enum cs_flow_control_state flow_control_state; - }; - - struct flow_control_service { -@@ -81,10 +81,10 @@ - unsigned int service; - char id[1024]; - unsigned int id_len; -- void (*flow_control_state_set_fn) (void *context, enum corosync_flow_control_state flow_control_state); -+ void (*flow_control_state_set_fn) (void *context, enum cs_flow_control_state flow_control_state); - void *context; - unsigned int processor_count; -- enum corosync_flow_control_state flow_control_state; -+ enum cs_flow_control_state flow_control_state; - struct list_head list; - struct list_head list_all; - }; -@@ -108,7 +108,7 @@ - - static inline int flow_control_xmit ( - struct flow_control_service *flow_control_service, -- enum corosync_flow_control_state flow_control_state) -+ enum cs_flow_control_state flow_control_state) - { - struct flow_control_message flow_control_message; - struct iovec iovec; -@@ -165,11 +165,11 @@ - * Determine if any flow control is enabled on any nodes and set - * the internal variable appropriately - */ -- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_DISABLED; -+ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_DISABLED; - flow_control_service->flow_control_state_set_fn (flow_control_service->context, flow_control_service->flow_control_state); - for (i = 0; i < flow_control_service->processor_count; i++) { -- if (flow_control_service->flow_control_node_state[i].flow_control_state == COROSYNC_FLOW_CONTROL_STATE_ENABLED) { -- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_ENABLED; -+ if (flow_control_service->flow_control_node_state[i].flow_control_state == CS_FLOW_CONTROL_STATE_ENABLED) { -+ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_ENABLED; - flow_control_service->flow_control_state_set_fn (flow_control_service->context, flow_control_service->flow_control_state); - } - } -@@ -204,7 +204,7 @@ - */ - for (i = 0; i < member_list_entries; i++) { - flow_control_node_state_temp[i].nodeid = member_list[i]; -- flow_control_node_state_temp[i].flow_control_state = COROSYNC_FLOW_CONTROL_STATE_DISABLED; -+ flow_control_node_state_temp[i].flow_control_state = CS_FLOW_CONTROL_STATE_DISABLED; - - /* - * Determine if previous state was set for this processor -@@ -231,10 +231,10 @@ - * Turn on all flow control after a configuration change - */ - flow_control_service->processor_count = flow_control_member_list_entries; -- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_DISABLED; -+ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_DISABLED; - for (i = 0; i < member_list_entries; i++) { -- if (flow_control_service->flow_control_node_state[i].flow_control_state == COROSYNC_FLOW_CONTROL_STATE_ENABLED) { -- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_ENABLED; -+ if (flow_control_service->flow_control_node_state[i].flow_control_state == CS_FLOW_CONTROL_STATE_ENABLED) { -+ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_ENABLED; - flow_control_service->flow_control_state_set_fn (flow_control_service->context, flow_control_service->flow_control_state); - } - } -@@ -244,7 +244,7 @@ - /* - * External API - */ --unsigned int corosync_flow_control_initialize (void) -+unsigned int cs_flow_control_initialize (void) - { - unsigned int res; - -@@ -271,7 +271,7 @@ - return (0); - } - --unsigned int corosync_flow_control_ipc_init ( -+unsigned int cs_flow_control_ipc_init ( - unsigned int *flow_control_handle, - unsigned int service) - { -@@ -301,19 +301,19 @@ - - } - --unsigned int corosync_flow_control_ipc_exit ( -+unsigned int cs_flow_control_ipc_exit ( - unsigned int flow_control_handle) - { - hdb_handle_destroy (&flow_control_hdb, flow_control_handle); - return (0); - } - --unsigned int corosync_flow_control_create ( -+unsigned int cs_flow_control_create ( - unsigned int flow_control_handle, - unsigned int service, - void *id, - unsigned int id_len, -- void (*flow_control_state_set_fn) (void *context, enum corosync_flow_control_state flow_control_state), -+ void (*flow_control_state_set_fn) (void *context, enum cs_flow_control_state flow_control_state), - void *context) - { - struct flow_control_service *flow_control_service; -@@ -337,7 +337,7 @@ - */ - memset (flow_control_service, 0, sizeof (struct flow_control_service)); - -- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_DISABLED; -+ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_DISABLED; - flow_control_service->service = service; - memcpy (flow_control_service->id, id, id_len); - flow_control_service->id_len = id_len; -@@ -363,7 +363,7 @@ - return (res); - } - --unsigned int corosync_flow_control_destroy ( -+unsigned int cs_flow_control_destroy ( - unsigned int flow_control_identifier, - unsigned int service, - unsigned char *id, -@@ -389,7 +389,7 @@ - if ((flow_control_service->id_len == id_len) && - (memcmp (flow_control_service->id, id, id_len) == 0)) { - flow_control_xmit (flow_control_service, -- COROSYNC_FLOW_CONTROL_STATE_DISABLED); -+ CS_FLOW_CONTROL_STATE_DISABLED); - list_del (&flow_control_service->list); - list_del (&flow_control_service->list_all); - free (flow_control_service); -@@ -406,7 +406,7 @@ - * Disable the ability for new messages to be sent for this service - * with the handle id of length id_len - */ --unsigned int corosync_flow_control_disable ( -+unsigned int cs_flow_control_disable ( - unsigned int flow_control_handle) - { - struct flow_control_instance *instance; -@@ -425,8 +425,8 @@ - list = list->next) { - - flow_control_service = list_entry (list, struct flow_control_service, list); -- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_DISABLED; -- flow_control_xmit (flow_control_service, COROSYNC_FLOW_CONTROL_STATE_DISABLED); -+ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_DISABLED; -+ flow_control_xmit (flow_control_service, CS_FLOW_CONTROL_STATE_DISABLED); - } - hdb_handle_put (&flow_control_hdb, flow_control_handle); - -@@ -438,7 +438,7 @@ - * Enable the ability for new messagess to be sent for this service - * with the handle id of length id_len - */ --unsigned int corosync_flow_control_enable ( -+unsigned int cs_flow_control_enable ( - unsigned int flow_control_handle) - { - struct flow_control_instance *instance; -@@ -458,8 +458,8 @@ - - - flow_control_service = list_entry (list, struct flow_control_service, list); -- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_ENABLED; -- flow_control_xmit (flow_control_service, COROSYNC_FLOW_CONTROL_STATE_ENABLED); -+ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_ENABLED; -+ flow_control_xmit (flow_control_service, CS_FLOW_CONTROL_STATE_ENABLED); - } - hdb_handle_put (&flow_control_hdb, flow_control_handle); - -diff -Naurd corosync-0.92/exec/flow.h corosync-trunk/exec/flow.h ---- corosync-0.92/exec/flow.h 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/exec/flow.h 2008-11-06 22:49:07.000000000 +0100 -@@ -37,38 +37,38 @@ - #define FLOW_H_DEFINED - - #define COROSYNC_FLOW_CONTROL_STATE --enum corosync_flow_control_state { -- COROSYNC_FLOW_CONTROL_STATE_DISABLED, -- COROSYNC_FLOW_CONTROL_STATE_ENABLED -+enum cs_flow_control_state { -+ CS_FLOW_CONTROL_STATE_DISABLED, -+ CS_FLOW_CONTROL_STATE_ENABLED - }; - --unsigned int corosync_flow_control_initialize (void); -+unsigned int cs_flow_control_initialize (void); - --unsigned int corosync_flow_control_ipc_init ( -+unsigned int cs_flow_control_ipc_init ( - unsigned int *flow_control_identifier, - unsigned int service); - --unsigned int corosync_flow_control_ipc_exit ( -+unsigned int cs_flow_control_ipc_exit ( - unsigned int flow_control_identifier); - --unsigned int corosync_flow_control_create ( -+unsigned int cs_flow_control_create ( - unsigned int flow_control_handle, - unsigned int service, - void *id, - unsigned int id_len, -- void (*flow_control_state_set_fn) (void *context, enum corosync_flow_control_state flow_control_state), -+ void (*flow_control_state_set_fn) (void *context, enum cs_flow_control_state flow_control_state), - void *context); - --unsigned int corosync_flow_control_destroy ( -+unsigned int cs_flow_control_destroy ( - unsigned int flow_control_identifier, - unsigned int service, - unsigned char *id, - unsigned int id_len); - --unsigned int corosync_flow_control_disable ( -+unsigned int cs_flow_control_disable ( - unsigned int flow_control_identifier); - --unsigned int corosync_flow_control_enable ( -+unsigned int cs_flow_control_enable ( - unsigned int flow_control_identifier); - - #endif /* FLOW_H_DEFINED */ -diff -Naurd corosync-0.92/exec/ipc.c corosync-trunk/exec/ipc.c ---- corosync-0.92/exec/ipc.c 2008-09-17 21:15:00.000000000 +0200 -+++ corosync-trunk/exec/ipc.c 2008-12-28 10:25:17.000000000 +0100 -@@ -62,7 +62,7 @@ - #endif - - #include --#include -+#include - #include - #include - #include -@@ -72,6 +72,7 @@ - #include - #include - -+#include "quorum.h" - #include "poll.h" - #include "totemsrp.h" - #include "mempool.h" -@@ -153,7 +154,7 @@ - unsigned int flow_control_handle; /* flow control identifier */ - unsigned int flow_control_enabled; /* flow control enabled bit */ - unsigned int flow_control_local_count; /* flow control local count */ -- enum corosync_lib_flow_control flow_control; /* Does this service use IPC flow control */ -+ enum cs_lib_flow_control flow_control; /* Does this service use IPC flow control */ - pthread_mutex_t flow_control_mutex; - int (*lib_exit_fn) (void *conn); - struct timerlist timerlist; -@@ -193,26 +194,26 @@ - struct conn_info *conn_info, - void *message) - { -- SaAisErrorT error = SA_AIS_ERR_ACCESS; -+ cs_error_t error = CS_ERR_ACCESS; - uintptr_t cinfo = (uintptr_t)conn_info; - mar_req_lib_response_init_t *req_lib_response_init = (mar_req_lib_response_init_t *)message; - mar_res_lib_response_init_t res_lib_response_init; - - if (conn_info->authenticated) { - conn_info->service = req_lib_response_init->resdis_header.service; -- error = SA_AIS_OK; -+ error = CS_OK; - } - res_lib_response_init.header.size = sizeof (mar_res_lib_response_init_t); - res_lib_response_init.header.id = MESSAGE_RES_INIT; - res_lib_response_init.header.error = error; - res_lib_response_init.conn_info = (mar_uint64_t)cinfo; - -- corosync_conn_send_response ( -+ cs_conn_send_response ( - conn_info, - &res_lib_response_init, - sizeof (res_lib_response_init)); - -- if (error == SA_AIS_ERR_ACCESS) { -+ if (error == CS_ERR_ACCESS) { - libais_disconnect_security (conn_info); - return (-1); - } -@@ -223,7 +224,7 @@ - struct conn_info *conn_info, - void *message) - { -- SaAisErrorT error = SA_AIS_ERR_ACCESS; -+ cs_error_t error = CS_ERR_ACCESS; - uintptr_t cinfo; - mar_req_lib_dispatch_init_t *req_lib_dispatch_init = (mar_req_lib_dispatch_init_t *)message; - mar_res_lib_dispatch_init_t res_lib_dispatch_init; -@@ -232,9 +233,9 @@ - if (conn_info->authenticated) { - conn_info->service = req_lib_dispatch_init->resdis_header.service; - if (!ais_service[req_lib_dispatch_init->resdis_header.service]) -- error = SA_AIS_ERR_NOT_SUPPORTED; -+ error = CS_ERR_NOT_SUPPORTED; - else -- error = SA_AIS_OK; -+ error = CS_OK; - - cinfo = (uintptr_t)req_lib_dispatch_init->conn_info; - conn_info->conn_info_partner = (struct conn_info *)cinfo; -@@ -252,7 +253,7 @@ - msg_conn_info = (struct conn_info *)cinfo; - msg_conn_info->conn_info_partner = conn_info; - -- if (error == SA_AIS_OK) { -+ if (error == CS_OK) { - int private_data_size; - - private_data_size = ais_service[req_lib_dispatch_init->resdis_header.service]->private_data_size; -@@ -261,7 +262,7 @@ - - conn_info->conn_info_partner->private_data = conn_info->private_data; - if (conn_info->private_data == NULL) { -- error = SA_AIS_ERR_NO_MEMORY; -+ error = CS_ERR_NO_MEMORY; - } else { - memset (conn_info->private_data, 0, private_data_size); - } -@@ -276,16 +277,16 @@ - res_lib_dispatch_init.header.id = MESSAGE_RES_INIT; - res_lib_dispatch_init.header.error = error; - -- corosync_conn_send_response ( -+ cs_conn_send_response ( - conn_info, - &res_lib_dispatch_init, - sizeof (res_lib_dispatch_init)); - -- if (error == SA_AIS_ERR_ACCESS) { -+ if (error == CS_ERR_ACCESS) { - libais_disconnect_security (conn_info); - return (-1); - } -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (-1); - } - -@@ -296,8 +297,8 @@ - - conn_info->flow_control = ais_service[conn_info->service]->flow_control; - conn_info->conn_info_partner->flow_control = ais_service[conn_info->service]->flow_control; -- if (ais_service[conn_info->service]->flow_control == COROSYNC_LIB_FLOW_CONTROL_REQUIRED) { -- corosync_flow_control_ipc_init ( -+ if (ais_service[conn_info->service]->flow_control == CS_LIB_FLOW_CONTROL_REQUIRED) { -+ cs_flow_control_ipc_init ( - &conn_info->flow_control_handle, - conn_info->service); - -@@ -448,7 +449,7 @@ - conn_info->state = CONN_STATE_DISCONNECTED; - conn_info->conn_info_partner->state = CONN_STATE_DISCONNECTED; - if (conn_info->flow_control_enabled == 1) { -- corosync_flow_control_disable (conn_info->flow_control_handle); -+ cs_flow_control_disable (conn_info->flow_control_handle); - } - return (0); - } -@@ -486,6 +487,7 @@ - struct sched_param sched_param; - int res; - pthread_mutex_t *rel_mutex; -+ pthread_mutex_t *rel2_mutex; - unsigned int service; - struct conn_info *cinfo_partner; - void *private_data; -@@ -523,11 +525,12 @@ - - case CONN_STATE_DISCONNECTED: - rel_mutex = conn_info->shared_mutex; -+ rel2_mutex = &conn_info->mutex; - private_data = conn_info->private_data; - cinfo_partner = conn_info->conn_info_partner; - conn_info_destroy (conn); - if (service == SOCKET_SERVICE_INIT) { -- pthread_mutex_unlock (&conn_info->mutex); -+ pthread_mutex_unlock (rel2_mutex); - } else { - pthread_mutex_unlock (rel_mutex); - } -@@ -633,34 +636,37 @@ - /* - * IPC group-wide flow control - */ -- if (conn_info->flow_control == COROSYNC_LIB_FLOW_CONTROL_REQUIRED) { -+ if (conn_info->flow_control == CS_LIB_FLOW_CONTROL_REQUIRED) { - if (conn_info->flow_control_enabled == 0 && - ((fcc + FLOW_CONTROL_ENTRIES_ENABLE) > SIZEQUEUE)) { - - log_printf (LOG_LEVEL_NOTICE, "Enabling flow control [%d/%d] - [%d].\n", - entries_usedhw, SIZEQUEUE, - flow_control_local_count); -- corosync_flow_control_enable (conn_info->flow_control_handle); -+ cs_flow_control_enable (conn_info->flow_control_handle); - conn_info->flow_control_enabled = 1; -- conn_info->conn_info_partner->flow_control_enabled = 1; -+ if (conn_info->conn_info_partner) { -+ conn_info->conn_info_partner->flow_control_enabled = 1; -+ } - } - if (conn_info->flow_control_enabled == 1 && -- - fcc <= FLOW_CONTROL_ENTRIES_DISABLE) { - - log_printf (LOG_LEVEL_NOTICE, "Disabling flow control [%d/%d] - [%d].\n", - entries_usedhw, SIZEQUEUE, - flow_control_local_count); -- corosync_flow_control_disable (conn_info->flow_control_handle); -+ cs_flow_control_disable (conn_info->flow_control_handle); - conn_info->flow_control_enabled = 0; -- conn_info->conn_info_partner->flow_control_enabled = 0; -+ if (conn_info->conn_info_partner) { -+ conn_info->conn_info_partner->flow_control_enabled = 0; -+ } - } - } - } - - static int conn_info_outq_flush (struct conn_info *conn_info) { - struct queue *outq; -- int res = 0; -+ ssize_t res = 0; - struct outq_item *queue_item; - struct msghdr msg_send; - struct iovec iov_send; -@@ -731,14 +737,15 @@ - - - --struct res_overlay { -+struct ipc_res_overlay { - mar_res_header_t header __attribute((aligned(8))); - char buf[4096]; - }; - - static void libais_deliver (struct conn_info *conn_info) - { -- int res; -+ ssize_t res; -+ int dispatch_res; - mar_req_header_t *header; - int service; - struct msghdr msg_recv; -@@ -752,7 +759,7 @@ - int send_ok = 0; - int send_ok_joined = 0; - struct iovec send_ok_joined_iovec; -- struct res_overlay res_overlay; -+ struct ipc_res_overlay res_overlay; - - msg_recv.msg_iov = &iov_recv; - msg_recv.msg_iovlen = 1; -@@ -841,7 +848,7 @@ - #ifdef COROSYNC_LINUX - if (conn_info->authenticated == 0) { - cmsg = CMSG_FIRSTHDR (&msg_recv); -- assert (cmsg); -+ assert (cmsg != NULL); - cred = (struct ucred *)CMSG_DATA (cmsg); - if (cred) { - if (cred->uid == 0 || cred->gid == g_gid_valid) { -@@ -861,7 +868,8 @@ - conn_info->inb_inuse += res; - conn_info->inb_start += res; - -- while (conn_info->inb_inuse >= sizeof (mar_req_header_t) && res != -1) { -+ dispatch_res = 0; -+ while (conn_info->inb_inuse >= sizeof (mar_req_header_t) && dispatch_res != -1) { - header = (mar_req_header_t *)&conn_info->inb[conn_info->inb_start - conn_info->inb_inuse]; - - if (header->size > conn_info->inb_inuse) { -@@ -874,7 +882,7 @@ - * else handle message using service service - */ - if (service == SOCKET_SERVICE_INIT) { -- res = ais_init_service[header->id] (conn_info, header); -+ dispatch_res = ais_init_service[header->id] (conn_info, header); - } else { - /* - * Not an init service, but a standard service -@@ -897,11 +905,11 @@ - &send_ok_joined_iovec, 1); - - send_ok = -- (sync_primary_designated() == 1) && ( -- (ais_service[service]->lib_engine[header->id].flow_control == COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED) || -- ((ais_service[service]->lib_engine[header->id].flow_control == COROSYNC_LIB_FLOW_CONTROL_REQUIRED) && -+ (corosync_quorum_is_quorate() == 1 || ais_service[service]->allow_inquorate == CS_LIB_ALLOW_INQUORATE) && ( -+ (ais_service[service]->lib_engine[header->id].flow_control == CS_LIB_FLOW_CONTROL_NOT_REQUIRED) || -+ ((ais_service[service]->lib_engine[header->id].flow_control == CS_LIB_FLOW_CONTROL_REQUIRED) && - (send_ok_joined) && -- (sync_in_process() == 0))); -+ (sync_in_process() == 0))); - - if (send_ok) { - ais_service[service]->lib_engine[header->id].lib_handler_fn(conn_info, header); -@@ -914,8 +922,8 @@ - ais_service[service]->lib_engine[header->id].response_size; - res_overlay.header.id = - ais_service[service]->lib_engine[header->id].response_id; -- res_overlay.header.error = SA_AIS_ERR_TRY_AGAIN; -- corosync_conn_send_response ( -+ res_overlay.header.error = CS_ERR_TRY_AGAIN; -+ cs_conn_send_response ( - conn_info, - &res_overlay, - res_overlay.header.size); -@@ -1030,7 +1038,7 @@ - { - } - --void corosync_ipc_init ( -+void cs_ipc_init ( - void (*serialize_lock_fn) (void), - void (*serialize_unlock_fn) (void), - unsigned int gid_valid) -@@ -1102,7 +1110,7 @@ - /* - * Get the conn info private data - */ --void *corosync_conn_private_data_get (void *conn) -+void *cs_conn_private_data_get (void *conn) - { - struct conn_info *conn_info = (struct conn_info *)conn; - -@@ -1116,7 +1124,7 @@ - /* - * Get the conn info partner connection - */ --void *corosync_conn_partner_get (void *conn) -+void *cs_conn_partner_get (void *conn) - { - struct conn_info *conn_info = (struct conn_info *)conn; - -@@ -1127,25 +1135,27 @@ - } - } - --int corosync_conn_send_response_no_fcc ( -+int cs_conn_send_response_no_fcc ( - void *conn, - void *msg, - int mlen) - { -+ int ret; - dont_call_flow_control = 1; -- corosync_conn_send_response ( -+ ret = cs_conn_send_response ( - conn, msg, mlen); - dont_call_flow_control = 0; -+ return ret; - } - --int corosync_conn_send_response ( -+int cs_conn_send_response ( - void *conn, - void *msg, - int mlen) - { - struct queue *outq; - char *cmsg; -- int res = 0; -+ ssize_t res = 0; - int queue_empty; - struct outq_item *queue_item; - struct outq_item queue_item_out; -@@ -1282,17 +1292,17 @@ - return (0); - } - --void corosync_ipc_flow_control_create ( -+void cs_ipc_flow_control_create ( - void *conn, - unsigned int service, - char *id, - int id_len, -- void (*flow_control_state_set_fn) (void *conn, enum corosync_flow_control_state), -+ void (*flow_control_state_set_fn) (void *conn, enum cs_flow_control_state), - void *context) - { - struct conn_info *conn_info = (struct conn_info *)conn; - -- corosync_flow_control_create ( -+ cs_flow_control_create ( - conn_info->flow_control_handle, - service, - id, -@@ -1302,7 +1312,7 @@ - conn_info->conn_info_partner->flow_control_handle = conn_info->flow_control_handle; - } - --void corosync_ipc_flow_control_destroy ( -+void cs_ipc_flow_control_destroy ( - void *conn, - unsigned int service, - unsigned char *id, -@@ -1310,14 +1320,14 @@ - { - struct conn_info *conn_info = (struct conn_info *)conn; - -- corosync_flow_control_destroy ( -+ cs_flow_control_destroy ( - conn_info->flow_control_handle, - service, - id, - id_len); - } - --void corosync_ipc_flow_control_local_increment ( -+void cs_ipc_flow_control_local_increment ( - void *conn) - { - struct conn_info *conn_info = (struct conn_info *)conn; -@@ -1329,7 +1339,7 @@ - pthread_mutex_unlock (&conn_info->flow_control_mutex); - } - --void corosync_ipc_flow_control_local_decrement ( -+void cs_ipc_flow_control_local_decrement ( - void *conn) - { - struct conn_info *conn_info = (struct conn_info *)conn; -diff -Naurd corosync-0.92/exec/ipc.h corosync-trunk/exec/ipc.h ---- corosync-0.92/exec/ipc.h 2008-09-17 21:15:00.000000000 +0200 -+++ corosync-trunk/exec/ipc.h 2008-11-06 22:49:07.000000000 +0100 -@@ -46,52 +46,52 @@ - - extern int message_source_is_local (mar_message_source_t *source); - --extern void *corosync_conn_partner_get (void *conn); -+extern void *cs_conn_partner_get (void *conn); - --extern void *corosync_conn_private_data_get (void *conn); -+extern void *cs_conn_private_data_get (void *conn); - --extern int corosync_conn_send_response (void *conn, void *msg, int mlen); -+extern int cs_conn_send_response (void *conn, void *msg, int mlen); - --extern int corosync_conn_send_response_no_fcc (void *conn, void *msg,int mlen); -+extern int cs_conn_send_response_no_fcc (void *conn, void *msg,int mlen); - --extern void corosync_ipc_init ( -+extern void cs_ipc_init ( - void (*serialize_lock_fn) (void), - void (*serialize_unlock_fn) (void), - unsigned int gid_valid); - --extern int corosync_ipc_timer_add ( -+extern int cs_ipc_timer_add ( - void *conn, - void (*timer_fn) (void *data), - void *data, - unsigned int msec_in_future, - timer_handle *handle); - --extern void corosync_ipc_timer_del ( -+extern void cs_ipc_timer_del ( - void *conn, - timer_handle timer_handle); - --extern void corosync_ipc_timer_del_data ( -+extern void cs_ipc_timer_del_data ( - void *conn, - timer_handle timer_handle); - --extern void corosync_ipc_flow_control_create ( -+extern void cs_ipc_flow_control_create ( - void *conn, - unsigned int service, - char *id, - int id_len, -- void (*flow_control_state_set_fn) (void *context, enum corosync_flow_control_state flow_control_state_set), -+ void (*flow_control_state_set_fn) (void *context, enum cs_flow_control_state flow_control_state_set), - void *context); - --extern void corosync_ipc_flow_control_destroy ( -+extern void cs_ipc_flow_control_destroy ( - void *conn, - unsigned int service, - unsigned char *id, - int id_len); - --extern void corosync_ipc_flow_control_local_increment ( -+extern void cs_ipc_flow_control_local_increment ( - void *conn); - --extern void corosync_ipc_flow_control_local_decrement ( -+extern void cs_ipc_flow_control_local_decrement ( - void *conn); - - #endif /* IPC_H_DEFINED */ -diff -Naurd corosync-0.92/exec/logsys.c corosync-trunk/exec/logsys.c ---- corosync-0.92/exec/logsys.c 2008-09-17 20:22:58.000000000 +0200 -+++ corosync-trunk/exec/logsys.c 2009-01-26 14:15:57.000000000 +0100 -@@ -1,6 +1,6 @@ - /* - * Copyright (c) 2002-2004 MontaVista Software, Inc. -- * Copyright (c) 2006-2007 Red Hat, Inc. -+ * Copyright (c) 2006-2009 Red Hat, Inc. - * - * Author: Steven Dake (sdake@redhat.com) - * Author: Lon Hohberger (lhh@redhat.com) -@@ -35,13 +35,17 @@ - */ - #include - #include -+#include - #include - #include - #include -+#include -+#include - #include - #include - #include - #include -+#include - #if defined(COROSYNC_LINUX) - #include - #endif -@@ -54,14 +58,54 @@ - #include - - #include --#include "wthread.h" -+ -+/* similar to syslog facilities/priorities tables, -+ * make a tag table for internal use -+ */ -+ -+#ifdef SYSLOG_NAMES -+CODE tagnames[] = -+ { -+ { "log", LOGSYS_TAG_LOG }, -+ { "enter", LOGSYS_TAG_ENTER }, -+ { "leave", LOGSYS_TAG_LEAVE }, -+ { "trace1", LOGSYS_TAG_TRACE1 }, -+ { "trace2", LOGSYS_TAG_TRACE2 }, -+ { "trace3", LOGSYS_TAG_TRACE3 }, -+ { "trace4", LOGSYS_TAG_TRACE4 }, -+ { "trace5", LOGSYS_TAG_TRACE5 }, -+ { "trace6", LOGSYS_TAG_TRACE6 }, -+ { "trace7", LOGSYS_TAG_TRACE7 }, -+ { "trace8", LOGSYS_TAG_TRACE8 }, -+ { NULL, -1 } -+ }; -+#endif -+ -+/* -+ * These are not static so they can be read from the core file -+ */ -+int *flt_data; -+ -+int flt_data_size; -+ -+#define SUBSYS_MAX 32 -+ -+#define COMBINE_BUFFER_SIZE 2048 -+ -+struct logsys_logger { -+ char subsys[64]; -+ unsigned int facility; -+ unsigned int priority; -+ unsigned int tags; -+ unsigned int mode; -+}; - - /* - * Configuration parameters for logging system - */ - static char *logsys_name = NULL; - --static unsigned int logsys_mode = 0; -+static unsigned int logsys_mode = LOG_MODE_NOSUBSYS; - - static char *logsys_file = NULL; - -@@ -69,35 +113,44 @@ - - static int logsys_facility = LOG_DAEMON; - --static int logsys_wthread_active = 0; -+static char *logsys_format = NULL; -+ -+/* -+ * operating global variables -+ */ -+static struct logsys_logger logsys_loggers[SUBSYS_MAX]; -+ -+static int wthread_active = 0; -+ -+static int wthread_should_exit = 0; - - static pthread_mutex_t logsys_config_mutex = PTHREAD_MUTEX_INITIALIZER; - --static pthread_mutex_t logsys_new_log_mutex = PTHREAD_MUTEX_INITIALIZER; -+static unsigned int records_written = 1; - --static struct worker_thread_group log_thread_group; -+static pthread_t logsys_thread_id; - --static unsigned int dropped_log_entries = 0; -+static pthread_cond_t logsys_cond; - --#ifndef MAX_LOGGERS --#define MAX_LOGGERS 32 --#endif --struct logsys_logger logsys_loggers[MAX_LOGGERS]; -+static pthread_mutex_t logsys_cond_mutex; - --int logsys_single_id = 0; -+static pthread_spinlock_t logsys_idx_spinlock; - -+static unsigned int log_rec_idx; - --struct log_entry { -- char *file; -- int line; -- int priority; -- char str[128]; -- struct log_entry *next; --}; -+static int logsys_buffer_full = 0; - --static struct log_entry *head; -+static char *format_buffer="[%6s] %b"; - --static struct log_entry *tail; -+static int log_requests_pending = 0; -+ -+static int log_requests_lost = 0; -+ -+void *logsys_rec_end; -+ -+#define FDHEAD_INDEX (flt_data_size) -+ -+#define FDTAIL_INDEX (flt_data_size + 1) - - struct log_data { - unsigned int syslog_pos; -@@ -105,324 +158,674 @@ - char *log_string; - }; - --enum logsys_config_mutex_state { -- LOGSYS_CONFIG_MUTEX_LOCKED, -- LOGSYS_CONFIG_MUTEX_UNLOCKED --}; -- - static void logsys_atexit (void); - --#define LEVELMASK 0x07 /* 3 bits */ --#define LOG_LEVEL(p) ((p) & LEVELMASK) --#define LOGSYS_IDMASK (0x3f << 3) /* 6 bits */ --#define LOG_ID(p) (((p) & LOGSYS_IDMASK) >> 3) -- --static void logsys_buffer_flush (void); -+/* -+ * Helpers for _logsys_log_rec functionality -+ */ -+static inline void my_memcpy_32bit (int *dest, int *src, unsigned int words) -+{ -+ unsigned int word_idx; -+ for (word_idx = 0; word_idx < words; word_idx++) { -+ dest[word_idx] = src[word_idx]; -+ } -+} - --void _logsys_nosubsys_set (void) -+static inline void my_memcpy_8bit (char *dest, char *src, unsigned int bytes) - { -- logsys_mode |= LOG_MODE_NOSUBSYS; -+ unsigned int byte_idx; -+ -+ for (byte_idx = 0; byte_idx < bytes; byte_idx++) { -+ dest[byte_idx] = src[byte_idx]; -+ } - } - --int logsys_facility_id_get (const char *name) -+/* -+ * Before any write operation, a reclaim on the buffer area must be executed -+ */ -+static inline void records_reclaim (unsigned int idx, unsigned int words) - { -- unsigned int i; -+ unsigned int should_reclaim; - -- for (i = 0; facilitynames[i].c_name != NULL; i++) { -- if (strcasecmp(name, facilitynames[i].c_name) == 0) { -- return (facilitynames[i].c_val); -+ should_reclaim = 0; -+ -+ if ((idx + words) >= flt_data_size) { -+ logsys_buffer_full = 1; -+ } -+ if (logsys_buffer_full == 0) { -+ return; -+ } -+ -+ pthread_spin_lock (&logsys_idx_spinlock); -+ if (flt_data[FDTAIL_INDEX] > flt_data[FDHEAD_INDEX]) { -+ if (idx + words >= flt_data[FDTAIL_INDEX]) { -+ should_reclaim = 1; -+ } -+ } else { -+ if ((idx + words) >= (flt_data[FDTAIL_INDEX] + flt_data_size)) { -+ should_reclaim = 1; - } - } -- return (-1); -+ -+ if (should_reclaim) { -+ int words_needed = 0; -+ -+ words_needed = words + 1; -+ do { -+ unsigned int old_tail; -+ -+ words_needed -= flt_data[flt_data[FDTAIL_INDEX]]; -+ old_tail = flt_data[FDTAIL_INDEX]; -+ flt_data[FDTAIL_INDEX] = -+ (flt_data[FDTAIL_INDEX] + -+ flt_data[flt_data[FDTAIL_INDEX]]) % (flt_data_size); -+ if (log_rec_idx == old_tail) { -+ log_requests_lost += 1; -+ log_rec_idx = flt_data[FDTAIL_INDEX]; -+ } -+ } while (words_needed > 0); -+ } -+ pthread_spin_unlock (&logsys_idx_spinlock); - } - --const char *logsys_facility_name_get (unsigned int facility) -+#define idx_word_step(idx) \ -+do { \ -+ if (idx > (flt_data_size - 1)) { \ -+ idx = 0; \ -+ } \ -+} while (0); -+ -+#define idx_buffer_step(idx) \ -+do { \ -+ if (idx > (flt_data_size - 1)) { \ -+ idx = ((idx) % (flt_data_size)); \ -+ } \ -+} while (0); -+ -+/* -+ * Internal threaded logging implementation -+ */ -+static inline int strcpy_cutoff (char *dest, char *src, int cutoff) - { -- unsigned int i; -+ unsigned int len; - -- for (i = 0; facilitynames[i].c_name != NULL; i++) { -- if (facility == facilitynames[i].c_val) { -- return (facilitynames[i].c_name); -+ if (cutoff == -1) { -+ strcpy (dest, src); -+ return (strlen (dest)); -+ } else { -+ assert (cutoff > 0); -+ strncpy (dest, src, cutoff); -+ dest[cutoff] = '\0'; -+ len = strlen (dest); -+ if (len != cutoff) { -+ memset (&dest[len], ' ', cutoff - len); - } - } -- return (NULL); -+ return (cutoff); - } - --int logsys_priority_id_get (const char *name) -+/* -+ * %s SUBSYSTEM -+ * %n FUNCTION NAME -+ * %f FILENAME -+ * %l FILELINE -+ * %p PRIORITY -+ * %t TIMESTAMP -+ * %b BUFFER -+ * -+ * any number between % and character specify field length to pad or chop -+*/ -+static void log_printf_to_logs ( -+ char *subsys, -+ char *function_name, -+ char *file_name, -+ int file_line, -+ unsigned int level, -+ char *buffer) - { -- unsigned int i; -+ char output_buffer[COMBINE_BUFFER_SIZE]; -+ char char_time[128]; -+ char line_no[30]; -+ unsigned int format_buffer_idx = 0; -+ unsigned int output_buffer_idx = 0; -+ struct timeval tv; -+ int cutoff; -+ unsigned int len; -+ -+ while (format_buffer[format_buffer_idx]) { -+ cutoff = -1; -+ if (format_buffer[format_buffer_idx] == '%') { -+ format_buffer_idx += 1; -+ if (isdigit (format_buffer[format_buffer_idx])) { -+ cutoff = atoi (&format_buffer[format_buffer_idx]); -+ } -+ while (isdigit (format_buffer[format_buffer_idx])) { -+ format_buffer_idx += 1; -+ } -+ -+ switch (format_buffer[format_buffer_idx]) { -+ case 's': -+ len = strcpy_cutoff (&output_buffer[output_buffer_idx], subsys, cutoff); -+ output_buffer_idx += len; -+ break; - -- for (i = 0; prioritynames[i].c_name != NULL; i++) { -- if (strcasecmp(name, prioritynames[i].c_name) == 0) { -- return (prioritynames[i].c_val); -+ case 'n': -+ len = strcpy_cutoff (&output_buffer[output_buffer_idx], function_name, cutoff); -+ output_buffer_idx += len; -+ break; -+ -+ case 'l': -+ sprintf (line_no, "%d", file_line); -+ len = strcpy_cutoff (&output_buffer[output_buffer_idx], line_no, cutoff); -+ output_buffer_idx += len; -+ break; -+ -+ case 'p': -+ break; -+ -+ case 't': -+ gettimeofday (&tv, NULL); -+ (void)strftime (char_time, sizeof (char_time), "%b %e %k:%M:%S", localtime ((time_t *)&tv.tv_sec)); -+ len = strcpy_cutoff (&output_buffer[output_buffer_idx], char_time, cutoff); -+ output_buffer_idx += len; -+ break; -+ -+ case 'b': -+ len = strcpy_cutoff (&output_buffer[output_buffer_idx], buffer, cutoff); -+ output_buffer_idx += len; -+ break; -+ } -+ format_buffer_idx += 1; -+ } else { -+ output_buffer[output_buffer_idx++] = format_buffer[format_buffer_idx++]; - } - } -- return (-1); -+ -+ output_buffer[output_buffer_idx] = '\0'; -+ -+ /* -+ * Output to syslog -+ */ -+ if (logsys_mode & LOG_MODE_OUTPUT_SYSLOG) { -+ syslog (level, "%s", output_buffer); -+ } -+ -+ /* -+ * Terminate string with \n \0 -+ */ -+ if (logsys_mode & (LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_STDERR)) { -+ output_buffer[output_buffer_idx++] = '\n'; -+ output_buffer[output_buffer_idx] = '\0'; -+ } -+ -+ /* -+ * Output to configured file -+ */ -+ if ((logsys_mode & LOG_MODE_OUTPUT_FILE) && logsys_file_fp) { -+ /* -+ * Output to a file -+ */ -+ (void)fwrite (output_buffer, strlen (output_buffer), 1, logsys_file_fp); -+ fflush (logsys_file_fp); -+ } -+ -+ /* -+ * Output to stderr -+ */ -+ if (logsys_mode & LOG_MODE_OUTPUT_STDERR) { -+ (void)write (STDERR_FILENO, output_buffer, strlen (output_buffer)); -+ } - } - --const char *logsys_priority_name_get (unsigned int priority) -+static void record_print (char *buf) - { -+ int *buf_uint32t = (int *)buf; -+ unsigned int rec_size = buf_uint32t[0]; -+ unsigned int rec_ident = buf_uint32t[1]; -+ unsigned int file_line = buf_uint32t[2]; -+ unsigned int level = rec_ident >> 28; - unsigned int i; -+ unsigned int words_processed; -+ unsigned int arg_size_idx; -+ void *arguments[64]; -+ unsigned int arg_count; - -- for (i = 0; prioritynames[i].c_name != NULL; i++) { -- if (priority == prioritynames[i].c_val) { -- return (prioritynames[i].c_name); -- } -+ arg_size_idx = 4; -+ words_processed = 4; -+ arg_count = 0; -+ -+ for (i = 0; words_processed < rec_size; i++) { -+ arguments[arg_count++] = &buf_uint32t[arg_size_idx + 1]; -+ arg_size_idx += buf_uint32t[arg_size_idx] + 1; -+ words_processed += buf_uint32t[arg_size_idx] + 1; - } -- return (NULL); -+ log_printf_to_logs ( -+ (char *)arguments[0], -+ (char *)arguments[1], -+ (char *)arguments[2], -+ file_line, -+ level, -+ (char *)arguments[3]); - } -+ -+static int record_read (char *buf, int rec_idx, int *log_msg) { -+ unsigned int rec_size; -+ unsigned int rec_ident; -+ int firstcopy, secondcopy; - --unsigned int logsys_config_subsys_set ( -- const char *subsys, -- unsigned int tags, -- unsigned int priority) --{ -- int i; -+ rec_size = flt_data[rec_idx]; -+ rec_ident = flt_data[(rec_idx + 1) % flt_data_size]; - -- pthread_mutex_lock (&logsys_config_mutex); -- for (i = 0; i < MAX_LOGGERS; i++) { -- if (strcmp (logsys_loggers[i].subsys, subsys) == 0) { -- logsys_loggers[i].tags = tags; -- logsys_loggers[i].priority = priority; -+ /* -+ * Not a log record -+ */ -+ if ((rec_ident & LOGSYS_TAG_LOG) == 0) { -+ *log_msg = 0; -+ return ((rec_idx + rec_size) % flt_data_size); -+ } - -- break; -- } -+ /* -+ * A log record -+ */ -+ *log_msg = 1; -+ -+ firstcopy = rec_size; -+ secondcopy = 0; -+ if (firstcopy + rec_idx > flt_data_size) { -+ firstcopy = flt_data_size - rec_idx; -+ secondcopy -= firstcopy - rec_size; -+ } -+ memcpy (&buf[0], &flt_data[rec_idx], firstcopy << 2); -+ if (secondcopy) { -+ memcpy (&buf[(firstcopy << 2)], &flt_data[0], secondcopy << 2); -+ } -+ return ((rec_idx + rec_size) % flt_data_size); -+} -+ -+static inline void wthread_signal (void) -+{ -+ if (wthread_active == 0) { -+ return; - } -+ pthread_mutex_lock (&logsys_cond_mutex); -+ pthread_cond_signal (&logsys_cond); -+ pthread_mutex_unlock (&logsys_cond_mutex); -+} - -- if (i == MAX_LOGGERS) { -- for (i = 0; i < MAX_LOGGERS; i++) { -- if (strcmp (logsys_loggers[i].subsys, "") == 0) { -- strncpy (logsys_loggers[i].subsys, subsys, -- sizeof(logsys_loggers[i].subsys)); -- logsys_loggers[i].tags = tags; -- logsys_loggers[i].priority = priority; -+static inline void wthread_wait (void) -+{ -+ pthread_mutex_lock (&logsys_cond_mutex); -+ pthread_cond_wait (&logsys_cond, &logsys_cond_mutex); -+ pthread_mutex_unlock (&logsys_cond_mutex); -+} -+ -+static inline void wthread_wait_locked (void) -+{ -+ pthread_cond_wait (&logsys_cond, &logsys_cond_mutex); -+ pthread_mutex_unlock (&logsys_cond_mutex); -+} -+ -+static void *logsys_worker_thread (void *data) -+{ -+ int log_msg; -+ char buf[COMBINE_BUFFER_SIZE]; -+ -+ /* -+ * Signal wthread_create that the initialization process may continue -+ */ -+ wthread_signal (); -+ pthread_spin_lock (&logsys_idx_spinlock); -+ log_rec_idx = flt_data[FDTAIL_INDEX]; -+ pthread_spin_unlock (&logsys_idx_spinlock); -+ -+ for (;;) { -+ wthread_wait (); -+ /* -+ * Read and copy the logging record index position -+ * It may have been updated by records_reclaim if -+ * messages were lost or or log_rec on the first new -+ * logging record available -+ */ -+ /* -+ * Process any pending log messages here -+ */ -+ for (;;) { -+ pthread_spin_lock (&logsys_idx_spinlock); -+ if (log_requests_lost > 0) { -+ printf ("lost %d log requests\n", log_requests_lost); -+ log_requests_pending -= log_requests_lost; -+ log_requests_lost = 0; -+ } -+ if (log_requests_pending == 0) { -+ pthread_spin_unlock (&logsys_idx_spinlock); - break; - } -+ log_rec_idx = record_read (buf, log_rec_idx, &log_msg); -+ if (log_msg) { -+ log_requests_pending -= 1; -+ } -+ pthread_spin_unlock (&logsys_idx_spinlock); -+ -+ /* -+ * print the stored buffer -+ */ -+ if (log_msg) { -+ record_print (buf); -+ } -+ } -+ -+ if (wthread_should_exit) { -+ pthread_exit (NULL); - } - } -- assert(i < MAX_LOGGERS); -+} - -- pthread_mutex_unlock (&logsys_config_mutex); -- return i; -+static void wthread_create (void) -+{ -+ int res; -+ -+ if (wthread_active) { -+ return; -+ } -+ -+ wthread_active = 1; -+ -+ pthread_mutex_init (&logsys_cond_mutex, NULL); -+ pthread_cond_init (&logsys_cond, NULL); -+ pthread_mutex_lock (&logsys_cond_mutex); -+ res = pthread_create (&logsys_thread_id, NULL, -+ logsys_worker_thread, NULL); -+ -+ -+ /* -+ * Wait for thread to be started -+ */ -+ wthread_wait_locked (); - } - --inline int logsys_mkpri (int priority, int id) -+/* -+ * Internal API - exported -+ */ -+void _logsys_nosubsys_set (void) - { -- return (((id) << 3) | (priority)); -+ logsys_mode |= LOG_MODE_NOSUBSYS; - } - --int logsys_config_subsys_get ( -+unsigned int _logsys_subsys_create ( - const char *subsys, -- unsigned int *tags, -- unsigned int *priority) -+ unsigned int priority) - { -- unsigned int i; -+ assert (subsys != NULL); - -- pthread_mutex_lock (&logsys_config_mutex); -+ return logsys_config_subsys_set ( -+ subsys, -+ LOGSYS_TAG_LOG, -+ priority); -+} - -- for (i = 0; i < MAX_LOGGERS; i++) { -- if (strcmp (logsys_loggers[i].subsys, subsys) == 0) { -- *tags = logsys_loggers[i].tags; -- *priority = logsys_loggers[i].priority; -- pthread_mutex_unlock (&logsys_config_mutex); -- return i; -+int _logsys_wthread_create (void) -+{ -+ if ((logsys_mode & LOG_MODE_FORK) == 0) { -+ if (logsys_name != NULL) { -+ openlog (logsys_name, LOG_CONS|LOG_PID, logsys_facility); - } -+ wthread_create(); -+ atexit (logsys_atexit); - } -- -- pthread_mutex_unlock (&logsys_config_mutex); -- -- return (-1); -+ return (0); - } - --static void buffered_log_printf ( -- char *file, -- int line, -- int priority, -- char *format, -- va_list ap) -+int _logsys_rec_init (unsigned int size) - { -- struct log_entry *entry = malloc(sizeof(struct log_entry)); -+ /* -+ * First record starts at zero -+ * Last record ends at zero -+ */ -+ flt_data = malloc ((size + 2) * sizeof (unsigned int)); -+ assert (flt_data != NULL); -+ flt_data_size = size; -+ assert (flt_data != NULL); -+ flt_data[FDHEAD_INDEX] = 0; -+ flt_data[FDTAIL_INDEX] = 0; -+ pthread_spin_init (&logsys_idx_spinlock, 0); - -- entry->file = file; -- entry->line = line; -- entry->priority = priority; -- entry->next = NULL; -- if (head == NULL) { -- head = tail = entry; -- } else { -- tail->next = entry; -- tail = entry; -- } -- vsnprintf(entry->str, sizeof(entry->str), format, ap); -+ return (0); - } - --static void log_printf_worker_fn (void *thread_data, void *work_item) -+ -+/* -+ * u32 RECORD SIZE -+ * u32 record ident -+ * u32 arg count -+ * u32 file line -+ * u32 subsys length -+ * buffer null terminated subsys -+ * u32 filename length -+ * buffer null terminated filename -+ * u32 filename length -+ * buffer null terminated function -+ * u32 arg1 length -+ * buffer arg1 -+ * ... repeats length & arg -+ */ -+void _logsys_log_rec ( -+ int subsys, -+ char *function_name, -+ char *file_name, -+ int file_line, -+ unsigned int rec_ident, -+ ...) - { -- struct log_data *log_data = (struct log_data *)work_item; -+ va_list ap; -+ void *buf_args[64]; -+ unsigned int buf_len[64]; -+ unsigned int i; -+ unsigned int idx; -+ unsigned int arguments = 0; -+ unsigned int record_reclaim_size; -+ unsigned int index_start; -+ int words_written; - -- if (logsys_wthread_active) -- pthread_mutex_lock (&logsys_config_mutex); -+ record_reclaim_size = 0; -+ - /* -- * Output the log data -+ * Decode VA Args - */ -- if (logsys_mode & LOG_MODE_OUTPUT_FILE && logsys_file_fp != 0) { -- fprintf (logsys_file_fp, "%s", log_data->log_string); -- fflush (logsys_file_fp); -+ va_start (ap, rec_ident); -+ arguments = 3; -+ for (;;) { -+ assert (arguments < 64); -+ buf_args[arguments] = va_arg (ap, void *); -+ if (buf_args[arguments] == LOG_REC_END) { -+ break; -+ } -+ buf_len[arguments] = va_arg (ap, int); -+ record_reclaim_size += ((buf_len[arguments] + 3) >> 2) + 1; -+ arguments++; - } -- if (logsys_mode & LOG_MODE_OUTPUT_STDERR) { -- fprintf (stderr, "%s", log_data->log_string); -- fflush (stdout); -+ va_end (ap); -+ -+ /* -+ * Encode logsys subsystem identity, filename, and function -+ */ -+ buf_args[0] = logsys_loggers[subsys].subsys; -+ buf_len[0] = strlen (logsys_loggers[subsys].subsys) + 1; -+ buf_args[1] = file_name; -+ buf_len[1] = strlen (file_name) + 1; -+ buf_args[2] = function_name; -+ buf_len[2] = strlen (function_name) + 1; -+ for (i = 0; i < 3; i++) { -+ record_reclaim_size += ((buf_len[i] + 3) >> 2) + 1; - } - -- /* release mutex here in case syslog blocks */ -- if (logsys_wthread_active) -- pthread_mutex_unlock (&logsys_config_mutex); -+ idx = flt_data[FDHEAD_INDEX]; -+ index_start = idx; - -- if ((logsys_mode & LOG_MODE_OUTPUT_SYSLOG_THREADED) && -- (!((logsys_mode & LOG_MODE_FILTER_DEBUG_FROM_SYSLOG) && -- (log_data->priority == LOG_LEVEL_DEBUG)))) { -- syslog (log_data->priority, -- &log_data->log_string[log_data->syslog_pos]); -- } -- free (log_data->log_string); --} -+ /* -+ * Reclaim data needed for record including 4 words for the header -+ */ -+ records_reclaim (idx, record_reclaim_size + 4); - --static void _log_printf ( -- enum logsys_config_mutex_state config_mutex_state, -- char *file, -- int line, -- int priority, -- int id, -- char *format, -- va_list ap) --{ -- char newstring[4096]; -- char log_string[4096]; -- char char_time[512]; -- char *p = NULL; -- struct timeval tv; -- int i = 0; -- int len; -- struct log_data log_data; -- unsigned int res = 0; -+ /* -+ * Write record size of zero and rest of header information -+ */ -+ flt_data[idx++] = 0; -+ idx_word_step(idx); - -- assert (id < MAX_LOGGERS); -+ flt_data[idx++] = rec_ident; -+ idx_word_step(idx); - -- if (config_mutex_state == LOGSYS_CONFIG_MUTEX_UNLOCKED) { -- pthread_mutex_lock (&logsys_config_mutex); -- } -- pthread_mutex_lock (&logsys_new_log_mutex); -+ flt_data[idx++] = file_line; -+ idx_word_step(idx); -+ -+ flt_data[idx++] = records_written; -+ idx_word_step(idx); - /* -- ** Buffer before log has been configured has been called. -- */ -- if (logsys_mode & LOG_MODE_BUFFER_BEFORE_CONFIG) { -- buffered_log_printf(file, line, logsys_mkpri(priority, id), format, ap); -- pthread_mutex_unlock (&logsys_new_log_mutex); -- if (config_mutex_state == LOGSYS_CONFIG_MUTEX_UNLOCKED) { -- pthread_mutex_unlock (&logsys_config_mutex); -- } -- return; -- } -+ * Encode all of the arguments into the log message -+ */ -+ for (i = 0; i < arguments; i++) { -+ unsigned int bytes; -+ unsigned int full_words; -+ unsigned int total_words; - -- if (((logsys_mode & LOG_MODE_OUTPUT_FILE) || (logsys_mode & LOG_MODE_OUTPUT_STDERR)) && -- (logsys_mode & LOG_MODE_DISPLAY_TIMESTAMP)) { -- gettimeofday (&tv, NULL); -- strftime (char_time, sizeof (char_time), "%b %e %k:%M:%S", -- localtime ((time_t *)&tv.tv_sec)); -- i = sprintf (newstring, "%s.%06ld ", char_time, (long)tv.tv_usec); -- } -+ bytes = buf_len[i]; -+ full_words = bytes >> 2; -+ total_words = (bytes + 3) >> 2; -+ -+ flt_data[idx++] = total_words; -+ idx_word_step(idx); - -- if ((priority == LOG_LEVEL_DEBUG) || (logsys_mode & LOG_MODE_DISPLAY_FILELINE)) { -- if (logsys_mode & LOG_MODE_SHORT_FILELINE) { -- p = strrchr(file, '/'); -- if (p) -- file = ++p; -- } -- sprintf (&newstring[i], "[%s:%04u] %s", file, line, format); -- } else { -- if (logsys_mode & LOG_MODE_NOSUBSYS) { -- sprintf (&newstring[i], "%s", format); -- } else { -- sprintf (&newstring[i], "[%-5s] %s", logsys_loggers[id].subsys, format); -- } -- } -- if (dropped_log_entries) { - /* -- * Get rid of \n if there is one -+ * determine if this is a wrapped write or normal write - */ -- if (newstring[strlen (newstring) - 1] == '\n') { -- newstring[strlen (newstring) - 1] = '\0'; -+ if (idx + total_words < flt_data_size) { -+ /* -+ * dont need to wrap buffer -+ */ -+ my_memcpy_32bit (&flt_data[idx], buf_args[i], full_words); -+ if (bytes % 4) { -+ my_memcpy_8bit ((char *)&flt_data[idx + full_words], -+ ((char *)buf_args[i]) + (full_words << 2), bytes % 4); -+ } -+ } else { -+ /* -+ * need to wrap buffer -+ */ -+ unsigned int first; -+ unsigned int second; -+ -+ first = flt_data_size - idx; -+ if (first > full_words) { -+ first = full_words; -+ } -+ second = full_words - first; -+ my_memcpy_32bit (&flt_data[idx], (int *)buf_args[i], first); -+ my_memcpy_32bit (&flt_data[0], -+ (int *)(((unsigned char *)buf_args[i]) + (first << 2)), -+ second); -+ if (bytes % 4) { -+ my_memcpy_8bit ((char *)&flt_data[0 + second], -+ ((char *)buf_args[i]) + (full_words << 2), bytes % 4); -+ } - } -- len = sprintf (log_string, -- "%s - prior to this log entry, corosync logger dropped '%d' messages because of overflow.", newstring, dropped_log_entries + 1); -- } else { -- len = vsprintf (log_string, newstring, ap); -+ idx += total_words; -+ idx_buffer_step (idx); -+ } -+ words_written = idx - index_start; -+ if (words_written < 0) { -+ words_written += flt_data_size; - } - - /* -- ** add line feed if not done yet -- */ -- if (log_string[len - 1] != '\n') { -- log_string[len] = '\n'; -- log_string[len + 1] = '\0'; -- } -+ * Commit the write of the record size now that the full record -+ * is in the memory buffer -+ */ -+ flt_data[index_start] = words_written; - - /* -- * Create work thread data -+ * If the index of the current head equals the current log_rec_idx, -+ * and this is not a log_printf operation, set the log_rec_idx to -+ * the new head position and commit the new head. - */ -- log_data.syslog_pos = i; -- log_data.priority = priority; -- log_data.log_string = strdup (log_string); -- if (log_data.log_string == NULL) { -- goto drop_log_msg; -+ pthread_spin_lock (&logsys_idx_spinlock); -+ if (rec_ident & LOGSYS_TAG_LOG) { -+ log_requests_pending += 1; - } -- -- if (logsys_wthread_active) { -- res = worker_thread_group_work_add (&log_thread_group, &log_data); -- if (res == 0) { -- dropped_log_entries = 0; -- } else { -- dropped_log_entries += 1; -- } -- } else { -- log_printf_worker_fn (NULL, &log_data); -+ if (log_requests_pending == 0) { -+ log_rec_idx = idx; - } -+ flt_data[FDHEAD_INDEX] = idx; -+ pthread_spin_unlock (&logsys_idx_spinlock); -+ records_written++; -+} - -- pthread_mutex_unlock (&logsys_new_log_mutex); -- if (config_mutex_state == LOGSYS_CONFIG_MUTEX_UNLOCKED) { -- pthread_mutex_unlock (&logsys_config_mutex); -+void _logsys_log_printf ( -+ int subsys, -+ char *function_name, -+ char *file_name, -+ int file_line, -+ unsigned int level, -+ char *format, -+ ...) -+{ -+ char logsys_print_buffer[COMBINE_BUFFER_SIZE]; -+ unsigned int len; -+ va_list ap; -+ -+ if (logsys_mode & LOG_MODE_NOSUBSYS) { -+ subsys = 0; -+ } -+ if (level > logsys_loggers[subsys].priority) { -+ return; -+ } -+ va_start (ap, format); -+ len = vsprintf (logsys_print_buffer, format, ap); -+ va_end (ap); -+ if (logsys_print_buffer[len - 1] == '\n') { -+ logsys_print_buffer[len - 1] = '\0'; -+ len -= 1; - } -- return; - --drop_log_msg: -- dropped_log_entries++; -- pthread_mutex_unlock (&logsys_new_log_mutex); -- if (config_mutex_state == LOGSYS_CONFIG_MUTEX_UNLOCKED) { -- pthread_mutex_unlock (&logsys_config_mutex); -+ /* -+ * Create a log record -+ */ -+ _logsys_log_rec (subsys, -+ function_name, -+ file_name, -+ file_line, -+ (level+1) << 28, -+ logsys_print_buffer, len + 1, -+ LOG_REC_END); -+ -+ if ((logsys_mode & LOG_MODE_THREADED) == 0) { -+ /* -+ * Output (and block) if the log mode is not threaded otherwise -+ * expect the worker thread to output the log data once signaled -+ */ -+ log_printf_to_logs (logsys_loggers[subsys].subsys, -+ function_name, file_name, file_line, level, -+ logsys_print_buffer); -+ } else { -+ /* -+ * Signal worker thread to display logging output -+ */ -+ wthread_signal (); - } - } - --unsigned int _logsys_subsys_create ( -- const char *subsys, -- unsigned int priority) -+/* -+ * External Configuration and Initialization API -+ */ -+void logsys_fork_completed (void) - { -- assert (subsys != NULL); -- -- return logsys_config_subsys_set ( -- subsys, -- LOGSYS_TAG_LOG, -- priority); -+ logsys_mode &= ~LOG_MODE_FORK; -+ _logsys_wthread_create (); - } - -- - void logsys_config_mode_set (unsigned int mode) - { - pthread_mutex_lock (&logsys_config_mutex); - logsys_mode = mode; -- if (mode & LOG_MODE_FLUSH_AFTER_CONFIG) { -- _logsys_wthread_create (); -- logsys_buffer_flush (); -- } - pthread_mutex_unlock (&logsys_config_mutex); - } - -@@ -431,22 +834,28 @@ - return logsys_mode; - } - -+static void logsys_close_logfile() -+{ -+ if (logsys_file_fp != NULL) { -+ fclose (logsys_file_fp); -+ logsys_file_fp = NULL; -+ } -+} -+ - int logsys_config_file_set (char **error_string, char *file) - { - static char error_string_response[512]; - - if (file == NULL) { -+ logsys_close_logfile(); - return (0); - } - -- pthread_mutex_lock (&logsys_new_log_mutex); - pthread_mutex_lock (&logsys_config_mutex); - - if (logsys_mode & LOG_MODE_OUTPUT_FILE) { - logsys_file = file; -- if (logsys_file_fp != NULL) { -- fclose (logsys_file_fp); -- } -+ logsys_close_logfile(); - logsys_file_fp = fopen (file, "a+"); - if (logsys_file_fp == 0) { - sprintf (error_string_response, -@@ -454,222 +863,243 @@ - file, strerror (errno)); - *error_string = error_string_response; - pthread_mutex_unlock (&logsys_config_mutex); -- pthread_mutex_unlock (&logsys_new_log_mutex); - return (-1); - } -- } -+ } else -+ logsys_close_logfile(); - - pthread_mutex_unlock (&logsys_config_mutex); -- pthread_mutex_unlock (&logsys_new_log_mutex); - return (0); - } - --void logsys_config_facility_set (char *name, unsigned int facility) -+void logsys_format_set (char *format) - { -- pthread_mutex_lock (&logsys_new_log_mutex); - pthread_mutex_lock (&logsys_config_mutex); - -- logsys_name = name; -- logsys_facility = facility; -+ logsys_format = format; - - pthread_mutex_unlock (&logsys_config_mutex); -- pthread_mutex_unlock (&logsys_new_log_mutex); - } - --void _logsys_config_priority_set (unsigned int id, unsigned int priority) -+void logsys_config_facility_set (char *name, unsigned int facility) - { -- pthread_mutex_lock (&logsys_new_log_mutex); -+ pthread_mutex_lock (&logsys_config_mutex); - -- logsys_loggers[id].priority = priority; -+ logsys_name = name; -+ logsys_facility = facility; - -- pthread_mutex_unlock (&logsys_new_log_mutex); -+ pthread_mutex_unlock (&logsys_config_mutex); - } - --static void child_cleanup (void) -+int logsys_facility_id_get (const char *name) - { -- memset(&log_thread_group, 0, sizeof(log_thread_group)); -- logsys_wthread_active = 0; -- pthread_mutex_init(&logsys_config_mutex, NULL); -- pthread_mutex_init(&logsys_new_log_mutex, NULL); -+ unsigned int i; -+ -+ for (i = 0; facilitynames[i].c_name != NULL; i++) { -+ if (strcasecmp(name, facilitynames[i].c_name) == 0) { -+ return (facilitynames[i].c_val); -+ } -+ } -+ return (-1); - } - --int _logsys_wthread_create (void) -+const char *logsys_facility_name_get (unsigned int facility) - { -- worker_thread_group_init ( -- &log_thread_group, -- 1, -- 1024, -- sizeof (struct log_data), -- 0, -- NULL, -- log_printf_worker_fn); -- -- logsys_flush(); -- -- atexit (logsys_atexit); -- pthread_atfork(NULL, NULL, child_cleanup); -+ unsigned int i; - -- if (logsys_mode & LOG_MODE_OUTPUT_SYSLOG_THREADED && logsys_name != NULL) { -- openlog (logsys_name, LOG_CONS|LOG_PID, logsys_facility); -+ for (i = 0; facilitynames[i].c_name != NULL; i++) { -+ if (facility == facilitynames[i].c_val) { -+ return (facilitynames[i].c_name); -+ } - } -+ return (NULL); -+} - -- logsys_wthread_active = 1; -+int logsys_priority_id_get (const char *name) -+{ -+ unsigned int i; - -- return (0); -+ for (i = 0; prioritynames[i].c_name != NULL; i++) { -+ if (strcasecmp(name, prioritynames[i].c_name) == 0) { -+ return (prioritynames[i].c_val); -+ } -+ } -+ return (-1); - } - --void logsys_log_printf ( -- char *file, -- int line, -- int priority, -- char *format, -- ...) -+const char *logsys_priority_name_get (unsigned int priority) - { -- int id = LOG_ID(priority); -- int level = LOG_LEVEL(priority); -- va_list ap; -- -- assert (id < MAX_LOGGERS); -+ unsigned int i; - -- if (LOG_LEVEL(priority) > logsys_loggers[id].priority) { -- return; -+ for (i = 0; prioritynames[i].c_name != NULL; i++) { -+ if (priority == prioritynames[i].c_val) { -+ return (prioritynames[i].c_name); -+ } - } -- -- va_start (ap, format); -- _log_printf (LOGSYS_CONFIG_MUTEX_UNLOCKED, file, line, level, id, -- format, ap); -- va_end(ap); -+ return (NULL); - } - --static void logsys_log_printf_locked ( -- char *file, -- int line, -- int priority, -- char *format, -- ...) -+int logsys_tag_id_get (const char *name) - { -- int id = LOG_ID(priority); -- int level = LOG_LEVEL(priority); -- va_list ap; -- -- assert (id < MAX_LOGGERS); -+ unsigned int i; - -- if (LOG_LEVEL(priority) > logsys_loggers[id].priority) { -- return; -+ for (i = 0; tagnames[i].c_name != NULL; i++) { -+ if (strcasecmp(name, tagnames[i].c_name) == 0) { -+ return (tagnames[i].c_val); -+ } - } -- -- va_start (ap, format); -- _log_printf (LOGSYS_CONFIG_MUTEX_LOCKED, file, line, level, id, -- format, ap); -- va_end(ap); -+ return (-1); - } - --void _logsys_log_printf2 ( -- char *file, -- int line, -- int priority, -- int id, -- char *format, ...) -+const char *logsys_tag_name_get (unsigned int tag) - { -- va_list ap; -- -- assert (id < MAX_LOGGERS); -+ unsigned int i; - -- va_start (ap, format); -- _log_printf (LOGSYS_CONFIG_MUTEX_UNLOCKED, file, line, priority, id, -- format, ap); -- va_end(ap); -+ for (i = 0; tagnames[i].c_name != NULL; i++) { -+ if (tag == tagnames[i].c_val) { -+ return (tagnames[i].c_name); -+ } -+ } -+ return (NULL); - } - --void _logsys_trace (char *file, int line, int tag, int id, char *format, ...) -+unsigned int logsys_config_subsys_set ( -+ const char *subsys, -+ unsigned int tags, -+ unsigned int priority) - { -- assert (id < MAX_LOGGERS); -+ int i; - - pthread_mutex_lock (&logsys_config_mutex); -+ for (i = 0; i < SUBSYS_MAX; i++) { -+ if (strcmp (logsys_loggers[i].subsys, subsys) == 0) { -+ logsys_loggers[i].tags = tags; -+ logsys_loggers[i].priority = priority; - -- if (tag & logsys_loggers[id].tags) { -- va_list ap; -+ break; -+ } -+ } - -- va_start (ap, format); -- _log_printf (LOGSYS_CONFIG_MUTEX_LOCKED, file, line, -- LOG_LEVEL_DEBUG, id, format, ap); -- va_end(ap); -+ if (i == SUBSYS_MAX) { -+ for (i = 0; i < SUBSYS_MAX; i++) { -+ if (strcmp (logsys_loggers[i].subsys, "") == 0) { -+ strncpy (logsys_loggers[i].subsys, subsys, -+ sizeof(logsys_loggers[i].subsys)); -+ logsys_loggers[i].tags = tags; -+ logsys_loggers[i].priority = priority; -+ break; -+ } -+ } - } -+ assert(i < SUBSYS_MAX); -+ - pthread_mutex_unlock (&logsys_config_mutex); -+ return i; - } - --static void logsys_atexit (void) -+int logsys_config_subsys_get ( -+ const char *subsys, -+ unsigned int *tags, -+ unsigned int *priority) - { -- if (logsys_wthread_active) { -- worker_thread_group_wait (&log_thread_group); -- } -- if (logsys_mode & LOG_MODE_OUTPUT_SYSLOG_THREADED) { -- closelog (); -+ unsigned int i; -+ -+ pthread_mutex_lock (&logsys_config_mutex); -+ -+ for (i = 0; i < SUBSYS_MAX; i++) { -+ if (strcmp (logsys_loggers[i].subsys, subsys) == 0) { -+ *tags = logsys_loggers[i].tags; -+ *priority = logsys_loggers[i].priority; -+ pthread_mutex_unlock (&logsys_config_mutex); -+ return i; -+ } - } -+ -+ pthread_mutex_unlock (&logsys_config_mutex); -+ -+ return (-1); - } - --static void logsys_buffer_flush (void) -+int logsys_log_rec_store (char *filename) - { -- struct log_entry *entry = head; -- struct log_entry *tmp; -+ int fd; -+ ssize_t written_size; -+ size_t size_to_write = (flt_data_size + 2) * sizeof (unsigned int); - -- if (logsys_mode & LOG_MODE_FLUSH_AFTER_CONFIG) { -- logsys_mode &= ~LOG_MODE_FLUSH_AFTER_CONFIG; -+ fd = open (filename, O_CREAT|O_RDWR, 0700); -+ if (fd == -1) { -+ return (-1); -+ } - -- while (entry) { -- logsys_log_printf_locked ( -- entry->file, -- entry->line, -- entry->priority, -- entry->str); -- tmp = entry; -- entry = entry->next; -- free (tmp); -- } -+ written_size = write (fd, flt_data, size_to_write); -+ if (written_size < 0) { -+ return (-1); -+ } else if ((size_t)written_size != size_to_write) { -+ return (-1); - } -+ return (0); -+} - -- head = tail = NULL; -+static void logsys_atexit (void) -+{ -+ if (wthread_active) { -+ wthread_should_exit = 1; -+ wthread_signal (); -+ pthread_join (logsys_thread_id, NULL); -+ } - } - --void logsys_flush (void) -+void logsys_atsegv (void) - { -- worker_thread_group_wait (&log_thread_group); -+ if (wthread_active) { -+ wthread_should_exit = 1; -+ wthread_signal (); -+ pthread_join (logsys_thread_id, NULL); -+ } - } - --int logsys_init (char *name, int mode, int facility, int priority, char *file) -+int logsys_init ( -+ char *name, -+ int mode, -+ int facility, -+ int priority, -+ char *file, -+ char *format, -+ int rec_size) - { - char *errstr; - -- /* logsys_subsys_id will be 0 */ -- logsys_single_id = 1; -- -+ _logsys_nosubsys_set (); -+ _logsys_subsys_create (name, priority); - strncpy (logsys_loggers[0].subsys, name, - sizeof (logsys_loggers[0].subsys)); - logsys_config_mode_set (mode); - logsys_config_facility_set (name, facility); - logsys_config_file_set (&errstr, file); -- _logsys_config_priority_set (0, priority); -- if ((mode & LOG_MODE_BUFFER_BEFORE_CONFIG) == 0) { -- _logsys_wthread_create (); -- } -+ logsys_format_set (format); -+ _logsys_rec_init (rec_size); -+ _logsys_wthread_create (); - return (0); - } - --int logsys_conf (char *name, int mode, int facility, int priority, char *file) -+int logsys_conf ( -+ char *name, -+ int mode, -+ int facility, -+ int priority, -+ char *file) - { - char *errstr; - -+ _logsys_rec_init (100000); - strncpy (logsys_loggers[0].subsys, name, - sizeof (logsys_loggers[0].subsys)); - logsys_config_mode_set (mode); - logsys_config_facility_set (name, facility); - logsys_config_file_set (&errstr, file); -- _logsys_config_priority_set (0, priority); - return (0); - } - - void logsys_exit (void) - { -- logsys_flush (); - } -- -diff -Naurd corosync-0.92/exec/main.c corosync-trunk/exec/main.c ---- corosync-0.92/exec/main.c 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/exec/main.c 2009-01-23 17:12:13.000000000 +0100 -@@ -34,8 +34,6 @@ - */ - #include - #include --#include --#include - #include - #include - #include -@@ -56,7 +54,7 @@ - #include - - #include --#include -+#include - #include - #include - #include -@@ -66,6 +64,7 @@ - #include - #include - -+#include "quorum.h" - #include "totemsrp.h" - #include "mempool.h" - #include "mainconfig.h" -@@ -83,18 +82,16 @@ - #include "version.h" - - LOGSYS_DECLARE_SYSTEM ("corosync", -- LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED | LOG_MODE_BUFFER_BEFORE_CONFIG, -+ LOG_MODE_OUTPUT_STDERR | LOG_MODE_THREADED | LOG_MODE_FORK, - NULL, -- LOG_DAEMON); -+ LOG_DAEMON, -+ "[%6s] %b", -+ 1000000); - - LOGSYS_DECLARE_SUBSYS ("MAIN", LOG_INFO); - - #define SERVER_BACKLOG 5 - --static int ais_uid = 0; -- --static int gid_valid = 0; -- - static unsigned int service_count = 32; - - static pthread_mutex_t serialize_mutex = PTHREAD_MUTEX_INITIALIZER; -@@ -145,7 +142,6 @@ - #endif - - totempg_finalize (); -- logsys_flush (); - - corosync_exit_error (AIS_DONE_EXIT); - -@@ -170,15 +166,17 @@ - - static void sigsegv_handler (int num) - { -- signal (SIGSEGV, SIG_DFL); -- logsys_flush (); -+ (void)signal (SIGSEGV, SIG_DFL); -+ logsys_atsegv(); -+ logsys_log_rec_store ("/var/lib/corosync/fdata"); - raise (SIGSEGV); - } - - static void sigabrt_handler (int num) - { -- signal (SIGABRT, SIG_DFL); -- logsys_flush (); -+ (void)signal (SIGABRT, SIG_DFL); -+ logsys_atsegv(); -+ logsys_log_rec_store ("/var/lib/corosync/fdata"); - raise (SIGABRT); - } - -@@ -271,36 +269,11 @@ - } - } - --static void aisexec_uid_determine (struct main_config *main_config) --{ -- struct passwd *passwd; -- -- passwd = getpwnam(main_config->user); -- if (passwd == 0) { -- log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' user is not found in /etc/passwd, please read the documentation.\n", main_config->user); -- corosync_exit_error (AIS_DONE_UID_DETERMINE); -- } -- ais_uid = passwd->pw_uid; -- endpwent (); --} -- --static void aisexec_gid_determine (struct main_config *main_config) --{ -- struct group *group; -- group = getgrnam (main_config->group); -- if (group == 0) { -- log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' group is not found in /etc/group, please read the documentation.\n", group->gr_name); -- corosync_exit_error (AIS_DONE_GID_DETERMINE); -- } -- gid_valid = group->gr_gid; -- endgrent (); --} -- --static void aisexec_priv_drop (void) -+static void priv_drop (struct main_config *main_config) - { --return; -- setuid (ais_uid); -- setegid (ais_uid); -+return; /* TODO: we are still not dropping privs */ -+ setuid (main_config->uid); -+ setegid (main_config->gid); - } - - static void aisexec_mempool_init (void) -@@ -341,7 +314,7 @@ - } - - /* Create new session */ -- setsid(); -+ (void)setsid(); - - /* - * Map stdin/out/err to /dev/null. -@@ -408,7 +381,6 @@ - #endif - } - -- - static void deliver_fn ( - unsigned int nodeid, - struct iovec *iovec, -@@ -448,6 +420,8 @@ - */ - service = header->id >> 16; - fn_id = header->id & 0xffff; -+ if (!ais_service[service]) -+ return; - if (endian_conversion_required) { - assert(ais_service[service]->exec_engine[fn_id].exec_endian_convert_fn != NULL); - ais_service[service]->exec_engine[fn_id].exec_endian_convert_fn -@@ -494,7 +468,6 @@ - char *iface; - int res, ch; - int background, setprio; -- int totem_log_service; - - /* default configuration - */ -@@ -506,7 +479,7 @@ - switch (ch) { - case 'f': - background = 0; -- logsys_config_mode_set (LOG_MODE_OUTPUT_STDERR|LOG_MODE_FLUSH_AFTER_CONFIG); -+ logsys_config_mode_set (LOG_MODE_OUTPUT_STDERR|LOG_MODE_THREADED|LOG_MODE_FORK); - break; - case 'p': - setprio = 0; -@@ -527,11 +500,11 @@ - log_printf (LOG_LEVEL_NOTICE, "Copyright (C) 2002-2006 MontaVista Software, Inc and contributors.\n"); - log_printf (LOG_LEVEL_NOTICE, "Copyright (C) 2006-2008 Red Hat, Inc.\n"); - -- signal (SIGINT, sigintr_handler); -- signal (SIGUSR2, sigusr2_handler); -- signal (SIGSEGV, sigsegv_handler); -- signal (SIGABRT, sigabrt_handler); -- signal (SIGQUIT, sigquit_handler); -+ (void)signal (SIGINT, sigintr_handler); -+ (void)signal (SIGUSR2, sigusr2_handler); -+ (void)signal (SIGSEGV, sigsegv_handler); -+ (void)signal (SIGABRT, sigabrt_handler); -+ (void)signal (SIGQUIT, sigquit_handler); - - corosync_timer_init ( - serialize_mutex_lock, -@@ -635,14 +608,6 @@ - corosync_exit_error (AIS_DONE_MAINCONFIGREAD); - } - -- logsys_config_facility_set ("corosync", main_config.syslog_facility); -- logsys_config_mode_set (main_config.logmode); -- logsys_config_file_set (&error_string, main_config.logfile); -- -- aisexec_uid_determine (&main_config); -- -- aisexec_gid_determine (&main_config); -- - /* - * Set round robin realtime scheduling with priority 99 - * Lock all memory to avoid page faults which may interrupt -@@ -654,13 +619,14 @@ - aisexec_mlockall (); - - totem_config.totem_logging_configuration = totem_logging_configuration; -- totem_log_service = _logsys_subsys_create ("TOTEM", LOG_INFO); -- totem_config.totem_logging_configuration.log_level_security = logsys_mkpri (LOG_LEVEL_SECURITY, totem_log_service); -- totem_config.totem_logging_configuration.log_level_error = logsys_mkpri (LOG_LEVEL_ERROR, totem_log_service); -- totem_config.totem_logging_configuration.log_level_warning = logsys_mkpri (LOG_LEVEL_WARNING, totem_log_service); -- totem_config.totem_logging_configuration.log_level_notice = logsys_mkpri (LOG_LEVEL_NOTICE, totem_log_service); -- totem_config.totem_logging_configuration.log_level_debug = logsys_mkpri (LOG_LEVEL_DEBUG, totem_log_service); -- totem_config.totem_logging_configuration.log_printf = logsys_log_printf; -+ totem_config.totem_logging_configuration.log_subsys_id = -+ _logsys_subsys_create ("TOTEM", LOG_INFO); -+ totem_config.totem_logging_configuration.log_level_security = LOG_LEVEL_SECURITY; -+ totem_config.totem_logging_configuration.log_level_error = LOG_LEVEL_ERROR; -+ totem_config.totem_logging_configuration.log_level_warning = LOG_LEVEL_WARNING; -+ totem_config.totem_logging_configuration.log_level_notice = LOG_LEVEL_NOTICE; -+ totem_config.totem_logging_configuration.log_level_debug = LOG_LEVEL_DEBUG; -+ totem_config.totem_logging_configuration.log_printf = _logsys_log_printf; - - /* - * Sleep for a while to let other nodes in the cluster -@@ -704,11 +670,9 @@ - } - - -- sync_register (corosync_sync_callbacks_retrieve, corosync_sync_completed, -- totem_config.vsf_type); -- -+ sync_register (corosync_sync_callbacks_retrieve, corosync_sync_completed); - -- res = corosync_flow_control_initialize (); -+ res = cs_flow_control_initialize (); - - /* - * Drop root privleges to user 'ais' -@@ -718,14 +682,14 @@ - * CAP_SYS_NICE (setscheduler) - * CAP_IPC_LOCK (mlockall) - */ -- aisexec_priv_drop (); -+ priv_drop (&main_config); - - aisexec_mempool_init (); - -- corosync_ipc_init ( -+ cs_ipc_init ( - serialize_mutex_lock, - serialize_mutex_unlock, -- gid_valid); -+ main_config.gid); - - /* - * Start main processing loop -diff -Naurd corosync-0.92/exec/mainconfig.c corosync-trunk/exec/mainconfig.c ---- corosync-0.92/exec/mainconfig.c 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/exec/mainconfig.c 2009-01-23 17:12:13.000000000 +0100 -@@ -40,8 +40,10 @@ - #include - #include - #include -+#include -+#include - --#include -+#include - #include - #include - #include -@@ -51,6 +53,12 @@ - #include "mempool.h" - - static char error_string_response[512]; -+static struct objdb_iface_ver0 *global_objdb; -+ -+static void add_logsys_config_notification( -+ struct objdb_iface_ver0 *objdb, -+ struct main_config *main_config); -+ - - /* This just makes the code below a little neater */ - static inline int objdb_get_string ( -@@ -98,7 +106,10 @@ - unsigned int tags; - } logsys_logger; - --int corosync_main_config_read ( -+ -+ -+ -+int corosync_main_config_read_logging ( - struct objdb_iface_ver0 *objdb, - char **error_string, - struct main_config *main_config) -@@ -109,10 +120,6 @@ - char *error_reason = error_string_response; - unsigned int object_find_handle; - unsigned int object_find_logsys_handle; -- int global_debug = 0; -- -- -- memset (main_config, 0, sizeof (struct main_config)); - - objdb->object_find_create ( - OBJECT_PARENT_HANDLE, -@@ -120,7 +127,7 @@ - strlen ("logging"), - &object_find_handle); - -- main_config->logmode = LOG_MODE_FLUSH_AFTER_CONFIG; -+ main_config->logmode = LOG_MODE_THREADED | LOG_MODE_FORK; - if (objdb->object_find_next ( - object_find_handle, - &object_service_handle) == 0) { -@@ -135,10 +142,10 @@ - } - if (!objdb_get_string (objdb,object_service_handle, "to_syslog", &value)) { - if (strcmp (value, "yes") == 0) { -- main_config->logmode |= LOG_MODE_OUTPUT_SYSLOG_THREADED; -+ main_config->logmode |= LOG_MODE_OUTPUT_SYSLOG; - } else - if (strcmp (value, "no") == 0) { -- main_config->logmode &= ~LOG_MODE_OUTPUT_SYSLOG_THREADED; -+ main_config->logmode &= ~LOG_MODE_OUTPUT_SYSLOG; - } - } - if (!objdb_get_string (objdb,object_service_handle, "to_stderr", &value)) { -@@ -149,18 +156,8 @@ - main_config->logmode &= ~LOG_MODE_OUTPUT_STDERR; - } - } -- -- if (!objdb_get_string (objdb,object_service_handle, "debug", &value)) { -- if (strcmp (value, "on") == 0) { -- global_debug = 1; -- } else -- if (strcmp (value, "off") == 0) { -- global_debug = 0; -- } else { -- goto parse_error; -- } -- } - if (!objdb_get_string (objdb,object_service_handle, "timestamp", &value)) { -+/* todo change format string - if (strcmp (value, "on") == 0) { - main_config->logmode |= LOG_MODE_DISPLAY_TIMESTAMP; - } else -@@ -169,12 +166,20 @@ - } else { - goto parse_error; - } -+*/ -+ } -+ -+ /* free old string on reload */ -+ if (main_config->logfile) { -+ free(main_config->logfile); -+ main_config->logfile = NULL; - } - if (!objdb_get_string (objdb,object_service_handle, "logfile", &value)) { - main_config->logfile = strdup (value); - } - - if (!objdb_get_string (objdb,object_service_handle, "fileline", &value)) { -+/* TODO - if (strcmp (value, "on") == 0) { - main_config->logmode |= LOG_MODE_DISPLAY_FILELINE; - } else -@@ -183,41 +188,21 @@ - } else { - goto parse_error; - } -+*/ - } - - if (!objdb_get_string (objdb,object_service_handle, "syslog_facility", &value)) { -- if (strcmp (value, "daemon") == 0) { -- main_config->syslog_facility = LOG_DAEMON; -- } else -- if (strcmp (value, "local0") == 0) { -- main_config->syslog_facility = LOG_LOCAL0; -- } else -- if (strcmp (value, "local1") == 0) { -- main_config->syslog_facility = LOG_LOCAL1; -- } else -- if (strcmp (value, "local2") == 0) { -- main_config->syslog_facility = LOG_LOCAL2; -- } else -- if (strcmp (value, "local3") == 0) { -- main_config->syslog_facility = LOG_LOCAL3; -- } else -- if (strcmp (value, "local4") == 0) { -- main_config->syslog_facility = LOG_LOCAL4; -- } else -- if (strcmp (value, "local5") == 0) { -- main_config->syslog_facility = LOG_LOCAL5; -- } else -- if (strcmp (value, "local6") == 0) { -- main_config->syslog_facility = LOG_LOCAL6; -- } else -- if (strcmp (value, "local7") == 0) { -- main_config->syslog_facility = LOG_LOCAL7; -- } else { -+ main_config->syslog_facility = logsys_facility_id_get(value); -+ if (main_config->syslog_facility < 0) { - error_reason = "unknown syslog facility specified"; - goto parse_error; - } - } - -+ logsys_config_facility_set ("corosync", main_config->syslog_facility); -+ logsys_config_mode_set (main_config->logmode); -+ logsys_config_file_set (error_string, main_config->logfile); -+ - objdb->object_find_create ( - object_service_handle, - "logger_subsys", -@@ -239,6 +224,13 @@ - error_reason = "subsys required for logger directive"; - goto parse_error; - } -+ if (!objdb_get_string (objdb, object_logger_subsys_handle, "syslog_level", &value)) { -+ logsys_logger.priority = logsys_priority_id_get(value); -+ if (logsys_logger.priority < 0) { -+ error_reason = "unknown syslog priority specified"; -+ goto parse_error; -+ } -+ } - if (!objdb_get_string (objdb, object_logger_subsys_handle, "debug", &value)) { - if (strcmp (value, "on") == 0) { - logsys_logger.priority = LOG_LEVEL_DEBUG; -@@ -253,31 +245,14 @@ - char *token = strtok (value, "|"); - - while (token != NULL) { -- if (strcmp (token, "enter") == 0) { -- logsys_logger.tags |= LOGSYS_TAG_ENTER; -- } else if (strcmp (token, "leave") == 0) { -- logsys_logger.tags |= LOGSYS_TAG_LEAVE; -- } else if (strcmp (token, "trace1") == 0) { -- logsys_logger.tags |= LOGSYS_TAG_TRACE1; -- } else if (strcmp (token, "trace2") == 0) { -- logsys_logger.tags |= LOGSYS_TAG_TRACE2; -- } else if (strcmp (token, "trace3") == 0) { -- logsys_logger.tags |= LOGSYS_TAG_TRACE3; -- } else if (strcmp (token, "trace4") == 0) { -- logsys_logger.tags |= LOGSYS_TAG_TRACE4; -- } else if (strcmp (token, "trace5") == 0) { -- logsys_logger.tags |= LOGSYS_TAG_TRACE5; -- } else if (strcmp (token, "trace6") == 0) { -- logsys_logger.tags |= LOGSYS_TAG_TRACE6; -- } else if (strcmp (token, "trace7") == 0) { -- logsys_logger.tags |= LOGSYS_TAG_TRACE7; -- } else if (strcmp (token, "trace8") == 0) { -- logsys_logger.tags |= LOGSYS_TAG_TRACE8; -- } else { -+ int val; -+ -+ val = logsys_tag_id_get(token); -+ if (val < 0) { - error_reason = "bad tags value"; - goto parse_error; - } -- -+ logsys_logger.tags |= val; - token = strtok(NULL, "|"); - } - } -@@ -295,6 +270,61 @@ - - objdb->object_find_destroy (object_find_handle); - -+ return 0; -+ -+parse_error: -+ sprintf (error_string_response, -+ "parse error in config: %s.\n", -+ error_reason); -+ -+ *error_string = error_string_response; -+ return (-1); -+} -+ -+static int uid_determine (char *req_user) -+{ -+ struct passwd *passwd; -+ int ais_uid = 0; -+ -+ passwd = getpwnam(req_user); -+ if (passwd == 0) { -+ log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' user is not found in /etc/passwd, please read the documentation.\n", req_user); -+ corosync_exit_error (AIS_DONE_UID_DETERMINE); -+ } -+ ais_uid = passwd->pw_uid; -+ endpwent (); -+ return ais_uid; -+} -+ -+static int gid_determine (char *req_group) -+{ -+ struct group *group; -+ int ais_gid = 0; -+ -+ group = getgrnam (req_group); -+ if (group == 0) { -+ log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' group is not found in /etc/group, please read the documentation.\n", req_group); -+ corosync_exit_error (AIS_DONE_GID_DETERMINE); -+ } -+ ais_gid = group->gr_gid; -+ endgrent (); -+ return ais_gid; -+} -+ -+int corosync_main_config_read ( -+ struct objdb_iface_ver0 *objdb, -+ char **error_string, -+ struct main_config *main_config) -+{ -+ unsigned int object_service_handle; -+ char *value; -+ char *error_reason = error_string_response; -+ unsigned int object_find_handle; -+ -+ memset (main_config, 0, sizeof (struct main_config)); -+ -+ corosync_main_config_read_logging(objdb, error_string, main_config); -+ - objdb->object_find_create ( - OBJECT_PARENT_HANDLE, - "aisexec", -@@ -306,22 +336,18 @@ - &object_service_handle) == 0) { - - if (!objdb_get_string (objdb,object_service_handle, "user", &value)) { -- main_config->user = strdup(value); -- } -+ main_config->uid = uid_determine(value); -+ } else -+ main_config->uid = uid_determine("ais"); -+ - if (!objdb_get_string (objdb,object_service_handle, "group", &value)) { -- main_config->group = strdup(value); -- } -+ main_config->gid = gid_determine(value); -+ } else -+ main_config->gid = gid_determine("ais"); - } - - objdb->object_find_destroy (object_find_handle); - -- /* Default user/group */ -- if (!main_config->user) -- main_config->user = "ais"; -- -- if (!main_config->group) -- main_config->group = "ais"; -- - if ((main_config->logmode & LOG_MODE_OUTPUT_FILE) && - (main_config->logfile == NULL)) { - error_reason = "logmode set to 'file' but no logfile specified"; -@@ -331,6 +357,10 @@ - if (main_config->syslog_facility == 0) - main_config->syslog_facility = LOG_DAEMON; - -+ add_logsys_config_notification(objdb, main_config); -+ -+ logsys_fork_completed (); -+ - return 0; - - parse_error: -@@ -341,3 +371,38 @@ - *error_string = error_string_response; - return (-1); - } -+ -+ -+static void main_objdb_reload_notify(objdb_reload_notify_type_t type, int flush, -+ void *priv_data_pt) -+{ -+ struct main_config *main_config = priv_data_pt; -+ char *error_string; -+ -+ if (type == OBJDB_RELOAD_NOTIFY_END) { -+ -+ /* -+ * Reload the logsys configuration -+ */ -+ corosync_main_config_read_logging(global_objdb, -+ &error_string, -+ main_config); -+ } -+} -+ -+static void add_logsys_config_notification( -+ struct objdb_iface_ver0 *objdb, -+ struct main_config *main_config) -+{ -+ -+ global_objdb = objdb; -+ -+ objdb->object_track_start(OBJECT_PARENT_HANDLE, -+ 1, -+ NULL, -+ NULL, -+ NULL, -+ main_objdb_reload_notify, -+ main_config); -+ -+} -diff -Naurd corosync-0.92/exec/mainconfig.h corosync-trunk/exec/mainconfig.h ---- corosync-0.92/exec/mainconfig.h 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/exec/mainconfig.h 2009-01-23 17:12:13.000000000 +0100 -@@ -61,13 +61,13 @@ - /* - * user/group to run as - */ -- char *user; -- char *group; -+ int uid; -+ int gid; - }; - - extern int corosync_main_config_read ( - struct objdb_iface_ver0 *objdb, - char **error_string, - struct main_config *main_config); -- -+ - #endif /* MAINCONFIG_H_DEFINED */ -diff -Naurd corosync-0.92/exec/main.h corosync-trunk/exec/main.h ---- corosync-0.92/exec/main.h 2008-08-20 02:57:40.000000000 +0200 -+++ corosync-trunk/exec/main.h 2008-11-06 22:49:07.000000000 +0100 -@@ -37,7 +37,7 @@ - - #define TRUE 1 - #define FALSE 0 --#include -+#include - #include - #include - #include -diff -Naurd corosync-0.92/exec/Makefile corosync-trunk/exec/Makefile ---- corosync-0.92/exec/Makefile 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/exec/Makefile 2008-12-08 16:55:41.000000000 +0100 -@@ -59,14 +59,14 @@ - EXEC_LIBS = libtotem_pg.a liblogsys.a - - # LCR objects --LCR_SRC = vsf_ykd.c objdb.c coroparse.c --LCR_OBJS = vsf_ykd.o objdb.o coroparse.o -+LCR_SRC = vsf_ykd.c objdb.c coroparse.c vsf_quorum.c -+LCR_OBJS = vsf_ykd.o objdb.o coroparse.o vsf_quorum.o - - # main executive objects - MAIN_SRC = main.c mempool.c util.c sync.c apidef.c service.c ipc.c flow.c \ -- timer.c totemconfig.c mainconfig.c -+ quorum.c timer.c totemconfig.c mainconfig.c - MAIN_OBJS = main.o mempool.o util.o sync.o apidef.o service.o ipc.o flow.o \ -- timer.o totemconfig.o mainconfig.o ../lcr/lcr_ifact.o -+ quorum.o timer.o totemconfig.o mainconfig.o ../lcr/lcr_ifact.o - - ifeq (${BUILD_DYNAMIC}, 1) - #EXEC_OBJS = $(TOTEM_OBJS) $(LOGSYS_OBJS) $(MAIN_OBJS) -@@ -75,7 +75,7 @@ - - all:libtotem_pg.a libtotem_pg.so.2.0.0 liblogsys.a liblogsys.so.2.0.0 \ - ../lcr/lcr_ifact.o corosync_ \ -- objdb.lcrso vsf_ykd.lcrso coroparse.lcrso -+ objdb.lcrso vsf_ykd.lcrso coroparse.lcrso vsf_quorum.lcrso - else - EXEC_OBJS = $(MAIN_OBJS) $(LCR_OBJS) - all: libtotem_pg.a liblogsys.a corosync -@@ -90,6 +90,9 @@ - vsf_ykd.lcrso: vsf_ykd.o - $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./corosync -bind_at_load vsf_ykd.o -o $@ - -+vsf_quorum.lcrso: vsf_quorum.o -+ $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./corosync -bind_at_load vsf_quorum.o -o $@ -+ - coroparse.lcrso: coroparse.o - $(CC) -bundle -bundle_loader ./corosync -bind_at_load coroparse.o -o $@ - -@@ -98,9 +101,15 @@ - vsf_ykd.lcrso: vsf_ykd.o - $(CC) -shared -Wl,-soname,vsf_ykd.lcrso vsf_ykd.o -o $@ - -+vsf_quorum.lcrso: vsf_quorum.o -+ $(CC) -shared -Wl,-soname,vsf_quorum.lcrso vsf_quorum.o -o $@ -+ - objdb.lcrso: objdb.o - $(CC) -shared -Wl,-soname,objdb.lcrso objdb.o -o $@ - -+testquorum.lcrso: testquorum.o -+ $(CC) -shared -Wl,-soname,testquorum.lcrso objdb.o -o $@ -+ - coroparse.lcrso: coroparse.o - $(CC) -shared -Wl,-soname,coroparse.lcrso coroparse.o -o $@ - endif -@@ -131,6 +140,9 @@ - - endif - -+lint: -+ -splint $(LINT_FLAGS) $(CFLAGS) *.c -+ - clean: - rm -f corosync $(OBJS) *.o *.lcrso libtotem_pg.so* libtotem_pg.a gmon.out - rm -f *.da *.bb *.bbg liblogsys.so* liblogsys.a -@@ -145,9 +157,15 @@ - vsf_ykd.o: vsf_ykd.c - $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< - -+vsf_quorum.o: vsf_quorum.c -+ $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -+ - objdb.o: objdb.c - $(CC) $(CFLAGS) -c -o $@ $< - -+testquorum.o: testquorum.c -+ $(CC) $(CFLAGS) -c -o $@ $< -+ - coroparse.o: coroparse.c - $(CC) $(CFLAGS) -c -o $@ $< - -diff -Naurd corosync-0.92/exec/objdb.c corosync-trunk/exec/objdb.c ---- corosync-0.92/exec/objdb.c 2008-09-03 12:01:31.000000000 +0200 -+++ corosync-trunk/exec/objdb.c 2009-01-23 16:41:06.000000000 +0100 -@@ -1,6 +1,6 @@ - /* - * Copyright (c) 2006 MontaVista Software, Inc. -- * Copyright (c) 2007-2008 Red Hat, Inc. -+ * Copyright (c) 2007-2009 Red Hat, Inc. - * - * All rights reserved. - * -@@ -59,6 +59,7 @@ - object_key_change_notify_fn_t key_change_notify_fn; - object_create_notify_fn_t object_create_notify_fn; - object_destroy_notify_fn_t object_destroy_notify_fn; -+ object_reload_notify_fn_t object_reload_notify_fn; - struct list_head tracker_list; - struct list_head object_list; - }; -@@ -91,6 +92,9 @@ - - struct objdb_iface_ver0 objdb_iface; - struct list_head objdb_trackers_head; -+static pthread_rwlock_t reload_lock; -+static pthread_t lock_thread; -+static pthread_mutex_t meta_lock; - - static struct hdb_handle_database object_instance_database = { - .handle_count = 0, -@@ -107,6 +111,38 @@ - }; - - -+static void objdb_wrlock() -+{ -+ pthread_mutex_lock(&meta_lock); -+ pthread_rwlock_wrlock(&reload_lock); -+ lock_thread = pthread_self(); -+ pthread_mutex_unlock(&meta_lock); -+} -+ -+static void objdb_rdlock() -+{ -+ pthread_mutex_lock(&meta_lock); -+ if (lock_thread != pthread_self()) -+ pthread_rwlock_rdlock(&reload_lock); -+ pthread_mutex_unlock(&meta_lock); -+} -+ -+static void objdb_rdunlock() -+{ -+ pthread_mutex_lock(&meta_lock); -+ if (lock_thread != pthread_self()) -+ pthread_rwlock_unlock(&reload_lock); -+ pthread_mutex_unlock(&meta_lock); -+} -+ -+static void objdb_wrunlock() -+{ -+ pthread_mutex_lock(&meta_lock); -+ pthread_rwlock_unlock(&reload_lock); -+ lock_thread = 0; -+ pthread_mutex_unlock(&meta_lock); -+} -+ - static int objdb_init (void) - { - unsigned int handle; -@@ -135,6 +171,8 @@ - list_init (&instance->child_list); - list_init (&instance->track_head); - list_init (&objdb_trackers_head); -+ pthread_rwlock_init(&reload_lock, NULL); -+ pthread_mutex_init(&meta_lock, NULL); - - hdb_handle_put (&object_instance_database, handle); - return (0); -@@ -293,6 +331,30 @@ - } while (obj_pt->object_handle != OBJECT_PARENT_HANDLE); - } - -+static void object_reload_notification(int startstop, int flush) -+{ -+ struct list_head * list; -+ struct object_instance * obj_pt; -+ struct object_tracker * tracker_pt; -+ unsigned int res; -+ -+ res = hdb_handle_get (&object_instance_database, -+ OBJECT_PARENT_HANDLE, (void *)&obj_pt); -+ -+ for (list = obj_pt->track_head.next; -+ list != &obj_pt->track_head; list = list->next) { -+ -+ tracker_pt = list_entry (list, struct object_tracker, object_list); -+ -+ if (tracker_pt->object_reload_notify_fn != NULL) { -+ tracker_pt->object_reload_notify_fn(startstop, flush, -+ tracker_pt->data_pt); -+ } -+ } -+ hdb_handle_put (&object_instance_database, OBJECT_PARENT_HANDLE); -+} -+ -+ - /* - * object db create/destroy/set - */ -@@ -308,6 +370,7 @@ - int found = 0; - int i; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_instance_database, - parent_object_handle, (void *)&parent_instance); - if (res != 0) { -@@ -380,7 +443,7 @@ - object_instance->parent_handle, - object_instance->object_name, - object_instance->object_name_len); -- -+ objdb_rdunlock(); - return (0); - - error_put_destroy: -@@ -393,6 +456,7 @@ - hdb_handle_put (&object_instance_database, parent_object_handle); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -403,6 +467,8 @@ - int res; - struct object_instance *object_instance; - -+ objdb_rdlock(); -+ - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&object_instance); - if (res != 0) { -@@ -412,9 +478,11 @@ - object_instance->priv = priv; - - hdb_handle_put (&object_instance_database, object_handle); -+ objdb_rdunlock(); - return (0); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -432,6 +500,8 @@ - int i; - unsigned int val; - -+ objdb_rdlock(); -+ - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -@@ -493,7 +563,7 @@ - list_add_tail (&object_key->list, &instance->key_head); - object_key_changed_notification(object_handle, key_name, key_len, - value, value_len, OBJECT_KEY_CREATED); -- -+ objdb_rdunlock(); - return (0); - - error_put_key: -@@ -506,6 +576,7 @@ - hdb_handle_put (&object_instance_database, object_handle); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -554,9 +625,12 @@ - struct object_instance *instance; - unsigned int res; - -+ objdb_rdlock(); -+ - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -+ objdb_rdunlock(); - return (res); - } - -@@ -572,6 +646,7 @@ - free(instance->object_name); - free(instance); - -+ objdb_rdunlock(); - return (res); - } - -@@ -583,6 +658,7 @@ - struct object_instance *instance; - unsigned int res; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -@@ -594,9 +670,11 @@ - - hdb_handle_put (&object_instance_database, object_handle); - -+ objdb_rdunlock(); - return (0); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -608,6 +686,7 @@ - struct object_instance *instance; - unsigned int res; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -@@ -619,9 +698,11 @@ - - hdb_handle_put (&object_instance_database, object_handle); - -+ objdb_rdunlock(); - return (0); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -638,6 +719,7 @@ - struct object_instance *object_instance; - struct object_find_instance *object_find_instance; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&object_instance); - if (res != 0) { -@@ -662,6 +744,8 @@ - - hdb_handle_put (&object_instance_database, object_handle); - hdb_handle_put (&object_find_instance_database, *object_find_handle); -+ -+ objdb_rdunlock(); - return (0); - - error_destroy: -@@ -671,6 +755,7 @@ - hdb_handle_put (&object_instance_database, object_handle); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -684,6 +769,7 @@ - struct list_head *list; - unsigned int found = 0; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_find_instance_database, - object_find_handle, (void *)&object_find_instance); - if (res != 0) { -@@ -714,16 +800,35 @@ - *object_handle = object_instance->object_handle; - res = 0; - } -+ objdb_rdunlock(); - return (res); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - - static int object_find_destroy ( - unsigned int object_find_handle) - { -+ struct object_find_instance *object_find_instance; -+ unsigned int res; -+ -+ objdb_rdlock(); -+ res = hdb_handle_get (&object_find_instance_database, -+ object_find_handle, (void *)&object_find_instance); -+ if (res != 0) { -+ goto error_exit; -+ } -+ hdb_handle_put(&object_find_instance_database, object_find_handle); -+ hdb_handle_destroy(&object_find_instance_database, object_find_handle); -+ -+ objdb_rdunlock(); - return (0); -+ -+error_exit: -+ objdb_rdunlock(); -+ return (-1); - } - - static int object_key_get ( -@@ -739,6 +844,7 @@ - struct list_head *list; - int found = 0; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -@@ -766,9 +872,11 @@ - } - - hdb_handle_put (&object_instance_database, object_handle); -+ objdb_rdunlock(); - return (res); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -784,6 +892,7 @@ - struct list_head *list; - int found = 0; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -@@ -809,9 +918,11 @@ - } - - hdb_handle_put (&object_instance_database, object_handle); -+ objdb_rdunlock(); - return (res); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -827,6 +938,7 @@ - struct list_head *list; - int found = 0; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -@@ -852,9 +964,11 @@ - } - - hdb_handle_put (&object_instance_database, object_handle); -+ objdb_rdunlock(); - return (res); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -872,6 +986,7 @@ - struct list_head *list; - int found = 0; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -@@ -906,9 +1021,11 @@ - if (ret == 0) - object_key_changed_notification(object_handle, key_name, key_len, - value, value_len, OBJECT_KEY_DELETED); -+ objdb_rdunlock(); - return (ret); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -928,6 +1045,8 @@ - struct list_head *list; - int found = 0; - -+ objdb_rdlock(); -+ - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -@@ -950,6 +1069,7 @@ - - if (found) { - int i; -+ int found_validator = 0; - - /* - * Do validation check if validation is configured for the parent object -@@ -962,7 +1082,7 @@ - instance->object_key_valid_list[i].key_name, - key_len) == 0)) { - -- found = 1; -+ found_validator = 1; - break; - } - } -@@ -970,7 +1090,7 @@ - /* - * Item not found in validation list - */ -- if (found == 0) { -+ if (found_validator == 0) { - goto error_put; - } else { - if (instance->object_key_valid_list[i].validate_callback) { -@@ -983,7 +1103,7 @@ - } - } - -- if (new_value_len <= object_key->value_len) { -+ if (new_value_len != object_key->value_len) { - void *replacement_value; - replacement_value = malloc(new_value_len); - if (!replacement_value) -@@ -1003,11 +1123,13 @@ - if (ret == 0) - object_key_changed_notification(object_handle, key_name, key_len, - new_value, new_value_len, OBJECT_KEY_REPLACED); -+ objdb_rdunlock(); - return (ret); - - error_put: - hdb_handle_put (&object_instance_database, object_handle); - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -1018,6 +1140,7 @@ - int res; - struct object_instance *object_instance; - -+ objdb_rdunlock(); - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&object_instance); - if (res != 0) { -@@ -1027,9 +1150,11 @@ - *priv = object_instance->priv; - - hdb_handle_put (&object_instance_database, object_handle); -+ objdb_rdunlock(); - return (0); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -1092,6 +1217,8 @@ - unsigned int res; - struct object_instance *instance; - -+ objdb_rdlock(); -+ - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -@@ -1100,9 +1227,11 @@ - instance->iter_key_list = &instance->key_head; - - hdb_handle_put (&object_instance_database, object_handle); -+ objdb_rdunlock(); - return (0); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -1119,6 +1248,8 @@ - struct list_head *list; - unsigned int found = 0; - -+ objdb_rdlock(); -+ - res = hdb_handle_get (&object_instance_database, - parent_object_handle, (void *)&instance); - if (res != 0) { -@@ -1145,9 +1276,11 @@ - } - - hdb_handle_put (&object_instance_database, parent_object_handle); -+ objdb_rdunlock(); - return (res); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -1165,6 +1298,8 @@ - struct list_head *list; - unsigned int found = 0; - -+ objdb_rdlock(); -+ - res = hdb_handle_get (&object_instance_database, - parent_object_handle, (void *)&instance); - if (res != 0) { -@@ -1197,9 +1332,11 @@ - } - - hdb_handle_put (&object_instance_database, parent_object_handle); -+ objdb_rdunlock(); - return (res); - - error_exit: -+ objdb_rdunlock(); - return (-1); - } - -@@ -1210,9 +1347,12 @@ - struct object_instance *instance; - unsigned int res; - -+ objdb_rdlock(); -+ - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -+ objdb_rdunlock(); - return (res); - } - -@@ -1222,6 +1362,7 @@ - *parent_handle = instance->parent_handle; - - hdb_handle_put (&object_instance_database, object_handle); -+ objdb_rdunlock(); - - return (0); - } -@@ -1233,9 +1374,11 @@ - struct object_instance *instance; - unsigned int res; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -+ objdb_rdunlock(); - return (res); - } - -@@ -1243,6 +1386,7 @@ - *object_name_len = instance->object_name_len; - - hdb_handle_put (&object_instance_database, object_handle); -+ objdb_rdunlock(); - - return (0); - } -@@ -1253,6 +1397,7 @@ - object_key_change_notify_fn_t key_change_notify_fn, - object_create_notify_fn_t object_create_notify_fn, - object_destroy_notify_fn_t object_destroy_notify_fn, -+ object_reload_notify_fn_t object_reload_notify_fn, - void * priv_data_pt) - { - struct object_instance *instance; -@@ -1271,6 +1416,7 @@ - tracker_pt->key_change_notify_fn = key_change_notify_fn; - tracker_pt->object_create_notify_fn = object_create_notify_fn; - tracker_pt->object_destroy_notify_fn = object_destroy_notify_fn; -+ tracker_pt->object_reload_notify_fn = object_reload_notify_fn; - tracker_pt->data_pt = priv_data_pt; - - list_init(&tracker_pt->object_list); -@@ -1287,6 +1433,7 @@ - static void object_track_stop(object_key_change_notify_fn_t key_change_notify_fn, - object_create_notify_fn_t object_create_notify_fn, - object_destroy_notify_fn_t object_destroy_notify_fn, -+ object_reload_notify_fn_t object_reload_notify_fn, - void * priv_data_pt) - { - struct object_instance *instance; -@@ -1305,6 +1452,7 @@ - if (tracker_pt && (tracker_pt->data_pt == priv_data_pt) && - (tracker_pt->object_create_notify_fn == object_create_notify_fn) && - (tracker_pt->object_destroy_notify_fn == object_destroy_notify_fn) && -+ (tracker_pt->object_reload_notify_fn == object_reload_notify_fn) && - (tracker_pt->key_change_notify_fn == key_change_notify_fn)) { - - /* get the object & take this tracker off of it's list. */ -@@ -1337,9 +1485,11 @@ - struct object_instance *instance; - unsigned int res; - -+ objdb_rdlock(); - res = hdb_handle_get (&object_instance_database, - object_handle, (void *)&instance); - if (res != 0) { -+ objdb_rdunlock(); - return (res); - } - -@@ -1347,6 +1497,7 @@ - - hdb_handle_put (&object_instance_database, object_handle); - -+ objdb_rdunlock(); - return (res); - } - -@@ -1358,13 +1509,19 @@ - int res; - - main_get_config_modules(&modules, &num_modules); -+ -+ objdb_wrlock(); -+ - for (i=0; iconfig_writeconfig) { - res = modules[i]->config_writeconfig(&objdb_iface, error_string); -- if (res) -+ if (res) { -+ objdb_wrunlock(); - return res; -+ } - } - } -+ objdb_wrunlock(); - return 0; - } - -@@ -1376,14 +1533,22 @@ - int res; - - main_get_config_modules(&modules, &num_modules); -+ object_reload_notification(OBJDB_RELOAD_NOTIFY_START, flush); -+ -+ objdb_wrlock(); - - for (i=0; iconfig_reloadconfig) { - res = modules[i]->config_reloadconfig(&objdb_iface, flush, error_string); -- if (res) -+ if (res) { -+ object_reload_notification(OBJDB_RELOAD_NOTIFY_FAILED, flush); -+ objdb_wrunlock(); - return res; -+ } - } - } -+ objdb_wrunlock(); -+ object_reload_notification(OBJDB_RELOAD_NOTIFY_END, flush); - return 0; - } - -diff -Naurd corosync-0.92/exec/quorum.c corosync-trunk/exec/quorum.c ---- corosync-0.92/exec/quorum.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/exec/quorum.c 2008-12-09 14:48:47.000000000 +0100 -@@ -0,0 +1,115 @@ -+/* -+ * Copyright (c) 2008 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 "quorum.h" -+#include "main.h" -+#include "sync.h" -+#include "vsf.h" -+ -+LOGSYS_DECLARE_SUBSYS ("QUORUM", LOG_INFO); -+ -+ -+static struct quorum_callin_functions *corosync_quorum_fns = NULL; -+ -+int corosync_quorum_is_quorate (void) -+{ -+ if (corosync_quorum_fns) { -+ return corosync_quorum_fns->quorate(); -+ } -+ else { -+ return 1; -+ } -+} -+ -+int corosync_quorum_register_callback (quorum_callback_fn_t fn, void *context) -+{ -+ if (corosync_quorum_fns) { -+ return corosync_quorum_fns->register_callback(fn, context); -+ } -+ else { -+ return 0; -+ } -+} -+ -+int corosync_quorum_unregister_callback (quorum_callback_fn_t fn, void *context) -+{ -+ if (corosync_quorum_fns) { -+ return corosync_quorum_fns->unregister_callback(fn, context); -+ } -+ else { -+ return 0; -+ } -+} -+ -+int corosync_quorum_initialize (struct quorum_callin_functions *fns, -+ sync_callback_fn_t *sync_callback_fn) -+{ -+ if (corosync_quorum_fns) -+ return -1; -+ -+ corosync_quorum_fns = fns; -+ *sync_callback_fn = sync_primary_callback_fn; -+ return 0; -+} -+ -+int quorum_none(void) -+{ -+ if (corosync_quorum_fns) -+ return 0; -+ else -+ return 1; -+} -diff -Naurd corosync-0.92/exec/quorum.h corosync-trunk/exec/quorum.h ---- corosync-0.92/exec/quorum.h 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/exec/quorum.h 2008-12-08 16:55:41.000000000 +0100 -@@ -0,0 +1,68 @@ -+/* -+ * Copyright (c) 2008 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 Red Hat, 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 QUORUM_H_DEFINED -+#define QUORUM_H_DEFINED -+ -+struct memb_ring_id; -+ -+typedef void (*quorum_callback_fn_t) (int quorate, void *context); -+ -+typedef void (*sync_callback_fn_t) ( -+ unsigned int *view_list, -+ int view_list_entries, -+ int primary_designated, -+ struct memb_ring_id *ring_id); -+ -+struct quorum_callin_functions -+{ -+ int (*quorate) (void); -+ int (*register_callback) (quorum_callback_fn_t, void*); -+ int (*unregister_callback) (quorum_callback_fn_t, void*); -+}; -+ -+extern int corosync_quorum_is_quorate (void); -+ -+extern int corosync_quorum_register_callback (quorum_callback_fn_t fn, void *context); -+ -+extern int corosync_quorum_unregister_callback (quorum_callback_fn_t fn, void *context); -+ -+extern int corosync_quorum_initialize (struct quorum_callin_functions *fns, -+ sync_callback_fn_t *sync_callback_fn); -+ -+ -+extern int quorum_none(void); -+ -+ -+#endif /* QUORUM_H_DEFINED */ -diff -Naurd corosync-0.92/exec/service.c corosync-trunk/exec/service.c ---- corosync-0.92/exec/service.c 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/exec/service.c 2009-01-27 09:59:14.000000000 +0100 -@@ -78,6 +78,10 @@ - .name = "corosync_confdb", - .ver = 0, - }, -+ { -+ .name = "corosync_pload", -+ .ver = 0, -+ } - }; - - struct corosync_service_engine *ais_service[SERVICE_HANDLER_MAXIMUM_COUNT]; -diff -Naurd corosync-0.92/exec/sync.c corosync-trunk/exec/sync.c ---- corosync-0.92/exec/sync.c 2008-09-17 21:04:19.000000000 +0200 -+++ corosync-trunk/exec/sync.c 2008-12-08 16:55:41.000000000 +0100 -@@ -49,16 +49,17 @@ - #include - #include - --#include -+#include - #include - #include - #include - #include - #include -+#include "quorum.h" - - #include "main.h" - #include "sync.h" --#include "vsf.h" -+ - - LOGSYS_DECLARE_SUBSYS ("SYNC", LOG_INFO); - -@@ -72,8 +73,6 @@ - - static struct memb_ring_id *sync_ring_id; - --static int vsf_none = 0; -- - static int (*sync_callbacks_retrieve) (int sync_id, struct sync_callbacks *callack); - - static struct sync_callbacks sync_callbacks; -@@ -93,8 +92,6 @@ - - static struct barrier_data barrier_data_process[PROCESSOR_COUNT_MAX]; - --static struct corosync_vsf_iface_ver0 *vsf_iface; -- - static int sync_barrier_send (struct memb_ring_id *ring_id); - - static int sync_start_process (enum totem_callback_token_type type, void *data); -@@ -116,12 +113,6 @@ - unsigned int *joined_list, int joined_list_entries, - struct memb_ring_id *ring_id); - --static void sync_primary_callback_fn ( -- unsigned int *view_list, -- int view_list_entries, -- int primary_designated, -- struct memb_ring_id *ring_id); -- - static struct totempg_group sync_group = { - .group = "sync", - .group_len = 4 -@@ -266,13 +257,10 @@ - - int sync_register ( - int (*callbacks_retrieve) (int sync_id, struct sync_callbacks *callack), -- void (*synchronization_completed) (void), -- char *vsf_type) -+ void (*synchronization_completed) (void)) -+ - { - unsigned int res; -- unsigned int vsf_handle; -- void *vsf_iface_p; -- char corosync_vsf_type[1024]; - - res = totempg_groups_initialize ( - &sync_group_handle, -@@ -292,42 +280,13 @@ - log_printf (LOG_LEVEL_ERROR, "Couldn't join group.\n"); - return (-1); - } -- -- if (strcmp (vsf_type, "none") == 0) { -- log_printf (LOG_LEVEL_NOTICE, -- "Not using a virtual synchrony filter.\n"); -- vsf_none = 1; -- } else { -- vsf_none = 0; -- -- sprintf (corosync_vsf_type, "corosync_vsf_%s", vsf_type); -- res = lcr_ifact_reference ( -- &vsf_handle, -- corosync_vsf_type, -- 0, -- &vsf_iface_p, -- 0); -- -- if (res == -1) { -- log_printf (LOG_LEVEL_NOTICE, -- "Couldn't load virtual synchrony filter %s\n", -- vsf_type); -- return (-1); -- } -- -- log_printf (LOG_LEVEL_NOTICE, -- "Using virtual synchrony filter %s\n", corosync_vsf_type); -- -- vsf_iface = (struct corosync_vsf_iface_ver0 *)vsf_iface_p; -- vsf_iface->init (sync_primary_callback_fn); -- } - - sync_callbacks_retrieve = callbacks_retrieve; - sync_synchronization_completed = synchronization_completed; - return (0); - } - --static void sync_primary_callback_fn ( -+void sync_primary_callback_fn ( - unsigned int *view_list, - int view_list_entries, - int primary_designated, -@@ -335,13 +294,6 @@ - { - int i; - -- if (primary_designated) { -- log_printf (LOG_LEVEL_NOTICE, "This node is within the primary component and will provide service.\n"); -- } else { -- log_printf (LOG_LEVEL_NOTICE, "This node is within the non-primary component and will NOT provide any services.\n"); -- return; -- } -- - /* - * Execute configuration change for synchronization service - */ -@@ -521,7 +473,7 @@ - * If no virtual synchrony filter configured, then start - * synchronization process - */ -- if (vsf_none == 1) { -+ if (quorum_none() == 1) { - sync_primary_callback_fn ( - member_list, - member_list_entries, -@@ -546,7 +498,7 @@ - struct iovec iovec[2]; - int name_len; - -- ENTER("'%s'", name); -+ ENTER(); - - name_len = strlen (name) + 1; - msg.header.size = sizeof (msg) + name_len; -@@ -589,15 +541,6 @@ - return (sync_processing); - } - --int sync_primary_designated (void) --{ -- if (vsf_none == 1) { -- return (1); -- } else { -- return (vsf_iface->primary()); -- } --} -- - /** - * Execute synchronization upon request for the named service - * @param name -@@ -608,7 +551,7 @@ - { - assert (name != NULL); - -- ENTER("'%s'", name); -+ ENTER(); - - if (sync_processing) { - return -1; -@@ -618,7 +561,7 @@ - TOTEM_CALLBACK_TOKEN_SENT, 0, /* don't delete after callback */ - sync_request_send, name); - -- LEAVE(""); -+ LEAVE(); - - return 0; - } -diff -Naurd corosync-0.92/exec/sync.h corosync-trunk/exec/sync.h ---- corosync-0.92/exec/sync.h 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/exec/sync.h 2008-12-08 16:55:41.000000000 +0100 -@@ -47,10 +47,10 @@ - char *name; - }; - -+struct corosync_api_v1; - int sync_register ( - int (*sync_callbacks_retrieve) (int sync_id, struct sync_callbacks *callbacks), -- void (*synchronization_completed) (void), -- char *vsf_type); -+ void (*synchronization_completed) (void)); - - int sync_in_process (void); - -@@ -64,4 +64,11 @@ - */ - extern int sync_request (char *name); - -+extern void sync_primary_callback_fn ( -+ unsigned int *view_list, -+ int view_list_entries, -+ int primary_designated, -+ struct memb_ring_id *ring_id); -+ -+ - #endif /* SYNC_H_DEFINED */ -diff -Naurd corosync-0.92/exec/timer.c corosync-trunk/exec/timer.c ---- corosync-0.92/exec/timer.c 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/exec/timer.c 2008-11-06 22:49:07.000000000 +0100 -@@ -56,7 +56,7 @@ - #include - - #include --#include -+#include - #include - #include - #include -diff -Naurd corosync-0.92/exec/totemconfig.c corosync-trunk/exec/totemconfig.c ---- corosync-0.92/exec/totemconfig.c 2008-08-20 02:57:40.000000000 +0200 -+++ corosync-trunk/exec/totemconfig.c 2008-12-12 12:27:27.000000000 +0100 -@@ -76,6 +76,13 @@ - #define RRP_PROBLEM_COUNT_THRESHOLD_MIN 5 - - static char error_string_response[512]; -+static struct objdb_iface_ver0 *global_objdb; -+ -+static void add_totem_config_notification( -+ struct objdb_iface_ver0 *objdb, -+ struct totem_config *totem_config, -+ unsigned int totem_object_handle); -+ - - /* These just makes the code below a little neater */ - static inline int objdb_get_string ( -@@ -163,6 +170,50 @@ - return (0); - } - -+static void totem_volatile_config_read ( -+ struct objdb_iface_ver0 *objdb, -+ struct totem_config *totem_config, -+ unsigned int object_totem_handle) -+{ -+ objdb_get_int (objdb,object_totem_handle, "token", &totem_config->token_timeout); -+ -+ objdb_get_int (objdb,object_totem_handle, "token_retransmit", &totem_config->token_retransmit_timeout); -+ -+ objdb_get_int (objdb,object_totem_handle, "hold", &totem_config->token_hold_timeout); -+ -+ objdb_get_int (objdb,object_totem_handle, "token_retransmits_before_loss_const", &totem_config->token_retransmits_before_loss_const); -+ -+ objdb_get_int (objdb,object_totem_handle, "join", &totem_config->join_timeout); -+ objdb_get_int (objdb,object_totem_handle, "send_join", &totem_config->send_join_timeout); -+ -+ objdb_get_int (objdb,object_totem_handle, "consensus", &totem_config->consensus_timeout); -+ -+ objdb_get_int (objdb,object_totem_handle, "merge", &totem_config->merge_timeout); -+ -+ objdb_get_int (objdb,object_totem_handle, "downcheck", &totem_config->downcheck_timeout); -+ -+ objdb_get_int (objdb,object_totem_handle, "fail_recv_const", &totem_config->fail_to_recv_const); -+ -+ objdb_get_int (objdb,object_totem_handle, "seqno_unchanged_const", &totem_config->seqno_unchanged_const); -+ -+ objdb_get_int (objdb,object_totem_handle, "rrp_token_expired_timeout", &totem_config->rrp_token_expired_timeout); -+ -+ objdb_get_int (objdb,object_totem_handle, "rrp_problem_count_timeout", &totem_config->rrp_problem_count_timeout); -+ -+ objdb_get_int (objdb,object_totem_handle, "rrp_problem_count_threshold", &totem_config->rrp_problem_count_threshold); -+ -+ objdb_get_int (objdb,object_totem_handle, "heartbeat_failures_allowed", &totem_config->heartbeat_failures_allowed); -+ -+ objdb_get_int (objdb,object_totem_handle, "max_network_delay", &totem_config->max_network_delay); -+ -+ objdb_get_int (objdb,object_totem_handle, "window_size", &totem_config->window_size); -+ objdb_get_string (objdb, object_totem_handle, "vsftype", &totem_config->vsf_type); -+ -+ objdb_get_int (objdb,object_totem_handle, "max_messages", &totem_config->max_messages); -+ -+} -+ -+ - extern int totem_config_read ( - struct objdb_iface_ver0 *objdb, - struct totem_config *totem_config, -@@ -222,41 +273,10 @@ - - objdb_get_int (objdb,object_totem_handle, "netmtu", &totem_config->net_mtu); - -- objdb_get_int (objdb,object_totem_handle, "token", &totem_config->token_timeout); -- -- objdb_get_int (objdb,object_totem_handle, "token_retransmit", &totem_config->token_retransmit_timeout); -- -- objdb_get_int (objdb,object_totem_handle, "hold", &totem_config->token_hold_timeout); -- -- objdb_get_int (objdb,object_totem_handle, "token_retransmits_before_loss_const", &totem_config->token_retransmits_before_loss_const); -- -- objdb_get_int (objdb,object_totem_handle, "join", &totem_config->join_timeout); -- objdb_get_int (objdb,object_totem_handle, "send_join", &totem_config->send_join_timeout); -- -- objdb_get_int (objdb,object_totem_handle, "consensus", &totem_config->consensus_timeout); -- -- objdb_get_int (objdb,object_totem_handle, "merge", &totem_config->merge_timeout); -- -- objdb_get_int (objdb,object_totem_handle, "downcheck", &totem_config->downcheck_timeout); -- -- objdb_get_int (objdb,object_totem_handle, "fail_recv_const", &totem_config->fail_to_recv_const); -- -- objdb_get_int (objdb,object_totem_handle, "seqno_unchanged_const", &totem_config->seqno_unchanged_const); -- -- objdb_get_int (objdb,object_totem_handle, "rrp_token_expired_timeout", &totem_config->rrp_token_expired_timeout); -- -- objdb_get_int (objdb,object_totem_handle, "rrp_problem_count_timeout", &totem_config->rrp_problem_count_timeout); -- -- objdb_get_int (objdb,object_totem_handle, "rrp_problem_count_threshold", &totem_config->rrp_problem_count_threshold); -- -- objdb_get_int (objdb,object_totem_handle, "heartbeat_failures_allowed", &totem_config->heartbeat_failures_allowed); -- -- objdb_get_int (objdb,object_totem_handle, "max_network_delay", &totem_config->max_network_delay); -- -- objdb_get_int (objdb,object_totem_handle, "window_size", &totem_config->window_size); -- objdb_get_string (objdb, object_totem_handle, "vsftype", &totem_config->vsf_type); -- -- objdb_get_int (objdb,object_totem_handle, "max_messages", &totem_config->max_messages); -+ /* -+ * Get things that might change in the future -+ */ -+ totem_volatile_config_read (objdb, totem_config, object_totem_handle); - - objdb->object_find_create ( - object_totem_handle, -@@ -297,6 +317,8 @@ - - objdb->object_find_destroy (object_find_interface_handle); - -+ add_totem_config_notification(objdb, totem_config, object_totem_handle); -+ - return 0; - } - -@@ -323,7 +345,7 @@ - error_reason = "No multicast address specified"; - goto parse_error; - } -- -+ - if (totem_config->interfaces[i].ip_port == 0) { - error_reason = "No multicast port specified"; - goto parse_error; -@@ -331,7 +353,7 @@ - - if (totem_config->interfaces[i].mcast_addr.family == AF_INET6 && - totem_config->node_id == 0) { -- -+ - error_reason = "An IPV6 network requires that a node ID be specified."; - goto parse_error; - } -@@ -498,7 +520,7 @@ - totem_config->rrp_token_expired_timeout = - totem_config->token_retransmit_timeout; - } -- -+ - if (totem_config->rrp_token_expired_timeout < MINIMUM_TIMEOUT) { - sprintf (local_error_reason, "The RRP token expired timeout parameter (%d ms) may not be less then (%d ms).", - totem_config->rrp_token_expired_timeout, MINIMUM_TIMEOUT); -@@ -658,3 +680,92 @@ - return (-1); - - } -+ -+static void totem_key_change_notify(object_change_type_t change_type, -+ unsigned int parent_object_handle, -+ unsigned int object_handle, -+ void *object_name_pt, int object_name_len, -+ void *key_name_pt, int key_len, -+ void *key_value_pt, int key_value_len, -+ void *priv_data_pt) -+{ -+ struct totem_config *totem_config = priv_data_pt; -+ -+ if (memcmp(object_name_pt, "totem", object_name_len) == 0) -+ totem_volatile_config_read(global_objdb, -+ totem_config, -+ object_handle); // CHECK -+} -+ -+static void totem_objdb_reload_notify(objdb_reload_notify_type_t type, int flush, -+ void *priv_data_pt) -+{ -+ struct totem_config *totem_config = priv_data_pt; -+ unsigned int totem_object_handle; -+ -+ /* -+ * A new totem {} key might exist, cancel the -+ * existing notification at the start of reload, -+ * and start a new one on the new object when -+ * it's all settled. -+ */ -+ -+ if (type == OBJDB_RELOAD_NOTIFY_START) { -+ global_objdb->object_track_stop( -+ totem_key_change_notify, -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ } -+ -+ if (type == OBJDB_RELOAD_NOTIFY_END || -+ type == OBJDB_RELOAD_NOTIFY_FAILED) { -+ -+ -+ if (!totem_handle_find(global_objdb, -+ &totem_object_handle)) { -+ add_totem_config_notification(global_objdb, totem_config, totem_object_handle); -+ -+ /* -+ * Reload the configuration -+ */ -+ totem_volatile_config_read(global_objdb, -+ totem_config, -+ totem_object_handle); -+ -+ } -+ else { -+ log_printf(LOG_LEVEL_ERROR, "totem objdb tracking stopped, cannot find totem{} handle on objdb\n"); -+ } -+ } -+} -+ -+ -+static void add_totem_config_notification( -+ struct objdb_iface_ver0 *objdb, -+ struct totem_config *totem_config, -+ unsigned int totem_object_handle) -+{ -+ -+ global_objdb = objdb; -+ objdb->object_track_start(totem_object_handle, -+ 1, -+ totem_key_change_notify, -+ NULL, // object_create_notify, -+ NULL, // object_destroy_notify, -+ NULL, // object_reload_notify -+ totem_config); // priv_data -+ -+ /* -+ * Reload notify must be on the parent object -+ */ -+ objdb->object_track_start(OBJECT_PARENT_HANDLE, -+ 1, -+ NULL, // key_change_notify, -+ NULL, // object_create_notify, -+ NULL, // object_destroy_notify, -+ totem_objdb_reload_notify, // object_reload_notify -+ totem_config); // priv_data -+ -+} -diff -Naurd corosync-0.92/exec/totemconfig.h corosync-trunk/exec/totemconfig.h ---- corosync-0.92/exec/totemconfig.h 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/exec/totemconfig.h 2008-11-06 22:49:07.000000000 +0100 -@@ -36,7 +36,7 @@ - #define TOTEMCONFIG_H_DEFINED - - #include --#include -+#include - #include - #include - #include -diff -Naurd corosync-0.92/exec/totemip.c corosync-trunk/exec/totemip.c ---- corosync-0.92/exec/totemip.c 2008-09-16 17:35:09.000000000 +0200 -+++ corosync-trunk/exec/totemip.c 2009-01-26 21:46:45.000000000 +0100 -@@ -226,7 +226,7 @@ - sin->sin_len = sizeof(struct sockaddr_in); - #endif - sin->sin_family = ip_addr->family; -- sin->sin_port = port; -+ sin->sin_port = ntohs(port); - memcpy(&sin->sin_addr, ip_addr->addr, sizeof(struct in_addr)); - *addrlen = sizeof(struct sockaddr_in); - ret = 0; -@@ -240,7 +240,7 @@ - sin->sin6_len = sizeof(struct sockaddr_in6); - #endif - sin->sin6_family = ip_addr->family; -- sin->sin6_port = port; -+ sin->sin6_port = ntohs(port); - sin->sin6_scope_id = 2; - memcpy(&sin->sin6_addr, ip_addr->addr, sizeof(struct in6_addr)); - -@@ -376,7 +376,8 @@ - int totemip_iface_check(struct totem_ip_address *bindnet, - struct totem_ip_address *boundto, - int *interface_up, -- int *interface_num) -+ int *interface_num, -+ int mask_high_bit) - { - int fd; - struct { -@@ -472,7 +473,7 @@ - memcpy(&network, RTA_DATA(tb[IFA_BROADCAST]), sizeof(uint32_t)); - memcpy(&addr, bindnet->addr, sizeof(uint32_t)); - -- if (addr == (network & netmask)) { -+ if ((addr & netmask) == (network & netmask)) { - memcpy(ipaddr.addr, RTA_DATA(tb[IFA_ADDRESS]), TOTEMIP_ADDRLEN); - found_if = 1; - } -@@ -514,6 +515,18 @@ - } - } - finished: -+ /* -+ * Mask 32nd bit off to workaround bugs in other poeples code -+ * if configuration requests it. -+ */ -+ if (ipaddr.family == AF_INET && ipaddr.nodeid == 0) { -+ unsigned int nodeid = 0; -+ memcpy (&nodeid, ipaddr.addr, sizeof (int)); -+ if (mask_high_bit) { -+ nodeid &= 0x7FFFFFFF; -+ } -+ ipaddr.nodeid = nodeid; -+ } - totemip_copy (boundto, &ipaddr); - close(fd); - return 0; -diff -Naurd corosync-0.92/exec/totemmrp.c corosync-trunk/exec/totemmrp.c ---- corosync-0.92/exec/totemmrp.c 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/exec/totemmrp.c 2008-12-01 19:44:55.000000000 +0100 -@@ -192,7 +192,7 @@ - return (res); - } - --int totemmrp_my_nodeid_get (void) -+unsigned int totemmrp_my_nodeid_get (void) - { - return (totemsrp_my_nodeid_get (totemsrp_handle_in)); - } -diff -Naurd corosync-0.92/exec/totemnet.c corosync-trunk/exec/totemnet.c ---- corosync-0.92/exec/totemnet.c 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/exec/totemnet.c 2009-01-25 22:15:25.000000000 +0100 -@@ -137,7 +137,11 @@ - - int totemnet_log_level_debug; - -- void (*totemnet_log_printf) (char *file, int line, int level, char *format, ...) __attribute__((format(printf, 4, 5))); -+ int totemnet_subsys_id; -+ -+ void (*totemnet_log_printf) (int subsys, char *function, char *file, -+ int line, unsigned int level, char *format, -+ ...)__attribute__((format(printf, 6, 7))); - - totemnet_handle handle; - -@@ -226,8 +230,12 @@ - instance->my_memb_entries = 1; - } - --#define log_printf(level, format, args...) \ -- instance->totemnet_log_printf (__FILE__, __LINE__, level, format, ##args) -+#define log_printf(level, format, args...) \ -+do { \ -+ instance->totemnet_log_printf (instance->totemnet_subsys_id, \ -+ (char *)__FUNCTION__, __FILE__, __LINE__, level, \ -+ format, ##args); \ -+} while (0); - - static int authenticate_and_decrypt ( - struct totemnet_instance *instance, -@@ -691,18 +699,9 @@ - int res; - - res = totemip_iface_check (bindnet, bound_to, -- interface_up, interface_num); -+ interface_up, interface_num, -++ 0); // TODO andrew can address this instance->totem_config->clear_node_high_bit); - -- /* -- * If the desired binding is to an IPV4 network and nodeid isn't -- * specified, retrieve the node id from this_ip network address -- * -- * IPV6 networks must have a node ID specified since the node id -- * field is only 32 bits. -- */ -- if (bound_to->family == AF_INET && bound_to->nodeid == 0) { -- memcpy (&bound_to->nodeid, bound_to->addr, sizeof (int)); -- } - - return (res); - } -@@ -1192,6 +1191,7 @@ - instance->totemnet_log_level_warning = totem_config->totem_logging_configuration.log_level_warning; - instance->totemnet_log_level_notice = totem_config->totem_logging_configuration.log_level_notice; - instance->totemnet_log_level_debug = totem_config->totem_logging_configuration.log_level_debug; -+ instance->totemnet_subsys_id = totem_config->totem_logging_configuration.log_subsys_id; - instance->totemnet_log_printf = totem_config->totem_logging_configuration.log_printf; - - /* -diff -Naurd corosync-0.92/exec/totempg.c corosync-trunk/exec/totempg.c ---- corosync-0.92/exec/totempg.c 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/exec/totempg.c 2009-01-25 22:25:25.000000000 +0100 -@@ -153,7 +153,10 @@ - static int totempg_log_level_warning; - static int totempg_log_level_notice; - static int totempg_log_level_debug; --static void (*totempg_log_printf) (char *file, int line, int level, char *format, ...) __attribute__((format(printf, 4, 5))) = NULL; -+static int totempg_subsys_id; -+static void (*totempg_log_printf) (int subsys_id, char *function, char *file, -+ int line, unsigned int level, char *format, -+ ...) __attribute__((format(printf, 6, 7))); - - struct totem_config *totempg_totem_config; - -@@ -165,6 +168,13 @@ - struct list_head list; - }; - -+enum throw_away_mode_t { -+ THROW_AWAY_INACTIVE, -+ THROW_AWAY_ACTIVE -+}; -+ -+static enum throw_away_mode_t throw_away_mode = THROW_AWAY_INACTIVE; -+ - DECLARE_LIST_INIT(assembly_list_inuse); - - DECLARE_LIST_INIT(assembly_list_free); -@@ -225,8 +235,11 @@ - - static pthread_mutex_t mcast_msg_mutex = PTHREAD_MUTEX_INITIALIZER; - --#define log_printf(level, format, args...) \ -- totempg_log_printf (__FILE__, __LINE__, level, format, ##args) -+#define log_printf(level, format, args...) \ -+do { \ -+ totempg_log_printf (totempg_subsys_id, (char *)__FUNCTION__, \ -+ __FILE__, __LINE__, level, format, ##args); \ -+} while (0); - - static struct assembly *assembly_ref (unsigned int nodeid) - { -@@ -558,43 +571,32 @@ - * the continued message. - */ - start = 0; -- if (continuation) { - -- if (continuation != assembly->last_frag_num) { -- log_printf (totempg_log_level_error, -- "Message continuation doesn't match previous frag e: %u - a: %u\n", -- assembly->last_frag_num, continuation); -- continuation = 0; -- } -+ if (throw_away_mode == THROW_AWAY_ACTIVE) { -+ /* Throw away the first msg block */ -+ if (mcast->fragmented == 0 || mcast->fragmented == 1) { -+ throw_away_mode = THROW_AWAY_INACTIVE; - -- if ((assembly->index == 0) || -- (!continuation && assembly->index)) { -- log_printf (totempg_log_level_error, -- "Throwing away broken message: continuation %u, index %u\n", -- continuation, assembly->index); -- continuation = 0; -- } -- -- /* -- * we decided to throw away the first continued message -- * in this buffer, if continuation was set to zero. -- */ -- if (!continuation) { - assembly->index += msg_lens[0]; - iov_delv.iov_base = &assembly->data[assembly->index]; - iov_delv.iov_len = msg_lens[1]; - start = 1; - } -- -- } -- -- for (i = start; i < msg_count; i++) { -- app_deliver_fn(nodeid, &iov_delv, 1, -- endian_conversion_required); -- assembly->index += msg_lens[i]; -- iov_delv.iov_base = &assembly->data[assembly->index]; -- if (i < (msg_count - 1)) { -- iov_delv.iov_len = msg_lens[i + 1]; -+ } else -+ if (throw_away_mode == THROW_AWAY_INACTIVE) { -+ if (continuation == assembly->last_frag_num) { -+ assembly->last_frag_num = mcast->fragmented; -+ for (i = start; i < msg_count; i++) { -+ app_deliver_fn(nodeid, &iov_delv, 1, -+ endian_conversion_required); -+ assembly->index += msg_lens[i]; -+ iov_delv.iov_base = &assembly->data[assembly->index]; -+ if (i < (msg_count - 1)) { -+ iov_delv.iov_len = msg_lens[i + 1]; -+ } -+ } -+ } else { -+ throw_away_mode = THROW_AWAY_ACTIVE; - } - } - -@@ -609,7 +611,6 @@ - /* - * Message is fragmented, keep around assembly list - */ -- assembly->last_frag_num = mcast->fragmented; - if (mcast->msg_count > 1) { - memmove (&assembly->data[0], - &assembly->data[assembly->index], -@@ -686,6 +687,7 @@ - totempg_log_level_notice = totem_config->totem_logging_configuration.log_level_notice; - totempg_log_level_debug = totem_config->totem_logging_configuration.log_level_debug; - totempg_log_printf = totem_config->totem_logging_configuration.log_printf; -+ totempg_subsys_id = totem_config->totem_logging_configuration.log_subsys_id; - - fragmentation_data = malloc (TOTEMPG_PACKET_SIZE); - if (fragmentation_data == 0) { -@@ -721,14 +723,16 @@ - * Multicast a message - */ - static int mcast_msg ( -- struct iovec *iovec, -+ struct iovec *iovec_in, - int iov_len, - int guarantee) - { - int res = 0; - struct totempg_mcast mcast; - struct iovec iovecs[3]; -+ struct iovec iovec[64]; - int i; -+ int dest, src; - int max_packet_size = 0; - int copy_len = 0; - int copy_base = 0; -@@ -737,6 +741,18 @@ - pthread_mutex_lock (&mcast_msg_mutex); - totemmrp_new_msg_signal (); - -+ /* -+ * Remove zero length iovectors from the list -+ */ -+ assert (iov_len < 64); -+ for (dest = 0, src = 0; src < iov_len; src++) { -+ if (iovec_in[src].iov_len) { -+ memcpy (&iovec[dest++], &iovec_in[src], -+ sizeof (struct iovec)); -+ } -+ } -+ iov_len = dest; -+ - max_packet_size = TOTEMPG_PACKET_SIZE - - (sizeof (unsigned short) * (mcast_packed_msg_count + 1)); - -@@ -774,6 +790,7 @@ - iovec[i].iov_base + copy_base, copy_len); - fragment_size += copy_len; - mcast_packed_msg_lens[mcast_packed_msg_count] += copy_len; -+ next_fragment = 1; - copy_len = 0; - copy_base = 0; - i++; -@@ -1243,7 +1260,7 @@ - return (iface_string); - } - --int totempg_my_nodeid_get (void) -+unsigned int totempg_my_nodeid_get (void) - { - return (totemmrp_my_nodeid_get()); - } -diff -Naurd corosync-0.92/exec/totemrrp.c corosync-trunk/exec/totemrrp.c ---- corosync-0.92/exec/totemrrp.c 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/exec/totemrrp.c 2008-10-30 23:25:56.000000000 +0100 -@@ -194,7 +194,11 @@ - - int totemrrp_log_level_debug; - -- void (*totemrrp_log_printf) (char *file, int line, int level, char *format, ...) __attribute__((format(printf, 4, 5))); -+ int totemrrp_subsys_id; -+ -+ void (*totemrrp_log_printf) (int subsys, char *function, char *file, -+ int line, unsigned int level, char *format, -+ ...)__attribute__((format(printf, 6, 7))); - - totemrrp_handle handle; - -@@ -459,8 +463,14 @@ - .mutex = PTHREAD_MUTEX_INITIALIZER - }; - --#define log_printf(level, format, args...) \ -- rrp_instance->totemrrp_log_printf (__FILE__, __LINE__, level, format, ##args) -+ -+#define log_printf(level, format, args...) \ -+do { \ -+ rrp_instance->totemrrp_log_printf ( \ -+ rrp_instance->totemrrp_subsys_id, \ -+ (char *)__FUNCTION__, __FILE__, __LINE__, level, \ -+ format, ##args); \ -+} while (0); - - /* - * None Replication Implementation -@@ -1426,6 +1436,7 @@ - instance->totemrrp_log_level_warning = totem_config->totem_logging_configuration.log_level_warning; - instance->totemrrp_log_level_notice = totem_config->totem_logging_configuration.log_level_notice; - instance->totemrrp_log_level_debug = totem_config->totem_logging_configuration.log_level_debug; -+ instance->totemrrp_subsys_id = totem_config->totem_logging_configuration.log_subsys_id; - instance->totemrrp_log_printf = totem_config->totem_logging_configuration.log_printf; - - instance->interfaces = totem_config->interfaces; -diff -Naurd corosync-0.92/exec/totemsrp.c corosync-trunk/exec/totemsrp.c ---- corosync-0.92/exec/totemsrp.c 2008-08-20 03:07:29.000000000 +0200 -+++ corosync-trunk/exec/totemsrp.c 2009-01-20 18:41:45.000000000 +0100 -@@ -429,7 +429,11 @@ - - int totemsrp_log_level_debug; - -- void (*totemsrp_log_printf) (char *file, int line, int level, char *format, ...) __attribute__((format(printf, 4, 5))); -+ int totemsrp_subsys_id; -+ -+ void (*totemsrp_log_printf) (int subsys, char *function, char *file, -+ int line, unsigned int level, char *format, -+ ...)__attribute__((format(printf, 6, 7)));; - - enum memb_state memb_state; - -@@ -607,8 +611,12 @@ - - static char *rundir = NULL; - --#define log_printf(level, format, args...) \ -- instance->totemsrp_log_printf (__FILE__, __LINE__, level, format, ##args) -+#define log_printf(level, format, args...) \ -+do { \ -+ instance->totemsrp_log_printf (instance->totemsrp_subsys_id, \ -+ (char *)__FUNCTION__, __FILE__, __LINE__, level, \ -+ format, ##args); \ -+} while (0); - - void totemsrp_instance_initialize (struct totemsrp_instance *instance) - { -@@ -618,7 +626,7 @@ - - list_init (&instance->token_callback_sent_listhead); - -- instance->my_received_flg = 0; -+ instance->my_received_flg = 1; - - instance->my_token_seq = SEQNO_START_TOKEN - 1; - -@@ -709,6 +717,7 @@ - instance->totemsrp_log_level_warning = totem_config->totem_logging_configuration.log_level_warning; - instance->totemsrp_log_level_notice = totem_config->totem_logging_configuration.log_level_notice; - instance->totemsrp_log_level_debug = totem_config->totem_logging_configuration.log_level_debug; -+ instance->totemsrp_subsys_id = totem_config->totem_logging_configuration.log_subsys_id; - instance->totemsrp_log_printf = totem_config->totem_logging_configuration.log_printf; - - /* -@@ -904,11 +913,11 @@ - return (res); - } - --int totemsrp_my_nodeid_get ( -+unsigned int totemsrp_my_nodeid_get ( - totemsrp_handle handle) - { - struct totemsrp_instance *instance; -- int res; -+ unsigned int res; - - res = hdb_handle_get (&totemsrp_instance_database, handle, - (void *)&instance); -@@ -1686,7 +1695,7 @@ - "entering OPERATIONAL state.\n"); - instance->memb_state = MEMB_STATE_OPERATIONAL; - -- instance->my_received_flg = 0; -+ instance->my_received_flg = 1; - - return; - } -@@ -2634,6 +2643,8 @@ - { - struct srp_addr *addr; - struct memb_commit_token_memb_entry *memb_list; -+ unsigned int high_aru; -+ unsigned int i; - - addr = (struct srp_addr *)commit_token->end_of_commit_token; - memb_list = (struct memb_commit_token_memb_entry *)(addr + commit_token->addr_entries); -@@ -2655,9 +2666,40 @@ - instance->my_received_flg = - (instance->my_aru == instance->my_high_seq_received); - -- memb_list[commit_token->memb_index].high_delivered = instance->my_high_delivered; - memb_list[commit_token->memb_index].received_flg = instance->my_received_flg; - -+ memb_list[commit_token->memb_index].high_delivered = instance->my_high_delivered; -+ /* -+ * find high aru up to current memb_index for all matching ring ids -+ * if any ring id matching memb_index has aru less then high aru set -+ * received flag for that entry to false -+ */ -+ high_aru = memb_list[commit_token->memb_index].aru; -+ for (i = 0; i <= commit_token->memb_index; i++) { -+ if (memcmp (&memb_list[commit_token->memb_index].ring_id, -+ &memb_list[i].ring_id, -+ sizeof (struct memb_ring_id)) == 0) { -+ -+ if (sq_lt_compare (high_aru, memb_list[i].aru)) { -+ high_aru = memb_list[i].aru; -+ } -+ } -+ } -+ -+ for (i = 0; i <= commit_token->memb_index; i++) { -+ if (memcmp (&memb_list[commit_token->memb_index].ring_id, -+ &memb_list[i].ring_id, -+ sizeof (struct memb_ring_id)) == 0) { -+ -+ if (sq_lt_compare (memb_list[i].aru, high_aru)) { -+ memb_list[i].received_flg = 0; -+ if (i == commit_token->memb_index) { -+ instance->my_received_flg = 0; -+ } -+ } -+ } -+ } -+ - commit_token->header.nodeid = instance->my_id.addr[0].nodeid; - commit_token->memb_index += 1; - assert (commit_token->memb_index <= commit_token->addr_entries); -@@ -2944,6 +2986,8 @@ - goto error_exit; - } - -+ token_hold_cancel_send (instance); -+ - callback_handle = (struct token_callback_instance *)malloc (sizeof (struct token_callback_instance)); - if (callback_handle == 0) { - return (-1); -diff -Naurd corosync-0.92/exec/totemsrp.h corosync-trunk/exec/totemsrp.h ---- corosync-0.92/exec/totemsrp.h 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/exec/totemsrp.h 2008-12-01 19:44:55.000000000 +0100 -@@ -104,7 +104,7 @@ - char ***status, - unsigned int *iface_count); - --extern int totemsrp_my_nodeid_get ( -+extern unsigned int totemsrp_my_nodeid_get ( - totemsrp_handle handle); - - extern int totemsrp_my_family_get ( -diff -Naurd corosync-0.92/exec/util.c corosync-trunk/exec/util.c ---- corosync-0.92/exec/util.c 2008-09-17 21:04:19.000000000 +0200 -+++ corosync-trunk/exec/util.c 2008-12-18 09:28:46.000000000 +0100 -@@ -39,7 +39,7 @@ - #include - #include - --#include -+#include - #include - #include - #include "util.h" -@@ -49,7 +49,7 @@ - /* - * Compare two names. returns non-zero on match. - */ --int name_match(SaNameT *name1, SaNameT *name2) -+int name_match(cs_name_t *name1, cs_name_t *name2) - { - if (name1->length == name2->length) { - return ((strncmp ((char *)name1->value, (char *)name2->value, -@@ -61,17 +61,17 @@ - /* - * Get the time of day and convert to nanoseconds - */ --SaTimeT clust_time_now(void) -+cs_time_t clust_time_now(void) - { - struct timeval tv; -- SaTimeT time_now; -+ cs_time_t time_now; - - if (gettimeofday(&tv, 0)) { - return 0ULL; - } - -- time_now = (SaTimeT)(tv.tv_sec) * 1000000000ULL; -- time_now += (SaTimeT)(tv.tv_usec) * 1000ULL; -+ time_now = (cs_time_t)(tv.tv_sec) * 1000000000ULL; -+ time_now += (cs_time_t)(tv.tv_usec) * 1000ULL; - - return time_now; - } -@@ -87,20 +87,19 @@ - { - log_printf (LOG_LEVEL_ERROR, "AIS Executive exiting " - "with status %d at %s:%u.\n", err, file, line); -- logsys_flush(); -- exit (EXIT_FAILURE); -+ exit (err); - } - - #define min(a,b) ((a) < (b) ? (a) : (b)) - --char *getSaNameT (SaNameT *name) -+char *getcs_name_t (cs_name_t *name) - { -- static char ret_name[SA_MAX_NAME_LENGTH]; -+ static char ret_name[CS_MAX_NAME_LENGTH]; - - /* if string is corrupt (non-terminated), ensure it's displayed safely */ -- if (name->length >= SA_MAX_NAME_LENGTH || name->value[name->length] != '\0') { -+ if (name->length >= CS_MAX_NAME_LENGTH || name->value[name->length] != '\0') { - memset (ret_name, 0, sizeof (ret_name)); -- memcpy (ret_name, name->value, min(name->length, SA_MAX_NAME_LENGTH -1)); -+ memcpy (ret_name, name->value, min(name->length, CS_MAX_NAME_LENGTH -1)); - return (ret_name); - } - return ((char *)name->value); -@@ -134,16 +133,16 @@ - return (end_address); - } - --void setSaNameT (SaNameT *name, char *str) { -- strncpy ((char *)name->value, str, SA_MAX_NAME_LENGTH); -- if (strlen ((char *)name->value) > SA_MAX_NAME_LENGTH) { -- name->length = SA_MAX_NAME_LENGTH; -+void setcs_name_t (cs_name_t *name, char *str) { -+ strncpy ((char *)name->value, str, CS_MAX_NAME_LENGTH); -+ if (strlen ((char *)name->value) > CS_MAX_NAME_LENGTH) { -+ name->length = CS_MAX_NAME_LENGTH; - } else { - name->length = strlen (str); - } - } - --int SaNameTisEqual (SaNameT *str1, char *str2) { -+int cs_name_tisEqual (cs_name_t *str1, char *str2) { - if (str1->length == strlen (str2)) { - return ((strncmp ((char *)str1->value, (char *)str2, - str1->length)) == 0); -diff -Naurd corosync-0.92/exec/util.h corosync-trunk/exec/util.h ---- corosync-0.92/exec/util.h 2008-09-17 21:04:19.000000000 +0200 -+++ corosync-trunk/exec/util.h 2008-11-06 22:49:07.000000000 +0100 -@@ -37,12 +37,12 @@ - - #include - #include --#include -+#include - - /* - * Get the time of day and convert to nanoseconds - */ --extern SaTimeT clust_time_now(void); -+extern cs_time_t clust_time_now(void); - - enum e_ais_done { - AIS_DONE_EXIT = -1, -@@ -66,15 +66,15 @@ - /* - * Compare two names. returns non-zero on match. - */ --extern int name_match(SaNameT *name1, SaNameT *name2); -+extern int name_match(cs_name_t *name1, cs_name_t *name2); - extern int mar_name_match(mar_name_t *name1, mar_name_t *name2); - #define corosync_exit_error(err) _corosync_exit_error ((err), __FILE__, __LINE__) - extern void _corosync_exit_error ( - enum e_ais_done err, const char *file, unsigned int line); - void _corosync_out_of_memory_error (void); --extern char *getSaNameT (SaNameT *name); -+extern char *getcs_name_t (cs_name_t *name); - extern char *strstr_rs (const char *haystack, const char *needle); --extern void setSaNameT (SaNameT *name, char *str); -+extern void setcs_name_t (cs_name_t *name, char *str); - char *get_mar_name_t (mar_name_t *name); --extern int SaNameTisEqual (SaNameT *str1, char *str2); -+extern int cs_name_tisEqual (cs_name_t *str1, char *str2); - #endif /* UTIL_H_DEFINED */ -diff -Naurd corosync-0.92/exec/vsf.h corosync-trunk/exec/vsf.h ---- corosync-0.92/exec/vsf.h 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/exec/vsf.h 2008-12-08 16:55:41.000000000 +0100 -@@ -34,12 +34,14 @@ - #ifndef VSF_H_DEFINED - #define VSF_H_DEFINED - -+struct corosync_api_v1; - struct corosync_vsf_iface_ver0 { - - /* - * Executes a callback whenever component changes - */ - int (*init) ( -+ struct corosync_api_v1 *api, - void (*primary_callback_fn) ( - unsigned int *view_list, - int view_list_entries, -diff -Naurd corosync-0.92/exec/vsf_quorum.c corosync-trunk/exec/vsf_quorum.c ---- corosync-0.92/exec/vsf_quorum.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/exec/vsf_quorum.c 2009-01-08 12:12:10.000000000 +0100 -@@ -0,0 +1,468 @@ -+/* -+ * Copyright (c) 2008 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 Red Hat 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+LOGSYS_DECLARE_SUBSYS ("QUORUM", LOG_INFO); -+ -+struct quorum_pd { -+ unsigned char track_flags; -+ int tracking_enabled; -+ struct list_head list; -+ void *conn; -+}; -+ -+struct internal_callback_pd { -+ struct list_head list; -+ quorum_callback_fn_t callback; -+ void *context; -+}; -+ -+static void message_handler_req_lib_quorum_getquorate (void *conn, void *msg); -+static void message_handler_req_lib_quorum_trackstart (void *conn, void *msg); -+static void message_handler_req_lib_quorum_trackstop (void *conn, void *msg); -+static void send_library_notification(void *conn); -+static void send_internal_notification(void); -+static int quorum_exec_init_fn (struct corosync_api_v1 *api); -+static int quorum_lib_init_fn (void *conn); -+static int quorum_lib_exit_fn (void *conn); -+ -+static int primary_designated = 0; -+static struct corosync_api_v1 *corosync_api; -+static struct list_head lib_trackers_list; -+static struct list_head internal_trackers_list; -+static struct memb_ring_id quorum_ring_id; -+static int quorum_view_list_entries = 0; -+static int quorum_view_list[PROCESSOR_COUNT_MAX]; -+struct quorum_services_api_ver1 *quorum_iface = NULL; -+ -+static void (*sync_primary_callback_fn) ( -+ unsigned int *view_list, -+ int view_list_entries, -+ int primary_designated, -+ struct memb_ring_id *ring_id); -+ -+/* Internal quorum API function */ -+static void quorum_api_set_quorum(unsigned int *view_list, -+ int view_list_entries, -+ int quorum, struct memb_ring_id *ring_id) -+{ -+ primary_designated = quorum; -+ -+ if (primary_designated) { -+ log_printf (LOG_LEVEL_NOTICE, "This node is within the primary component and will provide service.\n"); -+ } else { -+ log_printf (LOG_LEVEL_NOTICE, "This node is within the non-primary component and will NOT provide any services.\n"); -+ } -+ -+ memcpy(&quorum_ring_id, ring_id, sizeof (quorum_ring_id)); -+ -+ quorum_view_list_entries = view_list_entries; -+ memcpy(quorum_view_list, view_list, sizeof(unsigned int)*view_list_entries); -+ -+ /* Tell sync() */ -+ sync_primary_callback_fn(view_list, view_list_entries, -+ primary_designated, &quorum_ring_id); -+ -+ /* Tell internal listeners */ -+ send_internal_notification(); -+ -+ /* Tell IPC listeners */ -+ send_library_notification(NULL); -+} -+ -+static struct corosync_lib_handler quorum_lib_service[] = -+{ -+ { /* 0 */ -+ .lib_handler_fn = message_handler_req_lib_quorum_getquorate, -+ .response_size = sizeof (struct res_lib_quorum_getquorate), -+ .response_id = MESSAGE_RES_QUORUM_GETQUORATE, -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 1 */ -+ .lib_handler_fn = message_handler_req_lib_quorum_trackstart, -+ .response_size = sizeof (mar_res_header_t), -+ .response_id = MESSAGE_RES_QUORUM_NOTIFICATION, -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 2 */ -+ .lib_handler_fn = message_handler_req_lib_quorum_trackstop, -+ .response_size = sizeof (mar_res_header_t), -+ .response_id = MESSAGE_RES_QUORUM_TRACKSTOP, -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED -+ } -+}; -+ -+static struct corosync_service_engine quorum_service_handler = { -+ .name = "corosync cluster quorum service v0.1", -+ .id = QUORUM_SERVICE, -+ .private_data_size = sizeof (struct quorum_pd), -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED, -+ .allow_inquorate = CS_LIB_ALLOW_INQUORATE, -+ .lib_init_fn = quorum_lib_init_fn, -+ .lib_exit_fn = quorum_lib_exit_fn, -+ .lib_engine = quorum_lib_service, -+ .exec_init_fn = quorum_exec_init_fn, -+ .lib_engine_count = sizeof (quorum_lib_service) / sizeof (struct corosync_lib_handler), -+}; -+ -+static struct lcr_iface corosync_quorum_ver0[1] = { -+ { -+ .name = "corosync_quorum", -+ .version = 0, -+ .versions_replace = 0, -+ .versions_replace_count = 0, -+ .dependencies = 0, -+ .dependency_count = 0, -+ .constructor = NULL, -+ .destructor = NULL, -+ .interfaces = NULL, -+ }, -+}; -+ -+static struct corosync_service_engine *quorum_get_service_handler_ver0 (void) -+{ -+ return (&quorum_service_handler); -+} -+ -+static struct lcr_comp quorum_comp_ver0 = { -+ .iface_count = 1, -+ .ifaces = corosync_quorum_ver0 -+}; -+ -+static struct corosync_service_engine_iface_ver0 quorum_service_handler_iface = { -+ .corosync_get_service_engine_ver0 = quorum_get_service_handler_ver0 -+}; -+ -+__attribute__ ((constructor)) static void quorum_comp_register (void) { -+ lcr_component_register (&quorum_comp_ver0); -+ lcr_interfaces_set (&corosync_quorum_ver0[0], &quorum_service_handler_iface); -+} -+ -+/* -------------------------------------------------- */ -+ -+ -+/* -+ * Internal API functions for corosync -+ */ -+ -+static int quorum_quorate(void) -+{ -+ return primary_designated; -+} -+ -+ -+static int quorum_register_callback(quorum_callback_fn_t function, void *context) -+{ -+ struct internal_callback_pd *pd = malloc(sizeof(struct internal_callback_pd)); -+ if (!pd) -+ return -1; -+ -+ pd->context = context; -+ pd->callback = function; -+ list_add (&pd->list, &internal_trackers_list); -+ -+ return 0; -+} -+ -+static int quorum_unregister_callback(quorum_callback_fn_t function, void *context) -+{ -+ struct internal_callback_pd *pd; -+ struct list_head *tmp; -+ -+ for (tmp = internal_trackers_list.next; tmp != &internal_trackers_list; tmp = tmp->next) { -+ -+ pd = list_entry(tmp, struct internal_callback_pd, list); -+ if (pd->callback == function && pd->context == context) { -+ list_del(&pd->list); -+ return 0; -+ } -+ } -+ return -1; -+} -+ -+static struct quorum_callin_functions callins = { -+ .quorate = quorum_quorate, -+ .register_callback = quorum_register_callback, -+ .unregister_callback = quorum_unregister_callback -+}; -+ -+/* --------------------------------------------------------------------- */ -+ -+static int quorum_exec_init_fn (struct corosync_api_v1 *api) -+{ -+ unsigned int find_handle; -+ unsigned int quorum_handle = 0; -+ unsigned int q_handle; -+ char *quorum_module; -+ int res; -+ void *quorum_iface_p; -+ -+ corosync_api = api; -+ list_init (&lib_trackers_list); -+ list_init (&internal_trackers_list); -+ -+ /* -+ * Tell corosync we have a quorum engine. -+ */ -+ api->quorum_initialize(&callins, &sync_primary_callback_fn); -+ -+ /* -+ * Look for a quorum provider -+ */ -+ api->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle); -+ api->object_find_next(find_handle, &quorum_handle); -+ api->object_find_destroy(find_handle); -+ -+ if (quorum_handle) { -+ if ( !(res = api->object_key_get(quorum_handle, -+ "provider", -+ strlen("provider"), -+ (void *)&quorum_module, -+ NULL))) { -+ -+ res = lcr_ifact_reference ( -+ &q_handle, -+ quorum_module, -+ 0, -+ &quorum_iface_p, -+ 0); -+ -+ if (res == -1) { -+ log_printf (LOG_LEVEL_NOTICE, -+ "Couldn't load quorum provider %s\n", -+ quorum_module); -+ return (-1); -+ } -+ -+ log_printf (LOG_LEVEL_NOTICE, -+ "Using quorum provider %s\n", quorum_module); -+ -+ quorum_iface = (struct quorum_services_api_ver1 *)quorum_iface_p; -+ quorum_iface->init (api, quorum_api_set_quorum); -+ } -+ } -+ if (!quorum_iface) { -+ /* -+ * With no quorum provider, we are always quorate -+ */ -+ primary_designated = 1; -+ } -+ -+ return (0); -+} -+ -+static int quorum_lib_init_fn (void *conn) -+{ -+ struct quorum_pd *pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); -+ -+ log_printf(LOG_LEVEL_DEBUG, "lib_init_fn: conn=%p\n", conn); -+ -+ list_init (&pd->list); -+ pd->conn = conn; -+ -+ return (0); -+} -+ -+static int quorum_lib_exit_fn (void *conn) -+{ -+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); -+ -+ log_printf(LOG_LEVEL_DEBUG, "lib_exit_fn: conn=%p\n", conn); -+ -+ if (quorum_pd->tracking_enabled) { -+ list_del (&quorum_pd->list); -+ list_init (&quorum_pd->list); -+ } -+ return (0); -+} -+ -+ -+static void send_internal_notification(void) -+{ -+ struct list_head *tmp; -+ struct internal_callback_pd *pd; -+ -+ for (tmp = internal_trackers_list.next; tmp != &internal_trackers_list; tmp = tmp->next) { -+ -+ pd = list_entry(tmp, struct internal_callback_pd, list); -+ -+ pd->callback(primary_designated, pd->context); -+ } -+} -+ -+static void send_library_notification(void *conn) -+{ -+ int size = sizeof(struct res_lib_quorum_notification) + sizeof(unsigned int)*quorum_view_list_entries; -+ char buf[size]; -+ struct res_lib_quorum_notification *res_lib_quorum_notification = (struct res_lib_quorum_notification *)buf; -+ struct list_head *tmp; -+ int i; -+ -+ log_printf(LOG_LEVEL_DEBUG, "sending quorum notification to %p, length = %d\n", conn, size); -+ -+ res_lib_quorum_notification->quorate = primary_designated; -+ res_lib_quorum_notification->ring_seq = quorum_ring_id.seq; -+ res_lib_quorum_notification->view_list_entries = quorum_view_list_entries; -+ for (i=0; iview_list[i] = quorum_view_list[i]; -+ } -+ -+ res_lib_quorum_notification->header.id = MESSAGE_RES_QUORUM_NOTIFICATION; -+ res_lib_quorum_notification->header.size = size; -+ res_lib_quorum_notification->header.error = CS_OK; -+ -+ /* Send it to all interested parties */ -+ if (conn) { -+ corosync_api->ipc_conn_send_response(conn, res_lib_quorum_notification, size); -+ } -+ else { -+ struct quorum_pd *qpd; -+ -+ for (tmp = lib_trackers_list.next; tmp != &lib_trackers_list; tmp = tmp->next) { -+ -+ qpd = list_entry(tmp, struct quorum_pd, list); -+ -+ corosync_api->ipc_conn_send_response(corosync_api->ipc_conn_partner_get(qpd->conn), -+ res_lib_quorum_notification, size); -+ } -+ } -+ return; -+} -+ -+static void message_handler_req_lib_quorum_getquorate (void *conn, void *msg) -+{ -+ struct res_lib_quorum_getquorate res_lib_quorum_getquorate; -+ -+ log_printf(LOG_LEVEL_DEBUG, "got quorate request on %p\n", conn); -+ -+ /* send status */ -+ res_lib_quorum_getquorate.quorate = primary_designated; -+ res_lib_quorum_getquorate.header.size = sizeof(res_lib_quorum_getquorate); -+ res_lib_quorum_getquorate.header.id = MESSAGE_RES_QUORUM_GETQUORATE; -+ res_lib_quorum_getquorate.header.error = CS_OK; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_quorum_getquorate, sizeof(res_lib_quorum_getquorate)); -+} -+ -+ -+static void message_handler_req_lib_quorum_trackstart (void *conn, void *msg) -+{ -+ struct req_lib_quorum_trackstart *req_lib_quorum_trackstart = (struct req_lib_quorum_trackstart *)msg; -+ mar_res_header_t res; -+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); -+ -+ log_printf(LOG_LEVEL_DEBUG, "got trackstart request on %p\n", conn); -+ -+ /* -+ * If an immediate listing of the current cluster membership -+ * is requested, generate membership list -+ */ -+ if (req_lib_quorum_trackstart->track_flags & CS_TRACK_CURRENT || -+ req_lib_quorum_trackstart->track_flags & CS_TRACK_CHANGES) { -+ log_printf(LOG_LEVEL_DEBUG, "sending initial status to %p\n", conn); -+ send_library_notification(corosync_api->ipc_conn_partner_get (conn)); -+ } -+ -+ /* -+ * Record requests for tracking -+ */ -+ if (req_lib_quorum_trackstart->track_flags & CS_TRACK_CHANGES || -+ req_lib_quorum_trackstart->track_flags & CS_TRACK_CHANGES_ONLY) { -+ -+ quorum_pd->track_flags = req_lib_quorum_trackstart->track_flags; -+ quorum_pd->tracking_enabled = 1; -+ -+ list_add (&quorum_pd->list, &lib_trackers_list); -+ } -+ -+ /* send status */ -+ res.size = sizeof(res); -+ res.id = MESSAGE_RES_QUORUM_TRACKSTART; -+ res.error = CS_OK; -+ corosync_api->ipc_conn_send_response(conn, &res, sizeof(mar_res_header_t)); -+} -+ -+static void message_handler_req_lib_quorum_trackstop (void *conn, void *msg) -+{ -+ mar_res_header_t res; -+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); -+ -+ log_printf(LOG_LEVEL_DEBUG, "got trackstop request on %p\n", conn); -+ -+ if (quorum_pd->tracking_enabled) { -+ res.error = CS_OK; -+ quorum_pd->tracking_enabled = 0; -+ list_del (&quorum_pd->list); -+ list_init (&quorum_pd->list); -+ } else { -+ res.error = CS_ERR_NOT_EXIST; -+ } -+ -+ /* send status */ -+ res.size = sizeof(res); -+ res.id = MESSAGE_RES_QUORUM_TRACKSTOP; -+ res.error = CS_OK; -+ corosync_api->ipc_conn_send_response(conn, &res, sizeof(mar_res_header_t)); -+} -+ -diff -Naurd corosync-0.92/exec/vsf_ykd.c corosync-trunk/exec/vsf_ykd.c ---- corosync-0.92/exec/vsf_ykd.c 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/exec/vsf_ykd.c 2008-12-08 16:55:41.000000000 +0100 -@@ -56,12 +56,12 @@ - #include - - #include -+#include -+#include -+#include - #include - #include - --#include "main.h" --#include "vsf.h" -- - LOGSYS_DECLARE_SUBSYS ("YKD", LOG_INFO); - - #define YKD_PROCESSOR_COUNT_MAX 32 -@@ -108,7 +108,7 @@ - - struct ykd_state ykd_state; - --static totempg_groups_handle ykd_group_handle; -+static cs_tpg_handle ykd_group_handle; - - static struct state_received state_received_confchg[YKD_PROCESSOR_COUNT_MAX]; - -@@ -140,6 +140,8 @@ - - static void *ykd_state_send_callback_token_handle = 0; - -+static struct corosync_api_v1 *api; -+ - static void (*ykd_primary_callback_fn) ( - unsigned int *view_list, - int view_list_entries, -@@ -168,15 +170,15 @@ - iovec[1].iov_base = (char *)&ykd_state; - iovec[1].iov_len = sizeof (struct ykd_state); - -- res = totempg_groups_mcast_joined (ykd_group_handle, iovec, 2, -- TOTEMPG_AGREED); -+ res = api->tpg_joined_mcast (ykd_group_handle, iovec, 2, -+ TOTEM_AGREED); - - return (res); - } - - static void ykd_state_send (void) - { -- totempg_callback_token_create ( -+ api->totem_callback_token_create ( - &ykd_state_send_callback_token_handle, - TOTEM_CALLBACK_TOKEN_SENT, - 1, /* delete after callback */ -@@ -195,15 +197,15 @@ - iovec.iov_base = (char *)&header; - iovec.iov_len = sizeof (struct ykd_header); - -- res = totempg_groups_mcast_joined (ykd_group_handle, &iovec, 1, -- TOTEMPG_AGREED); -+ res = api->tpg_joined_mcast (ykd_group_handle, &iovec, 1, -+ TOTEM_AGREED); - - return (res); - } - - static void ykd_attempt_send (void) - { -- totempg_callback_token_create ( -+ api->totem_callback_token_create ( - &ykd_attempt_send_callback_token_handle, - TOTEM_CALLBACK_TOKEN_SENT, - 1, /* delete after callback */ -@@ -460,7 +462,7 @@ - memcpy (&ykd_ring_id, ring_id, sizeof (struct memb_ring_id)); - - if (first_run) { -- ykd_state.last_primary.member_list[0] = totempg_my_nodeid_get(); -+ ykd_state.last_primary.member_list[0] = api->totem_nodeid_get(); - ykd_state.last_primary.member_list_entries = 1; - ykd_state.last_primary.session_id = 0; - first_run = 0; -@@ -493,53 +495,41 @@ - ykd_state_send (); - } - --struct totempg_group ykd_group = { -+struct corosync_tpg_group ykd_group = { - .group = "ykd", - .group_len = 3 - }; - --static int ykd_init ( -- void (*primary_callback_fn) ( -- unsigned int *view_list, -- int view_list_entries, -- int primary_designated, -- struct memb_ring_id *ring_id)) -+static void ykd_init ( -+ struct corosync_api_v1 *corosync_api, -+ quorum_set_quorate_fn_t set_primary) - { -- ykd_primary_callback_fn = primary_callback_fn; -+ ykd_primary_callback_fn = set_primary; -+ api = corosync_api; - -- totempg_groups_initialize ( -+ api->tpg_init ( - &ykd_group_handle, - ykd_deliver_fn, - ykd_confchg_fn); - -- totempg_groups_join ( -+ api->tpg_join ( - ykd_group_handle, - &ykd_group, - 1); - - ykd_state_init (); -- -- return (0); --} -- --/* -- * Returns 1 if this processor is in the primary -- */ --static int ykd_primary (void) { -- return (primary_designated); - } - - /* - * lcrso object definition - */ --static struct corosync_vsf_iface_ver0 vsf_ykd_iface_ver0 = { -+static struct quorum_services_api_ver1 vsf_ykd_iface_ver0 = { - .init = ykd_init, -- .primary = ykd_primary - }; - - static struct lcr_iface corosync_vsf_ykd_ver0[1] = { - { -- .name = "corosync_vsf_ykd", -+ .name = "corosync_quorum_ykd", - .version = 0, - .versions_replace = 0, - .versions_replace_count = 0, -diff -Naurd corosync-0.92/include/corosync/ais_util.h corosync-trunk/include/corosync/ais_util.h ---- corosync-0.92/include/corosync/ais_util.h 2008-08-14 16:59:50.000000000 +0200 -+++ corosync-trunk/include/corosync/ais_util.h 2008-11-06 22:49:07.000000000 +0100 -@@ -67,71 +67,71 @@ - - struct saVersionDatabase { - int versionCount; -- SaVersionT *versionsSupported; -+ cs_version_t *versionsSupported; - }; - --SaAisErrorT saSendMsgRetry ( -+cs_error_t saSendMsgRetry ( - int s, - struct iovec *iov, - int iov_len); - --SaAisErrorT saSendMsgReceiveReply ( -+cs_error_t saSendMsgReceiveReply ( - int s, - struct iovec *iov, - int iov_len, - void *responseMessage, - int responseLen); - --SaAisErrorT saSendReceiveReply ( -+cs_error_t saSendReceiveReply ( - int s, - void *requestMessage, - int requestLen, - void *responseMessage, - int responseLen); - --SaAisErrorT -+cs_error_t - saPollRetry ( - struct pollfd *ufds, - unsigned int nfds, - int timeout); - --SaAisErrorT -+cs_error_t - saHandleCreate ( - struct saHandleDatabase *handleDatabase, - int instanceSize, -- SaUint64T *handleOut); -+ uint64_t *handleOut); - --SaAisErrorT -+cs_error_t - saHandleDestroy ( - struct saHandleDatabase *handleDatabase, -- SaUint64T handle); -+ uint64_t handle); - --SaAisErrorT -+cs_error_t - saHandleInstanceGet ( - struct saHandleDatabase *handleDatabase, -- SaUint64T handle, -+ uint64_t handle, - void **instance); - --SaAisErrorT -+cs_error_t - saHandleInstancePut ( - struct saHandleDatabase *handleDatabase, -- SaUint64T handle); -+ uint64_t handle); - --SaAisErrorT -+cs_error_t - saVersionVerify ( - struct saVersionDatabase *versionDatabase, -- SaVersionT *version); -+ cs_version_t *version); - - #define offset_of(type,member) (int)(&(((type *)0)->member)) - --SaTimeT -+cs_time_t - clustTimeNow(void); - --extern SaAisErrorT saServiceConnect ( -+extern cs_error_t saServiceConnect ( - int *responseOut, int *callbackOut, enum service_types service); - --extern SaAisErrorT saRecvRetry (int s, void *msg, size_t len); -+extern cs_error_t saRecvRetry (int s, void *msg, size_t len); - --extern SaAisErrorT saSendRetry (int s, const void *msg, size_t len); -+extern cs_error_t saSendRetry (int s, const void *msg, size_t len); - - #endif /* AIS_UTIL_H_DEFINED */ -diff -Naurd corosync-0.92/include/corosync/cfg.h corosync-trunk/include/corosync/cfg.h ---- corosync-0.92/include/corosync/cfg.h 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/include/corosync/cfg.h 2009-01-19 09:31:21.000000000 +0100 -@@ -1,6 +1,6 @@ - /* - * Copyright (c) 2005 MontaVista Software, Inc. -- * Copyright (c) 2006 Red Hat, Inc. -+ * Copyright (c) 2006-2009 Red Hat, Inc. - * - * All rights reserved. - * -@@ -36,33 +36,33 @@ - #define AIS_COROSYNCCFG_H_DEFINED - - #include --#include "saAis.h" -+#include - --typedef SaUint64T corosync_cfg_handle_t; -+typedef uint64_t corosync_cfg_handle_t; - - typedef enum { - COROSYNC_CFG_ADMINISTRATIVETARGET_SERVICEUNIT = 0, - COROSYNC_CFG_ADMINISTRATIVETARGET_SERVICEGROUP = 1, - COROSYNC_CFG_ADMINISTRATIVETARGET_COMPONENTSERVICEINSTANCE = 2, - COROSYNC_CFG_ADMINISTRATIVETARGET_NODE = 3 --} CorosyncCfgAdministrativeTargetT; -+} corosync_cfg_administrative_target_t; - - typedef enum { - COROSYNC_CFG_ADMINISTRATIVESTATE_UNLOCKED = 0, - COROSYNC_CFG_ADMINISTRATIVESTATE_LOCKED = 1, - COROSYNC_CFG_ADMINISTRATIVESTATE_STOPPING = 2 --} CorosyncCfgAdministrativeStateT; -+} corosync_cfg_administrative_state_t; - - typedef enum { - COROSYNC_CFG_OPERATIONALSTATE_ENABLED = 1, - COROSYNC_CFG_OPERATIONALSTATE_DISABLED = 2 --} CorosyncCfgOperationalStateT; -+} corosync_cfg_operational_state_t; - - typedef enum { - COROSYNC_CFG_READINESSSTATE_OUTOFSERVICE = 1, - COROSYNC_CFG_READINESSSTATE_INSERVICE = 2, - COROSYNC_CFG_READINESSSTATE_STOPPING = 3 --} CorosyncCfgReadinessStateT; -+} corosync_cfg_readiness_state_t; - - typedef enum { - COROSYNC_CFG_PRESENCESTATE_UNINSTANTIATED = 1, -@@ -72,7 +72,7 @@ - COROSYNC_CFG_PRESENCESTATE_RESTARTING = 5, - COROSYNC_CFG_PRESENCESTATE_INSTANTIATION_FAILED = 6, - COROSYNC_CFG_PRESENCESTATE_TERMINATION_FAILED = 7 --} CorosyncCfgPresenceStateT; -+} corosync_cfg_presence_state_t; - - typedef enum { - COROSYNC_CFG_STATETYPE_OPERATIONAL = 0, -@@ -80,27 +80,63 @@ - COROSYNC_CFG_STATETYPE_READINESS = 2, - COROSYNC_CFG_STATETYPE_HA = 3, - COROSYNC_CFG_STATETYPE_PRESENCE = 4 --} CorosyncCfgStateTypeT; -+} corosync_cfg_state_type_t; -+ -+/* Shutdown types. -+ REQUEST is the normal shutdown. other daemons will be consulted -+ REGARDLESS will tell other daemons but ignore their opinions -+ IMMEDIATE will shut down straight away (but still tell other nodes) -+*/ -+typedef enum { -+ COROSYNC_CFG_SHUTDOWN_FLAG_REQUEST = 0, -+ COROSYNC_CFG_SHUTDOWN_FLAG_REGARDLESS = 1, -+ COROSYNC_CFG_SHUTDOWN_FLAG_IMMEDIATE = 2, -+} corosync_cfg_shutdown_flags_t; -+ -+typedef enum { -+ COROSYNC_CFG_SHUTDOWN_FLAG_NO = 0, -+ COROSYNC_CFG_SHUTDOWN_FLAG_YES = 1, -+} corosync_cfg_shutdown_reply_flags_t; - - typedef struct { -- SaNameT name; -- CorosyncCfgStateTypeT stateType; -- CorosyncCfgAdministrativeStateT administrativeState; --} CorosyncCfgStateNotificationT; -+ cs_name_t name; -+ corosync_cfg_state_type_t state_type; -+ corosync_cfg_administrative_state_t administrative_state; -+} corosync_cfg_state_notification_t; - - typedef struct { -- SaUint32T numberOfItems; -- CorosyncCfgStateNotificationT *notification; --} CorosyncCfgStateNotificationBufferT; -+ uint32_t number_of_items; -+ corosync_cfg_state_notification_t *notification; -+} corosync_cfg_state_notification_buffer_t; - --typedef void (*CorosyncCfgStateTrackCallbackT) ( -- CorosyncCfgStateNotificationBufferT *notificationBuffer, -- SaAisErrorT error); -+typedef void (*corosync_cfg_state_track_callback_t) ( -+ corosync_cfg_state_notification_buffer_t *notification_buffer, -+ cs_error_t error); -+ -+typedef void (*corosync_cfg_shutdown_callback_t) ( -+ corosync_cfg_handle_t cfg_handle, -+ corosync_cfg_shutdown_flags_t flags); - - typedef struct { -- CorosyncCfgStateTrackCallbackT -- corosyncCfgStateTrackCallback; --} CorosyncCfgCallbacksT; -+ corosync_cfg_state_track_callback_t corosync_cfg_state_track_callback; -+ corosync_cfg_shutdown_callback_t corosync_cfg_shutdown_callback; -+} corosync_cfg_callbacks_t; -+ -+/* -+ * A node address. This is a complete sockaddr_in[6] -+ * To explain: -+ * If you cast cna_address to a 'struct sockaddr', the sa_family field -+ * will be AF_INET or AF_INET6. Armed with that knowledge you can then -+ * cast it to a sockaddr_in or sockaddr_in6 and pull out the address. -+ * No other sockaddr fields are valid. -+ * Also, you must ignore any part of the sockaddr beyond the length supplied -+ */ -+typedef struct -+{ -+ int addressLength; -+ char address[sizeof(struct sockaddr_in6)]; -+} corosync_cfg_node_address_t; -+ - - /* - * Interfaces -@@ -109,70 +145,97 @@ - extern "C" { - #endif - --SaAisErrorT -+cs_error_t - corosync_cfg_initialize ( - corosync_cfg_handle_t *cfg_handle, -- const CorosyncCfgCallbacksT *cfgCallbacks); -+ const corosync_cfg_callbacks_t *cfg_callbacks); - --SaAisErrorT -+cs_error_t - corosync_cfg_fd_get ( - corosync_cfg_handle_t cfg_handle, -- SaSelectionObjectT *selectionObject); -+ int32_t *selection_fd); - --SaAisErrorT -+cs_error_t - corosync_cfg_dispatch ( - corosync_cfg_handle_t cfg_handle, -- SaDispatchFlagsT dispatchFlags); -+ cs_dispatch_flags_t dispatch_flags); - --SaAisErrorT -+cs_error_t - corosync_cfg_finalize ( - corosync_cfg_handle_t cfg_handle); - --SaAisErrorT -+cs_error_t - corosync_cfg_ring_status_get ( - corosync_cfg_handle_t cfg_handle, - char ***interface_names, - char ***status, - unsigned int *interface_count); - --SaAisErrorT -+cs_error_t - corosync_cfg_ring_reenable ( - corosync_cfg_handle_t cfg_handle); - --SaAisErrorT -+cs_error_t - corosync_cfg_service_load ( - corosync_cfg_handle_t cfg_handle, - char *service_name, - unsigned int service_ver); - --SaAisErrorT -+cs_error_t - corosync_cfg_service_unload ( - corosync_cfg_handle_t cfg_handle, - char *service_name, - unsigned int service_ver); - --SaAisErrorT -+cs_error_t - corosync_cfg_administrative_state_get ( - corosync_cfg_handle_t cfg_handle, -- CorosyncCfgAdministrativeTargetT administrativeTarget, -- CorosyncCfgAdministrativeStateT *administrativeState); -+ corosync_cfg_administrative_target_t administrative_target, -+ corosync_cfg_administrative_state_t *administrative_state); - --SaAisErrorT -+cs_error_t - corosync_cfg_administrative_state_set ( - corosync_cfg_handle_t cfg_handle, -- CorosyncCfgAdministrativeTargetT administrativeTarget, -- CorosyncCfgAdministrativeStateT administrativeState); -+ corosync_cfg_administrative_target_t administrative_target, -+ corosync_cfg_administrative_state_t administrative_state); - --SaAisErrorT -+cs_error_t -+corosync_cfg_kill_node ( -+ corosync_cfg_handle_t cfg_handle, -+ unsigned int nodeid, -+ char *reason); -+ -+cs_error_t -+corosync_cfg_try_shutdown ( -+ corosync_cfg_handle_t cfg_handle, -+ corosync_cfg_shutdown_flags_t flags); -+ -+ -+cs_error_t -+corosync_cfg_replyto_shutdown ( -+ corosync_cfg_handle_t cfg_handle, -+ corosync_cfg_shutdown_reply_flags_t flags); -+ -+cs_error_t - corosync_cfg_state_track ( - corosync_cfg_handle_t cfg_handle, -- SaUint8T trackFlags, -- const CorosyncCfgStateNotificationT *notificationBuffer); -+ uint8_t track_flags, -+ const corosync_cfg_state_notification_t *notification_buffer); - --SaAisErrorT -+cs_error_t - corosync_cfg_state_track_stop ( - corosync_cfg_handle_t cfg_handle); - -+ -+cs_error_t -+corosync_cfg_get_node_addrs ( -+ corosync_cfg_handle_t cfg_handle, -+ int nodeid, -+ int max_addrs, -+ int *num_addrs, -+ corosync_cfg_node_address_t *addrs); -+ -+ - #ifdef __cplusplus - } - #endif -diff -Naurd corosync-0.92/include/corosync/confdb.h corosync-trunk/include/corosync/confdb.h ---- corosync-0.92/include/corosync/confdb.h 2008-09-03 09:58:08.000000000 +0200 -+++ corosync-trunk/include/corosync/confdb.h 2008-11-06 22:49:07.000000000 +0100 -@@ -34,6 +34,7 @@ - #ifndef COROSYNC_CONFDB_H_DEFINED - #define COROSYNC_CONFDB_H_DEFINED - -+#include - /** - * @addtogroup confdb_corosync - * -@@ -44,33 +45,11 @@ - #define OBJECT_PARENT_HANDLE 0 - - typedef enum { -- CONFDB_DISPATCH_ONE, -- CONFDB_DISPATCH_ALL, -- CONFDB_DISPATCH_BLOCKING --} confdb_dispatch_t; -- --typedef enum { - CONFDB_TRACK_DEPTH_ONE, - CONFDB_TRACK_DEPTH_RECURSIVE - } confdb_track_depth_t; - - typedef enum { -- CONFDB_OK = 1, -- CONFDB_ERR_LIBRARY = 2, -- CONFDB_ERR_TIMEOUT = 5, -- CONFDB_ERR_TRY_AGAIN = 6, -- CONFDB_ERR_INVALID_PARAM = 7, -- CONFDB_ERR_NO_MEMORY = 8, -- CONFDB_ERR_BAD_HANDLE = 9, -- CONFDB_ERR_ACCESS = 11, -- CONFDB_ERR_NOT_EXIST = 12, -- CONFDB_ERR_EXIST = 14, -- CONFDB_ERR_CONTEXT_NOT_FOUND = 17, -- CONFDB_ERR_NOT_SUPPORTED = 20, -- CONFDB_ERR_SECURITY = 29, --} confdb_error_t; -- --typedef enum { - OBJECT_KEY_CREATED, - OBJECT_KEY_REPLACED, - OBJECT_KEY_DELETED -@@ -112,28 +91,28 @@ - /* - * Create a new confdb connection - */ --confdb_error_t confdb_initialize ( -+cs_error_t confdb_initialize ( - confdb_handle_t *handle, - confdb_callbacks_t *callbacks); - - /* - * Close the confdb handle - */ --confdb_error_t confdb_finalize ( -+cs_error_t confdb_finalize ( - confdb_handle_t handle); - - - /* - * Write back the configuration - */ --confdb_error_t confdb_write ( -+cs_error_t confdb_write ( - confdb_handle_t handle, - char *error_text); - - /* - * Reload the configuration - */ --confdb_error_t confdb_reload ( -+cs_error_t confdb_reload ( - confdb_handle_t handle, - int flush, - char *error_text); -@@ -142,43 +121,43 @@ - * Get a file descriptor on which to poll. confdb_handle_t is NOT a - * file descriptor and may not be used directly. - */ --confdb_error_t confdb_fd_get ( -+cs_error_t confdb_fd_get ( - confdb_handle_t handle, - int *fd); - - /* - * Dispatch configuration changes - */ --confdb_error_t confdb_dispatch ( -+cs_error_t confdb_dispatch ( - confdb_handle_t handle, -- confdb_dispatch_t dispatch_types); -+ cs_dispatch_flags_t dispatch_types); - - /* - * Change notification - */ --confdb_error_t confdb_track_changes ( -+cs_error_t confdb_track_changes ( - confdb_handle_t handle, - unsigned int object_handle, - unsigned int flags); - --confdb_error_t confdb_stop_track_changes ( -+cs_error_t confdb_stop_track_changes ( - confdb_handle_t handle); - - /* - * Manipulate objects - */ --confdb_error_t confdb_object_create ( -+cs_error_t confdb_object_create ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *object_name, - int object_name_len, - unsigned int *object_handle); - --confdb_error_t confdb_object_destroy ( -+cs_error_t confdb_object_destroy ( - confdb_handle_t handle, - unsigned int object_handle); - --confdb_error_t confdb_object_parent_get ( -+cs_error_t confdb_object_parent_get ( - confdb_handle_t handle, - unsigned int object_handle, - unsigned int *parent_object_handle); -@@ -186,7 +165,7 @@ - /* - * Manipulate keys - */ --confdb_error_t confdb_key_create ( -+cs_error_t confdb_key_create ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -@@ -194,7 +173,7 @@ - void *value, - int value_len); - --confdb_error_t confdb_key_delete ( -+cs_error_t confdb_key_delete ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -@@ -205,7 +184,7 @@ - /* - * Key queries - */ --confdb_error_t confdb_key_get ( -+cs_error_t confdb_key_get ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -@@ -213,7 +192,7 @@ - void *value, - int *value_len); - --confdb_error_t confdb_key_replace ( -+cs_error_t confdb_key_replace ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -@@ -223,14 +202,14 @@ - void *new_value, - int new_value_len); - --confdb_error_t confdb_key_increment ( -+cs_error_t confdb_key_increment ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, - int key_name_len, - unsigned int *value); - --confdb_error_t confdb_key_decrement ( -+cs_error_t confdb_key_decrement ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -@@ -243,44 +222,44 @@ - * a quick way of finding a specific object, - * "iter" returns each object in sequence. - */ --confdb_error_t confdb_object_find_start ( -+cs_error_t confdb_object_find_start ( - confdb_handle_t handle, - unsigned int parent_object_handle); - --confdb_error_t confdb_object_find ( -+cs_error_t confdb_object_find ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *object_name, - int object_name_len, - unsigned int *object_handle); - --confdb_error_t confdb_object_find_destroy( -+cs_error_t confdb_object_find_destroy( - confdb_handle_t handle, - unsigned int parent_object_handle); - --confdb_error_t confdb_object_iter_start ( -+cs_error_t confdb_object_iter_start ( - confdb_handle_t handle, - unsigned int parent_object_handle); - --confdb_error_t confdb_object_iter ( -+cs_error_t confdb_object_iter ( - confdb_handle_t handle, - unsigned int parent_object_handle, - unsigned int *object_handle, - void *object_name, - int *object_name_len); - --confdb_error_t confdb_object_iter_destroy( -+cs_error_t confdb_object_iter_destroy( - confdb_handle_t handle, - unsigned int parent_object_handle); - - /* - * Key iterator - */ --confdb_error_t confdb_key_iter_start ( -+cs_error_t confdb_key_iter_start ( - confdb_handle_t handle, - unsigned int object_handle); - --confdb_error_t confdb_key_iter ( -+cs_error_t confdb_key_iter ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -diff -Naurd corosync-0.92/include/corosync/corotypes.h corosync-trunk/include/corosync/corotypes.h ---- corosync-0.92/include/corosync/corotypes.h 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/include/corosync/corotypes.h 2008-11-07 02:34:43.000000000 +0100 -@@ -0,0 +1,178 @@ -+/* -+ * Copyright (c) 2008 Allied Telesis Labs. -+ * -+ * All rights reserved. -+ * -+ * Author: Angus Salkeld (ahsalkeld@gmail.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 COROTYPES_H_DEFINED -+#define COROTYPES_H_DEFINED -+ -+#ifndef COROSYNC_SOLARIS -+#include -+#else -+#include -+#endif -+ -+typedef int64_t cs_time_t; -+ -+#define CS_FALSE 0 -+#define CS_TRUE !CS_FALSE -+#define CS_MAX_NAME_LENGTH 256 -+#define CS_TIME_END ((cs_time_t)0x7FFFFFFFFFFFFFFFULL) -+ -+typedef struct { -+ uint16_t length; -+ uint8_t value[CS_MAX_NAME_LENGTH]; -+} cs_name_t; -+ -+typedef struct { -+ char releaseCode; -+ unsigned char majorVersion; -+ unsigned char minorVersion; -+} cs_version_t; -+ -+typedef enum { -+ CS_DISPATCH_ONE = 1, -+ CS_DISPATCH_ALL = 2, -+ CS_DISPATCH_BLOCKING = 3 -+} cs_dispatch_flags_t; -+ -+#define CS_TRACK_CURRENT 0x01 -+#define CS_TRACK_CHANGES 0x02 -+#define CS_TRACK_CHANGES_ONLY 0x04 -+ -+typedef enum { -+ CS_OK = 1, -+ CS_ERR_LIBRARY = 2, -+ CS_ERR_VERSION = 3, -+ CS_ERR_INIT = 4, -+ CS_ERR_TIMEOUT = 5, -+ CS_ERR_TRY_AGAIN = 6, -+ CS_ERR_INVALID_PARAM = 7, -+ CS_ERR_NO_MEMORY = 8, -+ CS_ERR_BAD_HANDLE = 9, -+ CS_ERR_BUSY = 10, -+ CS_ERR_ACCESS = 11, -+ CS_ERR_NOT_EXIST = 12, -+ CS_ERR_NAME_TOO_LONG = 13, -+ CS_ERR_EXIST = 14, -+ CS_ERR_NO_SPACE = 15, -+ CS_ERR_INTERRUPT = 16, -+ CS_ERR_NAME_NOT_FOUND = 17, -+ CS_ERR_NO_RESOURCES = 18, -+ CS_ERR_NOT_SUPPORTED = 19, -+ CS_ERR_BAD_OPERATION = 20, -+ CS_ERR_FAILED_OPERATION = 21, -+ CS_ERR_MESSAGE_ERROR = 22, -+ CS_ERR_QUEUE_FULL = 23, -+ CS_ERR_QUEUE_NOT_AVAILABLE = 24, -+ CS_ERR_BAD_FLAGS = 25, -+ CS_ERR_TOO_BIG = 26, -+ CS_ERR_NO_SECTIONS = 27, -+ CS_ERR_CONTEXT_NOT_FOUND = 28, -+ CS_ERR_TOO_MANY_GROUPS = 30 -+} cs_error_t; -+ -+ -+/* -+ * DEPRECATED -+ */ -+#define EVS_DISPATCH_ONE CS_DISPATCH_ONE -+#define EVS_DISPATCH_ALL CS_DISPATCH_ALL -+#define EVS_DISPATCH_BLOCKING CS_DISPATCH_BLOCKING -+#define EVS_OK CS_OK -+#define EVS_ERR_LIBRARY CS_ERR_ERR_LIBRARY -+#define EVS_ERR_TIMEOUT CS_ERR_TIMEOUT -+#define EVS_ERR_TRY_AGAIN CS_ERR_TRY_AGAIN -+#define EVS_ERR_INVALID_PARAM CS_ERR_INVALID_PARAM -+#define EVS_ERR_NO_MEMORY CS_ERR_NO_MEMORY -+#define EVS_ERR_BAD_HANDLE CS_ERR_BAD_HANDLE -+#define EVS_ERR_ACCESS CS_ERR_ACCESS -+#define EVS_ERR_NOT_EXIST CS_ERR_NOT_EXIST -+#define EVS_ERR_EXIST CS_ERR_EXIST -+#define EVS_ERR_NOT_SUPPORTED CS_ERR_NOT_SUPPORTED -+#define EVS_ERR_SECURITY CS_ERR_SECURITY -+#define EVS_ERR_TOO_MANY_GROUPS CS_ERR_TOO_MANY_GROUPS -+#define evs_error_t cs_error_t -+ -+#define CPG_DISPATCH_ONE CS_DISPATCH_ONE -+#define CPG_DISPATCH_ALL CS_DISPATCH_ALL -+#define CPG_DISPATCH_BLOCKING CS_DISPATCH_BLOCKING -+#define CPG_OK CS_OK -+#define CPG_ERR_LIBRARY CS_ERR_ERR_LIBRARY -+#define CPG_ERR_TIMEOUT CS_ERR_TIMEOUT -+#define CPG_ERR_TRY_AGAIN CS_ERR_TRY_AGAIN -+#define CPG_ERR_INVALID_PARAM CS_ERR_INVALID_PARAM -+#define CPG_ERR_NO_MEMORY CS_ERR_NO_MEMORY -+#define CPG_ERR_BAD_HANDLE CS_ERR_BAD_HANDLE -+#define CPG_ERR_ACCESS CS_ERR_ACCESS -+#define CPG_ERR_NOT_EXIST CS_ERR_NOT_EXIST -+#define CPG_ERR_EXIST CS_ERR_EXIST -+#define CPG_ERR_NOT_SUPPORTED CS_ERR_NOT_SUPPORTED -+#define CPG_ERR_SECURITY CS_ERR_SECURITY -+#define cpg_error_t cs_error_t -+ -+#define CONFDB_DISPATCH_ONE CS_DISPATCH_ONE -+#define CONFDB_DISPATCH_ALL CS_DISPATCH_ALL -+#define CONFDB_DISPATCH_BLOCKING CS_DISPATCH_BLOCKING -+#define CONFDB_OK CS_OK -+#define CONFDB_ERR_LIBRARY CS_ERR_ERR_LIBRARY -+#define CONFDB_ERR_TIMEOUT CS_ERR_TIMEOUT -+#define CONFDB_ERR_TRY_AGAIN CS_ERR_TRY_AGAIN -+#define CONFDB_ERR_INVALID_PARAM CS_ERR_INVALID_PARAM -+#define CONFDB_ERR_NO_MEMORY CS_ERR_NO_MEMORY -+#define CONFDB_ERR_BAD_HANDLE CS_ERR_BAD_HANDLE -+#define CONFDB_ERR_ACCESS CS_ERR_ACCESS -+#define CONFDB_ERR_NOT_EXIST CS_ERR_NOT_EXIST -+#define CONFDB_ERR_EXIST CS_ERR_EXIST -+#define CONFDB_ERR_NOT_SUPPORTED CS_ERR_NOT_SUPPORTED -+#define CONFDB_ERR_SECURITY CS_ERR_SECURITY -+#define confdb_error_t cs_error_t -+ -+#define QUORUM_DISPATCH_ONE CS_DISPATCH_ONE -+#define QUORUM_DISPATCH_ALL CS_DISPATCH_ALL -+#define QUORUM_DISPATCH_BLOCKING CS_DISPATCH_BLOCKING -+#define QUORUM_OK CS_OK -+#define QUORUM_ERR_LIBRARY CS_ERR_ERR_LIBRARY -+#define QUORUM_ERR_TIMEOUT CS_ERR_TIMEOUT -+#define QUORUM_ERR_TRY_AGAIN CS_ERR_TRY_AGAIN -+#define QUORUM_ERR_INVALID_PARAM CS_ERR_INVALID_PARAM -+#define QUORUM_ERR_NO_MEMORY CS_ERR_NO_MEMORY -+#define QUORUM_ERR_BAD_HANDLE CS_ERR_BAD_HANDLE -+#define QUORUM_ERR_ACCESS CS_ERR_ACCESS -+#define QUORUM_ERR_NOT_EXIST CS_ERR_NOT_EXIST -+#define QUORUM_ERR_EXIST CS_ERR_EXIST -+#define QUORUM_ERR_NOT_SUPPORTED CS_ERR_NOT_SUPPORTED -+#define QUORUM_ERR_SECURITY CS_ERR_SECURITY -+#define quorum_error_t cs_error_t -+ -+#endif -+ -diff -Naurd corosync-0.92/include/corosync/cpg.h corosync-trunk/include/corosync/cpg.h ---- corosync-0.92/include/corosync/cpg.h 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/include/corosync/cpg.h 2008-11-06 22:49:07.000000000 +0100 -@@ -35,6 +35,7 @@ - #define COROSYNC_CPG_H_DEFINED - - #include -+#include - - /** - * @addtogroup cpg_corosync -@@ -44,12 +45,6 @@ - typedef uint64_t cpg_handle_t; - - typedef enum { -- CPG_DISPATCH_ONE, -- CPG_DISPATCH_ALL, -- CPG_DISPATCH_BLOCKING --} cpg_dispatch_t; -- --typedef enum { - CPG_TYPE_UNORDERED, /* not implemented */ - CPG_TYPE_FIFO, /* same as agreed */ - CPG_TYPE_AGREED, -@@ -61,21 +56,6 @@ - CPG_FLOW_CONTROL_ENABLED /* flow control is enabled - new messages should not be sent */ - } cpg_flow_control_state_t; - --typedef enum { -- CPG_OK = 1, -- CPG_ERR_LIBRARY = 2, -- CPG_ERR_TIMEOUT = 5, -- CPG_ERR_TRY_AGAIN = 6, -- CPG_ERR_INVALID_PARAM = 7, -- CPG_ERR_NO_MEMORY = 8, -- CPG_ERR_BAD_HANDLE = 9, -- CPG_ERR_ACCESS = 11, -- CPG_ERR_NOT_EXIST = 12, -- CPG_ERR_EXIST = 14, -- CPG_ERR_NOT_SUPPORTED = 20, -- CPG_ERR_SECURITY = 29, -- CPG_ERR_TOO_MANY_GROUPS=30 --} cpg_error_t; - - typedef enum { - CPG_REASON_JOIN = 1, -@@ -132,32 +112,32 @@ - /* - * Create a new cpg connection - */ --cpg_error_t cpg_initialize ( -+cs_error_t cpg_initialize ( - cpg_handle_t *handle, - cpg_callbacks_t *callbacks); - - /* - * Close the cpg handle - */ --cpg_error_t cpg_finalize ( -+cs_error_t cpg_finalize ( - cpg_handle_t handle); - - /* - * Get a file descriptor on which to poll. cpg_handle_t is NOT a - * file descriptor and may not be used directly. - */ --cpg_error_t cpg_fd_get ( -+cs_error_t cpg_fd_get ( - cpg_handle_t handle, - int *fd); - - /* - * Get and set contexts for a CPG handle - */ --cpg_error_t cpg_context_get ( -+cs_error_t cpg_context_get ( - cpg_handle_t handle, - void **context); - --cpg_error_t cpg_context_set ( -+cs_error_t cpg_context_set ( - cpg_handle_t handle, - void *context); - -@@ -165,9 +145,9 @@ - /* - * Dispatch messages and configuration changes - */ --cpg_error_t cpg_dispatch ( -+cs_error_t cpg_dispatch ( - cpg_handle_t handle, -- cpg_dispatch_t dispatch_types); -+ cs_dispatch_flags_t dispatch_types); - - /* - * Join one or more groups. -@@ -175,14 +155,14 @@ - * group that has been joined on handle handle. Any message multicasted - * to a group that has been previously joined will be delivered in cpg_dispatch - */ --cpg_error_t cpg_join ( -+cs_error_t cpg_join ( - cpg_handle_t handle, - struct cpg_name *group); - - /* - * Leave one or more groups - */ --cpg_error_t cpg_leave ( -+cs_error_t cpg_leave ( - cpg_handle_t handle, - struct cpg_name *group); - -@@ -191,7 +171,7 @@ - * The iovec described by iovec will be multicasted to all groups joined with - * the cpg_join interface for handle. - */ --cpg_error_t cpg_mcast_joined ( -+cs_error_t cpg_mcast_joined ( - cpg_handle_t handle, - cpg_guarantee_t guarantee, - struct iovec *iovec, -@@ -200,21 +180,21 @@ - /* - * Get membership information from cpg - */ --cpg_error_t cpg_membership_get ( -+cs_error_t cpg_membership_get ( - cpg_handle_t handle, - struct cpg_name *groupName, - struct cpg_address *member_list, - int *member_list_entries); - --cpg_error_t cpg_local_get ( -+cs_error_t cpg_local_get ( - cpg_handle_t handle, - unsigned int *local_nodeid); - --cpg_error_t cpg_groups_get ( -+cs_error_t cpg_groups_get ( - cpg_handle_t handle, - unsigned int *num_groups); - --cpg_error_t cpg_flow_control_state_get ( -+cs_error_t cpg_flow_control_state_get ( - cpg_handle_t handle, - cpg_flow_control_state_t *flow_control_enabled); - -diff -Naurd corosync-0.92/include/corosync/engine/coroapi.h corosync-trunk/include/corosync/engine/coroapi.h ---- corosync-0.92/include/corosync/engine/coroapi.h 2008-09-17 21:15:00.000000000 +0200 -+++ corosync-trunk/include/corosync/engine/coroapi.h 2009-01-20 14:19:05.000000000 +0100 -@@ -41,7 +41,7 @@ - - typedef void * corosync_timer_handle_t; - --typedef unsigned int corosync_tpg_handle; -+typedef unsigned int cs_tpg_handle; - - struct corosync_tpg_group { - void *group; -@@ -88,17 +88,36 @@ - }; - #endif - --enum corosync_lib_flow_control { -- COROSYNC_LIB_FLOW_CONTROL_REQUIRED = 1, -- COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED = 2 -+#if !defined(TOTEM_CALLBACK_TOKEN_TYPE) -+enum totem_callback_token_type { -+ TOTEM_CALLBACK_TOKEN_RECEIVED = 1, -+ TOTEM_CALLBACK_TOKEN_SENT = 2 -+}; -+#endif -+ -+enum cs_lib_flow_control { -+ CS_LIB_FLOW_CONTROL_REQUIRED = 1, -+ CS_LIB_FLOW_CONTROL_NOT_REQUIRED = 2 -+}; -+#define corosync_lib_flow_control cs_lib_flow_control -+#define COROSYNC_LIB_FLOW_CONTROL_REQUIRED CS_LIB_FLOW_CONTROL_REQUIRED -+#define COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED CS_LIB_FLOW_CONTROL_NOT_REQUIRED -+ -+enum cs_lib_allow_inquorate { -+ CS_LIB_DISALLOW_INQUORATE = 0, /* default */ -+ CS_LIB_ALLOW_INQUORATE = 1 - }; - - #if !defined (COROSYNC_FLOW_CONTROL_STATE) --enum corosync_flow_control_state { -- COROSYNC_FLOW_CONTROL_STATE_DISABLED, -- COROSYNC_FLOW_CONTROL_STATE_ENABLED -+enum cs_flow_control_state { -+ CS_FLOW_CONTROL_STATE_DISABLED, -+ CS_FLOW_CONTROL_STATE_ENABLED - }; --#endif -+#define corosync_flow_control_state cs_flow_control_state -+#define CS_FLOW_CONTROL_STATE_DISABLED CS_FLOW_CONTROL_STATE_DISABLED -+#define CS_FLOW_CONTROL_STATE_ENABLED CS_FLOW_CONTROL_STATE_ENABLED -+ -+#endif /* COROSYNC_FLOW_CONTROL_STATE */ - - typedef enum { - COROSYNC_FATAL_ERROR_EXIT = -1, -@@ -109,7 +128,8 @@ - COROSYNC_DYNAMICLOAD = -12, - COROSYNC_OUT_OF_MEMORY = -15, - COROSYNC_FATAL_ERR = -16 --} corosync_fatal_error_t; -+} cs_fatal_error_t; -+#define corosync_fatal_error_t cs_fatal_error_t; - - #ifndef OBJECT_PARENT_HANDLE - -@@ -125,6 +145,7 @@ - int key_len; - int (*validate_callback) (void *key, int key_len, void *value, int value_len); - }; -+/* deprecated */ - - typedef enum { - OBJECT_TRACK_DEPTH_ONE, -@@ -137,6 +158,12 @@ - OBJECT_KEY_DELETED - } object_change_type_t; - -+typedef enum { -+ OBJDB_RELOAD_NOTIFY_START, -+ OBJDB_RELOAD_NOTIFY_END, -+ OBJDB_RELOAD_NOTIFY_FAILED -+} objdb_reload_notify_type_t; -+ - typedef void (*object_key_change_notify_fn_t)(object_change_type_t change_type, - unsigned int parent_object_handle, - unsigned int object_handle, -@@ -159,8 +186,30 @@ - object_change_type_t type, - void * priv_data_pt); - -+typedef void (*object_reload_notify_fn_t) (objdb_reload_notify_type_t, int flush, -+ void *priv_data_pt); -+ - #endif /* OBJECT_PARENT_HANDLE_DEFINED */ - -+#ifndef QUORUM_H_DEFINED -+typedef void (*quorum_callback_fn_t) (int quorate, void *context); -+ -+struct quorum_callin_functions -+{ -+ int (*quorate) (void); -+ int (*register_callback) (quorum_callback_fn_t callback_fn, void *context); -+ int (*unregister_callback) (quorum_callback_fn_t callback_fn, void *context); -+}; -+ -+typedef void (*sync_callback_fn_t) ( -+ unsigned int *view_list, -+ int view_list_entries, -+ int primary_designated, -+ struct memb_ring_id *ring_id); -+ -+#endif /* QUORUM_H_DEFINED */ -+ -+ - struct corosync_api_v1 { - /* - * Object and configuration APIs -@@ -280,12 +329,14 @@ - object_key_change_notify_fn_t key_change_notify_fn, - object_create_notify_fn_t object_create_notify_fn, - object_destroy_notify_fn_t object_destroy_notify_fn, -+ object_reload_notify_fn_t object_reload_notify_fn, - void * priv_data_pt); - - void (*object_track_stop) ( - object_key_change_notify_fn_t key_change_notify_fn, - object_create_notify_fn_t object_create_notify_fn, - object_destroy_notify_fn_t object_destroy_notify_fn, -+ object_reload_notify_fn_t object_reload_notify_fn, - void * priv_data_pt); - - int (*object_write_config) (char **error_string); -@@ -357,7 +408,7 @@ - int id_len, - void (*flow_control_state_set_fn) - (void *context, -- enum corosync_flow_control_state flow_control_state_set), -+ enum cs_flow_control_state flow_control_state_set), - void *context); - - void (*ipc_fc_destroy) ( -@@ -373,7 +424,7 @@ - /* - * Totem APIs - */ -- int (*totem_nodeid_get) (void); -+ unsigned int (*totem_nodeid_get) (void); - - int (*totem_family_get) (void); - -@@ -393,12 +444,20 @@ - - char *(*totem_ip_print) (struct totem_ip_address *addr); - -+ -+ int (*totem_callback_token_create) ( -+ void **handle_out, -+ enum totem_callback_token_type type, -+ int delete, -+ int (*callback_fn) (enum totem_callback_token_type type, void *), -+ void *data); -+ - /* - * Totem open process groups API for those service engines - * wanting their own groups - */ - int (*tpg_init) ( -- corosync_tpg_handle *handle, -+ cs_tpg_handle *handle, - - void (*deliver_fn) ( - unsigned int nodeid, -@@ -414,31 +473,31 @@ - struct memb_ring_id *ring_id)); - - int (*tpg_exit) ( -- corosync_tpg_handle handle); -+ cs_tpg_handle handle); - - int (*tpg_join) ( -- corosync_tpg_handle handle, -+ cs_tpg_handle handle, - struct corosync_tpg_group *groups, - int gruop_cnt); - - int (*tpg_leave) ( -- corosync_tpg_handle handle, -+ cs_tpg_handle handle, - struct corosync_tpg_group *groups, - int gruop_cnt); - - int (*tpg_joined_mcast) ( -- corosync_tpg_handle handle, -+ cs_tpg_handle handle, - struct iovec *iovec, - int iov_len, - int guarantee); - - int (*tpg_joined_send_ok) ( -- corosync_tpg_handle handle, -+ cs_tpg_handle handle, - struct iovec *iovec, - int iov_len); - - int (*tpg_groups_mcast) ( -- corosync_tpg_handle handle, -+ cs_tpg_handle handle, - int guarantee, - struct corosync_tpg_group *groups, - int groups_cnt, -@@ -446,7 +505,7 @@ - int iov_len); - - int (*tpg_groups_send_ok) ( -- corosync_tpg_handle handle, -+ cs_tpg_handle handle, - struct corosync_tpg_group *groups, - int groups_cnt, - struct iovec *iovec, -@@ -456,6 +515,19 @@ - char *service_name); - - /* -+ * User plugin-callable functions for quorum -+ */ -+ int (*quorum_is_quorate) (void); -+ int (*quorum_register_callback) (quorum_callback_fn_t callback_fn, void *context); -+ int (*quorum_unregister_callback) (quorum_callback_fn_t callback_fn, void *context); -+ -+ /* -+ * This one is for the quorum management plugin's use -+ */ -+ int (*quorum_initialize)(struct quorum_callin_functions *fns, -+ sync_callback_fn_t *sync_callback_fn); -+ -+ /* - * Plugin loading and unloading - */ - int (*plugin_interface_reference) ( -@@ -485,7 +557,7 @@ - */ - void (*error_memory_failure) (void); - #define corosync_fatal_error(err) api->fatal_error ((err), __FILE__, __LINE__) -- void (*fatal_error) (corosync_fatal_error_t err, const char *file, unsigned int line); -+ void (*fatal_error) (cs_fatal_error_t err, const char *file, unsigned int line); - }; - - #define SERVICE_ID_MAKE(a,b) ( ((a)<<16) | (b) ) -@@ -496,7 +568,7 @@ - void (*lib_handler_fn) (void *conn, void *msg); - int response_size; - int response_id; -- enum corosync_lib_flow_control flow_control; -+ enum cs_lib_flow_control flow_control; - }; - - struct corosync_exec_handler { -@@ -512,7 +584,8 @@ - char *name; - unsigned short id; - unsigned int private_data_size; -- enum corosync_lib_flow_control flow_control; -+ enum cs_lib_flow_control flow_control; -+ enum cs_lib_allow_inquorate allow_inquorate; - int (*exec_init_fn) (struct corosync_api_v1 *); - int (*exec_exit_fn) (void); - void (*exec_dump_fn) (void); -diff -Naurd corosync-0.92/include/corosync/engine/logsys.h corosync-trunk/include/corosync/engine/logsys.h ---- corosync-0.92/include/corosync/engine/logsys.h 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/include/corosync/engine/logsys.h 2009-01-16 09:59:09.000000000 +0100 -@@ -1,6 +1,6 @@ - /* - * Copyright (c) 2002-2004 MontaVista Software, Inc. -- * Copyright (c) 2006-2007 Red Hat, Inc. -+ * Copyright (c) 2006-2008 Red Hat, Inc. - * - * Author: Steven Dake (sdake@redhat.com) - * Author: Lon Hohberger (lhh@redhat.com) -@@ -41,21 +41,14 @@ - #include - - /* -- * MODE_OUTPUT_SYSLOG_* modes are mutually exclusive -+ * All of the LOG_MODE's can be ORed together for combined behavior - */ - #define LOG_MODE_OUTPUT_FILE (1<<0) - #define LOG_MODE_OUTPUT_STDERR (1<<1) --#define LOG_MODE_OUTPUT_SYSLOG_THREADED (1<<2) --#define LOG_MODE_OUTPUT_SYSLOG_LOSSY (1<<3) --#define LOG_MODE_OUTPUT_SYSLOG_BLOCKING (1<<4) --#define LOG_MODE_DISPLAY_PRIORITY (1<<5) --#define LOG_MODE_DISPLAY_FILELINE (1<<6) --#define LOG_MODE_DISPLAY_TIMESTAMP (1<<7) --#define LOG_MODE_BUFFER_BEFORE_CONFIG (1<<8) --#define LOG_MODE_FLUSH_AFTER_CONFIG (1<<9) --#define LOG_MODE_SHORT_FILELINE (1<<10) --#define LOG_MODE_NOSUBSYS (1<<11) --#define LOG_MODE_FILTER_DEBUG_FROM_SYSLOG (1<<12) -+#define LOG_MODE_OUTPUT_SYSLOG (1<<3) -+#define LOG_MODE_NOSUBSYS (1<<4) -+#define LOG_MODE_FORK (1<<5) -+#define LOG_MODE_THREADED (1<<6) - - /* - * Log priorities, compliant with syslog and SA Forum Log spec. -@@ -71,37 +64,23 @@ - #define LOG_LEVEL_DEBUG LOG_DEBUG - - /* --** Log tags, used by _logsys_trace macros, uses 32 bits => 32 different tags --*/ --#define LOGSYS_TAG_LOG (1<<0) --#define LOGSYS_TAG_ENTER (1<<1) --#define LOGSYS_TAG_LEAVE (1<<2) --#define LOGSYS_TAG_TRACE1 (1<<3) --#define LOGSYS_TAG_TRACE2 (1<<4) --#define LOGSYS_TAG_TRACE3 (1<<5) --#define LOGSYS_TAG_TRACE4 (1<<6) --#define LOGSYS_TAG_TRACE5 (1<<7) --#define LOGSYS_TAG_TRACE6 (1<<8) --#define LOGSYS_TAG_TRACE7 (1<<9) --#define LOGSYS_TAG_TRACE8 (1<<10) -+ * The tag masks are all mutually exclusive -+ */ -+#define LOGSYS_TAG_LOG (0xff<<28) -+#define LOGSYS_TAG_ENTER (1<<27) -+#define LOGSYS_TAG_LEAVE (1<<26) -+#define LOGSYS_TAG_TRACE1 (1<<25) -+#define LOGSYS_TAG_TRACE2 (1<<24) -+#define LOGSYS_TAG_TRACE3 (1<<23) -+#define LOGSYS_TAG_TRACE4 (1<<22) -+#define LOGSYS_TAG_TRACE5 (1<<21) -+#define LOGSYS_TAG_TRACE6 (1<<20) -+#define LOGSYS_TAG_TRACE7 (1<<19) -+#define LOGSYS_TAG_TRACE8 (1<<18) - - /* - * External API - */ -- --struct logsys_logger { -- char subsys[6]; -- unsigned int priority; -- unsigned int tags; -- unsigned int mode; --}; -- --extern struct logsys_logger logsys_loggers[]; -- --extern int logsys_single_id; -- --extern inline int logsys_mkpri (int priority, int id); -- - extern void logsys_config_mode_set ( - unsigned int mode); - -@@ -115,6 +94,9 @@ - char *name, - unsigned int facility); - -+extern void logsys_format_set ( -+ char *format); -+ - extern unsigned int logsys_config_subsys_set ( - const char *subsys, - unsigned int tags, -@@ -137,33 +119,60 @@ - extern const char *logsys_priority_name_get ( - unsigned int priority); - -+extern int logsys_tag_id_get ( -+ const char *name); -+ -+extern const char *logsys_tag_name_get ( -+ unsigned int tag); -+ -+extern void logsys_fork_completed (void); -+ - extern void logsys_flush (void); - - extern void logsys_atsegv (void); - -+extern int logsys_log_rec_store (char *filename); -+ - /* - * Internal APIs that must be globally exported - */ --extern unsigned int _logsys_subsys_create (const char *ident, -+extern unsigned int _logsys_subsys_create ( -+ const char *ident, - unsigned int priority); - - extern void _logsys_nosubsys_set (void); - --extern int _logsys_wthread_create (void); -+extern int _logsys_rec_init (unsigned int size); - --extern void logsys_log_printf (char *file, int line, int priority, -- char *format, ...) __attribute__((format(printf, 4, 5))); -+extern void _logsys_log_printf ( -+ int subsys, -+ char *function_name, -+ char *file_name, -+ int file_line, -+ unsigned int level, -+ char *format, -+ ...) __attribute__((format(printf, 6, 7))); - --extern void _logsys_log_printf2 (char *file, int line, int priority, -- int id, char *format, ...) __attribute__((format(printf, 5, 6))); -+extern void _logsys_log_rec ( -+ int subsys, -+ char *function_name, -+ char *file_name, -+ int file_line, -+ unsigned int rec_ident, -+ ...); - --extern void _logsys_trace (char *file, int line, int tag, int id, -- char *format, ...) __attribute__((format(printf, 5, 6))); -+extern int _logsys_wthread_create (void); - -+static unsigned int logsys_subsys_id __attribute__((unused)) = -1; -+ - /* - * External definitions - */ --#define LOGSYS_DECLARE_SYSTEM(name,mode,file,facility) \ -+extern void *logsys_rec_end; -+ -+#define LOG_REC_END (&logsys_rec_end) -+ -+#define LOGSYS_DECLARE_SYSTEM(name,mode,file,facility,format,rec_size) \ - __attribute__ ((constructor)) static void logsys_system_init (void) \ - { \ - char *error_string; \ -@@ -171,13 +180,11 @@ - logsys_config_mode_set (mode); \ - logsys_config_file_set (&error_string, (file)); \ - logsys_config_facility_set (name, (facility)); \ -- if (((mode) & LOG_MODE_BUFFER_BEFORE_CONFIG) == 0) { \ -- _logsys_wthread_create (); \ -- } \ -+ logsys_format_set (format); \ -+ _logsys_rec_init (rec_size); \ -+ _logsys_wthread_create(); \ - } - --static unsigned int logsys_subsys_id __attribute__((unused)) = -1; \ -- - #define LOGSYS_DECLARE_NOSUBSYS(priority) \ - __attribute__ ((constructor)) static void logsys_nosubsys_init (void) \ - { \ -@@ -206,161 +213,88 @@ - _logsys_subsys_create ((subsys), (priority)); \ - } - --#define log_printf(lvl, format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if ((lvl) <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_log_printf2 (__FILE__, __LINE__, lvl, \ -- logsys_subsys_id, (format), ##args); \ -- } \ --} while(0) -- --#define dprintf(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_log_printf2 (__FILE__, __LINE__, LOG_DEBUG, \ -- logsys_subsys_id, (format), ##args); \ -- } \ --} while(0) -- --#define ENTER_VOID() do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_ENTER, \ -- logsys_subsys_id, ">%s\n", __FUNCTION__); \ -- } \ -+#define log_rec(rec_ident, args...) \ -+do { \ -+ _logsys_log_rec (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, rec_ident, ##args); \ - } while(0) - --#define ENTER(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_ENTER, \ -- logsys_subsys_id, ">%s: " format, __FUNCTION__, \ -- ##args); \ -- } \ -+#define log_printf(lvl, format, args...) \ -+ do { \ -+ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, lvl, format, ##args); \ - } while(0) - --#define LEAVE_VOID() do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_LEAVE, \ -- logsys_subsys_id, "<%s\n", __FUNCTION__); \ -- } \ -+#define ENTER() do { \ -+ _logsys_log_rec (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, LOGSYS_TAG_ENTER, LOG_REC_END); \ - } while(0) - --#define LEAVE(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_LEAVE, \ -- logsys_subsys_id, "<%s: " format, \ -- __FUNCTION__, ##args); \ -- } \ -+#define LEAVE() do { \ -+ _logsys_log_rec (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, LOGSYS_TAG_LEAVE, LOG_REC_END); \ - } while(0) - - #define TRACE1(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE1, \ -- logsys_subsys_id, (format), ##args); \ -- } \ -+ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, LOGSYS_TAG_TRACE1, format, ##args);\ - } while(0) - - #define TRACE2(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE2, \ -- logsys_subsys_id, (format), ##args); \ -- } \ -+ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, LOGSYS_TAG_TRACE2, format, ##args);\ - } while(0) - --#define TRACE3(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE3, \ -- logsys_subsys_id, (format), ##args); \ -- } \ -+#define TRACE3(format, args...) do { \ -+ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, LOGSYS_TAG_TRACE3, format, ##args);\ - } while(0) - --#define TRACE4(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE4, \ -- logsys_subsys_id, (format), ##args); \ -- } \ -+#define TRACE4(format, args...) do { \ -+ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, LOGSYS_TAG_TRACE4, format, ##args);\ - } while(0) - - #define TRACE5(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE5, \ -- logsys_subsys_id, (format), ##args); \ -- } \ -+ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, LOGSYS_TAG_TRACE5, format, ##args);\ - } while(0) - - #define TRACE6(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE6, \ -- logsys_subsys_id, (format), ##args); \ -- } \ -+ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, LOGSYS_TAG_TRACE6, format, ##args);\ - } while(0) - - #define TRACE7(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE7, \ -- logsys_subsys_id, (format), ##args); \ -- } \ -+ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, LOGSYS_TAG_TRACE7, format, ##args);\ - } while(0) - - #define TRACE8(format, args...) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ -- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE8, \ -- logsys_subsys_id, (format), ##args); \ -- } \ -+ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ -+ __FILE__, __LINE__, LOGSYS_TAG_TRACE8, format, ##args);\ - } while(0) - --extern void _logsys_config_priority_set (unsigned int id, unsigned int priority); -- --#define logsys_config_priority_set(priority) do { \ -- if (logsys_single_id) \ -- logsys_subsys_id = 0; \ -- assert (logsys_subsys_id != -1); \ -- _logsys_config_priority_set (logsys_subsys_id, priority); \ --} while(0) -+/* -+ * For one-time programmatic initialization and configuration of logsys -+ * instead of using the DECLARE macros. These APIs do not allow subsystems -+ */ -+int logsys_init ( -+ char *name, -+ int mode, -+ int facility, -+ int priority, -+ char *file, -+ char *format, -+ int rec_size); - --/* simple, function-based api */ -+int logsys_conf ( -+ char *name, -+ int mode, -+ int facility, -+ int priority, -+ char *file); - --int logsys_init (char *name, int mode, int facility, int priority, char *file); --int logsys_conf (char *name, int mode, int facility, int priority, char *file); - void logsys_exit (void); - - #endif /* LOGSYS_H_DEFINED */ -diff -Naurd corosync-0.92/include/corosync/engine/objdb.h corosync-trunk/include/corosync/engine/objdb.h ---- corosync-0.92/include/corosync/engine/objdb.h 2008-09-03 09:58:08.000000000 +0200 -+++ corosync-trunk/include/corosync/engine/objdb.h 2008-10-27 09:25:53.000000000 +0100 -@@ -51,6 +51,13 @@ - OBJECT_KEY_DELETED - } object_change_type_t; - -+typedef enum { -+ OBJDB_RELOAD_NOTIFY_START, -+ OBJDB_RELOAD_NOTIFY_END, -+ OBJDB_RELOAD_NOTIFY_FAILED -+} objdb_reload_notify_type_t; -+ -+ - typedef void (*object_key_change_notify_fn_t)(object_change_type_t change_type, - unsigned int parent_object_handle, - unsigned int object_handle, -@@ -68,6 +75,9 @@ - void *name_pt, int name_len, - void *priv_data_pt); - -+typedef void (*object_reload_notify_fn_t) (objdb_reload_notify_type_t, int flush, -+ void *priv_data_pt); -+ - struct object_valid { - char *object_name; - int object_len; -@@ -198,12 +208,14 @@ - object_key_change_notify_fn_t key_change_notify_fn, - object_create_notify_fn_t object_create_notify_fn, - object_destroy_notify_fn_t object_destroy_notify_fn, -+ object_reload_notify_fn_t object_reload_notify_fn, - void * priv_data_pt); - - void (*object_track_stop) ( - object_key_change_notify_fn_t key_change_notify_fn, - object_create_notify_fn_t object_create_notify_fn, - object_destroy_notify_fn_t object_destroy_notify_fn, -+ object_reload_notify_fn_t object_reload_notify_fn, - void * priv_data_pt); - - int (*object_write_config) (char **error_string); -diff -Naurd corosync-0.92/include/corosync/engine/quorum.h corosync-trunk/include/corosync/engine/quorum.h ---- corosync-0.92/include/corosync/engine/quorum.h 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/include/corosync/engine/quorum.h 2008-12-09 14:51:23.000000000 +0100 -@@ -0,0 +1,44 @@ -+/* -+ * Copyright (c) 2008 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 Red Hat 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 QUORUM_H_DEFINED -+#define QUORUM_H_DEFINED -+ -+typedef void (*quorum_set_quorate_fn_t) (unsigned int *view_list, int view_list_entries, -+ int quorate, struct memb_ring_id *); -+ -+struct quorum_services_api_ver1 { -+ void (*init) (struct corosync_api_v1 *api, quorum_set_quorate_fn_t); -+}; -+#endif /* QUORUM_H_DEFINED */ -diff -Naurd corosync-0.92/include/corosync/evs.h corosync-trunk/include/corosync/evs.h ---- corosync-0.92/include/corosync/evs.h 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/include/corosync/evs.h 2008-11-06 22:49:07.000000000 +0100 -@@ -36,6 +36,7 @@ - - #include - #include -+#include - - /** - * @defgroup corosync Other API services provided by corosync -@@ -49,34 +50,12 @@ - typedef uint64_t evs_handle_t; - - typedef enum { -- EVS_DISPATCH_ONE, -- EVS_DISPATCH_ALL, -- EVS_DISPATCH_BLOCKING --} evs_dispatch_t; -- --typedef enum { - EVS_TYPE_UNORDERED, /* not implemented */ - EVS_TYPE_FIFO, /* same as agreed */ - EVS_TYPE_AGREED, - EVS_TYPE_SAFE /* not implemented */ - } evs_guarantee_t; - --typedef enum { -- EVS_OK = 1, -- EVS_ERR_LIBRARY = 2, -- EVS_ERR_TIMEOUT = 5, -- EVS_ERR_TRY_AGAIN = 6, -- EVS_ERR_INVALID_PARAM = 7, -- EVS_ERR_NO_MEMORY = 8, -- EVS_ERR_BAD_HANDLE = 9, -- EVS_ERR_ACCESS = 11, -- EVS_ERR_NOT_EXIST = 12, -- EVS_ERR_EXIST = 14, -- EVS_ERR_NOT_SUPPORTED = 20, -- EVS_ERR_SECURITY = 29, -- EVS_ERR_TOO_MANY_GROUPS=30 --} evs_error_t; -- - #define TOTEMIP_ADDRLEN (sizeof(struct in6_addr)) - - /** These are the things that get passed around */ -@@ -110,30 +89,30 @@ - /* - * Create a new evs connection - */ --evs_error_t evs_initialize ( -+cs_error_t evs_initialize ( - evs_handle_t *handle, - evs_callbacks_t *callbacks); - - /* - * Close the evs handle - */ --evs_error_t evs_finalize ( -+cs_error_t evs_finalize ( - evs_handle_t handle); - - /* - * Get a file descriptor on which to poll. evs_handle_t is NOT a - * file descriptor and may not be used directly. - */ --evs_error_t evs_fd_get ( -+cs_error_t evs_fd_get ( - evs_handle_t handle, - int *fd); - - /* - * Dispatch messages and configuration changes - */ --evs_error_t evs_dispatch ( -+cs_error_t evs_dispatch ( - evs_handle_t handle, -- evs_dispatch_t dispatch_types); -+ cs_dispatch_flags_t dispatch_types); - - /* - * Join one or more groups. -@@ -141,7 +120,7 @@ - * group that has been joined on handle handle. Any message multicasted - * to a group that has been previously joined will be delivered in evs_dispatch - */ --evs_error_t evs_join ( -+cs_error_t evs_join ( - evs_handle_t handle, - struct evs_group *groups, - int group_cnt); -@@ -149,7 +128,7 @@ - /* - * Leave one or more groups - */ --evs_error_t evs_leave ( -+cs_error_t evs_leave ( - evs_handle_t handle, - struct evs_group *groups, - int group_cnt); -@@ -159,7 +138,7 @@ - * The iovec described by iovec will be multicasted to all groups joined with - * the evs_join interface for handle. - */ --evs_error_t evs_mcast_joined ( -+cs_error_t evs_mcast_joined ( - evs_handle_t handle, - evs_guarantee_t guarantee, - struct iovec *iovec, -@@ -170,7 +149,7 @@ - * Messages will be multicast to groups specified in the api call and not those - * that have been joined (unless they are in the groups parameter). - */ --evs_error_t evs_mcast_groups ( -+cs_error_t evs_mcast_groups ( - evs_handle_t handle, - evs_guarantee_t guarantee, - struct evs_group *groups, -@@ -181,7 +160,7 @@ - /* - * Get membership information from evs - */ --evs_error_t evs_membership_get ( -+cs_error_t evs_membership_get ( - evs_handle_t handle, - unsigned int *local_nodeid, - unsigned int *member_list, -diff -Naurd corosync-0.92/include/corosync/ipc_cfg.h corosync-trunk/include/corosync/ipc_cfg.h ---- corosync-0.92/include/corosync/ipc_cfg.h 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/include/corosync/ipc_cfg.h 2009-01-19 09:31:21.000000000 +0100 -@@ -1,5 +1,6 @@ - /* - * Copyright (c) 2005 MontaVista Software, Inc. -+ * Copyright (c) 2009 Red Hat, Inc. - * - * All rights reserved. - * -@@ -35,8 +36,8 @@ - #define AIS_IPC_CFG_H_DEFINED - - #include -+#include - #include "ipc_gen.h" --#include "saAis.h" - #include "cfg.h" - - enum req_lib_cfg_types { -@@ -47,7 +48,11 @@ - MESSAGE_REQ_CFG_ADMINISTRATIVESTATESET = 4, - MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET = 5, - MESSAGE_REQ_CFG_SERVICELOAD = 6, -- MESSAGE_REQ_CFG_SERVICEUNLOAD = 7 -+ MESSAGE_REQ_CFG_SERVICEUNLOAD = 7, -+ MESSAGE_REQ_CFG_KILLNODE = 8, -+ MESSAGE_REQ_CFG_TRYSHUTDOWN = 9, -+ MESSAGE_REQ_CFG_REPLYTOSHUTDOWN = 10, -+ MESSAGE_REQ_CFG_GET_NODE_ADDRS = 11 - }; - - enum res_lib_cfg_types { -@@ -58,13 +63,17 @@ - MESSAGE_RES_CFG_ADMINISTRATIVESTATESET = 4, - MESSAGE_RES_CFG_ADMINISTRATIVESTATEGET = 5, - MESSAGE_RES_CFG_SERVICELOAD = 6, -- MESSAGE_RES_CFG_SERVICEUNLOAD = 7 -+ MESSAGE_RES_CFG_SERVICEUNLOAD = 7, -+ MESSAGE_RES_CFG_KILLNODE = 8, -+ MESSAGE_RES_CFG_TRYSHUTDOWN = 9, -+ MESSAGE_RES_CFG_TESTSHUTDOWN = 10, -+ MESSAGE_RES_CFG_GET_NODE_ADDRS = 11 - }; - - struct req_lib_cfg_statetrack { - mar_req_header_t header; -- SaUint8T trackFlags; -- CorosyncCfgStateNotificationT *notificationBufferAddress; -+ uint8_t track_flags; -+ corosync_cfg_state_notification_t *notification_buffer_address; - }; - - struct res_lib_cfg_statetrack { -@@ -81,9 +90,9 @@ - - struct req_lib_cfg_administrativestateset { - mar_req_header_t header; -- SaNameT compName; -- CorosyncCfgAdministrativeTargetT administrativeTarget; -- CorosyncCfgAdministrativeStateT administrativeState; -+ cs_name_t comp_name; -+ corosync_cfg_administrative_target_t administrative_target; -+ corosync_cfg_administrative_state_t administrative_state; - }; - - struct res_lib_cfg_administrativestateset { -@@ -92,9 +101,9 @@ - - struct req_lib_cfg_administrativestateget { - mar_req_header_t header; -- SaNameT compName; -- CorosyncCfgAdministrativeTargetT administrativeTarget; -- CorosyncCfgAdministrativeStateT administrativeState; -+ cs_name_t comp_name; -+ corosync_cfg_administrative_target_t administrative_target; -+ corosync_cfg_administrative_state_t administrative_state; - }; - - struct res_lib_cfg_administrativestateget { -@@ -122,7 +131,7 @@ - - struct req_lib_cfg_serviceload { - mar_res_header_t header __attribute__((aligned(8))); -- char *service_name[256] __attribute__((aligned(8))); -+ char service_name[256] __attribute__((aligned(8))); - unsigned int service_ver; - }; - -@@ -132,7 +141,7 @@ - - struct req_lib_cfg_serviceunload { - mar_res_header_t header __attribute__((aligned(8))); -- char *service_name[256] __attribute__((aligned(8))); -+ char service_name[256] __attribute__((aligned(8))); - unsigned int service_ver; - }; - -@@ -140,17 +149,65 @@ - mar_res_header_t header __attribute__((aligned(8))); - }; - -+struct req_lib_cfg_killnode { -+ mar_req_header_t header __attribute__((aligned(8))); -+ unsigned int nodeid __attribute__((aligned(8))); -+ cs_name_t reason __attribute__((aligned(8))); -+}; -+ -+struct res_lib_cfg_killnode { -+ mar_res_header_t header __attribute__((aligned(8))); -+}; -+ -+struct req_lib_cfg_tryshutdown { -+ mar_req_header_t header __attribute__((aligned(8))); -+ unsigned int flags; -+}; -+ -+struct res_lib_cfg_tryshutdown { -+ mar_res_header_t header __attribute__((aligned(8))); -+}; -+ -+struct req_lib_cfg_replytoshutdown { -+ mar_res_header_t header __attribute__((aligned(8))); -+ unsigned int response; -+}; -+ -+struct res_lib_cfg_testshutdown { -+ mar_res_header_t header __attribute__((aligned(8))); -+ unsigned int flags; -+}; -+ -+struct req_lib_cfg_get_node_addrs { -+ mar_req_header_t header __attribute__((aligned(8))); -+ unsigned int nodeid; -+}; -+ -+struct res_lib_cfg_get_node_addrs { -+ mar_res_header_t header __attribute__((aligned(8))); -+ unsigned int family; -+ unsigned int num_addrs; -+ char addrs[TOTEMIP_ADDRLEN][0]; -+}; -+ - typedef enum { - AIS_AMF_ADMINISTRATIVETARGET_SERVICEUNIT = 0, - AIS_AMF_ADMINISTRATIVETARGET_SERVICEGROUP = 1, - AIS_AMF_ADMINISTRATIVETARGET_COMPONENTSERVICEINSTANCE = 2, - AIS_AMF_ADMINISTRATIVETARGET_NODE = 3 --} corosyncAdministrativeTarget; -+} corosync_administrative_target_t; - - typedef enum { - AIS_AMF_ADMINISTRATIVESTATE_UNLOCKED = 0, - AIS_AMF_ADMINISTRATIVESTATE_LOCKED = 1, - AIS_AMF_ADMINISTRATIVESTATE_STOPPING = 2 --} corosyncAdministrativeState; -+} corosync_administrative_state_t; -+ -+typedef enum { -+ CFG_SHUTDOWN_FLAG_REQUEST = 0, -+ CFG_SHUTDOWN_FLAG_REGARDLESS = 1, -+ CFG_SHUTDOWN_FLAG_IMMEDIATE = 2, -+} corosync_shutdown_flags_t; -+ - - #endif /* AIS_IPC_CFG_H_DEFINED */ -diff -Naurd corosync-0.92/include/corosync/ipc_confdb.h corosync-trunk/include/corosync/ipc_confdb.h ---- corosync-0.92/include/corosync/ipc_confdb.h 2008-09-03 09:58:08.000000000 +0200 -+++ corosync-trunk/include/corosync/ipc_confdb.h 2008-11-06 22:49:07.000000000 +0100 -@@ -35,7 +35,7 @@ - #define IPC_CONFDB_H_DEFINED - - #include --#include "saAis.h" -+#include - #include "ipc_gen.h" - - enum req_confdb_types { -diff -Naurd corosync-0.92/include/corosync/ipc_cpg.h corosync-trunk/include/corosync/ipc_cpg.h ---- corosync-0.92/include/corosync/ipc_cpg.h 2008-09-17 21:15:00.000000000 +0200 -+++ corosync-trunk/include/corosync/ipc_cpg.h 2009-01-08 07:29:16.000000000 +0100 -@@ -35,7 +35,7 @@ - #define IPC_CPG_H_DEFINED - - #include --#include "saAis.h" -+#include - #include "ipc_gen.h" - #include "mar_cpg.h" - -@@ -143,7 +143,7 @@ - - struct req_lib_cpg_membership { - mar_req_header_t header __attribute__((aligned(8))); -- mar_cpg_name_t group_name __attribute__((aligned(8))); -+// mar_cpg_name_t group_name __attribute__((aligned(8))); - }; - - struct res_lib_cpg_confchg_callback { -diff -Naurd corosync-0.92/include/corosync/ipc_evs.h corosync-trunk/include/corosync/ipc_evs.h ---- corosync-0.92/include/corosync/ipc_evs.h 2008-08-14 16:59:50.000000000 +0200 -+++ corosync-trunk/include/corosync/ipc_evs.h 2008-11-06 22:49:07.000000000 +0100 -@@ -34,8 +34,7 @@ - #ifndef IPC_EVS_H_DEFINED - #define IPC_EVS_H_DEFINED - --//#include --#include "saAis.h" -+#include - #include "evs.h" - #include "ipc_gen.h" - -diff -Naurd corosync-0.92/include/corosync/ipc_gen.h corosync-trunk/include/corosync/ipc_gen.h ---- corosync-0.92/include/corosync/ipc_gen.h 2008-08-14 16:59:50.000000000 +0200 -+++ corosync-trunk/include/corosync/ipc_gen.h 2008-11-06 22:49:07.000000000 +0100 -@@ -46,7 +46,9 @@ - MSG_SERVICE = 6, - CFG_SERVICE = 7, - CPG_SERVICE = 8, -- CONFDB_SERVICE = 10 -+ CONFDB_SERVICE = 10, -+ QUORUM_SERVICE = 11, -+ PLOAD_SERVICE = 12 - }; - - enum req_init_types { -@@ -72,7 +74,7 @@ - typedef struct { - int size; __attribute__((aligned(8))) - int id __attribute__((aligned(8))); -- SaAisErrorT error __attribute__((aligned(8))); -+ cs_error_t error __attribute__((aligned(8))); - } mar_res_header_t __attribute__((aligned(8))); - - typedef struct { -diff -Naurd corosync-0.92/include/corosync/ipc_pload.h corosync-trunk/include/corosync/ipc_pload.h ---- corosync-0.92/include/corosync/ipc_pload.h 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/include/corosync/ipc_pload.h 2008-11-06 22:49:07.000000000 +0100 -@@ -0,0 +1,71 @@ -+/* -+ * Copyright (c) 2008 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 IPC_PLOAD_H_DEFINED -+#define IPC_PLOAD_H_DEFINED -+ -+#include -+#include "pload.h" -+#include "ipc_gen.h" -+ -+enum req_lib_evs_types { -+ MESSAGE_REQ_PLOAD_START = 0, -+}; -+ -+enum res_lib_evs_types { -+ MESSAGE_RES_PLOAD_START = 0, -+}; -+ -+struct res_lib_pload_start { -+ mar_res_header_t header; -+ unsigned int dataset[1024]; -+}; -+ -+struct res_lib_pload_mcast { -+ mar_res_header_t header; -+}; -+ -+struct req_lib_pload_start { -+ mar_req_header_t header; -+ unsigned int msg_code; -+ unsigned int msg_size; -+ unsigned int msg_count; -+ unsigned int time_interval; -+}; -+ -+struct req_lib_pload_mcast { -+ mar_req_header_t header; -+ unsigned int code; -+}; -+ -+#endif /* IPC_PLOAD_H_DEFINED */ -diff -Naurd corosync-0.92/include/corosync/ipc_quorum.h corosync-trunk/include/corosync/ipc_quorum.h ---- corosync-0.92/include/corosync/ipc_quorum.h 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/include/corosync/ipc_quorum.h 2008-11-06 22:49:07.000000000 +0100 -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (c) 2008 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 IPC_QUORUM_H_DEFINED -+#define IPC_QUORUM_H_DEFINED -+ -+#include -+#include -+#include "corosync/ipc_gen.h" -+ -+enum req_quorum_types { -+ MESSAGE_REQ_QUORUM_GETQUORATE = 0, -+ MESSAGE_REQ_QUORUM_TRACKSTART, -+ MESSAGE_REQ_QUORUM_TRACKSTOP -+}; -+ -+enum res_quorum_types { -+ MESSAGE_RES_QUORUM_GETQUORATE = 0, -+ MESSAGE_RES_QUORUM_TRACKSTART, -+ MESSAGE_RES_QUORUM_TRACKSTOP, -+ MESSAGE_RES_QUORUM_NOTIFICATION -+}; -+ -+struct req_lib_quorum_trackstart { -+ mar_req_header_t header __attribute__((aligned(8))); -+ unsigned int track_flags; -+}; -+ -+ -+struct res_lib_quorum_getquorate { -+ mar_res_header_t header __attribute__((aligned(8))); -+ mar_uint32_t quorate; -+}; -+ -+struct res_lib_quorum_notification { -+ mar_res_header_t header __attribute__((aligned(8))); -+ mar_int32_t quorate __attribute__((aligned(8))); -+ mar_uint64_t ring_seq __attribute__((aligned(8))); -+ mar_uint32_t view_list_entries __attribute__((aligned(8))); -+ mar_uint32_t view_list[]; -+}; -+ -+#endif -diff -Naurd corosync-0.92/include/corosync/ipc_votequorum.h corosync-trunk/include/corosync/ipc_votequorum.h ---- corosync-0.92/include/corosync/ipc_votequorum.h 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/include/corosync/ipc_votequorum.h 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,149 @@ -+/* -+ * Copyright (c) 2009 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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 IPC_VOTEQUORUM_H_DEFINED -+#define IPC_VOTEQUORUM_H_DEFINED -+ -+#include "corosync/corotypes.h" -+#include "corosync/ipc_gen.h" -+ -+// ILLEGAL value!! -+#define VOTEQUORUM_SERVICE 15 -+ -+#define VOTEQUORUM_MAX_QDISK_NAME_LEN 255 -+ -+ -+enum req_votequorum_types { -+ MESSAGE_REQ_VOTEQUORUM_GETINFO = 0, -+ MESSAGE_REQ_VOTEQUORUM_SETEXPECTED, -+ MESSAGE_REQ_VOTEQUORUM_SETVOTES, -+ MESSAGE_REQ_VOTEQUORUM_QDISK_REGISTER, -+ MESSAGE_REQ_VOTEQUORUM_QDISK_UNREGISTER, -+ MESSAGE_REQ_VOTEQUORUM_QDISK_POLL, -+ MESSAGE_REQ_VOTEQUORUM_QDISK_GETINFO, -+ MESSAGE_REQ_VOTEQUORUM_SETSTATE, -+ MESSAGE_REQ_VOTEQUORUM_LEAVING, -+ MESSAGE_REQ_VOTEQUORUM_TRACKSTART, -+ MESSAGE_REQ_VOTEQUORUM_TRACKSTOP -+}; -+ -+enum res_votequorum_types { -+ MESSAGE_RES_VOTEQUORUM_STATUS = 0, -+ MESSAGE_RES_VOTEQUORUM_GETINFO, -+ MESSAGE_RES_VOTEQUORUM_QDISK_GETINFO, -+ MESSAGE_RES_VOTEQUORUM_TRACKSTART, -+ MESSAGE_RES_VOTEQUORUM_NOTIFICATION -+}; -+ -+struct req_lib_votequorum_setvotes { -+ mar_req_header_t header __attribute__((aligned(8))); -+ unsigned int votes; -+ int nodeid; -+}; -+ -+struct req_lib_votequorum_qdisk_register { -+ mar_req_header_t header __attribute__((aligned(8))); -+ unsigned int votes; -+ char name[VOTEQUORUM_MAX_QDISK_NAME_LEN]; -+}; -+ -+struct req_lib_votequorum_qdisk_poll { -+ mar_req_header_t header __attribute__((aligned(8))); -+ int state; -+}; -+ -+struct req_lib_votequorum_setexpected { -+ mar_req_header_t header __attribute__((aligned(8))); -+ unsigned int expected_votes; -+}; -+ -+struct req_lib_votequorum_trackstart { -+ mar_req_header_t header __attribute__((aligned(8))); -+ uint64_t context; -+ unsigned int track_flags; -+}; -+ -+struct req_lib_votequorum_general { -+ mar_req_header_t header __attribute__((aligned(8))); -+}; -+ -+#define VOTEQUORUM_REASON_KILL_REJECTED 1 -+#define VOTEQUORUM_REASON_KILL_APPLICATION 2 -+#define VOTEQUORUM_REASON_KILL_REJOIN 3 -+ -+struct req_lib_votequorum_getinfo { -+ mar_req_header_t header __attribute__((aligned(8))); -+ int nodeid; -+}; -+ -+struct res_lib_votequorum_status { -+ mar_res_header_t header __attribute__((aligned(8))); -+}; -+ -+#define VOTEQUORUM_INFO_FLAG_HASSTATE 1 -+#define VOTEQUORUM_INFO_FLAG_DISALLOWED 2 -+#define VOTEQUORUM_INFO_FLAG_TWONODE 4 -+#define VOTEQUORUM_INFO_FLAG_QUORATE 8 -+ -+struct res_lib_votequorum_getinfo { -+ mar_res_header_t header __attribute__((aligned(8))); -+ int nodeid; -+ unsigned int votes; -+ unsigned int expected_votes; -+ unsigned int highest_expected; -+ unsigned int total_votes; -+ unsigned int quorum; -+ unsigned int flags; -+}; -+ -+struct res_lib_votequorum_qdisk_getinfo { -+ mar_res_header_t header __attribute__((aligned(8))); -+ unsigned int votes; -+ unsigned int state; -+ char name[VOTEQUORUM_MAX_QDISK_NAME_LEN]; -+}; -+ -+struct votequorum_node { -+ mar_uint32_t nodeid; -+ mar_uint32_t state; -+}; -+ -+struct res_lib_votequorum_notification { -+ mar_res_header_t header __attribute__((aligned(8))); -+ mar_uint32_t quorate __attribute__((aligned(8))); -+ mar_uint64_t context __attribute__((aligned(8))); -+ mar_uint32_t node_list_entries __attribute__((aligned(8))); -+ struct votequorum_node node_list[] __attribute__((aligned(8))); -+}; -+ -+#endif -diff -Naurd corosync-0.92/include/corosync/mar_gen.h corosync-trunk/include/corosync/mar_gen.h ---- corosync-0.92/include/corosync/mar_gen.h 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/include/corosync/mar_gen.h 2008-11-06 22:49:07.000000000 +0100 -@@ -43,7 +43,7 @@ - #endif - #include - --#include -+#include - #include - - typedef int8_t mar_int8_t; -@@ -98,7 +98,7 @@ - - typedef struct { - mar_uint16_t length __attribute__((aligned(8))); -- mar_uint8_t value[SA_MAX_NAME_LENGTH] __attribute__((aligned(8))); -+ mar_uint8_t value[CS_MAX_NAME_LENGTH] __attribute__((aligned(8))); - } mar_name_t; - - static inline char *get_mar_name_t (mar_name_t *name) { -@@ -121,19 +121,19 @@ - } - - static inline void marshall_from_mar_name_t ( -- SaNameT *dest, -+ cs_name_t *dest, - mar_name_t *src) - { - dest->length = src->length; -- memcpy (dest->value, src->value, SA_MAX_NAME_LENGTH); -+ memcpy (dest->value, src->value, CS_MAX_NAME_LENGTH); - } - - static inline void marshall_to_mar_name_t ( - mar_name_t *dest, -- SaNameT *src) -+ cs_name_t *src) - { - dest->length = src->length; -- memcpy (dest->value, src->value, SA_MAX_NAME_LENGTH); -+ memcpy (dest->value, src->value, CS_MAX_NAME_LENGTH); - } - - typedef enum { -@@ -148,7 +148,7 @@ - swab_mar_uint64_t (to_swab); - } - --#define MAR_TIME_END ((SaTimeT)0x7fffffffffffffffull) -+#define MAR_TIME_END ((int64_t)0x7fffffffffffffffull) - #define MAR_TIME_BEGIN 0x0ULL - #define MAR_TIME_UNKNOWN 0x8000000000000000ULL - -@@ -158,7 +158,7 @@ - #define MAR_TIME_ONE_MINUTE 60000000000ULL - #define MAR_TIME_ONE_HOUR 3600000000000ULL - #define MAR_TIME_ONE_DAY 86400000000000ULL --#define MAR_TIME_MAX SA_TIME_END -+#define MAR_TIME_MAX CS_TIME_END - - #define MAR_TRACK_CURRENT 0x01 - #define MAR_TRACK_CHANGES 0x02 -diff -Naurd corosync-0.92/include/corosync/pload.h corosync-trunk/include/corosync/pload.h ---- corosync-0.92/include/corosync/pload.h 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/include/corosync/pload.h 2008-10-30 23:41:34.000000000 +0100 -@@ -0,0 +1,100 @@ -+/* -+ * Copyright (c) 2008 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 COROSYNC_PLOAD_H_DEFINED -+#define COROSYNC_PLOAD_H_DEFINED -+ -+#include -+#include -+ -+/** -+ * @defgroup corosync Other API services provided by corosync -+ */ -+/** -+ * @addtogroup pload_corosync -+ * -+ * @{ -+ */ -+ -+typedef uint64_t pload_handle_t; -+ -+typedef enum { -+ PLOAD_OK = 1, -+ PLOAD_ERR_LIBRARY = 2, -+ PLOAD_ERR_TIMEOUT = 5, -+ PLOAD_ERR_TRY_AGAIN = 6, -+ PLOAD_ERR_INVALID_PARAM = 7, -+ PLOAD_ERR_NO_MEMORY = 8, -+ PLOAD_ERR_BAD_HANDLE = 9, -+ PLOAD_ERR_ACCESS = 11, -+ PLOAD_ERR_NOT_EXIST = 12, -+ PLOAD_ERR_EXIST = 14, -+ PLOAD_ERR_NOT_SUPPORTED = 20, -+ PLOAD_ERR_SECURITY = 29, -+ PLOAD_ERR_TOO_MANY_GROUPS=30 -+} pload_error_t; -+ -+typedef struct { -+ int callback; -+} pload_callbacks_t; -+ -+/** @} */ -+ -+/* -+ * Create a new pload connection -+ */ -+pload_error_t pload_initialize ( -+ pload_handle_t *handle, -+ pload_callbacks_t *callbacks); -+ -+/* -+ * Close the pload handle -+ */ -+pload_error_t pload_finalize ( -+ pload_handle_t handle); -+ -+/* -+ * Get a file descriptor on which to poll. pload_handle_t is NOT a -+ * file descriptor and may not be used directly. -+ */ -+pload_error_t pload_fd_get ( -+ pload_handle_t handle, -+ int *fd); -+ -+unsigned int pload_start ( -+ pload_handle_t handle, -+ unsigned int code, -+ unsigned int msg_count, -+ unsigned int msg_size); -+ -+#endif /* COROSYNC_PLOAD_H_DEFINED */ -diff -Naurd corosync-0.92/include/corosync/quorum.h corosync-trunk/include/corosync/quorum.h ---- corosync-0.92/include/corosync/quorum.h 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/include/corosync/quorum.h 2008-12-08 16:55:41.000000000 +0100 -@@ -0,0 +1,97 @@ -+/* -+ * Copyright (c) 2008 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfi@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 Red Hat, 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 COROSYNC_QUORUM_H_DEFINED -+#define COROSYNC_QUORUM_H_DEFINED -+ -+#include -+ -+typedef uint64_t quorum_handle_t; -+ -+typedef struct { -+ uint32_t nodeid; -+ uint32_t state; -+} quorum_node_t; -+ -+typedef void (*quorum_notification_fn_t) ( -+ quorum_handle_t handle, -+ uint32_t quorate, -+ uint64_t ring_seq, -+ uint32_t view_list_entries, -+ uint32_t *view_list -+ ); -+ -+typedef struct { -+ quorum_notification_fn_t quorum_notify_fn; -+} quorum_callbacks_t; -+ -+ -+/* -+ * Create a new quorum connection -+ */ -+cs_error_t quorum_initialize ( -+ quorum_handle_t *handle, -+ quorum_callbacks_t *callbacks); -+ -+/* -+ * Close the quorum handle -+ */ -+cs_error_t quorum_finalize ( -+ quorum_handle_t handle); -+ -+ -+/* -+ * Dispatch messages and configuration changes -+ */ -+cs_error_t quorum_dispatch ( -+ quorum_handle_t handle, -+ cs_dispatch_flags_t dispatch_types); -+ -+ -+/* -+ * Get quorum information. -+ */ -+cs_error_t quorum_getquorate ( -+ quorum_handle_t handle, -+ int *quorate); -+ -+/* Track node and quorum changes */ -+cs_error_t quorum_trackstart ( -+ quorum_handle_t handle, -+ unsigned int flags ); -+ -+cs_error_t quorum_trackstop ( -+ quorum_handle_t handle); -+ -+ -+#endif /* COROSYNC_QUORUM_H_DEFINED */ -diff -Naurd corosync-0.92/include/corosync/saAis.h corosync-trunk/include/corosync/saAis.h ---- corosync-0.92/include/corosync/saAis.h 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/include/corosync/saAis.h 1970-01-01 01:00:00.000000000 +0100 -@@ -1,152 +0,0 @@ --/* -- * Copyright (c) 2002-2003 MontaVista Software, Inc. -- * Copyright (c) 2006-2008 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 AIS_TYPES_H_DEFINED --#define AIS_TYPES_H_DEFINED -- --/** -- * @defgroup saf Service Availability Forum Application Interface Specification -- */ -- --typedef enum { -- SA_FALSE = 0, -- SA_TRUE = 1 --} SaBoolT; -- --#ifndef COROSYNC_SOLARIS --#include --#else --#include --#endif -- --typedef int8_t SaInt8T; --typedef int16_t SaInt16T; --typedef int32_t SaInt32T; --typedef int64_t SaInt64T; -- --typedef uint8_t SaUint8T; --typedef uint16_t SaUint16T; --typedef uint32_t SaUint32T; --typedef uint64_t SaUint64T; -- --typedef float SaFloatT; --typedef double SaDoubleT; --typedef char * SaStringT; --typedef SaInt64T SaTimeT; -- --#define SA_TIME_END ((SaTimeT)0x7FFFFFFFFFFFFFFFULL) --#define SA_TIME_BEGIN 0x0ULL --#define SA_TIME_UNKNOWN 0x8000000000000000ULL -- --#define SA_TIME_ONE_MICROSECOND 1000ULL --#define SA_TIME_ONE_MILLISECOND 1000000ULL --#define SA_TIME_ONE_SECOND 1000000000ULL --#define SA_TIME_ONE_MINUTE 60000000000ULL --#define SA_TIME_ONE_HOUR 3600000000000ULL --#define SA_TIME_ONE_DAY 86400000000000ULL --#define SA_TIME_MAX SA_TIME_END -- --#define SA_MAX_NAME_LENGTH 256 -- --typedef struct { -- SaUint16T length; -- SaUint8T value[SA_MAX_NAME_LENGTH]; --} SaNameT; -- --typedef struct { -- char releaseCode; -- unsigned char majorVersion; -- unsigned char minorVersion; --} SaVersionT; -- --typedef SaUint64T SaNtfIdentifierT; -- --#define SA_TRACK_CURRENT 0x01 --#define SA_TRACK_CHANGES 0x02 --#define SA_TRACK_CHANGES_ONLY 0x04 -- --typedef enum { -- SA_DISPATCH_ONE = 1, -- SA_DISPATCH_ALL = 2, -- SA_DISPATCH_BLOCKING = 3 --} SaDispatchFlagsT; -- --typedef enum { -- SA_AIS_OK = 1, -- SA_AIS_ERR_LIBRARY = 2, -- SA_AIS_ERR_VERSION = 3, -- SA_AIS_ERR_INIT = 4, -- SA_AIS_ERR_TIMEOUT = 5, -- SA_AIS_ERR_TRY_AGAIN = 6, -- SA_AIS_ERR_INVALID_PARAM = 7, -- SA_AIS_ERR_NO_MEMORY = 8, -- SA_AIS_ERR_BAD_HANDLE = 9, -- SA_AIS_ERR_BUSY = 10, -- SA_AIS_ERR_ACCESS = 11, -- SA_AIS_ERR_NOT_EXIST = 12, -- SA_AIS_ERR_NAME_TOO_LONG = 13, -- SA_AIS_ERR_EXIST = 14, -- SA_AIS_ERR_NO_SPACE = 15, -- SA_AIS_ERR_INTERRUPT = 16, -- SA_AIS_ERR_NAME_NOT_FOUND = 17, -- SA_AIS_ERR_NO_RESOURCES = 18, -- SA_AIS_ERR_NOT_SUPPORTED = 19, -- SA_AIS_ERR_BAD_OPERATION = 20, -- SA_AIS_ERR_FAILED_OPERATION = 21, -- SA_AIS_ERR_MESSAGE_ERROR = 22, -- SA_AIS_ERR_QUEUE_FULL = 23, -- SA_AIS_ERR_QUEUE_NOT_AVAILABLE = 24, -- SA_AIS_ERR_BAD_FLAGS = 25, -- SA_AIS_ERR_TOO_BIG = 26, -- SA_AIS_ERR_NO_SECTIONS = 27 --} SaAisErrorT; -- --typedef union { -- SaInt64T int64Value; -- SaUint64T uint64Value; -- SaTimeT timeValue; -- SaFloatT floatValue; -- SaDoubleT doubleValue; --} SaLimitValueT; -- --typedef SaUint64T SaSelectionObjectT; -- --typedef SaUint64T SaInvocationT; -- --typedef SaUint64T SaSizeT; -- --#define SA_HANDLE_INVALID 0x0ULL -- --#endif /* AIS_TYPES_H_DEFINED */ -diff -Naurd corosync-0.92/include/corosync/totem/totem.h corosync-trunk/include/corosync/totem/totem.h ---- corosync-0.92/include/corosync/totem/totem.h 2008-08-20 02:57:40.000000000 +0200 -+++ corosync-trunk/include/corosync/totem/totem.h 2008-10-30 23:41:34.000000000 +0100 -@@ -50,26 +50,6 @@ - #define SEND_THREADS_MAX 16 - #define INTERFACE_MAX 2 - --/* -- * Array location of various timeouts as -- * specified in corosync.conf. The last enum -- * specifies the size of the timeouts array and -- * needs to remain the last item in the list. -- */ --enum { -- TOTEM_RETRANSMITS_BEFORE_LOSS, -- TOTEM_TOKEN, -- TOTEM_RETRANSMIT_TOKEN, -- TOTEM_HOLD_TOKEN, -- TOTEM_JOIN, -- TOTEM_CONSENSUS, -- TOTEM_MERGE, -- TOTEM_DOWNCHECK, -- TOTEM_FAIL_RECV_CONST, -- -- MAX_TOTEM_TIMEOUTS /* Last item */ --} totem_timeout_types; -- - struct totem_interface { - struct totem_ip_address bindnet; - struct totem_ip_address boundto; -@@ -78,12 +58,21 @@ - }; - - struct totem_logging_configuration { -- void (*log_printf) (char *, int, int, char *, ...) __attribute__((format(printf, 4, 5))); -+ void (*log_printf) ( -+ int subsys, -+ char *function_name, -+ char *file_name, -+ int file_line, -+ unsigned int level, -+ char *format, -+ ...) __attribute__((format(printf, 6, 7))); -+ - int log_level_security; - int log_level_error; - int log_level_warning; - int log_level_notice; - int log_level_debug; -+ int log_subsys_id; - }; - - struct totem_config { -@@ -161,6 +150,7 @@ - TOTEM_CONFIGURATION_TRANSITIONAL - }; - -+#define TOTEM_CALLBACK_TOKEN_TYPE - enum totem_callback_token_type { - TOTEM_CALLBACK_TOKEN_RECEIVED = 1, - TOTEM_CALLBACK_TOKEN_SENT = 2 -diff -Naurd corosync-0.92/include/corosync/totem/totemip.h corosync-trunk/include/corosync/totem/totemip.h ---- corosync-0.92/include/corosync/totem/totemip.h 2008-08-14 16:59:50.000000000 +0200 -+++ corosync-trunk/include/corosync/totem/totemip.h 2009-01-25 22:15:25.000000000 +0100 -@@ -72,7 +72,7 @@ - extern int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr, - uint16_t port, struct sockaddr_storage *saddr, int *addrlen); - extern int totemip_parse(struct totem_ip_address *totemip, char *addr, int family); --extern int totemip_iface_check(struct totem_ip_address *bindnet, struct totem_ip_address *boundto, int *interface_up, int *interface_num); -+extern int totemip_iface_check(struct totem_ip_address *bindnet, struct totem_ip_address *boundto, int *interface_up, int *interface_num, int mask_high_bit); - - /* These two simulate a zero in_addr by clearing the family field */ - static inline void totemip_zero_set(struct totem_ip_address *addr) -diff -Naurd corosync-0.92/include/corosync/totem/totempg.h corosync-trunk/include/corosync/totem/totempg.h ---- corosync-0.92/include/corosync/totem/totempg.h 2008-08-14 16:59:50.000000000 +0200 -+++ corosync-trunk/include/corosync/totem/totempg.h 2008-12-01 19:44:55.000000000 +0100 -@@ -139,7 +139,7 @@ - - extern char *totempg_ifaces_print (unsigned int nodeid); - --extern int totempg_my_nodeid_get (void); -+extern unsigned int totempg_my_nodeid_get (void); - - extern int totempg_my_family_get (void); - -diff -Naurd corosync-0.92/include/corosync/votequorum.h corosync-trunk/include/corosync/votequorum.h ---- corosync-0.92/include/corosync/votequorum.h 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/include/corosync/votequorum.h 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,198 @@ -+/* -+ * Copyright (c) 2009 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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 COROSYNC_VOTEQUORUM_H_DEFINED -+#define COROSYNC_VOTEQUORUM_H_DEFINED -+ -+typedef uint64_t votequorum_handle_t; -+ -+ -+#define VOTEQUORUM_MAX_QDISK_NAME_LEN 255 -+ -+#define VOTEQUORUM_INFO_FLAG_HASSTATE 1 -+#define VOTEQUORUM_INFO_FLAG_DISALLOWED 2 -+#define VOTEQUORUM_INFO_FLAG_TWONODE 4 -+#define VOTEQUORUM_INFO_FLAG_QUORATE 8 -+ -+#define NODESTATE_JOINING 1 -+#define NODESTATE_MEMBER 2 -+#define NODESTATE_DEAD 3 -+#define NODESTATE_LEAVING 4 -+#define NODESTATE_DISALLOWED 5 -+ -+ -+/** @} */ -+ -+struct votequorum_info { -+ unsigned int node_id; -+ unsigned int node_votes; -+ unsigned int node_expected_votes; -+ unsigned int highest_expected; -+ unsigned int total_votes; -+ unsigned int quorum; -+ unsigned int flags; -+}; -+ -+struct votequorum_qdisk_info { -+ unsigned int votes; -+ unsigned int state; -+ char name[VOTEQUORUM_MAX_QDISK_NAME_LEN]; -+}; -+ -+typedef struct { -+ uint32_t nodeid; -+ uint32_t state; -+} votequorum_node_t; -+ -+ -+typedef void (*votequorum_notification_fn_t) ( -+ votequorum_handle_t handle, -+ uint64_t context, -+ uint32_t quorate, -+ uint32_t node_list_entries, -+ votequorum_node_t node_list[] -+ ); -+ -+typedef struct { -+ votequorum_notification_fn_t votequorum_notify_fn; -+} votequorum_callbacks_t; -+ -+ -+/* -+ * Create a new quorum connection -+ */ -+cs_error_t votequorum_initialize ( -+ votequorum_handle_t *handle, -+ votequorum_callbacks_t *callbacks); -+ -+/* -+ * Close the quorum handle -+ */ -+cs_error_t votequorum_finalize ( -+ votequorum_handle_t handle); -+ -+ -+/* -+ * Dispatch messages and configuration changes -+ */ -+cs_error_t votequorum_dispatch ( -+ votequorum_handle_t handle, -+ cs_dispatch_flags_t dispatch_types); -+ -+ -+/* -+ * Get quorum information. -+ */ -+cs_error_t votequorum_getinfo ( -+ votequorum_handle_t handle, -+ unsigned int nodeid, -+ struct votequorum_info *info); -+ -+/* -+ * set expected_votes -+ */ -+cs_error_t votequorum_setexpected ( -+ votequorum_handle_t handle, -+ unsigned int expected_votes); -+ -+/* -+ * set votes for a node -+ */ -+cs_error_t votequorum_setvotes ( -+ votequorum_handle_t handle, -+ unsigned int nodeid, -+ unsigned int votes); -+ -+/* -+ * Register a quorum device -+ * it will be DEAD until polled -+ */ -+cs_error_t votequorum_qdisk_register ( -+ votequorum_handle_t handle, -+ char *name, -+ unsigned int votes); -+ -+/* -+ * Unregister a quorum device -+ */ -+cs_error_t votequorum_qdisk_unregister ( -+ votequorum_handle_t handle); -+ -+/* -+ * Poll a quorum device -+ */ -+cs_error_t votequorum_qdisk_poll ( -+ votequorum_handle_t handle, -+ unsigned int state); -+ -+/* -+ * Get quorum device information -+ */ -+cs_error_t votequorum_qdisk_getinfo ( -+ votequorum_handle_t handle, -+ struct votequorum_qdisk_info *info); -+ -+/* -+ * Set the "hasstate" bit for this node -+ */ -+cs_error_t votequorum_setstate ( -+ votequorum_handle_t handle); -+ -+/* Track node and quorum changes */ -+cs_error_t votequorum_trackstart ( -+ votequorum_handle_t handle, -+ uint64_t context, -+ unsigned int flags ); -+ -+cs_error_t votequorum_trackstop ( -+ votequorum_handle_t handle); -+ -+/* -+ * Set our LEAVING flag. we should exit soon after this -+ */ -+cs_error_t votequorum_leaving ( -+ votequorum_handle_t handle); -+ -+/* -+ * Save and retrieve private data/context -+ */ -+cs_error_t votequorum_context_get ( -+ votequorum_handle_t handle, -+ void **context); -+ -+cs_error_t votequorum_context_set ( -+ votequorum_handle_t handle, -+ void *context); -+ -+#endif /* COROSYNC_VOTEQUORUM_H_DEFINED */ -diff -Naurd corosync-0.92/lcr/Makefile corosync-trunk/lcr/Makefile ---- corosync-0.92/lcr/Makefile 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/lcr/Makefile 2008-11-11 18:26:58.000000000 +0100 -@@ -84,3 +84,6 @@ - rm -f test libtest.so* *.o uic liblcr.so* liblcr.a *.lcrso *.da *.ba *.bb *.bbg \ - test_static - -+lint: -+ -splint $(LINT_FLAGS) $(CFLAGS) lcr_ifact.c uic.c uis.c -+ -diff -Naurd corosync-0.92/lcr/uic.c corosync-trunk/lcr/uic.c ---- corosync-0.92/lcr/uic.c 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/lcr/uic.c 2008-11-11 19:13:47.000000000 +0100 -@@ -88,7 +88,7 @@ - return 0; - } - --struct req_msg { -+struct uic_req_msg { - int len; - char msg[0]; - }; -@@ -97,12 +97,13 @@ - { - struct msghdr msg_send; - struct iovec iov_send[2]; -- struct req_msg req_msg; -+ struct uic_req_msg req_msg; -+ ssize_t send_res; - int res; - - req_msg.len = strlen (msg) + 1; - iov_send[0].iov_base = (void *)&req_msg; -- iov_send[0].iov_len = sizeof (struct req_msg); -+ iov_send[0].iov_len = sizeof (struct uic_req_msg); - iov_send[1].iov_base = (void *)msg; - iov_send[1].iov_len = req_msg.len; - -@@ -120,12 +121,14 @@ - #endif - - retry_send: -- res = sendmsg (fd, &msg_send, 0); -- if (res == -1 && errno == EINTR) { -+ send_res = sendmsg (fd, &msg_send, 0); -+ if (send_res == -1 && errno == EINTR) { - goto retry_send; - } -- if (res == -1) { -+ if (send_res == -1) { - res = -errno; -+ } else { -+ res = (int)send_res; - } - return (res); - -diff -Naurd corosync-0.92/lcr/uis.c corosync-trunk/lcr/uis.c ---- corosync-0.92/lcr/uis.c 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/lcr/uis.c 2008-11-11 18:26:58.000000000 +0100 -@@ -115,14 +115,14 @@ - } - }; - --struct req_msg { -+struct uis_req_msg { - int len; - char msg[0]; - }; - - static void lcr_uis_dispatch (int fd) - { -- struct req_msg header; -+ struct uis_req_msg header; - char msg_contents[512]; - ssize_t readsize; - -diff -Naurd corosync-0.92/lib/cfg.c corosync-trunk/lib/cfg.c ---- corosync-0.92/lib/cfg.c 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/lib/cfg.c 2009-01-19 09:31:21.000000000 +0100 -@@ -1,13 +1,13 @@ - /* - * Copyright (c) 2002-2005 MontaVista Software, Inc. -- * Copyright (c) 2006-2007 Red Hat, Inc. -+ * Copyright (c) 2006-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: - * -@@ -40,19 +40,21 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - --#include -+#include - #include -+#include - #include - #include - #include - #include - --struct res_overlay { -+struct cfg_res_overlay { - mar_res_header_t header; - char data[4096]; - }; -@@ -63,15 +65,15 @@ - struct cfg_instance { - int response_fd; - int dispatch_fd; -- CorosyncCfgCallbacksT callbacks; -- SaNameT compName; -- int compRegistered; -+ corosync_cfg_callbacks_t callbacks; -+ cs_name_t comp_name; -+ int comp_registered; - int finalize; - pthread_mutex_t response_mutex; - pthread_mutex_t dispatch_mutex; - }; - --static void cfg_handleInstanceDestructor (void *); -+static void cfg_handle_instance_destructor (void *); - - /* - * All instances in one database -@@ -80,13 +82,13 @@ - .handleCount = 0, - .handles = 0, - .mutex = PTHREAD_MUTEX_INITIALIZER, -- .handleInstanceDestructor = cfg_handleInstanceDestructor -+ .handleInstanceDestructor = cfg_handle_instance_destructor - }; - - /* - * Implementation - */ --void cfg_handleInstanceDestructor (void *instance) -+void cfg_handle_instance_destructor (void *instance) - { - struct cfg_instance *cfg_instance = instance; - -@@ -94,84 +96,85 @@ - pthread_mutex_destroy (&cfg_instance->dispatch_mutex); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_initialize ( - corosync_cfg_handle_t *cfg_handle, -- const CorosyncCfgCallbacksT *cfgCallbacks) -+ const corosync_cfg_callbacks_t *cfg_callbacks) - { - struct cfg_instance *cfg_instance; -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - - error = saHandleCreate (&cfg_hdb, sizeof (struct cfg_instance), cfg_handle); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_no_destroy; - } - - error = saHandleInstanceGet (&cfg_hdb, *cfg_handle, (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_destroy; - } - - cfg_instance->response_fd = -1; - - cfg_instance->dispatch_fd = -1; -- -+ - error = saServiceConnect (&cfg_instance->response_fd, - &cfg_instance->dispatch_fd, CFG_SERVICE); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_put_destroy; - } - -- if (cfgCallbacks) { -- memcpy (&cfg_instance->callbacks, cfgCallbacks, sizeof (CorosyncCfgCallbacksT)); -+ if (cfg_callbacks) { -+ memcpy (&cfg_instance->callbacks, cfg_callbacks, sizeof (corosync_cfg_callbacks_t)); - } - - pthread_mutex_init (&cfg_instance->response_mutex, NULL); - - pthread_mutex_init (&cfg_instance->dispatch_mutex, NULL); - -- saHandleInstancePut (&cfg_hdb, *cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, *cfg_handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - - error_put_destroy: -- saHandleInstancePut (&cfg_hdb, *cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, *cfg_handle); - error_destroy: -- saHandleDestroy (&cfg_hdb, *cfg_handle); -+ (void)saHandleDestroy (&cfg_hdb, *cfg_handle); - error_no_destroy: - return (error); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_fd_get ( - corosync_cfg_handle_t cfg_handle, -- SaSelectionObjectT *selectionObject) -+ int32_t *selection_fd) - { - struct cfg_instance *cfg_instance; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -- *selectionObject = cfg_instance->dispatch_fd; -+ *selection_fd = cfg_instance->dispatch_fd; - -- saHandleInstancePut (&cfg_hdb, cfg_handle); -- return (SA_AIS_OK); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); -+ return (CS_OK); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_dispatch ( - corosync_cfg_handle_t cfg_handle, -- SaDispatchFlagsT dispatchFlags) -+ cs_dispatch_flags_t dispatch_flags) - { - struct pollfd ufds; - int timeout = -1; -- SaAisErrorT error; -+ cs_error_t error; - int cont = 1; /* always continue do loop except when set to 0 */ - int dispatch_avail; - struct cfg_instance *cfg_instance; -+ struct res_lib_cfg_testshutdown *res_lib_cfg_testshutdown; - #ifdef COMPILE_OUT - struct res_lib_corosync_healthcheckcallback *res_lib_corosync_healthcheckcallback; - struct res_lib_corosync_readinessstatesetcallback *res_lib_corosync_readinessstatesetcallback; -@@ -179,19 +182,19 @@ - struct res_lib_corosync_csiremovecallback *res_lib_corosync_csiremovecallback; - struct res_lib_cfg_statetrackcallback *res_lib_cfg_statetrackcallback; - #endif -- CorosyncCfgCallbacksT callbacks; -- struct res_overlay dispatch_data; -+ corosync_cfg_callbacks_t callbacks; -+ struct cfg_res_overlay dispatch_data; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, - (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - /* -- * Timeout instantly for SA_DISPATCH_ALL -+ * Timeout instantly for CS_DISPATCH_ALL - */ -- if (dispatchFlags == SA_DISPATCH_ALL) { -+ if (dispatch_flags == CS_DISPATCH_ALL) { - timeout = 0; - } - -@@ -204,14 +207,14 @@ - ufds.revents = 0; - - error = saPollRetry (&ufds, 1, timeout); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_nounlock; - } - - pthread_mutex_lock (&cfg_instance->dispatch_mutex); - - error = saPollRetry (&ufds, 1, 0); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_nounlock; - } - -@@ -219,13 +222,13 @@ - * Handle has been finalized in another thread - */ - if (cfg_instance->finalize == 1) { -- error = SA_AIS_OK; -+ error = CS_OK; - pthread_mutex_unlock (&cfg_instance->dispatch_mutex); - goto error_unlock; - } - - dispatch_avail = ufds.revents & POLLIN; -- if (dispatch_avail == 0 && dispatchFlags == SA_DISPATCH_ALL) { -+ if (dispatch_avail == 0 && dispatch_flags == CS_DISPATCH_ALL) { - pthread_mutex_unlock (&cfg_instance->dispatch_mutex); - break; /* exit do while cont is 1 loop */ - } else -@@ -240,13 +243,13 @@ - */ - error = saRecvRetry (cfg_instance->dispatch_fd, &dispatch_data.header, - sizeof (mar_res_header_t)); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_unlock; - } - if (dispatch_data.header.size > sizeof (mar_res_header_t)) { - error = saRecvRetry (cfg_instance->dispatch_fd, &dispatch_data.data, - dispatch_data.header.size - sizeof (mar_res_header_t)); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_unlock; - } - } -@@ -260,16 +263,21 @@ - * A risk of this dispatch method is that the callback routines may - * operate at the same time that cfgFinalize has been called in another thread. - */ -- memcpy (&callbacks, &cfg_instance->callbacks, sizeof (CorosyncCfgCallbacksT)); -+ memcpy (&callbacks, &cfg_instance->callbacks, sizeof (corosync_cfg_callbacks_t)); - pthread_mutex_unlock (&cfg_instance->dispatch_mutex); - - /* - * Dispatch incoming response - */ - switch (dispatch_data.header.id) { -- -+ case MESSAGE_RES_CFG_TESTSHUTDOWN: -+ if (callbacks.corosync_cfg_shutdown_callback) { -+ res_lib_cfg_testshutdown = (struct res_lib_cfg_testshutdown *)&dispatch_data; -+ callbacks.corosync_cfg_shutdown_callback(cfg_handle, res_lib_cfg_testshutdown->flags); -+ } -+ break; - default: -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - goto error_nounlock; - break; - } -@@ -277,32 +285,32 @@ - /* - * Determine if more messages should be processed - */ -- switch (dispatchFlags) { -- case SA_DISPATCH_ONE: -+ switch (dispatch_flags) { -+ case CS_DISPATCH_ONE: - cont = 0; - break; -- case SA_DISPATCH_ALL: -+ case CS_DISPATCH_ALL: - break; -- case SA_DISPATCH_BLOCKING: -+ case CS_DISPATCH_BLOCKING: - break; - } - } while (cont); - - error_unlock: -- saHandleInstancePut (&cfg_hdb, cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); - error_nounlock: - return (error); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_finalize ( - corosync_cfg_handle_t cfg_handle) - { - struct cfg_instance *cfg_instance; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -316,8 +324,8 @@ - if (cfg_instance->finalize) { - pthread_mutex_unlock (&cfg_instance->response_mutex); - pthread_mutex_unlock (&cfg_instance->dispatch_mutex); -- saHandleInstancePut (&cfg_hdb, cfg_handle); -- return (SA_AIS_ERR_BAD_HANDLE); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); -+ return (CS_ERR_BAD_HANDLE); - } - - cfg_instance->finalize = 1; -@@ -330,7 +338,7 @@ - - pthread_mutex_destroy (&cfg_instance->dispatch_mutex); - -- saHandleDestroy (&cfg_hdb, cfg_handle); -+ (void)saHandleDestroy (&cfg_hdb, cfg_handle); - - if (cfg_instance->response_fd != -1) { - shutdown (cfg_instance->response_fd, 0); -@@ -341,12 +349,12 @@ - close (cfg_instance->dispatch_fd); - } - -- saHandleInstancePut (&cfg_hdb, cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); - - return (error); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_ring_status_get ( - corosync_cfg_handle_t cfg_handle, - char ***interface_names, -@@ -357,10 +365,10 @@ - struct req_lib_cfg_ringstatusget req_lib_cfg_ringstatusget; - struct res_lib_cfg_ringstatusget res_lib_cfg_ringstatusget; - unsigned int i; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -380,13 +388,13 @@ - *interface_count = res_lib_cfg_ringstatusget.interface_count; - *interface_names = malloc (sizeof (char *) * *interface_count); - if (*interface_names == NULL) { -- return (SA_AIS_ERR_NO_MEMORY); -+ return (CS_ERR_NO_MEMORY); - } - memset (*interface_names, 0, sizeof (char *) * *interface_count); - - *status = malloc (sizeof (char *) * *interface_count); - if (*status == NULL) { -- error = SA_AIS_ERR_NO_MEMORY; -+ error = CS_ERR_NO_MEMORY; - goto error_free_interface_names; - } - memset (*status, 0, sizeof (char *) * *interface_count); -@@ -394,12 +402,12 @@ - for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) { - (*(interface_names))[i] = strdup (res_lib_cfg_ringstatusget.interface_name[i]); - if ((*(interface_names))[i] == NULL) { -- error = SA_AIS_ERR_NO_MEMORY; -+ error = CS_ERR_NO_MEMORY; - goto error_free_contents; - } - (*(status))[i] = strdup (res_lib_cfg_ringstatusget.interface_status[i]); - if ((*(status))[i] == NULL) { -- error = SA_AIS_ERR_NO_MEMORY; -+ error = CS_ERR_NO_MEMORY; - goto error_free_contents; - } - } -@@ -416,27 +424,27 @@ - } - - free (*status); -- -+ - error_free_interface_names: - free (*interface_names); -- -+ - no_error: -- saHandleInstancePut (&cfg_hdb, cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); - - return (error); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_ring_reenable ( - corosync_cfg_handle_t cfg_handle) - { - struct cfg_instance *cfg_instance; - struct req_lib_cfg_ringreenable req_lib_cfg_ringreenable; - struct res_lib_cfg_ringreenable res_lib_cfg_ringreenable; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -452,12 +460,12 @@ - sizeof (struct res_lib_cfg_ringreenable)); - - pthread_mutex_unlock (&cfg_instance->response_mutex); -- saHandleInstancePut (&cfg_hdb, cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); - - return (error); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_service_load ( - corosync_cfg_handle_t cfg_handle, - char *service_name, -@@ -466,10 +474,10 @@ - struct cfg_instance *cfg_instance; - struct req_lib_cfg_serviceload req_lib_cfg_serviceload; - struct res_lib_cfg_serviceload res_lib_cfg_serviceload; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -477,7 +485,7 @@ - req_lib_cfg_serviceload.header.id = MESSAGE_REQ_CFG_SERVICELOAD; - memset (&req_lib_cfg_serviceload.service_name, 0, - sizeof (req_lib_cfg_serviceload.service_name)); -- strncpy ((char *)req_lib_cfg_serviceload.service_name, service_name, -+ strncpy (req_lib_cfg_serviceload.service_name, service_name, - sizeof (req_lib_cfg_serviceload.service_name) - 1); - req_lib_cfg_serviceload.service_ver = service_ver; - -@@ -490,12 +498,12 @@ - sizeof (struct res_lib_cfg_serviceload)); - - pthread_mutex_unlock (&cfg_instance->response_mutex); -- saHandleInstancePut (&cfg_hdb, cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); - - return (error); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_service_unload ( - corosync_cfg_handle_t cfg_handle, - char *service_name, -@@ -504,10 +512,10 @@ - struct cfg_instance *cfg_instance; - struct req_lib_cfg_serviceunload req_lib_cfg_serviceunload; - struct res_lib_cfg_serviceunload res_lib_cfg_serviceunload; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -515,7 +523,7 @@ - req_lib_cfg_serviceunload.header.id = MESSAGE_REQ_CFG_SERVICEUNLOAD; - memset (&req_lib_cfg_serviceunload.service_name, 0, - sizeof (req_lib_cfg_serviceunload.service_name)); -- strncpy ((char *)req_lib_cfg_serviceunload.service_name, service_name, -+ strncpy (req_lib_cfg_serviceunload.service_name, service_name, - sizeof (req_lib_cfg_serviceunload.service_name) - 1); - req_lib_cfg_serviceunload.service_ver = service_ver; - -@@ -528,29 +536,29 @@ - sizeof (struct res_lib_cfg_serviceunload)); - - pthread_mutex_unlock (&cfg_instance->response_mutex); -- saHandleInstancePut (&cfg_hdb, cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); - - return (error); - } --SaAisErrorT -+cs_error_t - corosync_cfg_state_track ( - corosync_cfg_handle_t cfg_handle, -- SaUint8T trackFlags, -- const CorosyncCfgStateNotificationT *notificationBuffer) -+ uint8_t track_flags, -+ const corosync_cfg_state_notification_t *notification_buffer) - { - struct cfg_instance *cfg_instance; - struct req_lib_cfg_statetrack req_lib_cfg_statetrack; - struct res_lib_cfg_statetrack res_lib_cfg_statetrack; -- SaAisErrorT error; -+ cs_error_t error; - - req_lib_cfg_statetrack.header.size = sizeof (struct req_lib_cfg_statetrack); - req_lib_cfg_statetrack.header.id = MESSAGE_REQ_CFG_STATETRACKSTART; -- req_lib_cfg_statetrack.trackFlags = trackFlags; -- req_lib_cfg_statetrack.notificationBufferAddress = (CorosyncCfgStateNotificationT *)notificationBuffer; -+ req_lib_cfg_statetrack.track_flags = track_flags; -+ req_lib_cfg_statetrack.notification_buffer_address = (corosync_cfg_state_notification_t *)notification_buffer; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, - (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -564,23 +572,23 @@ - - pthread_mutex_unlock (&cfg_instance->response_mutex); - -- saHandleInstancePut (&cfg_hdb, cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); - -- return (error == SA_AIS_OK ? res_lib_cfg_statetrack.header.error : error); -+ return (error == CS_OK ? res_lib_cfg_statetrack.header.error : error); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_state_track_stop ( - corosync_cfg_handle_t cfg_handle) - { - struct cfg_instance *cfg_instance; - struct req_lib_cfg_statetrackstop req_lib_cfg_statetrackstop; - struct res_lib_cfg_statetrackstop res_lib_cfg_statetrackstop; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, - (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -597,31 +605,33 @@ - - pthread_mutex_unlock (&cfg_instance->response_mutex); - -- saHandleInstancePut (&cfg_hdb, cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); - -- return (error == SA_AIS_OK ? res_lib_cfg_statetrackstop.header.error : error); -+ return (error == CS_OK ? res_lib_cfg_statetrackstop.header.error : error); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_admin_state_get ( - corosync_cfg_handle_t cfg_handle, -- CorosyncCfgAdministrativeTargetT administrativeTarget, -- CorosyncCfgAdministrativeStateT *administrativeState) -+ corosync_cfg_administrative_target_t administrative_target, -+ corosync_cfg_administrative_state_t *administrative_state) - { - struct cfg_instance *cfg_instance; - struct req_lib_cfg_administrativestateget req_lib_cfg_administrativestateget; - struct res_lib_cfg_administrativestateget res_lib_cfg_administrativestateget; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, - (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - req_lib_cfg_administrativestateget.header.id = MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET; - req_lib_cfg_administrativestateget.header.size = sizeof (struct req_lib_cfg_administrativestateget); -- req_lib_cfg_administrativestateget.administrativeTarget = administrativeTarget; -+ req_lib_cfg_administrativestateget.administrative_target = administrative_target; -+ -+ pthread_mutex_lock (&cfg_instance->response_mutex); - - error = saSendReceiveReply (cfg_instance->response_fd, - &req_lib_cfg_administrativestateget, -@@ -633,32 +643,34 @@ - - pthread_mutex_unlock (&cfg_instance->response_mutex); - -- saHandleInstancePut (&cfg_hdb, cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); - -- return (error == SA_AIS_OK ? res_lib_cfg_administrativestateget.header.error : error); -+ return (error == CS_OK ? res_lib_cfg_administrativestateget.header.error : error); - } - --SaAisErrorT -+cs_error_t - corosync_cfg_admin_state_set ( - corosync_cfg_handle_t cfg_handle, -- CorosyncCfgAdministrativeTargetT administrativeTarget, -- CorosyncCfgAdministrativeStateT administrativeState) -+ corosync_cfg_administrative_target_t administrative_target, -+ corosync_cfg_administrative_state_t administrative_state) - { - struct cfg_instance *cfg_instance; - struct req_lib_cfg_administrativestateset req_lib_cfg_administrativestateset; - struct res_lib_cfg_administrativestateset res_lib_cfg_administrativestateset; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&cfg_hdb, cfg_handle, - (void *)&cfg_instance); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - req_lib_cfg_administrativestateset.header.id = MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET; - req_lib_cfg_administrativestateset.header.size = sizeof (struct req_lib_cfg_administrativestateset); -- req_lib_cfg_administrativestateset.administrativeTarget = administrativeTarget; -- req_lib_cfg_administrativestateset.administrativeState = administrativeState; -+ req_lib_cfg_administrativestateset.administrative_target = administrative_target; -+ req_lib_cfg_administrativestateset.administrative_state = administrative_state; -+ -+ pthread_mutex_lock (&cfg_instance->response_mutex); - - error = saSendReceiveReply (cfg_instance->response_fd, - &req_lib_cfg_administrativestateset, -@@ -670,7 +682,191 @@ - - pthread_mutex_unlock (&cfg_instance->response_mutex); - -- saHandleInstancePut (&cfg_hdb, cfg_handle); -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); - -- return (error == SA_AIS_OK ? res_lib_cfg_administrativestateset.header.error : error); -+ return (error == CS_OK ? res_lib_cfg_administrativestateset.header.error : error); -+} -+ -+cs_error_t -+corosync_cfg_kill_node ( -+ corosync_cfg_handle_t cfg_handle, -+ unsigned int nodeid, -+ char *reason) -+{ -+ struct cfg_instance *cfg_instance; -+ struct req_lib_cfg_killnode req_lib_cfg_killnode; -+ struct res_lib_cfg_killnode res_lib_cfg_killnode; -+ cs_error_t error; -+ -+ if (strlen(reason) >= CS_MAX_NAME_LENGTH) -+ return CS_ERR_NAME_TOO_LONG; -+ -+ error = saHandleInstanceGet (&cfg_hdb, cfg_handle, -+ (void *)&cfg_instance); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ req_lib_cfg_killnode.header.id = MESSAGE_REQ_CFG_KILLNODE; -+ req_lib_cfg_killnode.header.size = sizeof (struct req_lib_cfg_killnode); -+ req_lib_cfg_killnode.nodeid = nodeid; -+ strcpy((char *)req_lib_cfg_killnode.reason.value, reason); -+ req_lib_cfg_killnode.reason.length = strlen(reason)+1; -+ -+ pthread_mutex_lock (&cfg_instance->response_mutex); -+ -+ error = saSendReceiveReply (cfg_instance->response_fd, -+ &req_lib_cfg_killnode, -+ sizeof (struct req_lib_cfg_killnode), -+ &res_lib_cfg_killnode, -+ sizeof (struct res_lib_cfg_killnode)); -+ -+ error = res_lib_cfg_killnode.header.error; -+ -+ pthread_mutex_unlock (&cfg_instance->response_mutex); -+ -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); -+ -+ return (error == CS_OK ? res_lib_cfg_killnode.header.error : error); -+} -+ -+cs_error_t -+corosync_cfg_try_shutdown ( -+ corosync_cfg_handle_t cfg_handle, -+ corosync_cfg_shutdown_flags_t flags) -+{ -+ struct cfg_instance *cfg_instance; -+ struct req_lib_cfg_tryshutdown req_lib_cfg_tryshutdown; -+ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown; -+ cs_error_t error; -+ -+ error = saHandleInstanceGet (&cfg_hdb, cfg_handle, -+ (void *)&cfg_instance); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ req_lib_cfg_tryshutdown.header.id = MESSAGE_REQ_CFG_TRYSHUTDOWN; -+ req_lib_cfg_tryshutdown.header.size = sizeof (struct req_lib_cfg_tryshutdown); -+ req_lib_cfg_tryshutdown.flags = flags; -+ -+ pthread_mutex_lock (&cfg_instance->response_mutex); -+ -+ error = saSendReceiveReply (cfg_instance->response_fd, -+ &req_lib_cfg_tryshutdown, -+ sizeof (struct req_lib_cfg_tryshutdown), -+ &res_lib_cfg_tryshutdown, -+ sizeof (struct res_lib_cfg_tryshutdown)); -+ -+ pthread_mutex_unlock (&cfg_instance->response_mutex); -+ -+ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); -+ -+ return (error == CS_OK ? res_lib_cfg_tryshutdown.header.error : error); -+} -+ -+cs_error_t -+corosync_cfg_replyto_shutdown ( -+ corosync_cfg_handle_t cfg_handle, -+ corosync_cfg_shutdown_reply_flags_t response) -+{ -+ struct cfg_instance *cfg_instance; -+ struct req_lib_cfg_replytoshutdown req_lib_cfg_replytoshutdown; -+ struct iovec iov; -+ cs_error_t error; -+ -+ error = saHandleInstanceGet (&cfg_hdb, cfg_handle, -+ (void *)&cfg_instance); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ req_lib_cfg_replytoshutdown.header.id = MESSAGE_REQ_CFG_REPLYTOSHUTDOWN; -+ req_lib_cfg_replytoshutdown.header.size = sizeof (struct req_lib_cfg_replytoshutdown); -+ req_lib_cfg_replytoshutdown.response = response; -+ -+ iov.iov_base = &req_lib_cfg_replytoshutdown; -+ iov.iov_len = sizeof (struct req_lib_cfg_replytoshutdown); -+ -+ pthread_mutex_lock (&cfg_instance->response_mutex); -+ error = saSendMsgRetry (cfg_instance->response_fd, -+ &iov, 1); -+ -+ pthread_mutex_unlock (&cfg_instance->response_mutex); -+ -+ return (error); -+} -+ -+cs_error_t corosync_cfg_get_node_addrs ( -+ corosync_cfg_handle_t cfg_handle, -+ int nodeid, -+ int max_addrs, -+ int *num_addrs, -+ corosync_cfg_node_address_t *addrs) -+{ -+ cs_error_t error; -+ char buf[PIPE_BUF]; -+ struct req_lib_cfg_get_node_addrs req_lib_cfg_get_node_addrs; -+ struct res_lib_cfg_get_node_addrs * res_lib_cfg_get_node_addrs = (struct res_lib_cfg_get_node_addrs *)buf; -+ struct cfg_instance *cfg_instance; -+ int addrlen; -+ int i; -+ struct iovec iov[2]; -+ -+ error = saHandleInstanceGet (&cfg_hdb, cfg_handle, -+ (void *)&cfg_instance); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&cfg_instance->response_mutex); -+ -+ req_lib_cfg_get_node_addrs.header.size = sizeof (req_lib_cfg_get_node_addrs); -+ req_lib_cfg_get_node_addrs.header.id = MESSAGE_REQ_CFG_GET_NODE_ADDRS; -+ req_lib_cfg_get_node_addrs.nodeid = nodeid; -+ -+ iov[0].iov_base = (char *)&req_lib_cfg_get_node_addrs; -+ iov[0].iov_len = sizeof (req_lib_cfg_get_node_addrs); -+ -+ error = saSendMsgReceiveReply (cfg_instance->response_fd, iov, 1, -+ res_lib_cfg_get_node_addrs, sizeof (mar_res_header_t)); -+ -+ if (error == CS_OK && res_lib_cfg_get_node_addrs->header.size > sizeof(mar_res_header_t)) { -+ error = saRecvRetry (cfg_instance->response_fd, (char *)res_lib_cfg_get_node_addrs + sizeof (mar_res_header_t), -+ res_lib_cfg_get_node_addrs->header.size - sizeof (mar_res_header_t)); -+ } -+ pthread_mutex_unlock (&cfg_instance->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ if (res_lib_cfg_get_node_addrs->family == AF_INET) -+ addrlen = sizeof(struct sockaddr_in); -+ if (res_lib_cfg_get_node_addrs->family == AF_INET6) -+ addrlen = sizeof(struct sockaddr_in6); -+ -+ for (i=0; inum_addrs; i++) { -+ addrs[i].addressLength = addrlen; -+ struct sockaddr_in *in; -+ struct sockaddr_in6 *in6; -+ -+ if (res_lib_cfg_get_node_addrs->family == AF_INET) { -+ in = (struct sockaddr_in *)addrs[i].address; -+ in->sin_family = AF_INET; -+ memcpy(&in->sin_addr, &res_lib_cfg_get_node_addrs->addrs[i][0], sizeof(struct in_addr)); -+ } -+ if (res_lib_cfg_get_node_addrs->family == AF_INET6) { -+ in6 = (struct sockaddr_in6 *)addrs[i].address; -+ in6->sin6_family = AF_INET6; -+ memcpy(&in6->sin6_addr, &res_lib_cfg_get_node_addrs->addrs[i][0], sizeof(struct in6_addr)); -+ } -+ } -+ *num_addrs = res_lib_cfg_get_node_addrs->num_addrs; -+ errno = error = res_lib_cfg_get_node_addrs->header.error; -+ -+error_exit: -+ -+ pthread_mutex_unlock (&cfg_instance->response_mutex); -+ return (error); - } -diff -Naurd corosync-0.92/lib/confdb.c corosync-trunk/lib/confdb.c ---- corosync-0.92/lib/confdb.c 2008-09-03 09:58:08.000000000 +0200 -+++ corosync-trunk/lib/confdb.c 2009-01-23 16:41:06.000000000 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2008 Red Hat, Inc. -+ * Copyright (c) 2008-2009 Red Hat, Inc. - * - * All rights reserved. - * -@@ -42,7 +42,7 @@ - #include - #include - --#include -+#include - #include - #include - #include -@@ -86,7 +86,7 @@ - }; - - --static confdb_error_t do_find_destroy(struct confdb_inst *confdb_inst, unsigned int find_handle); -+static cs_error_t do_find_destroy(struct confdb_inst *confdb_inst, unsigned int find_handle); - - - /* Safely tidy one iterator context list */ -@@ -99,7 +99,7 @@ - iter != list; iter = tmp, tmp = iter->next) { - - context = list_entry (iter, struct iter_context, list); -- do_find_destroy(confdb_inst, context->find_handle); -+ (void)do_find_destroy(confdb_inst, context->find_handle); - free(context); - } - } -@@ -137,20 +137,20 @@ - * @{ - */ - --confdb_error_t confdb_initialize ( -+cs_error_t confdb_initialize ( - confdb_handle_t *handle, - confdb_callbacks_t *callbacks) - { -- SaAisErrorT error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - - error = saHandleCreate (&confdb_handle_t_db, sizeof (struct confdb_inst), handle); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_no_destroy; - } - - error = saHandleInstanceGet (&confdb_handle_t_db, *handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_destroy; - } - -@@ -163,7 +163,7 @@ - &confdb_inst->response_fd, - CONFDB_SERVICE); - } -- if (error != SA_AIS_OK) -+ if (error != CS_OK) - goto error_put_destroy; - - memcpy (&confdb_inst->callbacks, callbacks, sizeof (confdb_callbacks_t)); -@@ -175,26 +175,26 @@ - list_init (&confdb_inst->object_iter_head); - list_init (&confdb_inst->key_iter_head); - -- saHandleInstancePut (&confdb_handle_t_db, *handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, *handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - - error_put_destroy: -- saHandleInstancePut (&confdb_handle_t_db, *handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, *handle); - error_destroy: -- saHandleDestroy (&confdb_handle_t_db, *handle); -+ (void)saHandleDestroy (&confdb_handle_t_db, *handle); - error_no_destroy: - return (error); - } - --confdb_error_t confdb_finalize ( -+cs_error_t confdb_finalize ( - confdb_handle_t handle) - { - struct confdb_inst *confdb_inst; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -205,15 +205,15 @@ - */ - if (confdb_inst->finalize) { - pthread_mutex_unlock (&confdb_inst->response_mutex); -- saHandleInstancePut (&confdb_handle_t_db, handle); -- return (CONFDB_ERR_BAD_HANDLE); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); -+ return (CS_ERR_BAD_HANDLE); - } - - confdb_inst->finalize = 1; - - pthread_mutex_unlock (&confdb_inst->response_mutex); - -- saHandleDestroy (&confdb_handle_t_db, handle); -+ (void)saHandleDestroy (&confdb_handle_t_db, handle); - - /* Free saved context handles */ - free_context_list(confdb_inst, &confdb_inst->object_find_head); -@@ -233,80 +233,80 @@ - close(confdb_inst->dispatch_fd); - } - } -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - -- return (CONFDB_OK); -+ return (CS_OK); - } - --confdb_error_t confdb_fd_get ( -+cs_error_t confdb_fd_get ( - confdb_handle_t handle, - int *fd) - { -- SaAisErrorT error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - *fd = confdb_inst->dispatch_fd; - -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - } - --confdb_error_t confdb_context_get ( -+cs_error_t confdb_context_get ( - confdb_handle_t handle, - void **context) - { -- SaAisErrorT error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - *context = confdb_inst->context; - -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - } - --confdb_error_t confdb_context_set ( -+cs_error_t confdb_context_set ( - confdb_handle_t handle, - void *context) - { -- SaAisErrorT error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - confdb_inst->context = context; - -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - } - --struct res_overlay { -+struct confdb_res_overlay { - mar_res_header_t header __attribute__((aligned(8))); - char data[512000]; - }; - --confdb_error_t confdb_dispatch ( -+cs_error_t confdb_dispatch ( - confdb_handle_t handle, -- confdb_dispatch_t dispatch_types) -+ cs_dispatch_flags_t dispatch_types) - { - struct pollfd ufds; - int timeout = -1; -- SaAisErrorT error; -+ cs_error_t error; - int cont = 1; /* always continue do loop except when set to 0 */ - int dispatch_avail; - struct confdb_inst *confdb_inst; -@@ -314,16 +314,15 @@ - struct res_lib_confdb_key_change_callback *res_key_changed_pt; - struct res_lib_confdb_object_create_callback *res_object_created_pt; - struct res_lib_confdb_object_destroy_callback *res_object_destroyed_pt; -- struct res_overlay dispatch_data; -- int ignore_dispatch = 0; -+ struct confdb_res_overlay dispatch_data; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = CONFDB_ERR_NOT_SUPPORTED; -+ error = CS_ERR_NOT_SUPPORTED; - goto error_unlock; - } - -@@ -341,7 +340,7 @@ - ufds.revents = 0; - - error = saPollRetry (&ufds, 1, timeout); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_nounlock; - } - -@@ -351,7 +350,7 @@ - * Regather poll data in case ufds has changed since taking lock - */ - error = saPollRetry (&ufds, 1, timeout); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_nounlock; - } - -@@ -359,7 +358,7 @@ - * Handle has been finalized in another thread - */ - if (confdb_inst->finalize == 1) { -- error = CONFDB_OK; -+ error = CS_OK; - pthread_mutex_unlock (&confdb_inst->dispatch_mutex); - goto error_unlock; - } -@@ -380,14 +379,14 @@ - */ - error = saRecvRetry (confdb_inst->dispatch_fd, &dispatch_data.header, - sizeof (mar_res_header_t)); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_unlock; - } - if (dispatch_data.header.size > sizeof (mar_res_header_t)) { - error = saRecvRetry (confdb_inst->dispatch_fd, &dispatch_data.data, - dispatch_data.header.size - sizeof (mar_res_header_t)); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_unlock; - } - } -@@ -443,7 +442,7 @@ - break; - - default: -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - goto error_nounlock; - break; - } -@@ -453,16 +452,9 @@ - * */ - switch (dispatch_types) { - case CONFDB_DISPATCH_ONE: -- if (ignore_dispatch) { -- ignore_dispatch = 0; -- } else { -- cont = 0; -- } -+ cont = 0; - break; - case CONFDB_DISPATCH_ALL: -- if (ignore_dispatch) { -- ignore_dispatch = 0; -- } - break; - case CONFDB_DISPATCH_BLOCKING: - break; -@@ -470,36 +462,36 @@ - } while (cont); - - error_unlock: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - error_nounlock: - return (error); - } - --confdb_error_t confdb_object_create ( -+cs_error_t confdb_object_create ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *object_name, - int object_name_len, - unsigned int *object_handle) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct req_lib_confdb_object_create req_lib_confdb_object_create; - struct res_lib_confdb_object_create res_lib_confdb_object_create; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_object_create(parent_object_handle, - object_name, object_name_len, - object_handle)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -518,7 +510,7 @@ - &res_lib_confdb_object_create, sizeof (struct res_lib_confdb_object_create)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -526,31 +518,31 @@ - *object_handle = res_lib_confdb_object_create.object_handle; - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_object_destroy ( -+cs_error_t confdb_object_destroy ( - confdb_handle_t handle, - unsigned int object_handle) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct req_lib_confdb_object_destroy req_lib_confdb_object_destroy; - mar_res_header_t res; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_object_destroy(object_handle)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -567,39 +559,39 @@ - &res, sizeof ( mar_res_header_t)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res.error; - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_object_parent_get ( -+cs_error_t confdb_object_parent_get ( - confdb_handle_t handle, - unsigned int object_handle, - unsigned int *parent_object_handle) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct req_lib_confdb_object_parent_get req_lib_confdb_object_parent_get; - struct res_lib_confdb_object_parent_get res_lib_confdb_object_parent_get; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_object_parent_get(object_handle, parent_object_handle)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -616,7 +608,7 @@ - &res_lib_confdb_object_parent_get, sizeof (struct res_lib_confdb_object_parent_get)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -624,28 +616,28 @@ - *parent_object_handle = res_lib_confdb_object_parent_get.parent_object_handle; - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --static confdb_error_t do_find_destroy( -+static cs_error_t do_find_destroy( - struct confdb_inst *confdb_inst, - unsigned int find_handle) - { -- confdb_error_t error; -+ cs_error_t error; - struct iovec iov[2]; - struct req_lib_confdb_object_find_destroy req_lib_confdb_object_find_destroy; - mar_res_header_t res; - - if (!find_handle) -- return SA_AIS_OK; -+ return CS_OK; - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_find_destroy(find_handle)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -662,7 +654,7 @@ - &res, sizeof (mar_res_header_t)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -673,56 +665,56 @@ - return (error); - } - --confdb_error_t confdb_object_find_destroy( -+cs_error_t confdb_object_find_destroy( - confdb_handle_t handle, - unsigned int parent_object_handle) - { - struct iter_context *context; -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle); - error = do_find_destroy(confdb_inst, context->find_handle); -- if (error == SA_AIS_OK) { -+ if (error == CS_OK) { - list_del(&context->list); - free(context); - } - -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - return error; - } - --confdb_error_t confdb_object_iter_destroy( -+cs_error_t confdb_object_iter_destroy( - confdb_handle_t handle, - unsigned int parent_object_handle) - { - struct iter_context *context; -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - context = find_iter_context(&confdb_inst->object_iter_head, parent_object_handle); - error = do_find_destroy(confdb_inst, context->find_handle); -- if (error == SA_AIS_OK) { -+ if (error == CS_OK) { - list_del(&context->list); - free(context); - } - -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - return error; - } - - --confdb_error_t confdb_key_create ( -+cs_error_t confdb_key_create ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -@@ -730,24 +722,24 @@ - void *value, - int value_len) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct req_lib_confdb_key_create req_lib_confdb_key_create; - mar_res_header_t res; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_key_create(parent_object_handle, - key_name, key_name_len, - value, value_len)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -768,19 +760,19 @@ - &res, sizeof (res)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res.error; - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_key_delete ( -+cs_error_t confdb_key_delete ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -@@ -788,24 +780,24 @@ - void *value, - int value_len) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct req_lib_confdb_key_delete req_lib_confdb_key_delete; - mar_res_header_t res; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_key_delete(parent_object_handle, - key_name, key_name_len, - value, value_len)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -826,19 +818,19 @@ - &res, sizeof (res)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res.error; - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_key_get ( -+cs_error_t confdb_key_get ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -@@ -846,24 +838,24 @@ - void *value, - int *value_len) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct req_lib_confdb_key_get req_lib_confdb_key_get; - struct res_lib_confdb_key_get res_lib_confdb_key_get; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_key_get(parent_object_handle, - key_name, key_name_len, - value, value_len)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -882,47 +874,47 @@ - &res_lib_confdb_key_get, sizeof (struct res_lib_confdb_key_get)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_confdb_key_get.header.error; -- if (error == SA_AIS_OK) { -+ if (error == CS_OK) { - *value_len = res_lib_confdb_key_get.value.length; - memcpy(value, res_lib_confdb_key_get.value.value, *value_len); - } - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_key_increment ( -+cs_error_t confdb_key_increment ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, - int key_name_len, - unsigned int *value) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct req_lib_confdb_key_get req_lib_confdb_key_get; - struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_key_increment(parent_object_handle, - key_name, key_name_len, - value)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -941,46 +933,46 @@ - &res_lib_confdb_key_incdec, sizeof (struct res_lib_confdb_key_incdec)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_confdb_key_incdec.header.error; -- if (error == SA_AIS_OK) { -+ if (error == CS_OK) { - *value = res_lib_confdb_key_incdec.value; - } - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_key_decrement ( -+cs_error_t confdb_key_decrement ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, - int key_name_len, - unsigned int *value) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct req_lib_confdb_key_get req_lib_confdb_key_get; - struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_key_decrement(parent_object_handle, - key_name, key_name_len, - value)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -999,22 +991,22 @@ - &res_lib_confdb_key_incdec, sizeof (struct res_lib_confdb_key_incdec)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_confdb_key_incdec.header.error; -- if (error == SA_AIS_OK) { -+ if (error == CS_OK) { - *value = res_lib_confdb_key_incdec.value; - } - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_key_replace ( -+cs_error_t confdb_key_replace ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -@@ -1024,25 +1016,25 @@ - void *new_value, - int new_value_len) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct req_lib_confdb_key_replace req_lib_confdb_key_replace; - mar_res_header_t res; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_key_replace(parent_object_handle, - key_name, key_name_len, - old_value, old_value_len, - new_value, new_value_len)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - req_lib_confdb_key_replace.header.size = sizeof (struct req_lib_confdb_key_replace); -@@ -1064,28 +1056,28 @@ - &res, sizeof (res)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res.error; - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_object_iter_start ( -+cs_error_t confdb_object_iter_start ( - confdb_handle_t handle, - unsigned int object_handle) - { - struct confdb_inst *confdb_inst; -- confdb_error_t error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - struct iter_context *context; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -1093,7 +1085,7 @@ - if (!context) { - context = malloc(sizeof(struct iter_context)); - if (!context) { -- error = CONFDB_ERR_NO_MEMORY; -+ error = CS_ERR_NO_MEMORY; - goto ret; - } - context->parent_object_handle = object_handle; -@@ -1103,26 +1095,26 @@ - - /* Start a new find context */ - if (context->find_handle) { -- do_find_destroy(confdb_inst, context->find_handle); -+ (void)do_find_destroy(confdb_inst, context->find_handle); - context->find_handle = 0; - } - -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - ret: - return error; - } - --confdb_error_t confdb_key_iter_start ( -+cs_error_t confdb_key_iter_start ( - confdb_handle_t handle, - unsigned int object_handle) - { - struct confdb_inst *confdb_inst; -- confdb_error_t error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - struct iter_context *context; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -1130,7 +1122,7 @@ - if (!context) { - context = malloc(sizeof(struct iter_context)); - if (!context) { -- error = CONFDB_ERR_NO_MEMORY; -+ error = CS_ERR_NO_MEMORY; - goto ret; - } - context->parent_object_handle = object_handle; -@@ -1140,22 +1132,22 @@ - context->find_handle = 0; - context->next_entry = 0; - -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - ret: - return error; - } - --confdb_error_t confdb_object_find_start ( -+cs_error_t confdb_object_find_start ( - confdb_handle_t handle, - unsigned int parent_object_handle) - { - struct confdb_inst *confdb_inst; -- confdb_error_t error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - struct iter_context *context; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -1163,7 +1155,7 @@ - if (!context) { - context = malloc(sizeof(struct iter_context)); - if (!context) { -- error = CONFDB_ERR_NO_MEMORY; -+ error = CS_ERR_NO_MEMORY; - goto ret; - } - context->find_handle = 0; -@@ -1172,24 +1164,24 @@ - } - /* Start a new find context */ - if (context->find_handle) { -- do_find_destroy(confdb_inst, context->find_handle); -+ (void)do_find_destroy(confdb_inst, context->find_handle); - context->find_handle = 0; - } - -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - ret: - return error; - } - --confdb_error_t confdb_object_find ( -+cs_error_t confdb_object_find ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *object_name, - int object_name_len, - unsigned int *object_handle) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct iter_context *context; -@@ -1197,26 +1189,26 @@ - struct res_lib_confdb_object_find res_lib_confdb_object_find; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - /* You MUST call confdb_object_find_start first */ - context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle); - if (!context) { -- error = CONFDB_ERR_CONTEXT_NOT_FOUND; -+ error = CS_ERR_CONTEXT_NOT_FOUND; - goto error_exit; - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_object_find(parent_object_handle, - &context->find_handle, - object_handle, - object_name, &object_name_len, - 0)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -1236,7 +1228,7 @@ - &res_lib_confdb_object_find, sizeof (struct res_lib_confdb_object_find)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -1245,20 +1237,20 @@ - context->find_handle = res_lib_confdb_object_find.find_handle; - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - - --confdb_error_t confdb_object_iter ( -+cs_error_t confdb_object_iter ( - confdb_handle_t handle, - unsigned int parent_object_handle, - unsigned int *object_handle, - void *object_name, - int *object_name_len) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct iter_context *context; -@@ -1266,19 +1258,19 @@ - struct res_lib_confdb_object_iter res_lib_confdb_object_iter; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - /* You MUST call confdb_object_iter_start first */ - context = find_iter_context(&confdb_inst->object_iter_head, parent_object_handle); - if (!context) { -- error = CONFDB_ERR_CONTEXT_NOT_FOUND; -+ error = CS_ERR_CONTEXT_NOT_FOUND; - goto error_exit; - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - *object_name_len = 0; - if (confdb_sa_object_find(parent_object_handle, -@@ -1286,7 +1278,7 @@ - object_handle, - object_name, object_name_len, - 1)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto sa_exit; - } - -@@ -1304,12 +1296,12 @@ - &res_lib_confdb_object_iter, sizeof (struct res_lib_confdb_object_iter)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_confdb_object_iter.header.error; -- if (error == SA_AIS_OK) { -+ if (error == CS_OK) { - *object_name_len = res_lib_confdb_object_iter.object_name.length; - memcpy(object_name, res_lib_confdb_object_iter.object_name.value, *object_name_len); - *object_handle = res_lib_confdb_object_iter.object_handle; -@@ -1318,12 +1310,12 @@ - sa_exit: - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_key_iter ( -+cs_error_t confdb_key_iter ( - confdb_handle_t handle, - unsigned int parent_object_handle, - void *key_name, -@@ -1331,7 +1323,7 @@ - void *value, - int *value_len) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct iter_context *context; -@@ -1339,25 +1331,25 @@ - struct res_lib_confdb_key_iter res_lib_confdb_key_iter; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - /* You MUST call confdb_key_iter_start first */ - context = find_iter_context(&confdb_inst->key_iter_head, parent_object_handle); - if (!context) { -- error = CONFDB_ERR_CONTEXT_NOT_FOUND; -+ error = CS_ERR_CONTEXT_NOT_FOUND; - goto error_exit; - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_key_iter(parent_object_handle, - context->next_entry, - key_name, key_name_len, - value, value_len)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto sa_exit; - } - -@@ -1375,12 +1367,12 @@ - &res_lib_confdb_key_iter, sizeof (struct res_lib_confdb_key_iter)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_confdb_key_iter.header.error; -- if (error == SA_AIS_OK) { -+ if (error == CS_OK) { - *key_name_len = res_lib_confdb_key_iter.key_name.length; - memcpy(key_name, res_lib_confdb_key_iter.key_name.value, *key_name_len); - *value_len = res_lib_confdb_key_iter.value.length; -@@ -1391,31 +1383,31 @@ - context->next_entry++; - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_write ( -+cs_error_t confdb_write ( - confdb_handle_t handle, - char *error_text) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - mar_req_header_t req; - struct res_lib_confdb_write res_lib_confdb_write; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_write(error_text)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -1431,7 +1423,7 @@ - &res_lib_confdb_write, sizeof ( struct res_lib_confdb_write)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -1440,32 +1432,32 @@ - memcpy(error_text, res_lib_confdb_write.error.value, res_lib_confdb_write.error.length); - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_reload ( -+cs_error_t confdb_reload ( - confdb_handle_t handle, - int flush, - char *error_text) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct res_lib_confdb_reload res_lib_confdb_reload; - struct req_lib_confdb_reload req_lib_confdb_reload; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = SA_AIS_OK; -+ error = CS_OK; - - if (confdb_sa_reload(flush, error_text)) -- error = SA_AIS_ERR_ACCESS; -+ error = CS_ERR_ACCESS; - goto error_exit; - } - -@@ -1483,7 +1475,7 @@ - - pthread_mutex_unlock (&confdb_inst->response_mutex); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -1492,29 +1484,29 @@ - memcpy(error_text, res_lib_confdb_reload.error.value, res_lib_confdb_reload.error.length); - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_track_changes ( -+cs_error_t confdb_track_changes ( - confdb_handle_t handle, - unsigned int object_handle, - unsigned int flags) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - struct req_lib_confdb_object_track_start req; - mar_res_header_t res; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = CONFDB_ERR_NOT_SUPPORTED; -+ error = CS_ERR_NOT_SUPPORTED; - goto error_exit; - } - -@@ -1532,33 +1524,33 @@ - &res, sizeof ( mar_res_header_t)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res.error; - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } - --confdb_error_t confdb_stop_track_changes (confdb_handle_t handle) -+cs_error_t confdb_stop_track_changes (confdb_handle_t handle) - { -- confdb_error_t error; -+ cs_error_t error; - struct confdb_inst *confdb_inst; - struct iovec iov[2]; - mar_req_header_t req; - mar_res_header_t res; - - error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - if (confdb_inst->standalone) { -- error = CONFDB_ERR_NOT_SUPPORTED; -+ error = CS_ERR_NOT_SUPPORTED; - goto error_exit; - } - -@@ -1574,14 +1566,14 @@ - &res, sizeof ( mar_res_header_t)); - - pthread_mutex_unlock (&confdb_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res.error; - - error_exit: -- saHandleInstancePut (&confdb_handle_t_db, handle); -+ (void)saHandleInstancePut (&confdb_handle_t_db, handle); - - return (error); - } -diff -Naurd corosync-0.92/lib/cpg.c corosync-trunk/lib/cpg.c ---- corosync-0.92/lib/cpg.c 2008-09-17 21:15:00.000000000 +0200 -+++ corosync-trunk/lib/cpg.c 2009-01-08 07:29:16.000000000 +0100 -@@ -45,7 +45,7 @@ - #include - #include - --#include -+#include - #include - #include - #include -@@ -90,27 +90,27 @@ - * @{ - */ - --cpg_error_t cpg_initialize ( -+cs_error_t cpg_initialize ( - cpg_handle_t *handle, - cpg_callbacks_t *callbacks) - { -- SaAisErrorT error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - - error = saHandleCreate (&cpg_handle_t_db, sizeof (struct cpg_inst), handle); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_no_destroy; - } - - error = saHandleInstanceGet (&cpg_handle_t_db, *handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_destroy; - } - - error = saServiceConnect (&cpg_inst->dispatch_fd, - &cpg_inst->response_fd, - CPG_SERVICE); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_put_destroy; - } - -@@ -120,26 +120,26 @@ - - pthread_mutex_init (&cpg_inst->dispatch_mutex, NULL); - -- saHandleInstancePut (&cpg_handle_t_db, *handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, *handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - - error_put_destroy: -- saHandleInstancePut (&cpg_handle_t_db, *handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, *handle); - error_destroy: -- saHandleDestroy (&cpg_handle_t_db, *handle); -+ (void)saHandleDestroy (&cpg_handle_t_db, *handle); - error_no_destroy: - return (error); - } - --cpg_error_t cpg_finalize ( -+cs_error_t cpg_finalize ( - cpg_handle_t handle) - { - struct cpg_inst *cpg_inst; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -150,15 +150,15 @@ - */ - if (cpg_inst->finalize) { - pthread_mutex_unlock (&cpg_inst->response_mutex); -- saHandleInstancePut (&cpg_handle_t_db, handle); -- return (CPG_ERR_BAD_HANDLE); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); -+ return (CS_ERR_BAD_HANDLE); - } - - cpg_inst->finalize = 1; - - pthread_mutex_unlock (&cpg_inst->response_mutex); - -- saHandleDestroy (&cpg_handle_t_db, handle); -+ (void)saHandleDestroy (&cpg_handle_t_db, handle); - - /* - * Disconnect from the server -@@ -171,80 +171,80 @@ - shutdown(cpg_inst->dispatch_fd, 0); - close(cpg_inst->dispatch_fd); - } -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - -- return (CPG_OK); -+ return (CS_OK); - } - --cpg_error_t cpg_fd_get ( -+cs_error_t cpg_fd_get ( - cpg_handle_t handle, - int *fd) - { -- SaAisErrorT error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - *fd = cpg_inst->dispatch_fd; - -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - } - --cpg_error_t cpg_context_get ( -+cs_error_t cpg_context_get ( - cpg_handle_t handle, - void **context) - { -- SaAisErrorT error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - *context = cpg_inst->context; - -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - } - --cpg_error_t cpg_context_set ( -+cs_error_t cpg_context_set ( - cpg_handle_t handle, - void *context) - { -- SaAisErrorT error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - cpg_inst->context = context; - -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - } - --struct res_overlay { -+struct cpg_res_overlay { - mar_res_header_t header __attribute__((aligned(8))); - char data[512000]; - }; - --cpg_error_t cpg_dispatch ( -+cs_error_t cpg_dispatch ( - cpg_handle_t handle, -- cpg_dispatch_t dispatch_types) -+ cs_dispatch_flags_t dispatch_types) - { - struct pollfd ufds; - int timeout = -1; -- SaAisErrorT error; -+ cs_error_t error; - int cont = 1; /* always continue do loop except when set to 0 */ - int dispatch_avail; - struct cpg_inst *cpg_inst; -@@ -253,8 +253,7 @@ - struct res_lib_cpg_deliver_callback *res_cpg_deliver_callback; - struct res_lib_cpg_groups_get_callback *res_lib_cpg_groups_get_callback; - cpg_callbacks_t callbacks; -- struct res_overlay dispatch_data; -- int ignore_dispatch = 0; -+ struct cpg_res_overlay dispatch_data; - struct cpg_address member_list[CPG_MEMBERS_MAX]; - struct cpg_address left_list[CPG_MEMBERS_MAX]; - struct cpg_address joined_list[CPG_MEMBERS_MAX]; -@@ -264,7 +263,7 @@ - unsigned int i; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -272,7 +271,7 @@ - * Timeout instantly for SA_DISPATCH_ONE or SA_DISPATCH_ALL and - * wait indefinately for SA_DISPATCH_BLOCKING - */ -- if (dispatch_types == CPG_DISPATCH_ALL) { -+ if (dispatch_types == CS_DISPATCH_ALL) { - timeout = 0; - } - -@@ -282,7 +281,7 @@ - ufds.revents = 0; - - error = saPollRetry (&ufds, 1, timeout); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_nounlock; - } - -@@ -292,7 +291,7 @@ - * Regather poll data in case ufds has changed since taking lock - */ - error = saPollRetry (&ufds, 1, timeout); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_nounlock; - } - -@@ -300,13 +299,13 @@ - * Handle has been finalized in another thread - */ - if (cpg_inst->finalize == 1) { -- error = CPG_OK; -+ error = CS_OK; - pthread_mutex_unlock (&cpg_inst->dispatch_mutex); - goto error_unlock; - } - - dispatch_avail = ufds.revents & POLLIN; -- if (dispatch_avail == 0 && dispatch_types == CPG_DISPATCH_ALL) { -+ if (dispatch_avail == 0 && dispatch_types == CS_DISPATCH_ALL) { - pthread_mutex_unlock (&cpg_inst->dispatch_mutex); - break; /* exit do while cont is 1 loop */ - } else -@@ -321,14 +320,14 @@ - */ - error = saRecvRetry (cpg_inst->dispatch_fd, &dispatch_data.header, - sizeof (mar_res_header_t)); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_unlock; - } - if (dispatch_data.header.size > sizeof (mar_res_header_t)) { - error = saRecvRetry (cpg_inst->dispatch_fd, &dispatch_data.data, - dispatch_data.header.size - sizeof (mar_res_header_t)); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_unlock; - } - } -@@ -424,7 +423,7 @@ - break; - - default: -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - goto error_nounlock; - break; - } -@@ -433,34 +432,27 @@ - * Determine if more messages should be processed - * */ - switch (dispatch_types) { -- case CPG_DISPATCH_ONE: -- if (ignore_dispatch) { -- ignore_dispatch = 0; -- } else { -- cont = 0; -- } -+ case CS_DISPATCH_ONE: -+ cont = 0; - break; -- case CPG_DISPATCH_ALL: -- if (ignore_dispatch) { -- ignore_dispatch = 0; -- } -+ case CS_DISPATCH_ALL: - break; -- case CPG_DISPATCH_BLOCKING: -+ case CS_DISPATCH_BLOCKING: - break; - } - } while (cont); - - error_unlock: -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - error_nounlock: - return (error); - } - --cpg_error_t cpg_join ( -+cs_error_t cpg_join ( - cpg_handle_t handle, - struct cpg_name *group) - { -- cpg_error_t error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - struct iovec iov[2]; - struct req_lib_cpg_join req_lib_cpg_join; -@@ -469,7 +461,7 @@ - struct res_lib_cpg_trackstart res_lib_cpg_trackstart; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -487,7 +479,7 @@ - error = saSendMsgReceiveReply (cpg_inst->dispatch_fd, iov, 1, - &res_lib_cpg_trackstart, sizeof (struct res_lib_cpg_trackstart)); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - pthread_mutex_unlock (&cpg_inst->response_mutex); - goto error_exit; - } -@@ -507,30 +499,30 @@ - - pthread_mutex_unlock (&cpg_inst->response_mutex); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_cpg_join.header.error; - - error_exit: -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - - return (error); - } - --cpg_error_t cpg_leave ( -+cs_error_t cpg_leave ( - cpg_handle_t handle, - struct cpg_name *group) - { -- cpg_error_t error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - struct iovec iov[2]; - struct req_lib_cpg_leave req_lib_cpg_leave; - struct res_lib_cpg_leave res_lib_cpg_leave; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -549,26 +541,26 @@ - &res_lib_cpg_leave, sizeof (struct res_lib_cpg_leave)); - - pthread_mutex_unlock (&cpg_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_cpg_leave.header.error; - - error_exit: -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - - return (error); - } - --cpg_error_t cpg_mcast_joined ( -+cs_error_t cpg_mcast_joined ( - cpg_handle_t handle, - cpg_guarantee_t guarantee, - struct iovec *iovec, - int iov_len) - { - int i; -- cpg_error_t error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - struct iovec iov[64]; - struct req_lib_cpg_mcast req_lib_cpg_mcast; -@@ -576,7 +568,7 @@ - int msg_len = 0; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -602,7 +594,7 @@ - - pthread_mutex_unlock (&cpg_inst->response_mutex); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -612,85 +604,108 @@ - * Also, don't set to ENABLED if the return value is TRY_AGAIN as this can lead - * to Flow Control State sync issues between AIS LIB and EXEC. - */ -- if (res_lib_cpg_mcast.header.error == CPG_OK) { -+ if (res_lib_cpg_mcast.header.error == CS_OK) { - cpg_inst->flow_control_state = res_lib_cpg_mcast.flow_control_state; - } - error = res_lib_cpg_mcast.header.error; - - error_exit: -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - - return (error); - } - --cpg_error_t cpg_membership_get ( -+cs_error_t cpg_membership_get ( - cpg_handle_t handle, - struct cpg_name *group_name, - struct cpg_address *member_list, - int *member_list_entries) - { -- cpg_error_t error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - struct iovec iov; - struct req_lib_cpg_membership req_lib_cpg_membership_get; -- struct res_lib_cpg_confchg_callback res_lib_cpg_membership_get; -- unsigned int i; -+ struct res_lib_cpg_confchg_callback *res_lib_cpg_membership_get; -+ mar_res_header_t header; -+ unsigned int i, bytesleft; -+ char *buffer = NULL; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -- req_lib_cpg_membership_get.header.size = sizeof (mar_req_header_t); -+ req_lib_cpg_membership_get.header.size = sizeof (req_lib_cpg_membership_get); - req_lib_cpg_membership_get.header.id = MESSAGE_REQ_CPG_MEMBERSHIP; -- marshall_to_mar_cpg_name_t (&req_lib_cpg_membership_get.group_name, -- group_name); - - iov.iov_base = (char *)&req_lib_cpg_membership_get; -- iov.iov_len = sizeof (mar_req_header_t); -+ iov.iov_len = sizeof (req_lib_cpg_membership_get); - - pthread_mutex_lock (&cpg_inst->response_mutex); - - error = saSendMsgReceiveReply (cpg_inst->response_fd, &iov, 1, -- &res_lib_cpg_membership_get, sizeof (mar_res_header_t)); -+ &header, sizeof (header)); -+ if (error != CS_OK) { -+ goto error_exit; -+ } - -- pthread_mutex_unlock (&cpg_inst->response_mutex); -+ buffer = malloc(header.size); -+ if (buffer == NULL) { -+ error = CS_ERR_NO_MEMORY; -+ goto error_exit; -+ } - -- if (error != SA_AIS_OK) { -+ memcpy (buffer, &header, sizeof (header)); -+ bytesleft = header.size - sizeof (header); -+ -+ error = saRecvRetry (cpg_inst->response_fd, -+ buffer + sizeof (header), bytesleft); -+ if (error != CS_OK) { - goto error_exit; - } - -- error = res_lib_cpg_membership_get.header.error; -+ error = header.error; -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ res_lib_cpg_membership_get = (struct res_lib_cpg_confchg_callback *) buffer; - - /* - * Copy results to caller - */ -- *member_list_entries = res_lib_cpg_membership_get.member_list_entries; -+ *member_list_entries = res_lib_cpg_membership_get->member_list_entries; - if (member_list) { -- for (i = 0; i < res_lib_cpg_membership_get.member_list_entries; i++) { -+ for (i = 0; i < res_lib_cpg_membership_get->member_list_entries; i++) { - marshall_from_mar_cpg_address_t (&member_list[i], -- &res_lib_cpg_membership_get.member_list[i]); -+ &res_lib_cpg_membership_get->member_list[i]); - } - } - - error_exit: -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ -+ if (buffer != NULL) -+ free(buffer); -+ -+ pthread_mutex_unlock (&cpg_inst->response_mutex); -+ -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - - return (error); - } - --cpg_error_t cpg_local_get ( -+cs_error_t cpg_local_get ( - cpg_handle_t handle, - unsigned int *local_nodeid) - { -- cpg_error_t error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - struct iovec iov; - struct req_lib_cpg_local_get req_lib_cpg_local_get; - struct res_lib_cpg_local_get res_lib_cpg_local_get; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -707,7 +722,7 @@ - - pthread_mutex_unlock (&cpg_inst->response_mutex); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -716,23 +731,23 @@ - *local_nodeid = res_lib_cpg_local_get.local_nodeid; - - error_exit: -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - - return (error); - } - --cpg_error_t cpg_groups_get ( -+cs_error_t cpg_groups_get ( - cpg_handle_t handle, - unsigned int *num_groups) - { -- cpg_error_t error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - struct iovec iov; - struct req_lib_cpg_groups_get req_lib_cpg_groups_get; - struct res_lib_cpg_groups_get res_lib_cpg_groups_get; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -749,7 +764,7 @@ - - pthread_mutex_unlock (&cpg_inst->response_mutex); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -758,26 +773,26 @@ - - /* Real output is delivered via a callback */ - error_exit: -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - - return (error); - } - --cpg_error_t cpg_flow_control_state_get ( -+cs_error_t cpg_flow_control_state_get ( - cpg_handle_t handle, - cpg_flow_control_state_t *flow_control_state) - { -- cpg_error_t error; -+ cs_error_t error; - struct cpg_inst *cpg_inst; - - error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - *flow_control_state = cpg_inst->flow_control_state; - -- saHandleInstancePut (&cpg_handle_t_db, handle); -+ (void)saHandleInstancePut (&cpg_handle_t_db, handle); - - return (error); - } -diff -Naurd corosync-0.92/lib/evs.c corosync-trunk/lib/evs.c ---- corosync-0.92/lib/evs.c 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/lib/evs.c 2008-12-28 10:25:17.000000000 +0100 -@@ -48,7 +48,7 @@ - - #include - #include --#include -+#include - #include - #include - #include -@@ -62,7 +62,7 @@ - pthread_mutex_t dispatch_mutex; - }; - --struct res_overlay { -+struct evs_res_overlay { - mar_res_header_t header __attribute__((aligned(8))); - char data[512000]; - }; -@@ -98,29 +98,29 @@ - * test - * @param handle The handle of evs initialize - * @param callbacks The callbacks for evs_initialize -- * @returns EVS_OK -+ * @returns CS_OK - */ --evs_error_t evs_initialize ( -+cs_error_t evs_initialize ( - evs_handle_t *handle, - evs_callbacks_t *callbacks) - { -- SaAisErrorT error; -+ cs_error_t error; - struct evs_inst *evs_inst; - - error = saHandleCreate (&evs_handle_t_db, sizeof (struct evs_inst), handle); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_no_destroy; - } - - error = saHandleInstanceGet (&evs_handle_t_db, *handle, (void *)&evs_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_destroy; - } - - error = saServiceConnect (&evs_inst->response_fd, - &evs_inst->dispatch_fd, - EVS_SERVICE); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_put_destroy; - } - -@@ -130,26 +130,26 @@ - - pthread_mutex_init (&evs_inst->dispatch_mutex, NULL); - -- saHandleInstancePut (&evs_handle_t_db, *handle); -+ (void)saHandleInstancePut (&evs_handle_t_db, *handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - - error_put_destroy: -- saHandleInstancePut (&evs_handle_t_db, *handle); -+ (void)saHandleInstancePut (&evs_handle_t_db, *handle); - error_destroy: -- saHandleDestroy (&evs_handle_t_db, *handle); -+ (void)saHandleDestroy (&evs_handle_t_db, *handle); - error_no_destroy: - return (error); - } - --evs_error_t evs_finalize ( -+cs_error_t evs_finalize ( - evs_handle_t handle) - { - struct evs_inst *evs_inst; -- SaAisErrorT error; -+ cs_error_t error; - - error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - // TODO is the locking right here -@@ -160,15 +160,15 @@ - */ - if (evs_inst->finalize) { - pthread_mutex_unlock (&evs_inst->response_mutex); -- saHandleInstancePut (&evs_handle_t_db, handle); -- return (EVS_ERR_BAD_HANDLE); -+ (void)saHandleInstancePut (&evs_handle_t_db, handle); -+ return (CS_ERR_BAD_HANDLE); - } - - evs_inst->finalize = 1; - - pthread_mutex_unlock (&evs_inst->response_mutex); - -- saHandleDestroy (&evs_handle_t_db, handle); -+ (void)saHandleDestroy (&evs_handle_t_db, handle); - /* - * Disconnect from the server - */ -@@ -180,49 +180,48 @@ - shutdown(evs_inst->dispatch_fd, 0); - close(evs_inst->dispatch_fd); - } -- saHandleInstancePut (&evs_handle_t_db, handle); -+ (void)saHandleInstancePut (&evs_handle_t_db, handle); - - -- return (EVS_OK); -+ return (CS_OK); - } - --evs_error_t evs_fd_get ( -+cs_error_t evs_fd_get ( - evs_handle_t handle, - int *fd) - { -- SaAisErrorT error; -+ cs_error_t error; - struct evs_inst *evs_inst; - - error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - - *fd = evs_inst->dispatch_fd; - -- saHandleInstancePut (&evs_handle_t_db, handle); -+ (void)saHandleInstancePut (&evs_handle_t_db, handle); - -- return (SA_AIS_OK); -+ return (CS_OK); - } - --evs_error_t evs_dispatch ( -+cs_error_t evs_dispatch ( - evs_handle_t handle, -- evs_dispatch_t dispatch_types) -+ cs_dispatch_flags_t dispatch_types) - { - struct pollfd ufds; - int timeout = -1; -- SaAisErrorT error; -+ cs_error_t error; - int cont = 1; /* always continue do loop except when set to 0 */ - int dispatch_avail; - struct evs_inst *evs_inst; - struct res_evs_confchg_callback *res_evs_confchg_callback; - struct res_evs_deliver_callback *res_evs_deliver_callback; - evs_callbacks_t callbacks; -- struct res_overlay dispatch_data; -- int ignore_dispatch = 0; -+ struct evs_res_overlay dispatch_data; - - error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -230,7 +229,7 @@ - * Timeout instantly for SA_DISPATCH_ONE or SA_DISPATCH_ALL and - * wait indefinately for SA_DISPATCH_BLOCKING - */ -- if (dispatch_types == EVS_DISPATCH_ALL) { -+ if (dispatch_types == CS_DISPATCH_ALL) { - timeout = 0; - } - -@@ -240,7 +239,7 @@ - ufds.revents = 0; - - error = saPollRetry (&ufds, 1, timeout); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_nounlock; - } - -@@ -250,7 +249,7 @@ - * Regather poll data in case ufds has changed since taking lock - */ - error = saPollRetry (&ufds, 1, 0); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_nounlock; - } - -@@ -258,13 +257,13 @@ - * Handle has been finalized in another thread - */ - if (evs_inst->finalize == 1) { -- error = EVS_OK; -+ error = CS_OK; - pthread_mutex_unlock (&evs_inst->dispatch_mutex); - goto error_unlock; - } - - dispatch_avail = ufds.revents & POLLIN; -- if (dispatch_avail == 0 && dispatch_types == EVS_DISPATCH_ALL) { -+ if (dispatch_avail == 0 && dispatch_types == CS_DISPATCH_ALL) { - pthread_mutex_unlock (&evs_inst->dispatch_mutex); - break; /* exit do while cont is 1 loop */ - } else -@@ -279,14 +278,14 @@ - */ - error = saRecvRetry (evs_inst->dispatch_fd, &dispatch_data.header, - sizeof (mar_res_header_t)); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_unlock; - } - if (dispatch_data.header.size > sizeof (mar_res_header_t)) { - error = saRecvRetry (evs_inst->dispatch_fd, &dispatch_data.data, - dispatch_data.header.size - sizeof (mar_res_header_t)); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_unlock; - } - } -@@ -327,7 +326,7 @@ - break; - - default: -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - goto error_nounlock; - break; - } -@@ -336,42 +335,35 @@ - * Determine if more messages should be processed - * */ - switch (dispatch_types) { -- case EVS_DISPATCH_ONE: -- if (ignore_dispatch) { -- ignore_dispatch = 0; -- } else { -- cont = 0; -- } -+ case CS_DISPATCH_ONE: -+ cont = 0; - break; -- case EVS_DISPATCH_ALL: -- if (ignore_dispatch) { -- ignore_dispatch = 0; -- } -+ case CS_DISPATCH_ALL: - break; -- case EVS_DISPATCH_BLOCKING: -+ case CS_DISPATCH_BLOCKING: - break; - } - } while (cont); - - error_unlock: -- saHandleInstancePut (&evs_handle_t_db, handle); -+ (void)saHandleInstancePut (&evs_handle_t_db, handle); - error_nounlock: - return (error); - } - --evs_error_t evs_join ( -+cs_error_t evs_join ( - evs_handle_t handle, - struct evs_group *groups, - int group_entries) - { -- evs_error_t error; -+ cs_error_t error; - struct evs_inst *evs_inst; - struct iovec iov[2]; - struct req_lib_evs_join req_lib_evs_join; - struct res_lib_evs_join res_lib_evs_join; - - error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -392,31 +384,31 @@ - - pthread_mutex_unlock (&evs_inst->response_mutex); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_evs_join.header.error; - - error_exit: -- saHandleInstancePut (&evs_handle_t_db, handle); -+ (void)saHandleInstancePut (&evs_handle_t_db, handle); - - return (error); - } - --evs_error_t evs_leave ( -+cs_error_t evs_leave ( - evs_handle_t handle, - struct evs_group *groups, - int group_entries) - { -- evs_error_t error; -+ cs_error_t error; - struct evs_inst *evs_inst; - struct iovec iov[2]; - struct req_lib_evs_leave req_lib_evs_leave; - struct res_lib_evs_leave res_lib_evs_leave; - - error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -437,26 +429,26 @@ - - pthread_mutex_unlock (&evs_inst->response_mutex); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_evs_leave.header.error; - - error_exit: -- saHandleInstancePut (&evs_handle_t_db, handle); -+ (void)saHandleInstancePut (&evs_handle_t_db, handle); - - return (error); - } - --evs_error_t evs_mcast_joined ( -+cs_error_t evs_mcast_joined ( - evs_handle_t handle, - evs_guarantee_t guarantee, - struct iovec *iovec, - int iov_len) - { - int i; -- evs_error_t error; -+ cs_error_t error; - struct evs_inst *evs_inst; - struct iovec iov[64]; - struct req_lib_evs_mcast_joined req_lib_evs_mcast_joined; -@@ -464,7 +456,7 @@ - int msg_len = 0; - - error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -490,19 +482,19 @@ - - pthread_mutex_unlock (&evs_inst->response_mutex); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_evs_mcast_joined.header.error; - - error_exit: -- saHandleInstancePut (&evs_handle_t_db, handle); -+ (void)saHandleInstancePut (&evs_handle_t_db, handle); - - return (error); - } - --evs_error_t evs_mcast_groups ( -+cs_error_t evs_mcast_groups ( - evs_handle_t handle, - evs_guarantee_t guarantee, - struct evs_group *groups, -@@ -511,7 +503,7 @@ - int iov_len) - { - int i; -- evs_error_t error; -+ cs_error_t error; - struct evs_inst *evs_inst; - struct iovec iov[64]; - struct req_lib_evs_mcast_groups req_lib_evs_mcast_groups; -@@ -519,7 +511,7 @@ - int msg_len = 0; - - error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - for (i = 0; i < iov_len; i++) { -@@ -544,32 +536,32 @@ - &res_lib_evs_mcast_groups, sizeof (struct res_lib_evs_mcast_groups)); - - pthread_mutex_unlock (&evs_inst->response_mutex); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = res_lib_evs_mcast_groups.header.error; - - error_exit: -- saHandleInstancePut (&evs_handle_t_db, handle); -+ (void)saHandleInstancePut (&evs_handle_t_db, handle); - - return (error); - } - --evs_error_t evs_membership_get ( -+cs_error_t evs_membership_get ( - evs_handle_t handle, - unsigned int *local_nodeid, - unsigned int *member_list, - unsigned int *member_list_entries) - { -- evs_error_t error; -+ cs_error_t error; - struct evs_inst *evs_inst; - struct iovec iov; - struct req_lib_evs_membership_get req_lib_evs_membership_get; - struct res_lib_evs_membership_get res_lib_evs_membership_get; - - error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - return (error); - } - -@@ -586,7 +578,7 @@ - - pthread_mutex_unlock (&evs_inst->response_mutex); - -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -606,7 +598,7 @@ - } - - error_exit: -- saHandleInstancePut (&evs_handle_t_db, handle); -+ (void)saHandleInstancePut (&evs_handle_t_db, handle); - - return (error); - } -diff -Naurd corosync-0.92/lib/libpload.versions corosync-trunk/lib/libpload.versions ---- corosync-0.92/lib/libpload.versions 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/lib/libpload.versions 2008-10-30 23:41:34.000000000 +0100 -@@ -0,0 +1,21 @@ -+# Version and symbol export for libSaClm.so -+ -+COROSYNC_PLOAD_1.0 { -+ global: -+ pload_start; -+ -+ local: -+ saHandleCreate; -+ saHandleDestroy; -+ saHandleInstanceGet; -+ saHandleInstancePut; -+ saRecvRetry; -+ saSelectRetry; -+ saSendMsgReceiveReply; -+ saSendMsgRetry; -+ saSendReceiveReply; -+ saSendRetry; -+ saServiceConnect; -+ saVersionVerify; -+ clustTimeNow; -+}; -diff -Naurd corosync-0.92/lib/libquorum.versions corosync-trunk/lib/libquorum.versions ---- corosync-0.92/lib/libquorum.versions 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/lib/libquorum.versions 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,50 @@ -+# Version and symbol export for libquorum.so -+ -+OPENAIS_QUORUM_1.0 { -+ global: -+ quorum_initialize; -+ quorum_finalize; -+ quorum_getquorate; -+ quorum_initialize; -+ quorum_finalize; -+ quorum_dispatch; -+ -+ local: -+ saHandleCreate; -+ saHandleDestroy; -+ saHandleInstanceGet; -+ saHandleInstancePut; -+ saRecvRetry; -+ saSelectRetry; -+ saSendMsgReceiveReply; -+ saSendMsgRetry; -+ saSendReceiveReply; -+ saSendRetry; -+ saServiceConnect; -+ saVersionVerify; -+ clustTimeNow; -+}; -+# Version and symbol export for libquorum.so -+ -+COROSYNC_QUORUM_1.0 { -+ global: -+ quorum_initialize; -+ quorum_finalize; -+ quorum_getquorate; -+ quorum_dispatch; -+ -+ local: -+ saHandleCreate; -+ saHandleDestroy; -+ saHandleInstanceGet; -+ saHandleInstancePut; -+ saRecvRetry; -+ saSelectRetry; -+ saSendMsgReceiveReply; -+ saSendMsgRetry; -+ saSendReceiveReply; -+ saSendRetry; -+ saServiceConnect; -+ saVersionVerify; -+ clustTimeNow; -+}; -diff -Naurd corosync-0.92/lib/libvotequorum.versions corosync-trunk/lib/libvotequorum.versions ---- corosync-0.92/lib/libvotequorum.versions 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/lib/libvotequorum.versions 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,71 @@ -+# Version and symbol export for libvotequorum.so -+ -+OPENAIS_VOTEQUORUM_1.0 { -+ global: -+ votequorum_initialize; -+ votequorum_finalize; -+ votequorum_getinfo; -+ votequorum_setexpected; -+ votequorum_setvotes; -+ votequorum_qdisk_register; -+ votequorum_qdisk_unregister; -+ votequorum_qdisk_poll; -+ votequorum_qdisk_getinfo; -+ votequorum_setstate; -+ votequorum_leaving; -+ votequorum_trackstart; -+ votequorum_trackstop; -+ votequorum_context_get; -+ votequorum_context_set; -+ -+ local: -+ saHandleCreate; -+ saHandleDestroy; -+ saHandleInstanceGet; -+ saHandleInstancePut; -+ saRecvRetry; -+ saSelectRetry; -+ saSendMsgReceiveReply; -+ saSendMsgRetry; -+ saSendReceiveReply; -+ saSendRetry; -+ saServiceConnect; -+ saVersionVerify; -+ clustTimeNow; -+}; -+# Version and symbol export for libvotequorum.so -+ -+COROSYNC_VOTEQUORUM_1.0 { -+ global: -+ votequorum_initialize; -+ votequorum_finalize; -+ votequorum_getinfo; -+ votequorum_setexpected; -+ votequorum_setvotes; -+ votequorum_qdisk_register; -+ votequorum_qdisk_unregister; -+ votequorum_qdisk_poll; -+ votequorum_qdisk_getinfo; -+ votequorum_setdirty; -+ votequorum_killnode; -+ votequorum_leaving; -+ votequorum_trackstart; -+ votequorum_trackstop; -+ votequorum_context_get; -+ votequorum_context_set; -+ -+ local: -+ saHandleCreate; -+ saHandleDestroy; -+ saHandleInstanceGet; -+ saHandleInstancePut; -+ saRecvRetry; -+ saSelectRetry; -+ saSendMsgReceiveReply; -+ saSendMsgRetry; -+ saSendReceiveReply; -+ saSendRetry; -+ saServiceConnect; -+ saVersionVerify; -+ clustTimeNow; -+}; -diff -Naurd corosync-0.92/lib/Makefile corosync-trunk/lib/Makefile ---- corosync-0.92/lib/Makefile 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/lib/Makefile 2009-01-26 11:46:08.000000000 +0100 -@@ -41,7 +41,10 @@ - libconfdb.a libconfdb.so.2.0.0 \ - libevs.a libevs.so.2.0.0 \ - libcfg.a libcfg.so.2.0.0 \ -- libcoroutil.a libcoroutil.so.2.0.0 -+ libquorum.a libquorum.so.2.0.0 \ -+ libpload.a libpload.so.2.0.0 \ -+ libcoroutil.a libcoroutil.so.2.0.0 \ -+ libvotequorum.a libvotequorum.so.2.0.0 - - libcoroutil.a: util.o - $(AR) -rc libcoroutil.a util.o -@@ -58,14 +61,20 @@ - libcpg.so.2.0.0: util.o cpg.o - $(CC) $(DARWIN_OPTS) util.o cpg.o -o $@ - -+libquorum.so.2.0.0: util.o quorum.o -+ $(CC) $(DARWIN_OPTS) util.o quorum.o -o $@ -+ -+libvotequorum.so.2.0.0: util.o votequorum.o -+ $(CC) $(DARWIN_OPTS) util.o votequorum.o -o $@ -+ - libconfdb.so.2.0.0: util.o confdb.o sa-confdb.o - $(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o confdb.o sa-confdb.o ../lcr/lcr_ifact.o -o $@ - - libcfg.so.2.0.0: util.o cfg.o - $(CC) $(DARWIN_OPTS) util.o cfg.o -o $@ - --libcpg.so.2.0.0: util.o cpg.o -- $(CC) $(DARWIN_OPTS) util.o cpg.o -o $@ -+libpload.so.2.0.0: util.o pload.o -+ $(CC) $(DARWIN_OPTS) util.o pload.o -o $@ - - else - -@@ -78,12 +87,21 @@ - libcpg.so.2.0.0: util.o cpg.o - $(CC) -shared -Wl,-soname,libcpg.so.2,-version-script=$(srcdir)$(subdir)libcpg.versions util.o cpg.o -o $@ - -+libquorum.so.2.0.0: util.o quorum.o -+ $(CC) -shared -Wl,-soname,libquorum.so.2,-version-script=$(srcdir)$(subdir)libquorum.versions util.o quorum.o -o $@ -+ -+libvotequorum.so.2.0.0: util.o votequorum.o -+ $(CC) -shared -Wl,-soname,libvotequorum.so.2,-version-script=$(srcdir)$(subdir)libvotequorum.versions util.o votequorum.o -o $@ -+ - libconfdb.so.2.0.0: util.o confdb.o sa-confdb.o - $(CC) $(LDFLAGS) -shared -Wl,-soname,libconfdb.so.2,-version-script=$(srcdir)$(subdir)libconfdb.versions util.o confdb.o sa-confdb.o ../lcr/lcr_ifact.o -o $@ - - libcfg.so.2.0.0: util.o cfg.o - $(CC) -shared -Wl,-soname,libcfg.so.2,-version-script=$(srcdir)$(subdir)libcfg.versions util.o cfg.o -o $@ - -+libpload.so.2.0.0: util.o pload.o -+ $(CC) -shared -Wl,-soname,libpload.so.2,-version-script=$(srcdir)$(subdir)libpload.versions util.o cfg.o -o $@ -+ - endif - - libevs.a: util.o evs.o -@@ -92,17 +110,27 @@ - libcpg.a: util.o cpg.o - $(AR) -rc libcpg.a util.o cpg.o - -+libquorum.a: util.o quorum.o -+ $(AR) -rc libquorum.a util.o quorum.o -+ -+libvotequorum.a: util.o votequorum.o -+ $(AR) -rc libvotequorum.a util.o votequorum.o -+ - libconfdb.a: util.o confdb.o sa-confdb.o - $(AR) -rc libconfdb.a util.o confdb.o sa-confdb.o ../lcr/lcr_ifact.o - - libcfg.a: util.o cfg.o - $(AR) -rc libcfg.a util.o cfg.o - -+libpload.a: util.o pload.o -+ $(AR) -rc libpload.a util.o pload.o -+ - clean: -- rm -f *.o libcfg.so* libcoroutil.so* libcoroutil.a \ -- libevs.so* libevs.a libcpg.so* libcpg.a libcfg.a libconfdb.so* \ -- libconfdb.a libconfdb.a \ *.da *.bb *.bbg -+ rm -f *.o *.a *.so* *.da *.bb *.bbg - -+lint: -+ -splint $(LINT_FLAGS) $(CFLAGS) *.c -+ - # -fPIC rules required for all libraries - %.o: %.c - $(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c -o $@ $< -diff -Naurd corosync-0.92/lib/pload.c corosync-trunk/lib/pload.c ---- corosync-0.92/lib/pload.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/lib/pload.c 2008-11-11 18:25:22.000000000 +0100 -@@ -0,0 +1,238 @@ -+/* -+ * Copyright (c) 2008 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 -+ -+static void pload_instance_destructor (void *instance); -+ -+struct pload_inst { -+ int dispatch_fd; -+ int response_fd; -+ pthread_mutex_t response_mutex; -+ pthread_mutex_t dispatch_mutex; -+ unsigned int finalize; -+}; -+ -+static struct saHandleDatabase pload_handle_t_db = { -+ .handleCount = 0, -+ .handles = 0, -+ .mutex = PTHREAD_MUTEX_INITIALIZER, -+ .handleInstanceDestructor = pload_instance_destructor -+}; -+ -+/* -+ * Clean up function for an evt instance (saEvtInitialize) handle -+ */ -+static void pload_instance_destructor (void *instance) -+{ -+ struct pload_inst *pload_inst = instance; -+ -+ pthread_mutex_destroy (&pload_inst->response_mutex); -+ pthread_mutex_destroy (&pload_inst->dispatch_mutex); -+} -+ -+ -+/** -+ * @defgroup pload_corosync The extended virtual synchrony passthrough API -+ * @ingroup corosync -+ * -+ * @{ -+ */ -+/** -+ * test -+ * @param handle The handle of pload initialize -+ * @param callbacks The callbacks for pload_initialize -+ * @returns PLOAD_OK -+ */ -+unsigned int pload_initialize ( -+ pload_handle_t *handle, -+ pload_callbacks_t *callbacks) -+{ -+ cs_error_t error; -+ struct pload_inst *pload_inst; -+ -+ error = saHandleCreate (&pload_handle_t_db, sizeof (struct pload_inst), handle); -+ if (error != CS_OK) { -+ goto error_no_destroy; -+ } -+ -+ error = saHandleInstanceGet (&pload_handle_t_db, *handle, (void *)&pload_inst); -+ if (error != CS_OK) { -+ goto error_destroy; -+ } -+ -+ error = saServiceConnect (&pload_inst->response_fd, -+ &pload_inst->dispatch_fd, -+ PLOAD_SERVICE); -+ if (error != CS_OK) { -+ goto error_put_destroy; -+ } -+ -+ pthread_mutex_init (&pload_inst->response_mutex, NULL); -+ -+ pthread_mutex_init (&pload_inst->dispatch_mutex, NULL); -+ -+ (void)saHandleInstancePut (&pload_handle_t_db, *handle); -+ -+ return (CS_OK); -+ -+error_put_destroy: -+ (void)saHandleInstancePut (&pload_handle_t_db, *handle); -+error_destroy: -+ (void)saHandleDestroy (&pload_handle_t_db, *handle); -+error_no_destroy: -+ return (error); -+} -+ -+unsigned int pload_finalize ( -+ pload_handle_t handle) -+{ -+ struct pload_inst *pload_inst; -+ cs_error_t error; -+ -+ error = saHandleInstanceGet (&pload_handle_t_db, handle, (void *)&pload_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+// TODO is the locking right here -+ pthread_mutex_lock (&pload_inst->response_mutex); -+ -+ /* -+ * Another thread has already started finalizing -+ */ -+ if (pload_inst->finalize) { -+ pthread_mutex_unlock (&pload_inst->response_mutex); -+ (void)saHandleInstancePut (&pload_handle_t_db, handle); -+ return (PLOAD_ERR_BAD_HANDLE); -+ } -+ -+ pload_inst->finalize = 1; -+ -+ pthread_mutex_unlock (&pload_inst->response_mutex); -+ -+ (void)saHandleDestroy (&pload_handle_t_db, handle); -+ /* -+ * Disconnect from the server -+ */ -+ if (pload_inst->response_fd != -1) { -+ shutdown(pload_inst->response_fd, 0); -+ close(pload_inst->response_fd); -+ } -+ if (pload_inst->dispatch_fd != -1) { -+ shutdown(pload_inst->dispatch_fd, 0); -+ close(pload_inst->dispatch_fd); -+ } -+ (void)saHandleInstancePut (&pload_handle_t_db, handle); -+ -+ -+ return (PLOAD_OK); -+} -+ -+unsigned int pload_fd_get ( -+ pload_handle_t handle, -+ int *fd) -+{ -+ cs_error_t error; -+ struct pload_inst *pload_inst; -+ -+ error = saHandleInstanceGet (&pload_handle_t_db, handle, (void *)&pload_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ *fd = pload_inst->dispatch_fd; -+ -+ (void)saHandleInstancePut (&pload_handle_t_db, handle); -+ -+ return (CS_OK); -+} -+ -+unsigned int pload_start ( -+ pload_handle_t handle, -+ unsigned int code, -+ unsigned int msg_count, -+ unsigned int msg_size) -+{ -+ unsigned int error; -+ struct pload_inst *pload_inst; -+ struct iovec iov; -+ struct req_lib_pload_start req_lib_pload_start; -+ struct res_lib_pload_start res_lib_pload_start; -+ -+ error = saHandleInstanceGet (&pload_handle_t_db, handle, (void *)&pload_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ req_lib_pload_start.header.size = sizeof (struct req_lib_pload_start); -+ req_lib_pload_start.header.id = MESSAGE_REQ_PLOAD_START; -+ req_lib_pload_start.msg_code = code; -+ req_lib_pload_start.msg_count = msg_count; -+ req_lib_pload_start.msg_size = msg_size; -+ -+ iov.iov_base = (char *)&req_lib_pload_start; -+ iov.iov_len = sizeof (struct req_lib_pload_start); -+ -+ pthread_mutex_lock (&pload_inst->response_mutex); -+ -+ error = saSendMsgReceiveReply (pload_inst->response_fd, &iov, 1, -+ &res_lib_pload_start, sizeof (struct res_lib_pload_start)); -+ -+ pthread_mutex_unlock (&pload_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_pload_start.header.error; -+ -+error_exit: -+ (void)saHandleInstancePut (&pload_handle_t_db, handle); -+ -+ return (error); -+} -+ -+/** @} */ -diff -Naurd corosync-0.92/lib/quorum.c corosync-trunk/lib/quorum.c ---- corosync-0.92/lib/quorum.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/lib/quorum.c 2008-11-11 18:26:58.000000000 +0100 -@@ -0,0 +1,493 @@ -+/* -+ * Copyright (c) 2008 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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. -+ */ -+/* -+ * Provides a quorum API using the corosync executive -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include "corosync/quorum.h" -+#include "corosync/ipc_quorum.h" -+ -+struct quorum_inst { -+ int response_fd; -+ int dispatch_fd; -+ int finalize; -+ void *context; -+ quorum_callbacks_t callbacks; -+ pthread_mutex_t response_mutex; -+ pthread_mutex_t dispatch_mutex; -+}; -+ -+static void quorum_instance_destructor (void *instance); -+ -+static struct saHandleDatabase quorum_handle_t_db = { -+ .handleCount = 0, -+ .handles = 0, -+ .mutex = PTHREAD_MUTEX_INITIALIZER, -+ .handleInstanceDestructor = quorum_instance_destructor -+}; -+ -+/* -+ * Clean up function for a quorum instance (quorum_initialize) handle -+ */ -+static void quorum_instance_destructor (void *instance) -+{ -+ struct quorum_inst *quorum_inst = instance; -+ -+ pthread_mutex_destroy (&quorum_inst->response_mutex); -+} -+ -+cs_error_t quorum_initialize ( -+ quorum_handle_t *handle, -+ quorum_callbacks_t *callbacks) -+{ -+ cs_error_t error; -+ struct quorum_inst *quorum_inst; -+ -+ error = saHandleCreate (&quorum_handle_t_db, sizeof (struct quorum_inst), handle); -+ if (error != CS_OK) { -+ goto error_no_destroy; -+ } -+ -+ error = saHandleInstanceGet (&quorum_handle_t_db, *handle, (void *)&quorum_inst); -+ if (error != CS_OK) { -+ goto error_destroy; -+ } -+ -+ error = saServiceConnect (&quorum_inst->dispatch_fd, -+ &quorum_inst->response_fd, -+ QUORUM_SERVICE); -+ if (error != CS_OK) { -+ goto error_put_destroy; -+ } -+ -+ pthread_mutex_init (&quorum_inst->response_mutex, NULL); -+ pthread_mutex_init (&quorum_inst->dispatch_mutex, NULL); -+ if (callbacks) -+ memcpy(&quorum_inst->callbacks, callbacks, sizeof (callbacks)); -+ else -+ memset(&quorum_inst->callbacks, 0, sizeof (callbacks)); -+ -+ (void)saHandleInstancePut (&quorum_handle_t_db, *handle); -+ -+ return (CS_OK); -+ -+error_put_destroy: -+ (void)saHandleInstancePut (&quorum_handle_t_db, *handle); -+error_destroy: -+ (void)saHandleDestroy (&quorum_handle_t_db, *handle); -+error_no_destroy: -+ return (error); -+} -+ -+cs_error_t quorum_finalize ( -+ quorum_handle_t handle) -+{ -+ struct quorum_inst *quorum_inst; -+ cs_error_t error; -+ -+ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&quorum_inst->response_mutex); -+ -+ /* -+ * Another thread has already started finalizing -+ */ -+ if (quorum_inst->finalize) { -+ pthread_mutex_unlock (&quorum_inst->response_mutex); -+ (void)saHandleInstancePut (&quorum_handle_t_db, handle); -+ return (CS_ERR_BAD_HANDLE); -+ } -+ -+ quorum_inst->finalize = 1; -+ -+ pthread_mutex_unlock (&quorum_inst->response_mutex); -+ -+ (void)saHandleDestroy (&quorum_handle_t_db, handle); -+ -+ /* -+ * Disconnect from the server -+ */ -+ if (quorum_inst->response_fd != -1) { -+ shutdown(quorum_inst->response_fd, 0); -+ close(quorum_inst->response_fd); -+ } -+ (void)saHandleInstancePut (&quorum_handle_t_db, handle); -+ -+ return (CS_OK); -+} -+ -+cs_error_t quorum_getquorate ( -+ quorum_handle_t handle, -+ int *quorate) -+{ -+ cs_error_t error; -+ struct quorum_inst *quorum_inst; -+ struct iovec iov[2]; -+ mar_req_header_t req; -+ struct res_lib_quorum_getquorate res_lib_quorum_getquorate; -+ -+ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&quorum_inst->response_mutex); -+ -+ req.size = sizeof (req); -+ req.id = MESSAGE_REQ_QUORUM_GETQUORATE; -+ -+ iov[0].iov_base = (char *)&req; -+ iov[0].iov_len = sizeof (req); -+ -+ error = saSendMsgReceiveReply (quorum_inst->response_fd, iov, 1, -+ &res_lib_quorum_getquorate, sizeof (struct res_lib_quorum_getquorate)); -+ -+ pthread_mutex_unlock (&quorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_quorum_getquorate.header.error; -+ -+ *quorate = res_lib_quorum_getquorate.quorate; -+ -+error_exit: -+ (void)saHandleInstancePut (&quorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t quorum_fd_get ( -+ quorum_handle_t handle, -+ int *fd) -+{ -+ cs_error_t error; -+ struct quorum_inst *quorum_inst; -+ -+ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ *fd = quorum_inst->dispatch_fd; -+ -+ (void)saHandleInstancePut (&quorum_handle_t_db, handle); -+ -+ return (CS_OK); -+} -+ -+ -+cs_error_t quorum_context_get ( -+ quorum_handle_t handle, -+ void **context) -+{ -+ cs_error_t error; -+ struct quorum_inst *quorum_inst; -+ -+ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ *context = quorum_inst->context; -+ -+ (void)saHandleInstancePut (&quorum_handle_t_db, handle); -+ -+ return (CS_OK); -+} -+ -+cs_error_t quorum_context_set ( -+ quorum_handle_t handle, -+ void *context) -+{ -+ cs_error_t error; -+ struct quorum_inst *quorum_inst; -+ -+ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ quorum_inst->context = context; -+ -+ (void)saHandleInstancePut (&quorum_handle_t_db, handle); -+ -+ return (CS_OK); -+} -+ -+ -+cs_error_t quorum_trackstart ( -+ quorum_handle_t handle, -+ unsigned int flags ) -+{ -+ cs_error_t error; -+ struct quorum_inst *quorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_quorum_trackstart req_lib_quorum_trackstart; -+ mar_res_header_t res; -+ -+ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&quorum_inst->response_mutex); -+ -+ req_lib_quorum_trackstart.header.size = sizeof (struct req_lib_quorum_trackstart); -+ req_lib_quorum_trackstart.header.id = MESSAGE_REQ_QUORUM_TRACKSTART; -+ req_lib_quorum_trackstart.track_flags = flags; -+ -+ iov[0].iov_base = (char *)&req_lib_quorum_trackstart; -+ iov[0].iov_len = sizeof (struct req_lib_quorum_trackstart); -+ -+ error = saSendMsgReceiveReply (quorum_inst->response_fd, iov, 1, -+ &res, sizeof (res)); -+ -+ pthread_mutex_unlock (&quorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res.error; -+ -+error_exit: -+ (void)saHandleInstancePut (&quorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t quorum_trackstop ( -+ quorum_handle_t handle) -+{ -+ cs_error_t error; -+ struct quorum_inst *quorum_inst; -+ struct iovec iov[2]; -+ mar_req_header_t req; -+ mar_res_header_t res; -+ -+ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&quorum_inst->response_mutex); -+ -+ req.size = sizeof (req); -+ req.id = MESSAGE_REQ_QUORUM_TRACKSTOP; -+ -+ iov[0].iov_base = (char *)&req; -+ iov[0].iov_len = sizeof (req); -+ -+ error = saSendMsgReceiveReply (quorum_inst->response_fd, iov, 1, -+ &res, sizeof (res)); -+ -+ pthread_mutex_unlock (&quorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res.error; -+ -+error_exit: -+ (void)saHandleInstancePut (&quorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+struct quorum_res_overlay { -+ mar_res_header_t header __attribute__((aligned(8))); -+ char data[512000]; -+}; -+ -+cs_error_t quorum_dispatch ( -+ quorum_handle_t handle, -+ cs_dispatch_flags_t dispatch_types) -+{ -+ struct pollfd ufds; -+ int timeout = -1; -+ cs_error_t error; -+ int cont = 1; /* always continue do loop except when set to 0 */ -+ int dispatch_avail; -+ struct quorum_inst *quorum_inst; -+ quorum_callbacks_t callbacks; -+ struct quorum_res_overlay dispatch_data; -+ struct res_lib_quorum_notification *res_lib_quorum_notification; -+ -+ if (dispatch_types != CS_DISPATCH_ONE && -+ dispatch_types != CS_DISPATCH_ALL && -+ dispatch_types != CS_DISPATCH_BLOCKING) { -+ -+ return (CS_ERR_INVALID_PARAM); -+ } -+ -+ error = saHandleInstanceGet (&quorum_handle_t_db, handle, -+ (void *)&quorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ /* -+ * Timeout instantly for CS_DISPATCH_ONE or SA_DISPATCH_ALL and -+ * wait indefinately for CS_DISPATCH_BLOCKING -+ */ -+ if (dispatch_types == CS_DISPATCH_ALL) { -+ timeout = 0; -+ } -+ -+ do { -+ ufds.fd = quorum_inst->dispatch_fd; -+ ufds.events = POLLIN; -+ ufds.revents = 0; -+ -+ pthread_mutex_lock (&quorum_inst->dispatch_mutex); -+ -+ error = saPollRetry (&ufds, 1, timeout); -+ if (error != CS_OK) { -+ goto error_unlock; -+ } -+ -+ /* -+ * Handle has been finalized in another thread -+ */ -+ if (quorum_inst->finalize == 1) { -+ error = CS_OK; -+ goto error_unlock; -+ } -+ -+ if ((ufds.revents & (POLLERR|POLLHUP|POLLNVAL)) != 0) { -+ error = CS_ERR_BAD_HANDLE; -+ goto error_unlock; -+ } -+ -+ dispatch_avail = ufds.revents & POLLIN; -+ if (dispatch_avail == 0 && dispatch_types == CS_DISPATCH_ALL) { -+ pthread_mutex_unlock (&quorum_inst->dispatch_mutex); -+ break; /* exit do while cont is 1 loop */ -+ } else -+ if (dispatch_avail == 0) { -+ pthread_mutex_unlock (&quorum_inst->dispatch_mutex); -+ continue; /* next poll */ -+ } -+ -+ if (ufds.revents & POLLIN) { -+ error = saRecvRetry (quorum_inst->dispatch_fd, &dispatch_data.header, -+ sizeof (mar_res_header_t)); -+ if (error != CS_OK) { -+ goto error_unlock; -+ } -+ if (dispatch_data.header.size > sizeof (mar_res_header_t)) { -+ error = saRecvRetry (quorum_inst->dispatch_fd, &dispatch_data.data, -+ dispatch_data.header.size - sizeof (mar_res_header_t)); -+ if (error != CS_OK) { -+ goto error_unlock; -+ } -+ } -+ } else { -+ pthread_mutex_unlock (&quorum_inst->dispatch_mutex); -+ continue; -+ } -+ -+ /* -+ * Make copy of callbacks, message data, unlock instance, and call callback -+ * A risk of this dispatch method is that the callback routines may -+ * operate at the same time that quorum_finalize has been called in another thread. -+ */ -+ memcpy (&callbacks, &quorum_inst->callbacks, sizeof (quorum_callbacks_t)); -+ pthread_mutex_unlock (&quorum_inst->dispatch_mutex); -+ -+ /* -+ * Dispatch incoming message -+ */ -+ switch (dispatch_data.header.id) { -+ -+ case MESSAGE_RES_QUORUM_NOTIFICATION: -+ if (callbacks.quorum_notify_fn == NULL) { -+ continue; -+ } -+ res_lib_quorum_notification = (struct res_lib_quorum_notification *)&dispatch_data; -+ -+ callbacks.quorum_notify_fn ( handle, -+ res_lib_quorum_notification->quorate, -+ res_lib_quorum_notification->ring_seq, -+ res_lib_quorum_notification->view_list_entries, -+ res_lib_quorum_notification->view_list); -+ break; -+ -+ default: -+ error = CS_ERR_LIBRARY; -+ goto error_put; -+ break; -+ } -+ -+ /* -+ * Determine if more messages should be processed -+ * */ -+ switch (dispatch_types) { -+ case CS_DISPATCH_ONE: -+ cont = 0; -+ break; -+ case CS_DISPATCH_ALL: -+ break; -+ case CS_DISPATCH_BLOCKING: -+ break; -+ } -+ } while (cont); -+ -+ goto error_put; -+ -+error_unlock: -+ pthread_mutex_unlock (&quorum_inst->dispatch_mutex); -+ -+error_put: -+ (void)saHandleInstancePut (&quorum_handle_t_db, handle); -+ return (error); -+} -diff -Naurd corosync-0.92/lib/sa-confdb.c corosync-trunk/lib/sa-confdb.c ---- corosync-0.92/lib/sa-confdb.c 2008-09-03 09:58:08.000000000 +0200 -+++ corosync-trunk/lib/sa-confdb.c 2008-11-12 18:39:37.000000000 +0100 -@@ -43,7 +43,7 @@ - #include - #include - --#include -+#include - #include - #include - #include -@@ -80,7 +80,7 @@ - objdb = (struct objdb_iface_ver0 *)objdb_p; - - objdb->objdb_init (); -- return SA_AIS_OK; -+ return CS_OK; - } - - static int load_config() -@@ -130,7 +130,7 @@ - if (config_iface) - free(config_iface); - -- return SA_AIS_OK; -+ return CS_OK; - } - - /* Needed by objdb when it writes back the configuration */ -@@ -174,7 +174,7 @@ - int res; - - res = load_objdb(); -- if (res != SA_AIS_OK) -+ if (res != CS_OK) - return res; - - res = load_config(); -@@ -295,7 +295,6 @@ - } - - int confdb_sa_write ( -- unsigned int parent_object_handle, - char *error_text) - { - char *errtext; -@@ -309,7 +308,6 @@ - } - - int confdb_sa_reload ( -- unsigned int parent_object_handle, - int flush, - char *error_text) - { -diff -Naurd corosync-0.92/lib/sa-confdb.h corosync-trunk/lib/sa-confdb.h ---- corosync-0.92/lib/sa-confdb.h 2008-08-26 09:34:22.000000000 +0200 -+++ corosync-trunk/lib/sa-confdb.h 2008-10-06 09:46:04.000000000 +0200 -@@ -42,6 +42,8 @@ - extern int confdb_sa_key_replace(unsigned int parent_object_handle, void *key_name, int key_name_len, void *old_value, int old_value_len, void *new_value, int new_value_len); - extern int confdb_sa_object_find(unsigned int parent_object_handle, unsigned int *find_handle, unsigned int *object_handle, void *object_name, int *object_name_len, int copy_name); - extern int confdb_sa_key_iter(unsigned int parent_object_handle, unsigned int start_pos, void *key_name, int *key_name_len, void *value, int *value_len); -+extern int confdb_sa_key_increment(unsigned int parent_object_handle, void *key_name, int key_name_len, unsigned int *value); -+extern int confdb_sa_key_decrement(unsigned int parent_object_handle, void *key_name, int key_name_len, unsigned int *value); - extern int confdb_sa_find_destroy(unsigned int find_handle); - extern int confdb_sa_write(char *error_text); - extern int confdb_sa_reload(int flush, char *error_text); -diff -Naurd corosync-0.92/lib/util.c corosync-trunk/lib/util.c ---- corosync-0.92/lib/util.c 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/lib/util.c 2008-11-11 19:13:47.000000000 +0100 -@@ -53,7 +53,7 @@ - #include - #include - --#include -+#include - #include - #include - -@@ -96,7 +96,7 @@ - } - #endif - --SaAisErrorT -+cs_error_t - saServiceConnect ( - int *responseOut, - int *callbackOut, -@@ -110,7 +110,7 @@ - mar_res_lib_response_init_t res_lib_response_init; - mar_req_lib_dispatch_init_t req_lib_dispatch_init; - mar_res_lib_dispatch_init_t res_lib_dispatch_init; -- SaAisErrorT error; -+ cs_error_t error; - gid_t egid; - - /* -@@ -131,7 +131,7 @@ - #endif - responseFD = socket (PF_UNIX, SOCK_STREAM, 0); - if (responseFD == -1) { -- return (SA_AIS_ERR_NO_RESOURCES); -+ return (CS_ERR_NO_RESOURCES); - } - - socket_nosigpipe (responseFD); -@@ -139,7 +139,7 @@ - result = connect (responseFD, (struct sockaddr *)&address, AIS_SUN_LEN(&address)); - if (result == -1) { - close (responseFD); -- return (SA_AIS_ERR_TRY_AGAIN); -+ return (CS_ERR_TRY_AGAIN); - } - - req_lib_response_init.resdis_header.size = sizeof (req_lib_response_init); -@@ -148,19 +148,19 @@ - - error = saSendRetry (responseFD, &req_lib_response_init, - sizeof (mar_req_lib_response_init_t)); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - error = saRecvRetry (responseFD, &res_lib_response_init, - sizeof (mar_res_lib_response_init_t)); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - /* - * Check for security errors - */ -- if (res_lib_response_init.header.error != SA_AIS_OK) { -+ if (res_lib_response_init.header.error != CS_OK) { - error = res_lib_response_init.header.error; - goto error_exit; - } -@@ -171,7 +171,7 @@ - callbackFD = socket (PF_UNIX, SOCK_STREAM, 0); - if (callbackFD == -1) { - close (responseFD); -- return (SA_AIS_ERR_NO_RESOURCES); -+ return (CS_ERR_NO_RESOURCES); - } - - socket_nosigpipe (callbackFD); -@@ -180,7 +180,7 @@ - if (result == -1) { - close (callbackFD); - close (responseFD); -- return (SA_AIS_ERR_TRY_AGAIN); -+ return (CS_ERR_TRY_AGAIN); - } - - req_lib_dispatch_init.resdis_header.size = sizeof (req_lib_dispatch_init); -@@ -191,25 +191,25 @@ - - error = saSendRetry (callbackFD, &req_lib_dispatch_init, - sizeof (mar_req_lib_dispatch_init_t)); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit_two; - } - error = saRecvRetry (callbackFD, &res_lib_dispatch_init, - sizeof (mar_res_lib_dispatch_init_t)); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit_two; - } - - /* - * Check for security errors - */ -- if (res_lib_dispatch_init.header.error != SA_AIS_OK) { -+ if (res_lib_dispatch_init.header.error != CS_OK) { - error = res_lib_dispatch_init.header.error; - goto error_exit; - } - - *callbackOut = callbackFD; -- return (SA_AIS_OK); -+ return (CS_OK); - - error_exit_two: - close (callbackFD); -@@ -218,14 +218,14 @@ - return (error); - } - --SaAisErrorT -+cs_error_t - saRecvRetry ( - int s, - void *msg, - size_t len) - { -- SaAisErrorT error = SA_AIS_OK; -- int result; -+ cs_error_t error = CS_OK; -+ ssize_t result; - struct msghdr msg_recv; - struct iovec iov_recv; - char *rbuf = (char *)msg; -@@ -260,12 +260,12 @@ - * EOF is detected when recvmsg return 0. - */ - if (result == 0) { -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - goto error_exit; - } - #endif - if (result == -1 || result == 0) { -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - goto error_exit; - } - processed += result; -@@ -277,14 +277,14 @@ - return (error); - } - --SaAisErrorT -+cs_error_t - saSendRetry ( - int s, - const void *msg, - size_t len) - { -- SaAisErrorT error = SA_AIS_OK; -- int result; -+ cs_error_t error = CS_OK; -+ ssize_t result; - struct msghdr msg_send; - struct iovec iov_send; - char *rbuf = (char *)msg; -@@ -315,15 +315,15 @@ - */ - if (result == -1 && processed == 0) { - if (errno == EINTR) { -- error = SA_AIS_ERR_TRY_AGAIN; -+ error = CS_ERR_TRY_AGAIN; - goto error_exit; - } - if (errno == EAGAIN) { -- error = SA_AIS_ERR_TRY_AGAIN; -+ error = CS_ERR_TRY_AGAIN; - goto error_exit; - } - if (errno == EFAULT) { -- error = SA_AIS_ERR_INVALID_PARAM; -+ error = CS_ERR_INVALID_PARAM; - goto error_exit; - } - } -@@ -340,7 +340,7 @@ - goto retry_send; - } - if (errno == EFAULT) { -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - goto error_exit; - } - } -@@ -349,7 +349,7 @@ - * return ERR_LIBRARY on any other syscall error - */ - if (result == -1) { -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - goto error_exit; - } - -@@ -362,13 +362,13 @@ - return (error); - } - --SaAisErrorT saSendMsgRetry ( -+cs_error_t saSendMsgRetry ( - int s, - struct iovec *iov, - int iov_len) - { -- SaAisErrorT error = SA_AIS_OK; -- int result; -+ cs_error_t error = CS_OK; -+ ssize_t result; - int total_size = 0; - int i; - int csize; -@@ -404,15 +404,15 @@ - */ - if (result == -1 && iovec_saved_position == -1) { - if (errno == EINTR) { -- error = SA_AIS_ERR_TRY_AGAIN; -+ error = CS_ERR_TRY_AGAIN; - goto error_exit; - } - if (errno == EAGAIN) { -- error = SA_AIS_ERR_TRY_AGAIN; -+ error = CS_ERR_TRY_AGAIN; - goto error_exit; - } - if (errno == EFAULT) { -- error = SA_AIS_ERR_INVALID_PARAM; -+ error = CS_ERR_INVALID_PARAM; - goto error_exit; - } - } -@@ -428,7 +428,7 @@ - goto retry_sendmsg; - } - if (errno == EFAULT) { -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - goto error_exit; - } - } -@@ -437,7 +437,7 @@ - * ERR_LIBRARY for any other syscall error - */ - if (result == -1) { -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - goto error_exit; - } - -@@ -470,22 +470,22 @@ - return (error); - } - --SaAisErrorT saSendMsgReceiveReply ( -+cs_error_t saSendMsgReceiveReply ( - int s, - struct iovec *iov, - int iov_len, - void *responseMessage, - int responseLen) - { -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - - error = saSendMsgRetry (s, iov, iov_len); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = saRecvRetry (s, responseMessage, responseLen); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -493,22 +493,22 @@ - return (error); - } - --SaAisErrorT saSendReceiveReply ( -+cs_error_t saSendReceiveReply ( - int s, - void *requestMessage, - int requestLen, - void *responseMessage, - int responseLen) - { -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - - error = saSendRetry (s, requestMessage, requestLen); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - - error = saRecvRetry (s, responseMessage, responseLen); -- if (error != SA_AIS_OK) { -+ if (error != CS_OK) { - goto error_exit; - } - -@@ -516,13 +516,13 @@ - return (error); - } - --SaAisErrorT -+cs_error_t - saPollRetry ( - struct pollfd *ufds, - unsigned int nfds, - int timeout) - { -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - int result; - - retry_poll: -@@ -531,18 +531,18 @@ - goto retry_poll; - } - if (result == -1) { -- error = SA_AIS_ERR_LIBRARY; -+ error = CS_ERR_LIBRARY; - } - - return (error); - } - - --SaAisErrorT -+cs_error_t - saHandleCreate ( - struct saHandleDatabase *handleDatabase, - int instanceSize, -- SaUint64T *handleOut) -+ uint64_t *handleOut) - { - uint32_t handle; - uint32_t check; -@@ -566,7 +566,7 @@ - sizeof (struct saHandle) * handleDatabase->handleCount); - if (newHandles == NULL) { - pthread_mutex_unlock (&handleDatabase->mutex); -- return (SA_AIS_ERR_NO_MEMORY); -+ return (CS_ERR_NO_MEMORY); - } - handleDatabase->handles = newHandles; - } -@@ -575,7 +575,7 @@ - if (instance == 0) { - free (newHandles); - pthread_mutex_unlock (&handleDatabase->mutex); -- return (SA_AIS_ERR_NO_MEMORY); -+ return (CS_ERR_NO_MEMORY); - } - - -@@ -601,20 +601,20 @@ - - handleDatabase->handles[handle].check = check; - -- *handleOut = (SaUint64T)((uint64_t)check << 32 | handle); -+ *handleOut = (uint64_t)((uint64_t)check << 32 | handle); - - pthread_mutex_unlock (&handleDatabase->mutex); - -- return (SA_AIS_OK); -+ return (CS_OK); - } - - --SaAisErrorT -+cs_error_t - saHandleDestroy ( - struct saHandleDatabase *handleDatabase, -- SaUint64T inHandle) -+ uint64_t inHandle) - { -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - uint32_t check = inHandle >> 32; - uint32_t handle = inHandle & 0xffffffff; - -@@ -622,7 +622,7 @@ - - if (check != handleDatabase->handles[handle].check) { - pthread_mutex_unlock (&handleDatabase->mutex); -- error = SA_AIS_ERR_BAD_HANDLE; -+ error = CS_ERR_BAD_HANDLE; - return (error); - } - -@@ -630,34 +630,34 @@ - - pthread_mutex_unlock (&handleDatabase->mutex); - -- saHandleInstancePut (handleDatabase, inHandle); -+ (void)saHandleInstancePut (handleDatabase, inHandle); - - return (error); - } - - --SaAisErrorT -+cs_error_t - saHandleInstanceGet ( - struct saHandleDatabase *handleDatabase, -- SaUint64T inHandle, -+ uint64_t inHandle, - void **instance) - { - uint32_t check = inHandle >> 32; - uint32_t handle = inHandle & 0xffffffff; - -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - pthread_mutex_lock (&handleDatabase->mutex); - -- if (handle >= (SaUint64T)handleDatabase->handleCount) { -- error = SA_AIS_ERR_BAD_HANDLE; -+ if (handle >= (uint64_t)handleDatabase->handleCount) { -+ error = CS_ERR_BAD_HANDLE; - goto error_exit; - } - if (handleDatabase->handles[handle].state != SA_HANDLE_STATE_ACTIVE) { -- error = SA_AIS_ERR_BAD_HANDLE; -+ error = CS_ERR_BAD_HANDLE; - goto error_exit; - } - if (check != handleDatabase->handles[handle].check) { -- error = SA_AIS_ERR_BAD_HANDLE; -+ error = CS_ERR_BAD_HANDLE; - goto error_exit; - } - -@@ -673,20 +673,20 @@ - } - - --SaAisErrorT -+cs_error_t - saHandleInstancePut ( - struct saHandleDatabase *handleDatabase, -- SaUint64T inHandle) -+ uint64_t inHandle) - { - void *instance; -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - uint32_t check = inHandle >> 32; - uint32_t handle = inHandle & 0xffffffff; - - pthread_mutex_lock (&handleDatabase->mutex); - - if (check != handleDatabase->handles[handle].check) { -- error = SA_AIS_ERR_BAD_HANDLE; -+ error = CS_ERR_BAD_HANDLE; - goto error_exit; - } - -@@ -707,16 +707,16 @@ - } - - --SaAisErrorT -+cs_error_t - saVersionVerify ( - struct saVersionDatabase *versionDatabase, -- SaVersionT *version) -+ cs_version_t *version) - { - int i; -- SaAisErrorT error = SA_AIS_ERR_VERSION; -+ cs_error_t error = CS_ERR_VERSION; - - if (version == 0) { -- return (SA_AIS_ERR_INVALID_PARAM); -+ return (CS_ERR_INVALID_PARAM); - } - - /* -@@ -742,7 +742,7 @@ - * Check if we can support the major version requested. - */ - if (versionDatabase->versionsSupported[i].majorVersion >= version->majorVersion) { -- error = SA_AIS_OK; -+ error = CS_OK; - break; - } - -@@ -771,17 +771,17 @@ - /* - * Get the time of day and convert to nanoseconds - */ --SaTimeT clustTimeNow(void) -+cs_time_t clustTimeNow(void) - { - struct timeval tv; -- SaTimeT time_now; -+ cs_time_t time_now; - - if (gettimeofday(&tv, 0)) { - return 0ULL; - } - -- time_now = (SaTimeT)(tv.tv_sec) * 1000000000ULL; -- time_now += (SaTimeT)(tv.tv_usec) * 1000ULL; -+ time_now = (cs_time_t)(tv.tv_sec) * 1000000000ULL; -+ time_now += (cs_time_t)(tv.tv_usec) * 1000ULL; - - return time_now; - } -diff -Naurd corosync-0.92/lib/util.h corosync-trunk/lib/util.h ---- corosync-0.92/lib/util.h 2008-05-12 15:48:06.000000000 +0200 -+++ corosync-trunk/lib/util.h 2008-11-06 22:49:07.000000000 +0100 -@@ -72,72 +72,72 @@ - SaVersionT *versionsSupported; - }; - --SaAisErrorT -+cs_error_t - saServiceConnect ( - int *responseOut, - int *callbackOut, - enum service_types service); - --SaAisErrorT -+cs_error_t - saRecvRetry ( - int s, - void *msg, - size_t len); - --SaAisErrorT -+cs_error_t - saSendRetry ( - int s, - const void *msg, - size_t len); - --SaAisErrorT saSendMsgRetry ( -+cs_error_t saSendMsgRetry ( - int s, - struct iovec *iov, - int iov_len); - --SaAisErrorT saSendMsgReceiveReply ( -+cs_error_t saSendMsgReceiveReply ( - int s, - struct iovec *iov, - int iov_len, - void *responseMessage, - int responseLen); - --SaAisErrorT saSendReceiveReply ( -+cs_error_t saSendReceiveReply ( - int s, - void *requestMessage, - int requestLen, - void *responseMessage, - int responseLen); - --SaAisErrorT -+cs_error_t - saPollRetry ( - struct pollfd *ufds, - unsigned int nfds, - int timeout); - --SaAisErrorT -+cs_error_t - saHandleCreate ( - struct saHandleDatabase *handleDatabase, - int instanceSize, - SaUint64T *handleOut); - --SaAisErrorT -+cs_error_t - saHandleDestroy ( - struct saHandleDatabase *handleDatabase, - SaUint64T handle); - --SaAisErrorT -+cs_error_t - saHandleInstanceGet ( - struct saHandleDatabase *handleDatabase, - SaUint64T handle, - void **instance); - --SaAisErrorT -+cs_error_t - saHandleInstancePut ( - struct saHandleDatabase *handleDatabase, - SaUint64T handle); - --SaAisErrorT -+cs_error_t - saVersionVerify ( - struct saVersionDatabase *versionDatabase, - SaVersionT *version); -diff -Naurd corosync-0.92/lib/votequorum.c corosync-trunk/lib/votequorum.c ---- corosync-0.92/lib/votequorum.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/lib/votequorum.c 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,821 @@ -+/* -+ * Copyright (c) 2009 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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. -+ */ -+ -+/* -+ * Provides a quorum API using the corosync executive -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include "corosync/votequorum.h" -+#include "corosync/ipc_votequorum.h" -+ -+struct votequorum_inst { -+ int response_fd; -+ int dispatch_fd; -+ int finalize; -+ void *context; -+ votequorum_callbacks_t callbacks; -+ pthread_mutex_t response_mutex; -+ pthread_mutex_t dispatch_mutex; -+}; -+ -+static void votequorum_instance_destructor (void *instance); -+ -+static struct saHandleDatabase votequorum_handle_t_db = { -+ .handleCount = 0, -+ .handles = 0, -+ .mutex = PTHREAD_MUTEX_INITIALIZER, -+ .handleInstanceDestructor = votequorum_instance_destructor -+}; -+ -+/* -+ * Clean up function for a quorum instance (votequorum_initialize) handle -+ */ -+static void votequorum_instance_destructor (void *instance) -+{ -+ struct votequorum_inst *votequorum_inst = instance; -+ -+ pthread_mutex_destroy (&votequorum_inst->response_mutex); -+} -+ -+cs_error_t votequorum_initialize ( -+ votequorum_handle_t *handle, -+ votequorum_callbacks_t *callbacks) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ -+ error = saHandleCreate (&votequorum_handle_t_db, sizeof (struct votequorum_inst), handle); -+ if (error != CS_OK) { -+ goto error_no_destroy; -+ } -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, *handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ goto error_destroy; -+ } -+ -+ error = saServiceConnect (&votequorum_inst->dispatch_fd, -+ &votequorum_inst->response_fd, -+ VOTEQUORUM_SERVICE); -+ if (error != CS_OK) { -+ goto error_put_destroy; -+ } -+ -+ pthread_mutex_init (&votequorum_inst->response_mutex, NULL); -+ pthread_mutex_init (&votequorum_inst->dispatch_mutex, NULL); -+ if (callbacks) -+ memcpy(&votequorum_inst->callbacks, callbacks, sizeof (callbacks)); -+ else -+ memset(&votequorum_inst->callbacks, 0, sizeof (callbacks)); -+ -+ saHandleInstancePut (&votequorum_handle_t_db, *handle); -+ -+ return (CS_OK); -+ -+error_put_destroy: -+ saHandleInstancePut (&votequorum_handle_t_db, *handle); -+error_destroy: -+ saHandleDestroy (&votequorum_handle_t_db, *handle); -+error_no_destroy: -+ return (error); -+} -+ -+cs_error_t votequorum_finalize ( -+ votequorum_handle_t handle) -+{ -+ struct votequorum_inst *votequorum_inst; -+ cs_error_t error; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ /* -+ * Another thread has already started finalizing -+ */ -+ if (votequorum_inst->finalize) { -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ return (CS_ERR_BAD_HANDLE); -+ } -+ -+ votequorum_inst->finalize = 1; -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ saHandleDestroy (&votequorum_handle_t_db, handle); -+ -+ /* -+ * Disconnect from the server -+ */ -+ if (votequorum_inst->response_fd != -1) { -+ shutdown(votequorum_inst->response_fd, 0); -+ close(votequorum_inst->response_fd); -+ } -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (CS_OK); -+} -+ -+ -+cs_error_t votequorum_getinfo ( -+ votequorum_handle_t handle, -+ unsigned int nodeid, -+ struct votequorum_info *info) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_getinfo req_lib_votequorum_getinfo; -+ struct res_lib_votequorum_getinfo res_lib_votequorum_getinfo; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_getinfo.header.size = sizeof (struct req_lib_votequorum_getinfo); -+ req_lib_votequorum_getinfo.header.id = MESSAGE_REQ_VOTEQUORUM_GETINFO; -+ req_lib_votequorum_getinfo.nodeid = nodeid; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_getinfo; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_getinfo); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_getinfo, sizeof (struct res_lib_votequorum_getinfo)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_getinfo.header.error; -+ -+ info->node_id = res_lib_votequorum_getinfo.nodeid; -+ info->node_votes = res_lib_votequorum_getinfo.votes; -+ info->node_expected_votes = res_lib_votequorum_getinfo.expected_votes; -+ info->highest_expected = res_lib_votequorum_getinfo.highest_expected; -+ info->total_votes = res_lib_votequorum_getinfo.total_votes; -+ info->quorum = res_lib_votequorum_getinfo.quorum; -+ info->flags = res_lib_votequorum_getinfo.flags; -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t votequorum_setexpected ( -+ votequorum_handle_t handle, -+ unsigned int expected_votes) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_setexpected req_lib_votequorum_setexpected; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_setexpected.header.size = sizeof (struct req_lib_votequorum_setexpected); -+ req_lib_votequorum_setexpected.header.id = MESSAGE_REQ_VOTEQUORUM_SETEXPECTED; -+ req_lib_votequorum_setexpected.expected_votes = expected_votes; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_setexpected; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_setexpected); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_status.header.error; -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t votequorum_setvotes ( -+ votequorum_handle_t handle, -+ unsigned int nodeid, -+ unsigned int votes) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_setvotes req_lib_votequorum_setvotes; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_setvotes.header.size = sizeof (struct req_lib_votequorum_setvotes); -+ req_lib_votequorum_setvotes.header.id = MESSAGE_REQ_VOTEQUORUM_SETVOTES; -+ req_lib_votequorum_setvotes.nodeid = nodeid; -+ req_lib_votequorum_setvotes.votes = votes; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_setvotes; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_setvotes); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_status.header.error; -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t votequorum_qdisk_register ( -+ votequorum_handle_t handle, -+ char *name, -+ unsigned int votes) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_qdisk_register req_lib_votequorum_qdisk_register; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ -+ if (strlen(name) > VOTEQUORUM_MAX_QDISK_NAME_LEN) -+ return CS_ERR_INVALID_PARAM; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_qdisk_register.header.size = sizeof (struct req_lib_votequorum_qdisk_register); -+ req_lib_votequorum_qdisk_register.header.id = MESSAGE_REQ_VOTEQUORUM_QDISK_REGISTER; -+ strcpy(req_lib_votequorum_qdisk_register.name, name); -+ req_lib_votequorum_qdisk_register.votes = votes; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_qdisk_register; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_qdisk_register); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_status.header.error; -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t votequorum_qdisk_poll ( -+ votequorum_handle_t handle, -+ unsigned int state) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_qdisk_poll req_lib_votequorum_qdisk_poll; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_qdisk_poll.header.size = sizeof (struct req_lib_votequorum_qdisk_poll); -+ req_lib_votequorum_qdisk_poll.header.id = MESSAGE_REQ_VOTEQUORUM_QDISK_POLL; -+ req_lib_votequorum_qdisk_poll.state = state; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_qdisk_poll; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_qdisk_poll); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_status.header.error; -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t votequorum_qdisk_unregister ( -+ votequorum_handle_t handle) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_general req_lib_votequorum_general; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general); -+ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_QDISK_UNREGISTER; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_general; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_general); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_status.header.error; -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+ -+ -+cs_error_t votequorum_qdisk_getinfo ( -+ votequorum_handle_t handle, -+ struct votequorum_qdisk_info *qinfo) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_general req_lib_votequorum_general; -+ struct res_lib_votequorum_qdisk_getinfo res_lib_votequorum_qdisk_getinfo; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general); -+ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_QDISK_GETINFO; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_general; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_general); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_qdisk_getinfo, sizeof (struct res_lib_votequorum_qdisk_getinfo)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_qdisk_getinfo.header.error; -+ -+ qinfo->votes = res_lib_votequorum_qdisk_getinfo.votes; -+ qinfo->state = res_lib_votequorum_qdisk_getinfo.state; -+ strcpy(qinfo->name, res_lib_votequorum_qdisk_getinfo.name); -+ -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t votequorum_setstate ( -+ votequorum_handle_t handle) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_general req_lib_votequorum_general; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general); -+ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_SETSTATE; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_general; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_general); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_status.header.error; -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t votequorum_leaving ( -+ votequorum_handle_t handle) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_general req_lib_votequorum_general; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general); -+ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_LEAVING; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_general; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_general); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_status.header.error; -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t votequorum_trackstart ( -+ votequorum_handle_t handle, -+ uint64_t context, -+ unsigned int flags ) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_trackstart req_lib_votequorum_trackstart; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_trackstart.header.size = sizeof (struct req_lib_votequorum_trackstart); -+ req_lib_votequorum_trackstart.header.id = MESSAGE_REQ_VOTEQUORUM_TRACKSTART; -+ req_lib_votequorum_trackstart.track_flags = flags; -+ req_lib_votequorum_trackstart.context = context; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_trackstart; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_trackstart); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_status.header.error; -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+cs_error_t votequorum_trackstop ( -+ votequorum_handle_t handle) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ struct iovec iov[2]; -+ struct req_lib_votequorum_general req_lib_votequorum_general; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ pthread_mutex_lock (&votequorum_inst->response_mutex); -+ -+ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general); -+ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_TRACKSTOP; -+ -+ iov[0].iov_base = (char *)&req_lib_votequorum_general; -+ iov[0].iov_len = sizeof (struct req_lib_votequorum_general); -+ -+ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, -+ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); -+ -+ pthread_mutex_unlock (&votequorum_inst->response_mutex); -+ -+ if (error != CS_OK) { -+ goto error_exit; -+ } -+ -+ error = res_lib_votequorum_status.header.error; -+ -+error_exit: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (error); -+} -+ -+ -+cs_error_t votequorum_context_get ( -+ votequorum_handle_t handle, -+ void **context) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ *context = votequorum_inst->context; -+ -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (CS_OK); -+} -+ -+cs_error_t votequorum_context_set ( -+ votequorum_handle_t handle, -+ void *context) -+{ -+ cs_error_t error; -+ struct votequorum_inst *votequorum_inst; -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ votequorum_inst->context = context; -+ -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ -+ return (CS_OK); -+} -+ -+ -+struct res_overlay { -+ mar_res_header_t header __attribute__((aligned(8))); -+ char data[512000]; -+}; -+ -+cs_error_t votequorum_dispatch ( -+ votequorum_handle_t handle, -+ cs_dispatch_flags_t dispatch_types) -+{ -+ struct pollfd ufds; -+ int timeout = -1; -+ cs_error_t error; -+ int cont = 1; /* always continue do loop except when set to 0 */ -+ int dispatch_avail; -+ struct votequorum_inst *votequorum_inst; -+ votequorum_callbacks_t callbacks; -+ struct res_overlay dispatch_data; -+ struct res_lib_votequorum_notification *res_lib_votequorum_notification; -+ -+ if (dispatch_types != CS_DISPATCH_ONE && -+ dispatch_types != CS_DISPATCH_ALL && -+ dispatch_types != CS_DISPATCH_BLOCKING) { -+ -+ return (CS_ERR_INVALID_PARAM); -+ } -+ -+ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, -+ (void *)&votequorum_inst); -+ if (error != CS_OK) { -+ return (error); -+ } -+ -+ /* -+ * Timeout instantly for CS_DISPATCH_ONE or CS_DISPATCH_ALL and -+ * wait indefinately for CS_DISPATCH_BLOCKING -+ */ -+ if (dispatch_types == CS_DISPATCH_ALL) { -+ timeout = 0; -+ } -+ -+ do { -+ ufds.fd = votequorum_inst->dispatch_fd; -+ ufds.events = POLLIN; -+ ufds.revents = 0; -+ -+ pthread_mutex_lock (&votequorum_inst->dispatch_mutex); -+ -+ error = saPollRetry (&ufds, 1, timeout); -+ if (error != CS_OK) { -+ goto error_unlock; -+ } -+ -+ /* -+ * Handle has been finalized in another thread -+ */ -+ if (votequorum_inst->finalize == 1) { -+ error = CS_OK; -+ goto error_unlock; -+ } -+ -+ if ((ufds.revents & (POLLERR|POLLHUP|POLLNVAL)) != 0) { -+ error = CS_ERR_BAD_HANDLE; -+ goto error_unlock; -+ } -+ -+ dispatch_avail = ufds.revents & POLLIN; -+ if (dispatch_avail == 0 && dispatch_types == CS_DISPATCH_ALL) { -+ pthread_mutex_unlock (&votequorum_inst->dispatch_mutex); -+ break; /* exit do while cont is 1 loop */ -+ } else -+ if (dispatch_avail == 0) { -+ pthread_mutex_unlock (&votequorum_inst->dispatch_mutex); -+ continue; /* next poll */ -+ } -+ -+ if (ufds.revents & POLLIN) { -+ error = saRecvRetry (votequorum_inst->dispatch_fd, &dispatch_data.header, -+ sizeof (mar_res_header_t)); -+ if (error != CS_OK) { -+ goto error_unlock; -+ } -+ if (dispatch_data.header.size > sizeof (mar_res_header_t)) { -+ error = saRecvRetry (votequorum_inst->dispatch_fd, &dispatch_data.data, -+ dispatch_data.header.size - sizeof (mar_res_header_t)); -+ if (error != CS_OK) { -+ goto error_unlock; -+ } -+ } -+ } else { -+ pthread_mutex_unlock (&votequorum_inst->dispatch_mutex); -+ continue; -+ } -+ -+ /* -+ * Make copy of callbacks, message data, unlock instance, and call callback -+ * A risk of this dispatch method is that the callback routines may -+ * operate at the same time that votequorum_finalize has been called in another thread. -+ */ -+ memcpy (&callbacks, &votequorum_inst->callbacks, sizeof (votequorum_callbacks_t)); -+ pthread_mutex_unlock (&votequorum_inst->dispatch_mutex); -+ -+ /* -+ * Dispatch incoming message -+ */ -+ switch (dispatch_data.header.id) { -+ -+ case MESSAGE_RES_VOTEQUORUM_NOTIFICATION: -+ if (callbacks.votequorum_notify_fn == NULL) { -+ continue; -+ } -+ res_lib_votequorum_notification = (struct res_lib_votequorum_notification *)&dispatch_data; -+ -+ callbacks.votequorum_notify_fn ( handle, -+ res_lib_votequorum_notification->context, -+ res_lib_votequorum_notification->quorate, -+ res_lib_votequorum_notification->node_list_entries, -+ (votequorum_node_t *)res_lib_votequorum_notification->node_list ); -+ ; -+ break; -+ -+ default: -+ error = CS_ERR_LIBRARY; -+ goto error_put; -+ break; -+ } -+ -+ /* -+ * Determine if more messages should be processed -+ * */ -+ switch (dispatch_types) { -+ case CS_DISPATCH_ONE: -+ cont = 0; -+ break; -+ case CS_DISPATCH_ALL: -+ break; -+ case CS_DISPATCH_BLOCKING: -+ break; -+ } -+ } while (cont); -+ -+ goto error_put; -+ -+error_unlock: -+ pthread_mutex_unlock (&votequorum_inst->dispatch_mutex); -+ -+error_put: -+ saHandleInstancePut (&votequorum_handle_t_db, handle); -+ return (error); -+} -diff -Naurd corosync-0.92/Makefile corosync-trunk/Makefile ---- corosync-0.92/Makefile 2008-09-03 09:58:08.000000000 +0200 -+++ corosync-trunk/Makefile 2009-01-26 11:46:08.000000000 +0100 -@@ -115,10 +115,17 @@ - (cd $(builddir)test; echo ==== `pwd` ===; $(call sub_make,test,clean)); - rm -rf $(builddir)doc/api - --COROSYNC_LIBS = evs cpg cfg coroutil confdb -+lint: -+ (cd $(builddir)exec; echo ==== `pwd` ===; $(call sub_make,exec,lint)); -+ (cd $(builddir)services; echo ==== `pwd` ===; $(call sub_make,services,lint)); -+ (cd $(builddir)lcr; echo ==== `pwd` ===; $(call sub_make,lcr,lint)); -+ (cd $(builddir)lib; echo ==== `pwd` ===; $(call sub_make,lib,lint)); -+ (cd $(builddir)tools; echo ==== `pwd` ===; $(call sub_make,tools,lint)); -+ -+COROSYNC_LIBS = evs cpg cfg coroutil confdb quorum votequorum - - COROSYNC_HEADERS = cpg.h cfg.h evs.h ipc_gen.h mar_gen.h swab.h \ -- ais_util.h confdb.h list.h saAis.h -+ ais_util.h confdb.h quorum.h list.h corotypes.h votequorum.h - - EXEC_LIBS = totem_pg logsys - -@@ -145,7 +152,7 @@ - install -m 755 exec/lib$$eLib.so.2.* $(DESTDIR)$(LIBDIR); \ - if [ "xYES" = "x$(STATICLIBS)" ]; then \ - install -m 755 exec/lib$$eLib.a $(DESTDIR)$(LIBDIR); \ -- if [ ${OPENCOROSYNC_COMPAT} = "DARWIN" ]; then \ -+ if [ ${COROSYNC_COMPAT} = "DARWIN" ]; then \ - ranlib $(DESTDIR)$(LIBDIR)/lib$$eLib.a; \ - fi \ - fi \ -@@ -161,7 +168,7 @@ - install -m 755 lib/lib$$aLib.so.2.* $(DESTDIR)$(LIBDIR); \ - if [ "xYES" = "x$(STATICLIBS)" ]; then \ - install -m 755 lib/lib$$aLib.a $(DESTDIR)$(LIBDIR); \ -- if [ ${OPENCOROSYNC_COMPAT} = "DARWIN" ]; then \ -+ if [ ${COROSYNC_COMPAT} = "DARWIN" ]; then \ - ranlib $(DESTDIR)$(LIBDIR)/lib$$aLib.a; \ - fi \ - fi \ -@@ -177,7 +184,7 @@ - install -m 755 $(builddir)tools/corosync-cfgtool $(DESTDIR)$(SBINDIR) - install -m 755 $(builddir)tools/corosync-keygen $(DESTDIR)$(SBINDIR) - -- if [ ! -f $(DESTDIR)$(ETCDIR)/penais.conf ] ; then \ -+ if [ ! -f $(DESTDIR)$(ETCDIR)/corosync.conf ] ; then \ - install -m 644 $(srcdir)conf/corosync.conf $(DESTDIR)$(ETCDIR) ; \ - fi - -@@ -196,6 +203,7 @@ - install -m 644 $(srcdir)include/corosync/engine/coroapi.h $(DESTDIR)$(INCLUDEDIR_ENGINE) - install -m 644 $(srcdir)include/corosync/engine/objdb.h $(DESTDIR)$(INCLUDEDIR_ENGINE) - install -m 644 $(srcdir)include/corosync/engine/logsys.h $(DESTDIR)$(INCLUDEDIR_ENGINE) -+ install -m 644 $(srcdir)include/corosync/engine/quorum.h $(DESTDIR)$(INCLUDEDIR_ENGINE) - install -m 644 $(srcdir)include/corosync/engine/config.h $(DESTDIR)$(INCLUDEDIR_ENGINE) - install -m 644 $(srcdir)man/*.3 $(DESTDIR)$(MANDIR)/man3 - install -m 644 $(srcdir)man/*.5 $(DESTDIR)$(MANDIR)/man5 -diff -Naurd corosync-0.92/Makefile.inc corosync-trunk/Makefile.inc ---- corosync-0.92/Makefile.inc 2008-09-03 09:58:08.000000000 +0200 -+++ corosync-trunk/Makefile.inc 2008-12-09 14:48:47.000000000 +0100 -@@ -38,16 +38,15 @@ - # COROSYNC_BUILD can be defined as RELEASE or DEBUG - # - ifndef COROSYNC_BUILD -- COROSYNC_BUILD=DEBUG -+ COROSYNC_BUILD=RELEASE - endif - --# COROSYNC_PROFILE -- - # default CFLAGS, LDFLAGS - # - CFLAGS = - LDFLAGS = - DYFLAGS = -+LINT_FLAGS = -weak -unrecog +posixlib +ignoresigns -fcnuse -badflag -D__gnuc_va_list=va_list -D__attribute\(x\)= - - override CFLAGS += -DLCRSODIR='"$(LCRSODIR)"' - -@@ -58,35 +57,26 @@ - # build CFLAGS, LDFLAGS - # - ifeq (${COROSYNC_BUILD}, RELEASE) -- CFLAGS += -O3 -Wall --# -Wstrict-aliasing=2 TODO sameday fix all of these --ifndef COROSYNC_PROFILE -- CFLAGS += -fomit-frame-pointer --endif -- LDFLAGS += -+ override CFLAGS += -O3 -Wall -+ override LDFLAGS += - endif - ifeq (${COROSYNC_BUILD}, DEBUG) -- CFLAGS += -O0 -g -Wall -DDEBUG --time -- LDFLAGS += -g -+ override CFLAGS += -O0 -g -Wall -+ override LDFLAGS += -g - ifeq (${COROSYNC_COMPAT}, SOLARIS) - CFLAGS += -Werror -DTS_CLASS - endif - endif - ifeq (${COROSYNC_BUILD}, COVERAGE) -- CFLAGS += -O0 -g -ftest-coverage -fprofile-arcs -- LDFLAGS += -g -ftest-coverage -fprofile-arcs -+ override CFLAGS += -O0 -g -ftest-coverage -fprofile-arcs -+ override LDFLAGS += -g -ftest-coverage -fprofile-arcs - BUILD_DYNAMIC=0 - endif - --ifdef COROSYNC_PROFILE -- CFLAGS += -pg -- LDFLAGS += -pg --endif -- - # platform specific CFLAGS, LDFLAGS - # - ifeq (${COROSYNC_COMPAT}, LINUX) -- override CFLAGS += -DCOROSYNC_LINUX -+ override CFLAGS += -DCOROSYNC_LINUX -D_XOPEN_SOURCE=600 -D_GNU_SOURCE - override LDFLAGS += -ldl -lpthread - override DYFLAGS += -rdynamic - endif -diff -Naurd corosync-0.92/man/confdb_overview.8 corosync-trunk/man/confdb_overview.8 ---- corosync-0.92/man/confdb_overview.8 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/man/confdb_overview.8 2009-01-26 11:46:08.000000000 +0100 -@@ -34,16 +34,24 @@ - .TH CONFDB_OVERVIEW 8 2006-03-06 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" - .SH OVERVIEW - The CONFDB library is delivered with the corosync project. This library is used --to examine manipulate the configuratin databser used by corosync. -+to examine manipulate the configuration database used by corosync. - .PP - The library provides a mechanism to: -+.PP - * Create new objects -+.PP - * Create new key/value pairs within those objects -+.PP - * Remove existing keys -+.PP - * Remove an existing object and all it sub-objects and keys -+.PP - * Read keys and values -+.PP - * Iterate keys within an object -+.PP - * Iterate subobjects within a parent object -+.PP - * Find a named object - .PP - .SH BUGS -diff -Naurd corosync-0.92/man/corosync.conf.5 corosync-trunk/man/corosync.conf.5 ---- corosync-0.92/man/corosync.conf.5 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/man/corosync.conf.5 2008-10-21 00:05:51.000000000 +0200 -@@ -435,20 +435,6 @@ - No default. - - .TP --debug --This specifies whether debug output is logged for all services. This is --generally a bad idea, unless there is some specific bug or problem that must be --found in the executive. Set the value to --.B on --to debug, --.B off --to turn off debugging. If enabled, individual loggers can be disabled using a --.B logger_subsys --directive. -- --The default is off. -- --.TP - timestamp - This specifies that a timestamp is placed on all log messages. - -diff -Naurd corosync-0.92/man/index.html corosync-trunk/man/index.html ---- corosync-0.92/man/index.html 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/man/index.html 2009-01-26 11:46:08.000000000 +0100 -@@ -85,5 +85,30 @@ -
- confdb_object_parent_get(3): Description of the confdb_object_parent_get interface. - -+
-+votequorum_overview(8): An overview of the vote-based quorum service -+
-+votequorum_initialize(3): Description of the votequorum interface. -+
-+votequorum_finalize(3): Description of the votequorum interface. -+
-+votequorum_fd_get(3): Description of the votequorum interface. -+
-+votequorum_getinfo(3): Description of the votequorum interface. -+
-+votequorum_leaving(3): Description of the votequorum interface. -+
-+votequorum_setexpected(3): Description of the votequorum interface. -+
-+votequorum_setvotes(3): Description of the votequorum interface. -+
-+votequorum_qdisk_register(3): Description of the votequorum interface. -+
-+votequorum_qdisk_unregister(3): Description of the votequorum interface. -+
-+votequorum_qdisk_poll(3): Description of the votequorum interface. -+
-+votequorum_qdisk_getinfo(3): Description of the votequorum interface. -+
- - -diff -Naurd corosync-0.92/man/Makefile corosync-trunk/man/Makefile ---- corosync-0.92/man/Makefile 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/man/Makefile 2009-01-26 11:46:08.000000000 +0100 -@@ -74,6 +74,19 @@ - groff -mandoc -Thtml confdb_object_parent_get.3 > html/confdb_object_parent_get.html - groff -mandoc -Thtml confdb_overview.8 > html/confdb_overview.html - -+ groff -mandoc -Thtml votequorum_overview.8 > html/votequorum_overview.html -+ groff -mandoc -Thtml votequorum_initialize.3 > html/votequorum_initialize.html -+ groff -mandoc -Thtml votequorum_finalize.3 > html/votequorum_finalize.html -+ groff -mandoc -Thtml votequorum_fd_get.3 > html/votequorum_fd_get.html -+ groff -mandoc -Thtml votequorum_dispatch.3 > html/votequorum_dispatch.html -+ groff -mandoc -Thtml votequorum_getinfo.3 > html/votequorum_getinfo.html -+ groff -mandoc -Thtml votequorum_leaving.3 > html/votequorum_leaving.html -+ groff -mandoc -Thtml votequorum_setexpected.3 > html/votequorum_setexpected.html -+ groff -mandoc -Thtml votequorum_setvotes.3 > html/votequorum_setvotes.html -+ groff -mandoc -Thtml votequorum_qdisk_register.3 > html/votequorum_qdisk_register.html -+ groff -mandoc -Thtml votequorum_qdisk_unregister.3 > html/votequorum_qdisk_unregister.html -+ groff -mandoc -Thtml votequorum_qdisk_poll.3 > html/votequorum_poll.html -+ groff -mandoc -Thtml votequorum_qdisk_getinfo.3 > html/votequorum_qdisk_getinfo.html - cp index.html html - - clean: -diff -Naurd corosync-0.92/man/votequorum_dispatch.3 corosync-trunk/man/votequorum_dispatch.3 ---- corosync-0.92/man/votequorum_dispatch.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_dispatch.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,96 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_DISPATCH 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_dispatch \- Dispatches callbacks from the votequorum service -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_dispatch(votequorum_handle_t " handle ", votequorum_dispatch_t *" dispatch_types ");" -+.SH DESCRIPTION -+The -+.B votequorum_dispatch -+function is used to dispatch configuration changes. -+.PP -+Each application may have several connections to the votequorum API. Each application -+uses the -+.I handle -+argument to uniquely identify the connection. -+.PP -+The -+.I dispatch_types -+argument is used to identify the type of dispatch to execute. The possible types are -+defined by the structure: -+ -+.IP -+.RS -+.ne 18 -+.nf -+.ta 4n 30n 33n -+typedef enum { -+ CS_DISPATCH_ONE, -+ CS_DISPATCH_ALL, -+ CS_DISPATCH_BLOCKING -+} votequorum_dispatch_t; -+.ta -+.fi -+.RE -+.IP -+.PP -+.PP -+The dispatch values have the following meanings: -+.TP -+.B CS_DISPATCH_ONE -+Dispatch at least one callback, blocking until the callback is dispatched. -+.TP -+.B CS_DISPATCH_ALL -+Dispatch all waiting callbacks without blocking to wait for any callbacks. -+.TP -+.B CS_DISPATCH_BLOCKING -+Dispatch all callbacks blocking indefinitely. This is used in a threaded -+program where a thread is created, and then votequorum_dispatch() is called immediately -+from the created thread to execute callbacks. -+ -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_fd_get (3), -+ -+.PP -diff -Naurd corosync-0.92/man/votequorum_fd_get.3 corosync-trunk/man/votequorum_fd_get.3 ---- corosync-0.92/man/votequorum_fd_get.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_fd_get.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,64 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_FD_GET 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_fd_get \- Dispatches callbacks from the votequorum service -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_fd_get(votequorum_handle_t " handle ", int *" fd ");" -+.SH DESCRIPTION -+The -+.B votequorum_fd_get -+function is used to retrieve the file descriptor that may be used with the poll -+system call to determine when -+.B votequorum_dispatch(3) -+won't block. The -+.I handle -+argument may not be used directly with -+.B poll -+because it is not the file descriptor, but instead an internal identifier used -+by the votequorum library. -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_dispatch (3), -+.BR votequorum_fd_get (3), -+.PP -diff -Naurd corosync-0.92/man/votequorum_finalize.3 corosync-trunk/man/votequorum_finalize.3 ---- corosync-0.92/man/votequorum_finalize.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_finalize.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,61 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_FINALIZE 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_finalize \- Terminate a connection to the votequorum service -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_finalize(votequorum_handle_t " handle ");" -+.SH DESCRIPTION -+The -+.B votequorum_finalize -+function is used to close a connection to the configuration dabatase API. -+Once the connection is finalized, the handle may not be used again by applications. -+No more callbacks will be dispatched from the -+.B votequorum_dispatch function. -+.PP -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_dispatch (3), -+.BR votequorum_fd_get (3), -+ -+.PP -diff -Naurd corosync-0.92/man/votequorum_getinfo.3 corosync-trunk/man/votequorum_getinfo.3 ---- corosync-0.92/man/votequorum_getinfo.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_getinfo.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,91 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_GETINFO 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_getinfo \- Get information about the VoteQuorum service -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_getinfo(votequorum_handle_t *" handle ", unsigned int " nodeid ", struct votequorum_info *" info "); -+.SH DESCRIPTION -+The -+.B votequorum_getinfo -+function is used to get information about the voteing system and its nodes. -+ -+The votequorum_info structure is defined as follows: -+.PP -+.PP -+.IP -+.RS -+.ne 18 -+.nf -+.ta 4n 20n 32n -+ -+struct votequorum_info { -+ unsigned int node_id; -+ unsigned int node_votes; -+ unsigned int node_expected_votes; -+ unsigned int highest_expected; -+ unsigned int total_votes; -+ unsigned int quorum; -+ unsigned int flags; -+}; -+ -+#define VOTEQUORUM_INFO_FLAG_DIRTY 1 -+#define VOTEQUORUM_INFO_FLAG_DISALLOWED 2 -+#define VOTEQUORUM_INFO_FLAG_TWONODE 4 -+#define VOTEQUORUM_INFO_FLAG_QUORATE 8 -+ -+.ta -+.fi -+.RE -+.IP -+.PP -+.PP -+The members starting node_ hold information specific to the requested nodeid, the other are -+general to the voting system. -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH BUGS -+Callbacks are not support at the moment. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_finalize (3), -+.BR votequorum_fd_get (3), -+.BR votequorum_dispatch (3), -+.PP -diff -Naurd corosync-0.92/man/votequorum_initialize.3 corosync-trunk/man/votequorum_initialize.3 ---- corosync-0.92/man/votequorum_initialize.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_initialize.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,106 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_INITIALIZE 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_initialize \- Create a new connection to the VoteQuorum service -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_initialize(votequorum_handle_t *" handle ", votequorum_callbacks_t *" callbacks "); -+.SH DESCRIPTION -+The -+.B votequorum_initialize -+function is used to initialize a connection to the vote-based quorum database API. -+.PP -+Each application may have several connections to the votequorum API. Each application -+uses the -+.I handle -+argument to uniquely identify the connection. The -+.I handle -+argument is then used in other function calls to identify the connection to be used -+for communication with the votequorum service. -+.PP -+Every time the voting configuraton changes (eg a node joins or leave the cluster), the callback is called. -+The callback function is described by the following type definitions: -+ -+typedef void (*votequorum_notification_fn_t) ( -+ votequorum_handle_t handle, -+ uint64_t context, -+ uint32_t quorate, -+ uint32_t node_list_entries, -+ votequorum_node_t node_list[] -+ ); -+ -+.ta -+.fi -+.RE -+.IP -+.PP -+.PP -+The -+.I callbacks -+argument is of the type: -+.IP -+.RS -+.ne 18 -+.nf -+.PP -+typedef struct { -+ votequorum_notification_fn_t votequorum_notify_fn; -+} votequorum_callbacks_t; -+ -+.ta -+.fi -+.RE -+.IP -+.PP -+When a configuration change occurs, the callback -+is called from the -+.B votequorum_dispatch() -+function. -+.PP -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH BUGS -+Callbacks are not support at the moment. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_finalize (3), -+.BR votequorum_fd_get (3), -+.BR votequorum_dispatch (3), -+.PP -diff -Naurd corosync-0.92/man/votequorum_leaving.3 corosync-trunk/man/votequorum_leaving.3 ---- corosync-0.92/man/votequorum_leaving.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_leaving.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,67 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_LEAVING 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_leaving \- Tell other nodes that we are leaving the cluster -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_leaving(votequorum_handle_t " handle ");" -+.SH DESCRIPTION -+The -+.B votequorum_leaving -+function is used to tell the other nodes in the cluster that this node is leaving. They -+will (when the node actually leaves) reduce quorum to keep the cluster running without -+this node. -+.PP -+This function should only be called if it is known that the node is being shut down for -+a known reason and could be out of the cluster for an extended period of time. -+.PP -+Normal behaviour is for the cluster to reduce the total number of votes, but NOT expected_votes -+when a node leave the cluster, so the cluster could become inquorate. This is correct behaviour -+and is ther eto prevent split-brain. -+.PP -+Do NOT call this function unless you know what you are doing. -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_dispatch (3), -+.BR votequorum_fd_get (3), -+.PP -diff -Naurd corosync-0.92/man/votequorum_overview.8 corosync-trunk/man/votequorum_overview.8 ---- corosync-0.92/man/votequorum_overview.8 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_overview.8 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,82 @@ -+.\"/* -+.\" * Copyright (c) 2008 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_OVERVIEW 8 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH OVERVIEW -+The votequuorum library is delivered with the corosync project. It is the external interface to -+the vote-based quorum service. This service is optionally loaded into all ndes in a corosync cluster -+to avoid split-brain situations. It does this by having a number of votes assigned to each system -+in the cluster and ensuring that only when a majority of the votes are present, cluster operations are -+allowed to proceed. -+.PP -+The library provides a mechanism to: -+* Query the quorum status -+.PP -+* Get a list of nodes known to the quorum service -+.PP -+* Receive notifications of quorum state changes -+.PP -+* Change the number of votes assigned to a node -+.PP -+* Change the number of expected votes for a cluster to be quorate -+.PP -+* Connect an additional quorum device to allow small clusters to remain quorate during node outages. -+.PP -+.B votequorum -+reads its configuration from the objdb. The following keys are read when it starts up: -+.PP -+* quorum.expected_votes -+.br -+* quorum.votes -+.br -+* quorum.quorumdev_poll -+.br -+* quorum.disallowed -+.br -+* quorum.two_node -+.PP -+Most of those values can be changed while corosync is running with the following exceptions: -+.B quorum.disallowed -+cannot be changed, and -+.B two_node -+cannot be set on-the-fly, though it can be cleared. ie you can start with two nodes in the cluster -+and add a third without rebooting all the nodes. -+.PP -+.SH BUGS -+This software is not yet production, so there may still be some bugs. -+.SH "SEE ALSO" -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_fd_get (3), -+.BR votequorum_dispatch (3), -+.PP -diff -Naurd corosync-0.92/man/votequorum_qdisk_getinfo.3 corosync-trunk/man/votequorum_qdisk_getinfo.3 ---- corosync-0.92/man/votequorum_qdisk_getinfo.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_qdisk_getinfo.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,80 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_QDISK_GETINFO 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_qdisk_getinfo \- Get details of the quorum device -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_qdisk_getinfo(votequorum_handle_t " handle ", struct votequorum_qdisk_info " *info ");" -+.SH DESCRIPTION -+The -+.B votequorum_qdisk_getinfo -+Returns information about the quorum device in the following structure: -+.PP -+.PP -+.IP -+.RS -+.ne 18 -+.nf -+.ta 4n 20n 32n -+ -+struct votequorum_qdisk_info { -+ unsigned int votes; -+ unsigned int state; -+ char name[VOTEQUORUM_MAX_QDISK_NAME_LEN]; -+}; -+ -+.ta -+.fi -+.RE -+.IP -+.PP -+.PP -+ -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_dispatch (3), -+.BR votequorum_fd_get (3), -+.BR votequorum_qdisk_poll (3), -+.BR votequorum_qdisk_unregister (3), -+.BR votequorum_qdisk_getinfo (3), -+.PP -diff -Naurd corosync-0.92/man/votequorum_qdisk_poll.3 corosync-trunk/man/votequorum_qdisk_poll.3 ---- corosync-0.92/man/votequorum_qdisk_poll.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_qdisk_poll.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,69 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_QDISK_POLL 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_qdisk_poll \- Tells votequorum the result of the quorum device poll -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_qdisk_poll(votequorum_handle_t " handle ", unsigned int " state ");" -+.SH DESCRIPTION -+The -+.B votequorum_qdisk_poll -+is called by the quorum device subsyetem (not provided as part of votequorum) to tell -+the voting system if the qurum device is present/active or not. If -+.B state -+is 1 then the votes for the device are included in the quorum calculation, otherwise not. -+This routine should be called at regular intervals to ensure that the device status -+is always known to votequorum. If -+.B votequorum_qdisk_poll -+is not called after (default) 10 seconds then the device will be deeded to be dead and -+its votes removed from the cluster. This does not unregister the device. -+The default poll time can be changed by setting the object database variable -+quorum.quorumdev_poll. -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_dispatch (3), -+.BR votequorum_fd_get (3), -+.BR votequorum_qdisk_poll (3), -+.BR votequorum_qdisk_unregister (3), -+.BR votequorum_qdisk_getinfo (3), -+.PP -diff -Naurd corosync-0.92/man/votequorum_qdisk_register.3 corosync-trunk/man/votequorum_qdisk_register.3 ---- corosync-0.92/man/votequorum_qdisk_register.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_qdisk_register.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,68 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_QDISK_REGISTER 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_qdisk_register \- Registers a new quorum device -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_qdisk_register(votequorum_handle_t " handle ", char * " name ", unsigned int " votes ");" -+.SH DESCRIPTION -+The -+.B votequorum_qdisk_register -+is used to register a new quorum device. A quorum device is an external way of adding votes to a small -+cluster. The quorum device is, in effect, a pseudo node in the cluster that provide votes based on some -+external device, usually a shared disk partition or perhaps a network router. -+.br -+This call creates the device but does not mark it active. -+.B votequorum_qdisk_poll -+must be called for the votes to be included in the quorum calculation. -+.br -+Note that it is the responsibility of the quorum device subsystem (not provided as part of votequorum) -+to keep all nodes informed of the quorum device status. -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_dispatch (3), -+.BR votequorum_fd_get (3), -+.BR votequorum_qdisk_poll (3), -+.BR votequorum_qdisk_unregister (3), -+.BR votequorum_qdisk_getinfo (3), -+.PP -diff -Naurd corosync-0.92/man/votequorum_qdisk_unregister.3 corosync-trunk/man/votequorum_qdisk_unregister.3 ---- corosync-0.92/man/votequorum_qdisk_unregister.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_qdisk_unregister.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,60 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_QDISK_UNREGISTER 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_qdisk_unregister \- Unregisters a new quorum device -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_qdisk_unregister(votequorum_handle_t " handle ");" -+.SH DESCRIPTION -+The -+.B votequorum_qdisk_unregister -+unregisters a quorum device. Any votes it had will be removed from the cluster. Not that this could -+make the cluster inquorate. -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_dispatch (3), -+.BR votequorum_fd_get (3), -+.BR votequorum_qdisk_poll (3), -+.BR votequorum_qdisk_unregister (3), -+.BR votequorum_qdisk_getinfo (3), -+.PP -diff -Naurd corosync-0.92/man/votequorum_setexpected.3 corosync-trunk/man/votequorum_setexpected.3 ---- corosync-0.92/man/votequorum_setexpected.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_setexpected.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,60 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_SETEXPECTED 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_setexpected \- Sets the expected votes for the cluster -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_setexpected(votequorum_handle_t " handle ", int " expected_votes ");" -+.SH DESCRIPTION -+The -+.B votequorum_setexpected -+function is used to change the expected votes in the cluster. Expected votes is used to calculate -+quorum and should normally be the total number of votes that will exist when all the expected nodes -+are joined. Quorum will usually be half of this (rounded up). -+.br -+It is not possible to set expected votes up so that it makes the cluster inquorate using this command. -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_dispatch (3), -+.BR votequorum_fd_get (3), -+.PP -diff -Naurd corosync-0.92/man/votequorum_setvotes.3 corosync-trunk/man/votequorum_setvotes.3 ---- corosync-0.92/man/votequorum_setvotes.3 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/man/votequorum_setvotes.3 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,57 @@ -+.\"/* -+.\" * Copyright (c) 2009 Red Hat, Inc. -+.\" * -+.\" * All rights reserved. -+.\" * -+.\" * Author: Christine Caulfield -+.\" * -+.\" * 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. -+.\" */ -+.TH VOTEQUORUM_VOTES 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" -+.SH NAME -+votequorum_setvotes \- Sets the number of votes for a node -+.SH SYNOPSIS -+.B #include -+.sp -+.BI "int votequorum_setexpected(votequorum_handle_t " handle ", unsigned int " nodeid ", int " votes ");" -+.SH DESCRIPTION -+The -+.B votequorum_setvotes -+is used to change the number of votes that a node has. Note that it is not possible, using this function, -+to change the number of node votes such that the cluster goes inquorate. -+.SH RETURN VALUE -+This call returns the CS_OK value if successful, otherwise an error is returned. -+.PP -+.SH ERRORS -+The errors are undocumented. -+.SH "SEE ALSO" -+.BR votequorum_overview (8), -+.BR votequorum_initialize (3), -+.BR votequorum_finalize (3), -+.BR votequorum_dispatch (3), -+.BR votequorum_fd_get (3), -+.PP -diff -Naurd corosync-0.92/services/cfg.c corosync-trunk/services/cfg.c ---- corosync-0.92/services/cfg.c 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/services/cfg.c 2009-01-19 09:31:21.000000000 +0100 -@@ -1,13 +1,13 @@ - /* - * Copyright (c) 2005-2006 MontaVista Software, Inc. -- * Copyright (c) 2006-2008 Red Hat, Inc. -+ * Copyright (c) 2006-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: - * -@@ -42,16 +42,18 @@ - #include - #include - #include -+#include - #include - #include - #include - --#include -+#include - #include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -60,7 +62,31 @@ - LOGSYS_DECLARE_SUBSYS ("CFG", LOG_INFO); - - enum cfg_message_req_types { -- MESSAGE_REQ_EXEC_CFG_RINGREENABLE = 0 -+ MESSAGE_REQ_EXEC_CFG_RINGREENABLE = 0, -+ MESSAGE_REQ_EXEC_CFG_KILLNODE = 1, -+ MESSAGE_REQ_EXEC_CFG_SHUTDOWN = 2 -+}; -+ -+#define DEFAULT_SHUTDOWN_TIMEOUT 5 -+ -+static struct list_head trackers_list; -+ -+/* -+ * Variables controlling a requested shutdown -+ */ -+static corosync_timer_handle_t shutdown_timer; -+static struct cfg_info *shutdown_con; -+static uint32_t shutdown_flags; -+static int shutdown_yes; -+static int shutdown_no; -+static int shutdown_expected; -+ -+struct cfg_info -+{ -+ struct list_head list; -+ void *conn; -+ void *tracker_conn; -+ enum {SHUTDOWN_REPLY_UNKNOWN, SHUTDOWN_REPLY_YES, SHUTDOWN_REPLY_NO} shutdown_reply; - }; - - static void cfg_confchg_fn ( -@@ -82,6 +108,16 @@ - void *message, - unsigned int nodeid); - -+static void message_handler_req_exec_cfg_killnode ( -+ void *message, -+ unsigned int nodeid); -+ -+static void message_handler_req_exec_cfg_shutdown ( -+ void *message, -+ unsigned int nodeid); -+ -+static void exec_cfg_killnode_endian_convert (void *msg); -+ - static void message_handler_req_lib_cfg_ringstatusget ( - void *conn, - void *msg); -@@ -114,6 +150,22 @@ - void *conn, - void *msg); - -+static void message_handler_req_lib_cfg_killnode ( -+ void *conn, -+ void *msg); -+ -+static void message_handler_req_lib_cfg_tryshutdown ( -+ void *conn, -+ void *msg); -+ -+static void message_handler_req_lib_cfg_replytoshutdown ( -+ void *conn, -+ void *msg); -+ -+static void message_handler_req_lib_cfg_get_node_addrs ( -+ void *conn, -+ void *msg); -+ - /* - * Service Handler Definition - */ -@@ -123,56 +175,87 @@ - .lib_handler_fn = message_handler_req_lib_cfg_ringstatusget, - .response_size = sizeof (struct res_lib_cfg_ringstatusget), - .response_id = MESSAGE_RES_CFG_RINGSTATUSGET, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED - }, - { /* 1 */ - .lib_handler_fn = message_handler_req_lib_cfg_ringreenable, - .response_size = sizeof (struct res_lib_cfg_ringreenable), - .response_id = MESSAGE_RES_CFG_RINGREENABLE, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED - }, - { /* 2 */ - .lib_handler_fn = message_handler_req_lib_cfg_statetrack, - .response_size = sizeof (struct res_lib_cfg_statetrack), - .response_id = MESSAGE_RES_CFG_STATETRACKSTART, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED - }, - { /* 3 */ - .lib_handler_fn = message_handler_req_lib_cfg_statetrackstop, - .response_size = sizeof (struct res_lib_cfg_statetrackstop), - .response_id = MESSAGE_RES_CFG_STATETRACKSTOP, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED - }, - { /* 4 */ - .lib_handler_fn = message_handler_req_lib_cfg_administrativestateset, - .response_size = sizeof (struct res_lib_cfg_administrativestateset), - .response_id = MESSAGE_RES_CFG_ADMINISTRATIVESTATESET, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 5 */ - .lib_handler_fn = message_handler_req_lib_cfg_administrativestateget, - .response_size = sizeof (struct res_lib_cfg_administrativestateget), - .response_id = MESSAGE_RES_CFG_ADMINISTRATIVESTATEGET, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 6 */ - .lib_handler_fn = message_handler_req_lib_cfg_serviceload, - .response_size = sizeof (struct res_lib_cfg_serviceload), - .response_id = MESSAGE_RES_CFG_SERVICELOAD, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 7 */ - .lib_handler_fn = message_handler_req_lib_cfg_serviceunload, - .response_size = sizeof (struct res_lib_cfg_serviceunload), - .response_id = MESSAGE_RES_CFG_SERVICEUNLOAD, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 8 */ -+ .lib_handler_fn = message_handler_req_lib_cfg_killnode, -+ .response_size = sizeof (struct res_lib_cfg_killnode), -+ .response_id = MESSAGE_RES_CFG_KILLNODE, -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 9 */ -+ .lib_handler_fn = message_handler_req_lib_cfg_tryshutdown, -+ .response_size = sizeof (struct res_lib_cfg_tryshutdown), -+ .response_id = MESSAGE_RES_CFG_TRYSHUTDOWN, -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 10 */ -+ .lib_handler_fn = message_handler_req_lib_cfg_replytoshutdown, -+ .response_size = 0, -+ .response_id = 0, -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 11 */ -+ .lib_handler_fn = message_handler_req_lib_cfg_get_node_addrs, -+ .response_size = sizeof (struct res_lib_cfg_get_node_addrs), -+ .response_id = MESSAGE_RES_CFG_GET_NODE_ADDRS, -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - } - }; - - static struct corosync_exec_handler cfg_exec_engine[] = - { -- { -- message_handler_req_exec_cfg_ringreenable -+ { /* 0 */ -+ .exec_handler_fn = message_handler_req_exec_cfg_ringreenable, -+ }, -+ { /* 1 */ -+ .exec_handler_fn = message_handler_req_exec_cfg_killnode, -+ .exec_endian_convert_fn = exec_cfg_killnode_endian_convert -+ }, -+ { /* 2 */ -+ .exec_handler_fn = message_handler_req_exec_cfg_shutdown, - } - }; - -@@ -182,8 +265,9 @@ - struct corosync_service_engine cfg_service_engine = { - .name = "corosync configuration service", - .id = CFG_SERVICE, -- .private_data_size = 0, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED, -+ .private_data_size = sizeof(struct cfg_info), -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED, -+ .allow_inquorate = CS_LIB_ALLOW_INQUORATE, - .lib_init_fn = cfg_lib_init_fn, - .lib_exit_fn = cfg_lib_exit_fn, - .lib_engine = cfg_lib_engine, -@@ -238,12 +322,24 @@ - mar_message_source_t source __attribute__((aligned(8))); - }; - -+struct req_exec_cfg_killnode { -+ mar_req_header_t header __attribute__((aligned(8))); -+ mar_uint32_t nodeid __attribute__((aligned(8))); -+ mar_name_t reason __attribute__((aligned(8))); -+}; -+ -+struct req_exec_cfg_shutdown { -+ mar_req_header_t header __attribute__((aligned(8))); -+}; -+ - /* IMPL */ - - static int cfg_exec_init_fn ( - struct corosync_api_v1 *corosync_api_v1) - { - api = corosync_api_v1; -+ -+ list_init(&trackers_list); - return (0); - } - -@@ -256,16 +352,193 @@ - { - } - -+/* -+ * Tell other nodes we are shutting down -+ */ -+static int send_shutdown() -+{ -+ struct req_exec_cfg_shutdown req_exec_cfg_shutdown; -+ struct iovec iovec; -+ -+ ENTER(); -+ req_exec_cfg_shutdown.header.size = -+ sizeof (struct req_exec_cfg_shutdown); -+ req_exec_cfg_shutdown.header.id = SERVICE_ID_MAKE (CFG_SERVICE, -+ MESSAGE_REQ_EXEC_CFG_SHUTDOWN); -+ -+ iovec.iov_base = (char *)&req_exec_cfg_shutdown; -+ iovec.iov_len = sizeof (struct req_exec_cfg_shutdown); -+ -+ assert (api->totem_mcast (&iovec, 1, TOTEM_SAFE) == 0); -+ -+ LEAVE(); -+ return 0; -+} -+ -+static void send_test_shutdown(void * conn, int status) -+{ -+ struct res_lib_cfg_testshutdown res_lib_cfg_testshutdown; -+ struct list_head *iter; -+ -+ ENTER(); -+ res_lib_cfg_testshutdown.header.size = sizeof(struct res_lib_cfg_testshutdown); -+ res_lib_cfg_testshutdown.header.id = MESSAGE_RES_CFG_TESTSHUTDOWN; -+ res_lib_cfg_testshutdown.header.error = status; -+ res_lib_cfg_testshutdown.flags = shutdown_flags; -+ -+ if (conn) { -+ TRACE1("sending testshutdown to %p", conn); -+ api->ipc_conn_send_response(conn, &res_lib_cfg_testshutdown, -+ sizeof(res_lib_cfg_testshutdown)); -+ } else { -+ for (iter = trackers_list.next; iter != &trackers_list; iter = iter->next) { -+ struct cfg_info *ci = list_entry(iter, struct cfg_info, list); -+ -+ TRACE1("sending testshutdown to %p", ci->tracker_conn); -+ api->ipc_conn_send_response(ci->tracker_conn, &res_lib_cfg_testshutdown, -+ sizeof(res_lib_cfg_testshutdown)); -+ } -+ } -+ LEAVE(); -+} -+ -+static void check_shutdown_status() -+{ -+ ENTER(); -+ -+ /* -+ * Shutdown client might have gone away -+ */ -+ if (!shutdown_con) { -+ LEAVE(); -+ return; -+ } -+ -+ /* -+ * All replies safely gathered in ? -+ */ -+ if (shutdown_yes + shutdown_no >= shutdown_expected) { -+ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown; -+ -+ api->timer_delete(shutdown_timer); -+ -+ if (shutdown_yes >= shutdown_expected || -+ shutdown_flags == CFG_SHUTDOWN_FLAG_REGARDLESS) { -+ TRACE1("shutdown confirmed"); -+ -+ /* -+ * Tell other nodes we are going down -+ */ -+ send_shutdown(); -+ -+ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown); -+ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN; -+ res_lib_cfg_tryshutdown.header.error = CS_OK; -+ -+ /* -+ * Tell originator that shutdown was confirmed -+ */ -+ api->ipc_conn_send_response(shutdown_con->conn, &res_lib_cfg_tryshutdown, -+ sizeof(res_lib_cfg_tryshutdown)); -+ shutdown_con = NULL; -+ } -+ else { -+ -+ TRACE1("shutdown cancelled"); -+ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown); -+ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN; -+ res_lib_cfg_tryshutdown.header.error = CS_ERR_BUSY; -+ -+ /* -+ * Tell originator that shutdown was cancelled -+ */ -+ api->ipc_conn_send_response(shutdown_con->conn, &res_lib_cfg_tryshutdown, -+ sizeof(res_lib_cfg_tryshutdown)); -+ shutdown_con = NULL; -+ } -+ -+ log_printf(LOG_DEBUG, "shutdown decision is: (yes count: %d, no count: %d) flags=%x\n", shutdown_yes, shutdown_no, shutdown_flags); -+ } -+ LEAVE(); -+} -+ -+ -+/* -+ * Not all nodes responded to the shutdown (in time) -+ */ -+static void shutdown_timer_fn(void *arg) -+{ -+ ENTER(); -+ -+ /* -+ * Mark undecideds as "NO" -+ */ -+ shutdown_no = shutdown_expected; -+ check_shutdown_status(); -+ -+ send_test_shutdown(NULL, CS_ERR_TIMEOUT); -+ LEAVE(); -+} -+ -+static void remove_ci_from_shutdown(struct cfg_info *ci) -+{ -+ ENTER(); -+ -+ /* -+ * If the controlling shutdown process has quit, then cancel the -+ * shutdown session -+ */ -+ if (ci == shutdown_con) { -+ shutdown_con = NULL; -+ api->timer_delete(shutdown_timer); -+ } -+ -+ if (!list_empty(&ci->list)) { -+ list_del(&ci->list); -+ list_init(&ci->list); -+ -+ /* -+ * Remove our option -+ */ -+ if (shutdown_con) { -+ if (ci->shutdown_reply == SHUTDOWN_REPLY_YES) -+ shutdown_yes--; -+ if (ci->shutdown_reply == SHUTDOWN_REPLY_NO) -+ shutdown_no--; -+ } -+ -+ /* -+ * If we are leaving, then that's an implicit YES to shutdown -+ */ -+ ci->shutdown_reply = SHUTDOWN_REPLY_YES; -+ shutdown_yes++; -+ -+ check_shutdown_status(); -+ } -+ LEAVE(); -+} -+ -+ - int cfg_lib_exit_fn (void *conn) - { -+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); -+ -+ ENTER(); -+ if (!list_empty(&ci->list)) { -+ list_del(&ci->list); -+ remove_ci_from_shutdown(ci); -+ } -+ LEAVE(); - return (0); - } - - static int cfg_lib_init_fn (void *conn) - { -- -- ENTER(""); -- LEAVE(""); -+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); -+ -+ ENTER(); -+ list_init(&ci->list); -+ LEAVE(); - - return (0); - } -@@ -281,18 +554,64 @@ - (struct req_exec_cfg_ringreenable *)message; - struct res_lib_cfg_ringreenable res_lib_cfg_ringreenable; - -- ENTER(""); -+ ENTER(); - api->totem_ring_reenable (); - if (api->ipc_source_is_local(&req_exec_cfg_ringreenable->source)) { - res_lib_cfg_ringreenable.header.id = MESSAGE_RES_CFG_RINGREENABLE; - res_lib_cfg_ringreenable.header.size = sizeof (struct res_lib_cfg_ringreenable); -- res_lib_cfg_ringreenable.header.error = SA_AIS_OK; -+ res_lib_cfg_ringreenable.header.error = CS_OK; - api->ipc_conn_send_response ( - req_exec_cfg_ringreenable->source.conn, - &res_lib_cfg_ringreenable, - sizeof (struct res_lib_cfg_ringreenable)); - } -- LEAVE(""); -+ LEAVE(); -+} -+ -+static void exec_cfg_killnode_endian_convert (void *msg) -+{ -+ struct req_exec_cfg_killnode *req_exec_cfg_killnode = -+ (struct req_exec_cfg_killnode *)msg; -+ ENTER(); -+ -+ swab_mar_name_t(&req_exec_cfg_killnode->reason); -+ LEAVE(); -+} -+ -+ -+static void message_handler_req_exec_cfg_killnode ( -+ void *message, -+ unsigned int nodeid) -+{ -+ struct req_exec_cfg_killnode *req_exec_cfg_killnode = -+ (struct req_exec_cfg_killnode *)message; -+ cs_name_t reason; -+ -+ ENTER(); -+ log_printf(LOG_DEBUG, "request to kill node %d(us=%d): %s\n", req_exec_cfg_killnode->nodeid, api->totem_nodeid_get(), reason.value); -+ if (req_exec_cfg_killnode->nodeid == api->totem_nodeid_get()) { -+ marshall_from_mar_name_t(&reason, &req_exec_cfg_killnode->reason); -+ log_printf(LOG_NOTICE, "Killed by node %d: %s\n", -+ nodeid, reason.value); -+ corosync_fatal_error(COROSYNC_FATAL_ERROR_EXIT); -+ } -+ LEAVE(); -+} -+ -+/* -+ * Self shutdown -+ */ -+static void message_handler_req_exec_cfg_shutdown ( -+ void *message, -+ unsigned int nodeid) -+{ -+ ENTER(); -+ -+ log_printf(LOG_NOTICE, "Node %d was shut down by sysadmin\n", nodeid); -+ if (nodeid == api->totem_nodeid_get()) { -+ corosync_fatal_error(COROSYNC_FATAL_ERROR_EXIT); -+ } -+ LEAVE(); - } - - -@@ -310,11 +629,11 @@ - char *totem_ip_string; - unsigned int i; - -- ENTER(""); -+ ENTER(); - - res_lib_cfg_ringstatusget.header.id = MESSAGE_RES_CFG_RINGSTATUSGET; - res_lib_cfg_ringstatusget.header.size = sizeof (struct res_lib_cfg_ringstatusget); -- res_lib_cfg_ringstatusget.header.error = SA_AIS_OK; -+ res_lib_cfg_ringstatusget.header.error = CS_OK; - - api->totem_ifaces_get ( - api->totem_nodeid_get(), -@@ -336,7 +655,7 @@ - &res_lib_cfg_ringstatusget, - sizeof (struct res_lib_cfg_ringstatusget)); - -- LEAVE(""); -+ LEAVE(); - } - - static void message_handler_req_lib_cfg_ringreenable ( -@@ -346,7 +665,7 @@ - struct req_exec_cfg_ringreenable req_exec_cfg_ringreenable; - struct iovec iovec; - -- ENTER(""); -+ ENTER(); - req_exec_cfg_ringreenable.header.size = - sizeof (struct req_exec_cfg_ringreenable); - req_exec_cfg_ringreenable.header.id = SERVICE_ID_MAKE (CFG_SERVICE, -@@ -358,27 +677,56 @@ - - assert (api->totem_mcast (&iovec, 1, TOTEM_SAFE) == 0); - -- LEAVE(""); -+ LEAVE(); - } - - static void message_handler_req_lib_cfg_statetrack ( - void *conn, - void *msg) - { -+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); - // struct req_lib_cfg_statetrack *req_lib_cfg_statetrack = (struct req_lib_cfg_statetrack *)message; -+ struct res_lib_cfg_statetrack res_lib_cfg_statetrack; - -- ENTER(""); -- LEAVE(""); -+ ENTER(); -+ -+ /* -+ * We only do shutdown tracking at the moment -+ */ -+ if (list_empty(&ci->list)) { -+ list_add(&ci->list, &trackers_list); -+ ci->tracker_conn = api->ipc_conn_partner_get (conn); -+ -+ if (shutdown_con) { -+ /* -+ * Shutdown already in progress, ask the newcomer's opinion -+ */ -+ ci->shutdown_reply = SHUTDOWN_REPLY_UNKNOWN; -+ shutdown_expected++; -+ send_test_shutdown(ci->tracker_conn, CS_OK); -+ } -+ } -+ -+ res_lib_cfg_statetrack.header.size = sizeof(struct res_lib_cfg_statetrack); -+ res_lib_cfg_statetrack.header.id = MESSAGE_RES_CFG_STATETRACKSTART; -+ res_lib_cfg_statetrack.header.error = CS_OK; -+ -+ api->ipc_conn_send_response(conn, &res_lib_cfg_statetrack, -+ sizeof(res_lib_cfg_statetrack)); -+ -+ LEAVE(); - } - - static void message_handler_req_lib_cfg_statetrackstop ( - void *conn, - void *msg) - { -+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); - // struct req_lib_cfg_statetrackstop *req_lib_cfg_statetrackstop = (struct req_lib_cfg_statetrackstop *)message; - -- ENTER(""); -- LEAVE(""); -+ ENTER(); -+ remove_ci_from_shutdown(ci); -+ LEAVE(); - } - - static void message_handler_req_lib_cfg_administrativestateset ( -@@ -386,16 +734,17 @@ - void *msg) - { - // struct req_lib_cfg_administrativestateset *req_lib_cfg_administrativestateset = (struct req_lib_cfg_administrativestateset *)message; -- ENTER(""); -- LEAVE(""); -+ -+ ENTER(); -+ LEAVE(); - } - static void message_handler_req_lib_cfg_administrativestateget ( - void *conn, - void *msg) - { - // struct req_lib_cfg_administrativestateget *req_lib_cfg_administrativestateget = (struct req_lib_cfg_administrativestateget *)message; -- ENTER(""); -- LEAVE(""); -+ ENTER(); -+ LEAVE(); - } - - static void message_handler_req_lib_cfg_serviceload ( -@@ -406,7 +755,7 @@ - (struct req_lib_cfg_serviceload *)msg; - struct res_lib_cfg_serviceload res_lib_cfg_serviceload; - -- ENTER(""); -+ ENTER(); - api->service_link_and_init ( - api, - (char *)req_lib_cfg_serviceload->service_name, -@@ -414,12 +763,12 @@ - - res_lib_cfg_serviceload.header.id = MESSAGE_RES_CFG_SERVICEUNLOAD; - res_lib_cfg_serviceload.header.size = sizeof (struct res_lib_cfg_serviceload); -- res_lib_cfg_serviceload.header.error = SA_AIS_OK; -+ res_lib_cfg_serviceload.header.error = CS_OK; - api->ipc_conn_send_response ( - conn, - &res_lib_cfg_serviceload, - sizeof (struct res_lib_cfg_serviceload)); -- LEAVE(""); -+ LEAVE(); - } - - static void message_handler_req_lib_cfg_serviceunload ( -@@ -430,17 +779,225 @@ - (struct req_lib_cfg_serviceunload *)msg; - struct res_lib_cfg_serviceunload res_lib_cfg_serviceunload; - -- ENTER(""); -+ ENTER(); - api->service_unlink_and_exit ( - api, - (char *)req_lib_cfg_serviceunload->service_name, - req_lib_cfg_serviceunload->service_ver); - res_lib_cfg_serviceunload.header.id = MESSAGE_RES_CFG_SERVICEUNLOAD; - res_lib_cfg_serviceunload.header.size = sizeof (struct res_lib_cfg_serviceunload); -- res_lib_cfg_serviceunload.header.error = SA_AIS_OK; -+ res_lib_cfg_serviceunload.header.error = CS_OK; - api->ipc_conn_send_response ( - conn, - &res_lib_cfg_serviceunload, - sizeof (struct res_lib_cfg_serviceunload)); -- LEAVE(""); -+ LEAVE(); -+} -+ -+ -+static void message_handler_req_lib_cfg_killnode ( -+ void *conn, -+ void *msg) -+{ -+ struct req_lib_cfg_killnode *req_lib_cfg_killnode = (struct req_lib_cfg_killnode *)msg; -+ struct res_lib_cfg_killnode res_lib_cfg_killnode; -+ struct req_exec_cfg_killnode req_exec_cfg_killnode; -+ struct iovec iovec; -+ int res; -+ -+ ENTER(); -+ req_exec_cfg_killnode.header.size = -+ sizeof (struct req_exec_cfg_killnode); -+ req_exec_cfg_killnode.header.id = SERVICE_ID_MAKE (CFG_SERVICE, -+ MESSAGE_REQ_EXEC_CFG_KILLNODE); -+ req_exec_cfg_killnode.nodeid = req_lib_cfg_killnode->nodeid; -+ marshall_to_mar_name_t(&req_exec_cfg_killnode.reason, &req_lib_cfg_killnode->reason); -+ -+ iovec.iov_base = (char *)&req_exec_cfg_killnode; -+ iovec.iov_len = sizeof (struct req_exec_cfg_killnode); -+ -+ res = api->totem_mcast (&iovec, 1, TOTEM_SAFE); -+ -+ res_lib_cfg_killnode.header.size = sizeof(struct res_lib_cfg_killnode); -+ res_lib_cfg_killnode.header.id = MESSAGE_RES_CFG_KILLNODE; -+ res_lib_cfg_killnode.header.error = CS_OK; -+ -+ api->ipc_conn_send_response(conn, &res_lib_cfg_killnode, -+ sizeof(res_lib_cfg_killnode)); -+ -+ LEAVE(); -+} -+ -+ -+static void message_handler_req_lib_cfg_tryshutdown ( -+ void *conn, -+ void *msg) -+{ -+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); -+ struct req_lib_cfg_tryshutdown *req_lib_cfg_tryshutdown = (struct req_lib_cfg_tryshutdown *)msg; -+ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown; -+ struct list_head *iter; -+ -+ ENTER(); -+ -+ if (req_lib_cfg_tryshutdown->flags == CFG_SHUTDOWN_FLAG_IMMEDIATE) { -+ -+ /* -+ * Tell other nodes -+ */ -+ send_shutdown(); -+ -+ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown); -+ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN; -+ res_lib_cfg_tryshutdown.header.error = CS_OK; -+ api->ipc_conn_send_response(conn, &res_lib_cfg_tryshutdown, -+ sizeof(res_lib_cfg_tryshutdown)); -+ -+ LEAVE(); -+ return; -+ } -+ -+ /* -+ * Shutdown in progress, return an error -+ */ -+ if (shutdown_con) { -+ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown; -+ -+ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown); -+ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN; -+ res_lib_cfg_tryshutdown.header.error = CS_ERR_EXIST; -+ -+ api->ipc_conn_send_response(conn, &res_lib_cfg_tryshutdown, -+ sizeof(res_lib_cfg_tryshutdown)); -+ -+ -+ LEAVE(); -+ -+ return; -+ } -+ -+ ci->conn = conn; -+ shutdown_con = (struct cfg_info *)api->ipc_private_data_get (conn); -+ shutdown_flags = req_lib_cfg_tryshutdown->flags; -+ shutdown_yes = 0; -+ shutdown_no = 0; -+ -+ /* -+ * Count the number of listeners -+ */ -+ shutdown_expected = 0; -+ -+ for (iter = trackers_list.next; iter != &trackers_list; iter = iter->next) { -+ struct cfg_info *ci = list_entry(iter, struct cfg_info, list); -+ ci->shutdown_reply = SHUTDOWN_REPLY_UNKNOWN; -+ shutdown_expected++; -+ } -+ -+ /* -+ * If no-one is listening for events then we can just go down now -+ */ -+ if (shutdown_expected == 0) { -+ send_shutdown(); -+ LEAVE(); -+ return; -+ } -+ else { -+ unsigned int cfg_handle; -+ unsigned int find_handle; -+ char *timeout_str; -+ unsigned int shutdown_timeout = DEFAULT_SHUTDOWN_TIMEOUT; -+ -+ /* -+ * Look for a shutdown timeout in objdb -+ */ -+ api->object_find_create(OBJECT_PARENT_HANDLE, "cfg", strlen("cfg"), &find_handle); -+ api->object_find_next(find_handle, &cfg_handle); -+ api->object_find_destroy(find_handle); -+ -+ if (cfg_handle) { -+ if ( !api->object_key_get(cfg_handle, -+ "shutdown_timeout", -+ strlen("shutdown_timeout"), -+ (void *)&timeout_str, -+ NULL)) { -+ shutdown_timeout = atoi(timeout_str); -+ } -+ } -+ -+ /* -+ * Start the timer. If we don't get a full set of replies before this goes -+ * off we'll cancel the shutdown -+ */ -+ api->timer_add_duration((unsigned long long)shutdown_timeout*1000000000, NULL, -+ shutdown_timer_fn, &shutdown_timer); -+ -+ /* -+ * Tell the users we would like to shut down -+ */ -+ send_test_shutdown(NULL, CS_OK); -+ } -+ -+ /* -+ * We don't sent a reply to the caller here. -+ * We send it when we know if we can shut down or not -+ */ -+ -+ LEAVE(); -+} -+ -+static void message_handler_req_lib_cfg_replytoshutdown ( -+ void *conn, -+ void *msg) -+{ -+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); -+ struct req_lib_cfg_replytoshutdown *req_lib_cfg_replytoshutdown = (struct req_lib_cfg_replytoshutdown *)msg; -+ -+ ENTER(); -+ if (!shutdown_con) { -+ LEAVE(); -+ return; -+ } -+ -+ if (req_lib_cfg_replytoshutdown->response) { -+ shutdown_yes++; -+ ci->shutdown_reply = SHUTDOWN_REPLY_YES; -+ } -+ else { -+ shutdown_no++; -+ ci->shutdown_reply = SHUTDOWN_REPLY_NO; -+ } -+ check_shutdown_status(); -+ LEAVE(); -+} -+ -+static void message_handler_req_lib_cfg_get_node_addrs (void *conn, void *msg) -+{ -+ struct totem_ip_address node_ifs[INTERFACE_MAX]; -+ char buf[PIPE_BUF]; -+ char **status; -+ unsigned int num_interfaces = 0; -+ int ret = 0; -+ int i; -+ struct req_lib_cfg_get_node_addrs *req_lib_cfg_get_node_addrs = (struct req_lib_cfg_get_node_addrs *)msg; -+ struct res_lib_cfg_get_node_addrs *res_lib_cfg_get_node_addrs = (struct res_lib_cfg_get_node_addrs *)buf; -+ -+ if (req_lib_cfg_get_node_addrs->nodeid == 0) -+ req_lib_cfg_get_node_addrs->nodeid = api->totem_nodeid_get(); -+ -+ api->totem_ifaces_get(req_lib_cfg_get_node_addrs->nodeid, node_ifs, &status, &num_interfaces); -+ -+ res_lib_cfg_get_node_addrs->header.size = sizeof(struct res_lib_cfg_get_node_addrs) + (num_interfaces * TOTEMIP_ADDRLEN); -+ res_lib_cfg_get_node_addrs->header.id = MESSAGE_RES_CFG_GET_NODE_ADDRS; -+ res_lib_cfg_get_node_addrs->header.error = ret; -+ res_lib_cfg_get_node_addrs->num_addrs = num_interfaces; -+ if (num_interfaces) { -+ res_lib_cfg_get_node_addrs->family = node_ifs[0].family; -+ for (i = 0; iaddrs[i][0], node_ifs[i].addr, TOTEMIP_ADDRLEN); -+ } -+ } -+ else { -+ res_lib_cfg_get_node_addrs->header.error = CS_ERR_NOT_EXIST; -+ } -+ api->ipc_conn_send_response(conn, res_lib_cfg_get_node_addrs, res_lib_cfg_get_node_addrs->header.size); - } -diff -Naurd corosync-0.92/services/confdb.c corosync-trunk/services/confdb.c ---- corosync-0.92/services/confdb.c 2008-09-03 09:58:08.000000000 +0200 -+++ corosync-trunk/services/confdb.c 2009-01-23 16:41:06.000000000 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2008 Red Hat, Inc. -+ * Copyright (c) 2008-2009 Red Hat, Inc. - * - * All rights reserved. - * -@@ -38,7 +38,7 @@ - #include - #include - --#include -+#include - #include - #include - #include -@@ -106,103 +106,103 @@ - .lib_handler_fn = message_handler_req_lib_confdb_object_create, - .response_size = sizeof (mar_res_header_t), - .response_id = MESSAGE_RES_CONFDB_OBJECT_CREATE, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 1 */ - .lib_handler_fn = message_handler_req_lib_confdb_object_destroy, - .response_size = sizeof (mar_res_header_t), - .response_id = MESSAGE_RES_CONFDB_OBJECT_DESTROY, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 2 */ - .lib_handler_fn = message_handler_req_lib_confdb_object_find, - .response_size = sizeof (struct res_lib_confdb_object_find), - .response_id = MESSAGE_RES_CONFDB_OBJECT_FIND, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 3 */ - .lib_handler_fn = message_handler_req_lib_confdb_key_create, - .response_size = sizeof (mar_res_header_t), - .response_id = MESSAGE_RES_CONFDB_KEY_CREATE, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 4 */ - .lib_handler_fn = message_handler_req_lib_confdb_key_get, - .response_size = sizeof (struct res_lib_confdb_key_get), - .response_id = MESSAGE_RES_CONFDB_KEY_GET, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 5 */ - .lib_handler_fn = message_handler_req_lib_confdb_key_replace, - .response_size = sizeof (mar_res_header_t), - .response_id = MESSAGE_RES_CONFDB_KEY_REPLACE, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 6 */ - .lib_handler_fn = message_handler_req_lib_confdb_key_delete, - .response_size = sizeof (mar_res_header_t), - .response_id = MESSAGE_RES_CONFDB_KEY_DELETE, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 7 */ - .lib_handler_fn = message_handler_req_lib_confdb_object_iter, - .response_size = sizeof (struct res_lib_confdb_object_iter), - .response_id = MESSAGE_RES_CONFDB_OBJECT_ITER, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 8 */ - .lib_handler_fn = message_handler_req_lib_confdb_object_parent_get, - .response_size = sizeof (struct res_lib_confdb_object_parent_get), - .response_id = MESSAGE_RES_CONFDB_OBJECT_PARENT_GET, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 9 */ - .lib_handler_fn = message_handler_req_lib_confdb_key_iter, - .response_size = sizeof (struct res_lib_confdb_key_iter), - .response_id = MESSAGE_RES_CONFDB_KEY_ITER, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 10 */ - .lib_handler_fn = message_handler_req_lib_confdb_track_start, - .response_size = sizeof (mar_res_header_t), - .response_id = MESSAGE_RES_CONFDB_TRACK_START, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 11 */ - .lib_handler_fn = message_handler_req_lib_confdb_track_stop, - .response_size = sizeof (mar_res_header_t), - .response_id = MESSAGE_RES_CONFDB_TRACK_STOP, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 12 */ - .lib_handler_fn = message_handler_req_lib_confdb_write, - .response_size = sizeof (struct res_lib_confdb_write), - .response_id = MESSAGE_RES_CONFDB_WRITE, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 13 */ - .lib_handler_fn = message_handler_req_lib_confdb_reload, - .response_size = sizeof (struct res_lib_confdb_reload), - .response_id = MESSAGE_RES_CONFDB_RELOAD, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 14 */ - .lib_handler_fn = message_handler_req_lib_confdb_object_find_destroy, - .response_size = sizeof (mar_res_header_t), - .response_id = MESSAGE_RES_CONFDB_OBJECT_FIND_DESTROY, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 15 */ - .lib_handler_fn = message_handler_req_lib_confdb_key_increment, - .response_size = sizeof (struct res_lib_confdb_key_incdec), - .response_id = MESSAGE_RES_CONFDB_KEY_INCREMENT, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 16 */ - .lib_handler_fn = message_handler_req_lib_confdb_key_decrement, - .response_size = sizeof (struct res_lib_confdb_key_incdec), - .response_id = MESSAGE_RES_CONFDB_KEY_DECREMENT, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - }; - -@@ -211,7 +211,8 @@ - .name = "corosync cluster config database access v1.01", - .id = CONFDB_SERVICE, - .private_data_size = 0, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED, -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED, -+ .allow_inquorate = CS_LIB_ALLOW_INQUORATE, - .lib_init_fn = confdb_lib_init_fn, - .lib_exit_fn = confdb_lib_exit_fn, - .lib_engine = confdb_lib_engine, -@@ -279,6 +280,7 @@ - api->object_track_stop(confdb_notify_lib_of_key_change, - confdb_notify_lib_of_new_object, - confdb_notify_lib_of_destroyed_object, -+ NULL, - api->ipc_conn_partner_get (conn)); - return (0); - } -@@ -288,13 +290,13 @@ - struct req_lib_confdb_object_create *req_lib_confdb_object_create = (struct req_lib_confdb_object_create *)message; - struct res_lib_confdb_object_create res_lib_confdb_object_create; - unsigned int object_handle; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (api->object_create(req_lib_confdb_object_create->parent_object_handle, - &object_handle, - req_lib_confdb_object_create->object_name.value, - req_lib_confdb_object_create->object_name.length)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res_lib_confdb_object_create.object_handle = object_handle; - res_lib_confdb_object_create.header.size = sizeof(res_lib_confdb_object_create); -@@ -307,10 +309,10 @@ - { - struct req_lib_confdb_object_destroy *req_lib_confdb_object_destroy = (struct req_lib_confdb_object_destroy *)message; - mar_res_header_t res; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (api->object_destroy(req_lib_confdb_object_destroy->object_handle)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res.size = sizeof(res); - res.id = MESSAGE_RES_CONFDB_OBJECT_DESTROY; -@@ -322,12 +324,10 @@ - { - struct req_lib_confdb_object_find_destroy *req_lib_confdb_object_find_destroy = (struct req_lib_confdb_object_find_destroy *)message; - mar_res_header_t res; -- int ret = SA_AIS_OK; -- -- log_printf(LOG_LEVEL_DEBUG, "object_find_destroy for conn=%p, %d\n", conn, req_lib_confdb_object_find_destroy->find_handle); -+ int ret = CS_OK; - - if (api->object_find_destroy(req_lib_confdb_object_find_destroy->find_handle)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res.size = sizeof(res); - res.id = MESSAGE_RES_CONFDB_OBJECT_FIND_DESTROY; -@@ -340,14 +340,14 @@ - { - struct req_lib_confdb_key_create *req_lib_confdb_key_create = (struct req_lib_confdb_key_create *)message; - mar_res_header_t res; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (api->object_key_create(req_lib_confdb_key_create->object_handle, - req_lib_confdb_key_create->key_name.value, - req_lib_confdb_key_create->key_name.length, - req_lib_confdb_key_create->value.value, - req_lib_confdb_key_create->value.length)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res.size = sizeof(res); - res.id = MESSAGE_RES_CONFDB_KEY_CREATE; -@@ -361,14 +361,14 @@ - struct res_lib_confdb_key_get res_lib_confdb_key_get; - int value_len; - void *value; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (api->object_key_get(req_lib_confdb_key_get->parent_object_handle, - req_lib_confdb_key_get->key_name.value, - req_lib_confdb_key_get->key_name.length, - &value, - &value_len)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - else { - memcpy(res_lib_confdb_key_get.value.value, value, value_len); - res_lib_confdb_key_get.value.length = value_len; -@@ -384,15 +384,13 @@ - { - struct req_lib_confdb_key_get *req_lib_confdb_key_get = (struct req_lib_confdb_key_get *)message; - struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec; -- int value_len; -- void *value; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (api->object_key_increment(req_lib_confdb_key_get->parent_object_handle, - req_lib_confdb_key_get->key_name.value, - req_lib_confdb_key_get->key_name.length, - &res_lib_confdb_key_incdec.value)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res_lib_confdb_key_incdec.header.size = sizeof(res_lib_confdb_key_incdec); - res_lib_confdb_key_incdec.header.id = MESSAGE_RES_CONFDB_KEY_INCREMENT; -@@ -404,15 +402,13 @@ - { - struct req_lib_confdb_key_get *req_lib_confdb_key_get = (struct req_lib_confdb_key_get *)message; - struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec; -- int value_len; -- void *value; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (api->object_key_decrement(req_lib_confdb_key_get->parent_object_handle, - req_lib_confdb_key_get->key_name.value, - req_lib_confdb_key_get->key_name.length, - &res_lib_confdb_key_incdec.value)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res_lib_confdb_key_incdec.header.size = sizeof(res_lib_confdb_key_incdec); - res_lib_confdb_key_incdec.header.id = MESSAGE_RES_CONFDB_KEY_DECREMENT; -@@ -424,7 +420,7 @@ - { - struct req_lib_confdb_key_replace *req_lib_confdb_key_replace = (struct req_lib_confdb_key_replace *)message; - mar_res_header_t res; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (api->object_key_replace(req_lib_confdb_key_replace->object_handle, - req_lib_confdb_key_replace->key_name.value, -@@ -433,7 +429,7 @@ - req_lib_confdb_key_replace->old_value.length, - req_lib_confdb_key_replace->new_value.value, - req_lib_confdb_key_replace->new_value.length)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res.size = sizeof(res); - res.id = MESSAGE_RES_CONFDB_KEY_REPLACE; -@@ -445,14 +441,14 @@ - { - struct req_lib_confdb_key_delete *req_lib_confdb_key_delete = (struct req_lib_confdb_key_delete *)message; - mar_res_header_t res; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (api->object_key_delete(req_lib_confdb_key_delete->object_handle, - req_lib_confdb_key_delete->key_name.value, - req_lib_confdb_key_delete->key_name.length, - req_lib_confdb_key_delete->value.value, - req_lib_confdb_key_delete->value.length)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res.size = sizeof(res); - res.id = MESSAGE_RES_CONFDB_KEY_DELETE; -@@ -465,11 +461,11 @@ - struct req_lib_confdb_object_parent_get *req_lib_confdb_object_parent_get = (struct req_lib_confdb_object_parent_get *)message; - struct res_lib_confdb_object_parent_get res_lib_confdb_object_parent_get; - unsigned int object_handle; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (api->object_parent_get(req_lib_confdb_object_parent_get->object_handle, - &object_handle)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res_lib_confdb_object_parent_get.parent_object_handle = object_handle; - res_lib_confdb_object_parent_get.header.size = sizeof(res_lib_confdb_object_parent_get); -@@ -487,7 +483,7 @@ - int key_name_len; - void *value; - int value_len; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (api->object_key_iter_from(req_lib_confdb_key_iter->parent_object_handle, - req_lib_confdb_key_iter->next_entry, -@@ -495,7 +491,7 @@ - &key_name_len, - &value, - &value_len)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - else { - memcpy(res_lib_confdb_key_iter.key_name.value, key_name, key_name_len); - memcpy(res_lib_confdb_key_iter.value.value, value, value_len); -@@ -514,7 +510,7 @@ - struct req_lib_confdb_object_iter *req_lib_confdb_object_iter = (struct req_lib_confdb_object_iter *)message; - struct res_lib_confdb_object_iter res_lib_confdb_object_iter; - int object_name_len; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (!req_lib_confdb_object_iter->find_handle) { - api->object_find_create(req_lib_confdb_object_iter->parent_object_handle, -@@ -525,8 +521,10 @@ - res_lib_confdb_object_iter.find_handle = req_lib_confdb_object_iter->find_handle; - - if (api->object_find_next(res_lib_confdb_object_iter.find_handle, -- &res_lib_confdb_object_iter.object_handle)) -- ret = SA_AIS_ERR_ACCESS; -+ &res_lib_confdb_object_iter.object_handle)) { -+ ret = CS_ERR_ACCESS; -+ api->object_find_destroy(res_lib_confdb_object_iter.find_handle); -+ } - else { - api->object_name_get(res_lib_confdb_object_iter.object_handle, - (char *)res_lib_confdb_object_iter.object_name.value, -@@ -545,7 +543,7 @@ - { - struct req_lib_confdb_object_find *req_lib_confdb_object_find = (struct req_lib_confdb_object_find *)message; - struct res_lib_confdb_object_find res_lib_confdb_object_find; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - - if (!req_lib_confdb_object_find->find_handle) { - api->object_find_create(req_lib_confdb_object_find->parent_object_handle, -@@ -557,8 +555,10 @@ - res_lib_confdb_object_find.find_handle = req_lib_confdb_object_find->find_handle; - - if (api->object_find_next(res_lib_confdb_object_find.find_handle, -- &res_lib_confdb_object_find.object_handle)) -- ret = SA_AIS_ERR_ACCESS; -+ &res_lib_confdb_object_find.object_handle)) { -+ ret = CS_ERR_ACCESS; -+ api->object_find_destroy(res_lib_confdb_object_find.find_handle); -+ } - - res_lib_confdb_object_find.header.size = sizeof(res_lib_confdb_object_find); - res_lib_confdb_object_find.header.id = MESSAGE_RES_CONFDB_OBJECT_FIND; -@@ -571,11 +571,11 @@ - static void message_handler_req_lib_confdb_write (void *conn, void *message) - { - struct res_lib_confdb_write res_lib_confdb_write; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - char *error_string = NULL; - - if (api->object_write_config(&error_string)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res_lib_confdb_write.header.size = sizeof(res_lib_confdb_write); - res_lib_confdb_write.header.id = MESSAGE_RES_CONFDB_WRITE; -@@ -593,11 +593,11 @@ - { - struct req_lib_confdb_reload *req_lib_confdb_reload = (struct req_lib_confdb_reload *)message; - struct res_lib_confdb_reload res_lib_confdb_reload; -- int ret = SA_AIS_OK; -+ int ret = CS_OK; - char *error_string = NULL; - - if (api->object_reload_config(req_lib_confdb_reload->flush, &error_string)) -- ret = SA_AIS_ERR_ACCESS; -+ ret = CS_ERR_ACCESS; - - res_lib_confdb_reload.header.size = sizeof(res_lib_confdb_reload); - res_lib_confdb_reload.header.id = MESSAGE_RES_CONFDB_RELOAD; -@@ -624,7 +624,7 @@ - - res.header.size = sizeof(res); - res.header.id = MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK; -- res.header.error = SA_AIS_OK; -+ res.header.error = CS_OK; - // handle & type - res.change_type = change_type; - res.parent_object_handle = parent_object_handle; -@@ -651,7 +651,7 @@ - - res.header.size = sizeof(res); - res.header.id = MESSAGE_RES_CONFDB_OBJECT_CREATE_CALLBACK; -- res.header.error = SA_AIS_OK; -+ res.header.error = CS_OK; - res.parent_object_handle = parent_object_handle; - res.object_handle = object_handle; - memcpy(res.name.value, name_pt, name_len); -@@ -668,7 +668,7 @@ - - res.header.size = sizeof(res); - res.header.id = MESSAGE_RES_CONFDB_OBJECT_DESTROY_CALLBACK; -- res.header.error = SA_AIS_OK; -+ res.header.error = CS_OK; - res.parent_object_handle = parent_object_handle; - memcpy(res.name.value, name_pt, name_len); - res.name.length = name_len; -@@ -686,10 +686,11 @@ - confdb_notify_lib_of_key_change, - confdb_notify_lib_of_new_object, - confdb_notify_lib_of_destroyed_object, -+ NULL, - api->ipc_conn_partner_get (conn)); - res.size = sizeof(res); - res.id = MESSAGE_RES_CONFDB_TRACK_START; -- res.error = SA_AIS_OK; -+ res.error = CS_OK; - api->ipc_conn_send_response(conn, &res, sizeof(res)); - } - -@@ -700,11 +701,12 @@ - api->object_track_stop(confdb_notify_lib_of_key_change, - confdb_notify_lib_of_new_object, - confdb_notify_lib_of_destroyed_object, -+ NULL, - api->ipc_conn_partner_get (conn)); - - res.size = sizeof(res); - res.id = MESSAGE_RES_CONFDB_TRACK_STOP; -- res.error = SA_AIS_OK; -+ res.error = CS_OK; - api->ipc_conn_send_response(conn, &res, sizeof(res)); - } - -diff -Naurd corosync-0.92/services/cpg.c corosync-trunk/services/cpg.c ---- corosync-0.92/services/cpg.c 2008-09-17 21:15:00.000000000 +0200 -+++ corosync-trunk/services/cpg.c 2009-01-08 07:29:16.000000000 +0100 -@@ -51,7 +51,7 @@ - #include - #include - --#include -+#include - #include - #include - #include -@@ -99,7 +99,7 @@ - void *conn; - void *trackerconn; - struct group_info *group; -- enum corosync_flow_control_state flow_control_state; -+ enum cs_flow_control_state flow_control_state; - struct list_head list; /* on the group_info members list */ - }; - -@@ -189,49 +189,49 @@ - .lib_handler_fn = message_handler_req_lib_cpg_join, - .response_size = sizeof (struct res_lib_cpg_join), - .response_id = MESSAGE_RES_CPG_JOIN, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED - }, - { /* 1 */ - .lib_handler_fn = message_handler_req_lib_cpg_leave, - .response_size = sizeof (struct res_lib_cpg_leave), - .response_id = MESSAGE_RES_CPG_LEAVE, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED - }, - { /* 2 */ - .lib_handler_fn = message_handler_req_lib_cpg_mcast, - .response_size = sizeof (struct res_lib_cpg_mcast), - .response_id = MESSAGE_RES_CPG_MCAST, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED - }, - { /* 3 */ - .lib_handler_fn = message_handler_req_lib_cpg_membership, - .response_size = sizeof (mar_res_header_t), - .response_id = MESSAGE_RES_CPG_MEMBERSHIP, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 4 */ - .lib_handler_fn = message_handler_req_lib_cpg_trackstart, - .response_size = sizeof (struct res_lib_cpg_trackstart), - .response_id = MESSAGE_RES_CPG_TRACKSTART, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 5 */ - .lib_handler_fn = message_handler_req_lib_cpg_trackstop, - .response_size = sizeof (struct res_lib_cpg_trackstart), - .response_id = MESSAGE_RES_CPG_TRACKSTOP, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 6 */ - .lib_handler_fn = message_handler_req_lib_cpg_local_get, - .response_size = sizeof (struct res_lib_cpg_local_get), - .response_id = MESSAGE_RES_CPG_LOCAL_GET, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 7 */ - .lib_handler_fn = message_handler_req_lib_cpg_groups_get, - .response_size = sizeof (struct res_lib_cpg_groups_get), - .response_id = MESSAGE_RES_CPG_GROUPS_GET, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - } - }; - -@@ -263,7 +263,7 @@ - .name = "corosync cluster closed process group service v1.01", - .id = CPG_SERVICE, - .private_data_size = sizeof (struct process_info), -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED, -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED, - .lib_init_fn = cpg_lib_init_fn, - .lib_exit_fn = cpg_lib_exit_fn, - .lib_engine = cpg_lib_engine, -@@ -395,7 +395,7 @@ - sizeof(mar_cpg_address_t) * (count + left_list_entries + joined_list_entries); - buf = alloca(size); - if (!buf) -- return SA_AIS_ERR_NO_SPACE; -+ return CS_ERR_NO_SPACE; - - res = (struct res_lib_cpg_confchg_callback *)buf; - res->joined_list_entries = joined_list_entries; -@@ -404,6 +404,7 @@ - - res->header.size = size; - res->header.id = id; -+ res->header.error = CS_OK; - memcpy(&res->group_name, &gi->group_name, sizeof(mar_cpg_name_t)); - - /* Build up the message */ -@@ -453,7 +454,7 @@ - } - } - -- return SA_AIS_OK; -+ return CS_OK; - } - - static void remove_group(struct group_info *gi) -@@ -571,6 +572,8 @@ - return; - } - } -+ if (!buf) -+ continue; - - res = (struct res_lib_cpg_groups_get_callback *)buf; - retgi = res->member_list; -@@ -694,7 +697,7 @@ - struct memb_ring_id *ring_id) - { - int i; -- uint32_t lowest_nodeid = 0xffffff; -+ uint32_t lowest_nodeid = 0xffffffff; - struct iovec req_exec_cpg_iovec; - - /* We don't send the library joinlist in here because it can end up -@@ -736,7 +739,7 @@ - - static void cpg_flow_control_state_set_fn ( - void *context, -- enum corosync_flow_control_state flow_control_state) -+ enum cs_flow_control_state flow_control_state) - { - struct res_lib_cpg_flowcontrol_callback res_lib_cpg_flowcontrol_callback; - struct process_info *process_info = (struct process_info *)context; -@@ -1105,19 +1108,19 @@ - struct process_info *pi = (struct process_info *)api->ipc_private_data_get (conn); - struct res_lib_cpg_join res_lib_cpg_join; - struct group_info *gi; -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - - log_printf(LOG_LEVEL_DEBUG, "got join request on %p, pi=%p, pi->pid=%d\n", conn, pi, pi->pid); - - /* Already joined on this conn */ - if (pi->pid) { -- error = SA_AIS_ERR_INVALID_PARAM; -+ error = CS_ERR_INVALID_PARAM; - goto join_err; - } - - gi = get_group(&req_lib_cpg_join->group_name); - if (!gi) { -- error = SA_AIS_ERR_NO_SPACE; -+ error = CS_ERR_NO_SPACE; - goto join_err; - } - -@@ -1151,12 +1154,12 @@ - struct process_info *pi = (struct process_info *)api->ipc_private_data_get (conn); - struct res_lib_cpg_leave res_lib_cpg_leave; - struct group_info *gi; -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - - log_printf(LOG_LEVEL_DEBUG, "got leave request on %p\n", conn); - - if (!pi || !pi->pid || !pi->group) { -- error = SA_AIS_ERR_INVALID_PARAM; -+ error = CS_ERR_INVALID_PARAM; - goto leave_ret; - } - gi = pi->group; -@@ -1198,7 +1201,7 @@ - if (!gi) { - res_lib_cpg_mcast.header.size = sizeof(res_lib_cpg_mcast); - res_lib_cpg_mcast.header.id = MESSAGE_RES_CPG_MCAST; -- res_lib_cpg_mcast.header.error = SA_AIS_ERR_ACCESS; /* TODO Better error code ?? */ -+ res_lib_cpg_mcast.header.error = CS_ERR_ACCESS; /* TODO Better error code ?? */ - res_lib_cpg_mcast.flow_control_state = CPG_FLOW_CONTROL_DISABLED; - api->ipc_conn_send_response(conn, &res_lib_cpg_mcast, - sizeof(res_lib_cpg_mcast)); -@@ -1225,7 +1228,7 @@ - - res_lib_cpg_mcast.header.size = sizeof(res_lib_cpg_mcast); - res_lib_cpg_mcast.header.id = MESSAGE_RES_CPG_MCAST; -- res_lib_cpg_mcast.header.error = SA_AIS_OK; -+ res_lib_cpg_mcast.header.error = CS_OK; - res_lib_cpg_mcast.flow_control_state = pi->flow_control_state; - api->ipc_conn_send_response(conn, &res_lib_cpg_mcast, - sizeof(res_lib_cpg_mcast)); -@@ -1240,7 +1243,7 @@ - mar_res_header_t res; - res.size = sizeof(res); - res.id = MESSAGE_RES_CPG_MEMBERSHIP; -- res.error = SA_AIS_ERR_ACCESS; /* TODO Better error code */ -+ res.error = CS_ERR_ACCESS; /* TODO Better error code */ - api->ipc_conn_send_response(conn, &res, sizeof(res)); - return; - } -@@ -1256,13 +1259,13 @@ - struct group_info *gi; - struct process_info *otherpi; - void *otherconn; -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - - log_printf(LOG_LEVEL_DEBUG, "got trackstart request on %p\n", conn); - - gi = get_group(&req_lib_cpg_trackstart->group_name); - if (!gi) { -- error = SA_AIS_ERR_NO_SPACE; -+ error = CS_ERR_NO_SPACE; - goto tstart_ret; - } - -@@ -1274,7 +1277,7 @@ - tstart_ret: - res_lib_cpg_trackstart.header.size = sizeof(res_lib_cpg_trackstart); - res_lib_cpg_trackstart.header.id = MESSAGE_RES_CPG_TRACKSTART; -- res_lib_cpg_trackstart.header.error = SA_AIS_OK; -+ res_lib_cpg_trackstart.header.error = CS_OK; - api->ipc_conn_send_response(conn, &res_lib_cpg_trackstart, sizeof(res_lib_cpg_trackstart)); - } - -@@ -1285,13 +1288,13 @@ - struct process_info *otherpi; - void *otherconn; - struct group_info *gi; -- SaAisErrorT error = SA_AIS_OK; -+ cs_error_t error = CS_OK; - - log_printf(LOG_LEVEL_DEBUG, "got trackstop request on %p\n", conn); - - gi = get_group(&req_lib_cpg_trackstop->group_name); - if (!gi) { -- error = SA_AIS_ERR_NO_SPACE; -+ error = CS_ERR_NO_SPACE; - goto tstop_ret; - } - -@@ -1303,7 +1306,7 @@ - tstop_ret: - res_lib_cpg_trackstop.header.size = sizeof(res_lib_cpg_trackstop); - res_lib_cpg_trackstop.header.id = MESSAGE_RES_CPG_TRACKSTOP; -- res_lib_cpg_trackstop.header.error = SA_AIS_OK; -+ res_lib_cpg_trackstop.header.error = CS_OK; - api->ipc_conn_send_response(conn, &res_lib_cpg_trackstop.header, sizeof(res_lib_cpg_trackstop)); - } - -@@ -1313,7 +1316,7 @@ - - res_lib_cpg_local_get.header.size = sizeof(res_lib_cpg_local_get); - res_lib_cpg_local_get.header.id = MESSAGE_RES_CPG_LOCAL_GET; -- res_lib_cpg_local_get.header.error = SA_AIS_OK; -+ res_lib_cpg_local_get.header.error = CS_OK; - res_lib_cpg_local_get.local_nodeid = api->totem_nodeid_get (); - - api->ipc_conn_send_response(conn, &res_lib_cpg_local_get, -@@ -1326,7 +1329,7 @@ - - res_lib_cpg_groups_get.header.size = sizeof(res_lib_cpg_groups_get); - res_lib_cpg_groups_get.header.id = MESSAGE_RES_CPG_GROUPS_GET; -- res_lib_cpg_groups_get.header.error = SA_AIS_OK; -+ res_lib_cpg_groups_get.header.error = CS_OK; - res_lib_cpg_groups_get.num_groups = count_groups(); - - api->ipc_conn_send_response(conn, &res_lib_cpg_groups_get, -diff -Naurd corosync-0.92/services/evs.c corosync-trunk/services/evs.c ---- corosync-0.92/services/evs.c 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/services/evs.c 2008-11-06 22:49:07.000000000 +0100 -@@ -49,7 +49,7 @@ - #include - - #include --#include -+#include - #include - #include - #include -@@ -104,31 +104,31 @@ - .lib_handler_fn = message_handler_req_evs_join, - .response_size = sizeof (struct res_lib_evs_join), - .response_id = MESSAGE_RES_EVS_JOIN, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 1 */ - .lib_handler_fn = message_handler_req_evs_leave, - .response_size = sizeof (struct res_lib_evs_leave), - .response_id = MESSAGE_RES_EVS_LEAVE, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - }, - { /* 2 */ - .lib_handler_fn = message_handler_req_evs_mcast_joined, - .response_size = sizeof (struct res_lib_evs_mcast_joined), - .response_id = MESSAGE_RES_EVS_MCAST_JOINED, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED - }, - { /* 3 */ - .lib_handler_fn = message_handler_req_evs_mcast_groups, - .response_size = sizeof (struct res_lib_evs_mcast_groups), - .response_id = MESSAGE_RES_EVS_MCAST_GROUPS, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED - }, - { /* 4 */ - .lib_handler_fn = message_handler_req_evs_membership_get, - .response_size = sizeof (struct res_lib_evs_membership_get), - .response_id = MESSAGE_RES_EVS_MEMBERSHIP_GET, -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED - } - }; - -@@ -144,7 +144,7 @@ - .name = "corosync extended virtual synchrony service", - .id = EVS_SERVICE, - .private_data_size = sizeof (struct evs_pd), -- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED, -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED, - .lib_init_fn = evs_lib_init_fn, - .lib_exit_fn = evs_lib_exit_fn, - .lib_engine = evs_lib_engine, -@@ -223,7 +223,7 @@ - */ - res_evs_confchg_callback.header.size = sizeof (struct res_evs_confchg_callback); - res_evs_confchg_callback.header.id = MESSAGE_RES_EVS_CONFCHG_CALLBACK; -- res_evs_confchg_callback.header.error = SA_AIS_OK; -+ res_evs_confchg_callback.header.error = CS_OK; - - memcpy (res_evs_confchg_callback.member_list, - member_list, member_list_entries * sizeof(*member_list)); -@@ -276,21 +276,21 @@ - - static void message_handler_req_evs_join (void *conn, void *msg) - { -- evs_error_t error = EVS_OK; -+ cs_error_t error = CS_OK; - struct req_lib_evs_join *req_lib_evs_join = (struct req_lib_evs_join *)msg; - struct res_lib_evs_join res_lib_evs_join; - void *addr; - struct evs_pd *evs_pd = (struct evs_pd *)api->ipc_private_data_get (conn); - - if (req_lib_evs_join->group_entries > 50) { -- error = EVS_ERR_TOO_MANY_GROUPS; -+ error = CS_ERR_TOO_MANY_GROUPS; - goto exit_error; - } - - addr = realloc (evs_pd->groups, sizeof (struct evs_group) * - (evs_pd->group_entries + req_lib_evs_join->group_entries)); - if (addr == NULL) { -- error = SA_AIS_ERR_NO_MEMORY; -+ error = CS_ERR_NO_MEMORY; - goto exit_error; - } - evs_pd->groups = addr; -@@ -314,7 +314,7 @@ - { - struct req_lib_evs_leave *req_lib_evs_leave = (struct req_lib_evs_leave *)msg; - struct res_lib_evs_leave res_lib_evs_leave; -- evs_error_t error = EVS_OK; -+ cs_error_t error = CS_OK; - int error_index; - int i, j; - int found; -@@ -342,7 +342,7 @@ - } - } - if (found == 0) { -- error = EVS_ERR_NOT_EXIST; -+ error = CS_ERR_NOT_EXIST; - error_index = i; - break; - } -@@ -358,7 +358,7 @@ - - static void message_handler_req_evs_mcast_joined (void *conn, void *msg) - { -- evs_error_t error = EVS_ERR_TRY_AGAIN; -+ cs_error_t error = CS_ERR_TRY_AGAIN; - struct req_lib_evs_mcast_joined *req_lib_evs_mcast_joined = (struct req_lib_evs_mcast_joined *)msg; - struct res_lib_evs_mcast_joined res_lib_evs_mcast_joined; - struct iovec req_exec_evs_mcast_iovec[3]; -@@ -388,7 +388,7 @@ - res = api->totem_mcast (req_exec_evs_mcast_iovec, 3, TOTEM_AGREED); - // TODO - if (res == 0) { -- error = EVS_OK; -+ error = CS_OK; - } - - res_lib_evs_mcast_joined.header.size = sizeof (struct res_lib_evs_mcast_joined); -@@ -401,7 +401,7 @@ - - static void message_handler_req_evs_mcast_groups (void *conn, void *msg) - { -- evs_error_t error = EVS_ERR_TRY_AGAIN; -+ cs_error_t error = CS_ERR_TRY_AGAIN; - struct req_lib_evs_mcast_groups *req_lib_evs_mcast_groups = (struct req_lib_evs_mcast_groups *)msg; - struct res_lib_evs_mcast_groups res_lib_evs_mcast_groups; - struct iovec req_exec_evs_mcast_iovec[3]; -@@ -434,7 +434,7 @@ - send_ok = api->totem_send_ok (req_exec_evs_mcast_iovec, 3); - res = api->totem_mcast (req_exec_evs_mcast_iovec, 3, TOTEM_AGREED); - if (res == 0) { -- error = EVS_OK; -+ error = CS_OK; - } - - res_lib_evs_mcast_groups.header.size = sizeof (struct res_lib_evs_mcast_groups); -@@ -451,7 +451,7 @@ - - res_lib_evs_membership_get.header.size = sizeof (struct res_lib_evs_membership_get); - res_lib_evs_membership_get.header.id = MESSAGE_RES_EVS_MEMBERSHIP_GET; -- res_lib_evs_membership_get.header.error = EVS_OK; -+ res_lib_evs_membership_get.header.error = CS_OK; - res_lib_evs_membership_get.local_nodeid = api->totem_nodeid_get (); - memcpy (&res_lib_evs_membership_get.member_list, - &res_evs_confchg_callback.member_list, -@@ -488,7 +488,7 @@ - res_evs_deliver_callback.header.size = sizeof (struct res_evs_deliver_callback) + - req_exec_evs_mcast->msg_len; - res_evs_deliver_callback.header.id = MESSAGE_RES_EVS_DELIVER_CALLBACK; -- res_evs_deliver_callback.header.error = SA_AIS_OK; -+ res_evs_deliver_callback.header.error = CS_OK; - res_evs_deliver_callback.msglen = req_exec_evs_mcast->msg_len; - - msg_addr = (char *)req_exec_evs_mcast + sizeof (struct req_exec_evs_mcast) + -diff -Naurd corosync-0.92/services/Makefile corosync-trunk/services/Makefile ---- corosync-0.92/services/Makefile 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/services/Makefile 2009-01-26 11:46:08.000000000 +0100 -@@ -50,12 +50,12 @@ - endif - - # LCR objects --LCR_SRC = evs.c cfg.c cpg.c confdb.c --LCR_OBJS = evs.o cfg.o cpg.o confdb.o $(AMF_OBJS) -+LCR_SRC = evs.c cfg.c cpg.c confdb.c pload.c -+LCR_OBJS = evs.o cfg.o cpg.o confdb.o $(AMF_OBJS) pload.o - - override CFLAGS += -fPIC - --all: service_evs.lcrso service_cfg.lcrso service_cpg.lcrso service_confdb.lcrso -+all: service_evs.lcrso service_cfg.lcrso service_cpg.lcrso service_confdb.lcrso service_pload.lcrso testquorum.lcrso service_votequorum.lcrso - - ifeq (${COROSYNC_COMPAT}, DARWIN) - -@@ -71,6 +71,15 @@ - service_cpg.lcrso: cpg.o - $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ../exec/corosync -bind_at_load cpg.o -o $@ - -+service_pload.lcrso: pload.o -+ $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ../exec/corosync -bind_at_load pload.o -o $@ -+ -+service_votequorum.lcrso: votequorum.o -+ $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ../exec/corosync -bind_at_load votequorum.o -o $@ -+ -+testquorum.lcrso: testquorum.o -+ $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ../exec/corosync -bind_at_load testquorum.o -o $@ -+ - else - - service_evs.lcrso: evs.o -@@ -85,11 +94,23 @@ - service_cpg.lcrso: cpg.o - $(CC) -shared -Wl,-soname,service_cpg.lcrso cpg.o -o $@ - -+service_pload.lcrso: pload.o -+ $(CC) -shared -Wl,-soname,service_pload.lcrso pload.o -o $@ -+ -+service_votequorum.lcrso: votequorum.o -+ $(CC) -shared -Wl,-soname,service_votequorum.lcrso votequorum.o -o $@ -+ -+testquorum.lcrso: testquorum.o -+ $(CC) -shared -Wl,-soname,testquorum.lcrso testquorum.o -o $@ -+ - endif - - clean: - rm -f *.o *.lcrso - -+lint: -+ -splint $(LINT_FLAGS) $(CFLAGS) *.c -+ - depend: - makedepend -Y -- $(CFLAGS) $(CPPFLAGS) $(EXEC_SRC) $(TOTEM_SRC) $(LOGSYS_SRC) $(LCR_SRC) > /dev/null 2>&1 - -@@ -104,3 +125,6 @@ - - cpg.o: cpg.c - $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -+ -+testquorum.o: testquorum.c -+ $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -diff -Naurd corosync-0.92/services/pload.c corosync-trunk/services/pload.c ---- corosync-0.92/services/pload.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/services/pload.c 2008-11-06 22:49:07.000000000 +0100 -@@ -0,0 +1,356 @@ -+/* -+ * Copyright (c) 2008 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 -+#include -+ -+LOGSYS_DECLARE_SUBSYS ("PLOAD", LOG_INFO); -+ -+enum pload_exec_message_req_types { -+ MESSAGE_REQ_EXEC_PLOAD_START = 0, -+ MESSAGE_REQ_EXEC_PLOAD_MCAST = 1 -+}; -+ -+/* -+ * Service Interfaces required by service_message_handler struct -+ */ -+static int pload_exec_init_fn ( -+ struct corosync_api_v1 *corosync_api); -+ -+static void pload_confchg_fn ( -+ enum totem_configuration_type configuration_type, -+ unsigned int *member_list, int member_list_entries, -+ unsigned int *left_list, int left_list_entries, -+ unsigned int *joined_list, int joined_list_entries, -+ struct memb_ring_id *ring_id); -+ -+static void message_handler_req_exec_pload_start (void *msg, unsigned int nodeid); -+ -+static void message_handler_req_exec_pload_mcast (void *msg, unsigned int nodeid); -+ -+static void req_exec_pload_start_endian_convert (void *msg); -+ -+static void req_exec_pload_mcast_endian_convert (void *msg); -+ -+static void message_handler_req_pload_start (void *conn, void *msg); -+ -+static int pload_lib_init_fn (void *conn); -+ -+static int pload_lib_exit_fn (void *conn); -+ -+static char buffer[1000000]; -+ -+static unsigned int msgs_delivered = 0; -+ -+static unsigned int msgs_wanted = 0; -+ -+static unsigned int msg_size = 0; -+ -+static unsigned int msg_code = 1; -+ -+static unsigned int msgs_sent = 0; -+ -+ -+static struct corosync_api_v1 *api; -+ -+struct req_exec_pload_start { -+ mar_req_header_t header; -+ unsigned int msg_code; -+ unsigned int msg_count; -+ unsigned int msg_size; -+ unsigned int time_interval; -+}; -+ -+struct req_exec_pload_mcast { -+ mar_req_header_t header; -+ unsigned int msg_code; -+}; -+ -+static struct corosync_lib_handler pload_lib_engine[] = -+{ -+ { /* 0 */ -+ .lib_handler_fn = message_handler_req_pload_start, -+ .response_size = sizeof (struct res_lib_pload_start), -+ .response_id = MESSAGE_RES_PLOAD_START, -+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED -+ } -+}; -+ -+static struct corosync_exec_handler pload_exec_engine[] = -+{ -+ { -+ .exec_handler_fn = message_handler_req_exec_pload_start, -+ .exec_endian_convert_fn = req_exec_pload_start_endian_convert -+ }, -+ { -+ .exec_handler_fn = message_handler_req_exec_pload_mcast, -+ .exec_endian_convert_fn = req_exec_pload_mcast_endian_convert -+ } -+}; -+ -+struct corosync_service_engine pload_service_engine = { -+ .name = "corosync profile loading service", -+ .id = PLOAD_SERVICE, -+ .private_data_size = 0, -+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED, -+ .lib_init_fn = pload_lib_init_fn, -+ .lib_exit_fn = pload_lib_exit_fn, -+ .lib_engine = pload_lib_engine, -+ .lib_engine_count = sizeof (pload_lib_engine) / sizeof (struct corosync_lib_handler), -+ .exec_engine = pload_exec_engine, -+ .exec_engine_count = sizeof (pload_exec_engine) / sizeof (struct corosync_exec_handler), -+ .confchg_fn = pload_confchg_fn, -+ .exec_init_fn = pload_exec_init_fn, -+ .exec_dump_fn = NULL -+}; -+ -+static DECLARE_LIST_INIT (confchg_notify); -+ -+/* -+ * Dynamic loading descriptor -+ */ -+ -+static struct corosync_service_engine *pload_get_service_engine_ver0 (void); -+ -+static struct corosync_service_engine_iface_ver0 pload_service_engine_iface = { -+ .corosync_get_service_engine_ver0 = pload_get_service_engine_ver0 -+}; -+ -+static struct lcr_iface corosync_pload_ver0[1] = { -+ { -+ .name = "corosync_pload", -+ .version = 0, -+ .versions_replace = 0, -+ .versions_replace_count = 0, -+ .dependencies = 0, -+ .dependency_count = 0, -+ .constructor = NULL, -+ .destructor = NULL, -+ .interfaces = NULL, -+ } -+}; -+ -+static struct lcr_comp pload_comp_ver0 = { -+ .iface_count = 1, -+ .ifaces = corosync_pload_ver0 -+}; -+ -+static struct corosync_service_engine *pload_get_service_engine_ver0 (void) -+{ -+ return (&pload_service_engine); -+} -+ -+__attribute__ ((constructor)) static void pload_comp_register (void) { -+ lcr_interfaces_set (&corosync_pload_ver0[0], &pload_service_engine_iface); -+ -+ lcr_component_register (&pload_comp_ver0); -+} -+ -+static int pload_exec_init_fn ( -+ struct corosync_api_v1 *corosync_api) -+{ -+ api = corosync_api; -+ -+ return 0; -+} -+ -+static void pload_confchg_fn ( -+ enum totem_configuration_type configuration_type, -+ unsigned int *member_list, int member_list_entries, -+ unsigned int *left_list, int left_list_entries, -+ unsigned int *joined_list, int joined_list_entries, -+ struct memb_ring_id *ring_id) -+{ -+} -+ -+static int pload_lib_init_fn (void *conn) -+{ -+ return (0); -+} -+ -+static int pload_lib_exit_fn (void *conn) -+{ -+ return (0); -+} -+ -+static void message_handler_req_pload_start (void *conn, void *msg) -+{ -+ struct req_lib_pload_start *req_lib_pload_start = (struct req_lib_pload_start *)msg; -+ struct req_exec_pload_start req_exec_pload_start; -+ struct iovec iov; -+ -+ req_exec_pload_start.header.id = -+ SERVICE_ID_MAKE (PLOAD_SERVICE, MESSAGE_REQ_EXEC_PLOAD_START); -+ req_exec_pload_start.msg_code = req_lib_pload_start->msg_code; -+ req_exec_pload_start.msg_size = req_lib_pload_start->msg_size; -+ req_exec_pload_start.msg_count = req_lib_pload_start->msg_count; -+ req_exec_pload_start.time_interval = req_lib_pload_start->time_interval; -+ iov.iov_base = &req_exec_pload_start; -+ iov.iov_len = sizeof (struct req_exec_pload_start); -+ -+ api->totem_mcast (&iov, 1, TOTEM_AGREED); -+} -+ -+static void req_exec_pload_start_endian_convert (void *msg) -+{ -+} -+ -+static void req_exec_pload_mcast_endian_convert (void *msg) -+{ -+} -+ -+static int msg_no = 0; -+ -+int send_message (enum totem_callback_token_type type, void *arg) -+{ -+ struct req_exec_pload_mcast req_exec_pload_mcast; -+ struct iovec iov[2]; -+ unsigned int res; -+ int iov_len = 2; -+ -+ req_exec_pload_mcast.header.id = -+ SERVICE_ID_MAKE (PLOAD_SERVICE, MESSAGE_REQ_EXEC_PLOAD_MCAST); -+ req_exec_pload_mcast.header.size = sizeof (struct req_exec_pload_mcast) + msg_size; -+ -+ iov[0].iov_base = &req_exec_pload_mcast; -+ iov[0].iov_len = sizeof (struct req_exec_pload_mcast); -+ iov[1].iov_base = buffer; -+ iov[1].iov_len = msg_size - sizeof (struct req_exec_pload_mcast); -+ if (iov[1].iov_len < 0) { -+ iov_len = 1; -+ } -+ -+ do { -+ res = api->totem_mcast (iov, iov_len, TOTEM_AGREED); -+ if (res == -1) { -+ break; -+ } else { -+ msgs_sent++; -+ msg_code++; -+ } -+ } while (msgs_sent <= msgs_wanted); -+ if (msgs_sent == msgs_wanted) { -+ return (0); -+ } else { -+ return (-1); -+ } -+} -+ -+void *token_callback; -+void start_mcasting (void) -+{ -+ api->totem_callback_token_create ( -+ &token_callback, -+ TOTEM_CALLBACK_TOKEN_RECEIVED, -+ 1, -+ send_message, -+ &token_callback); -+} -+ -+static void message_handler_req_exec_pload_start ( -+ void *msg, -+ unsigned int nodeid) -+{ -+ struct req_exec_pload_start *req_exec_pload_start = (struct req_exec_pload_start *)msg; -+ -+ msgs_wanted = req_exec_pload_start->msg_count; -+ msg_size = req_exec_pload_start->msg_size; -+ msg_code = req_exec_pload_start->msg_code; -+ -+ start_mcasting (); -+} -+ -+# define timersub(a, b, result) \ -+ do { \ -+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ -+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ -+ if ((result)->tv_usec < 0) { \ -+ --(result)->tv_sec; \ -+ (result)->tv_usec += 1000000; \ -+ } \ -+ } while (0) -+ -+struct timeval tv1; -+struct timeval tv2; -+struct timeval tv_elapsed; -+int last_msg_no = 0; -+ -+static void message_handler_req_exec_pload_mcast ( -+ void *msg, -+ unsigned int nodeid) -+{ -+ struct req_exec_pload_mcast *pload_mcast = (struct req_exec_pload_mcast *)msg; -+ -+ assert (pload_mcast->msg_code - 1 == last_msg_no); -+ last_msg_no = pload_mcast->msg_code; -+ if (msgs_delivered == 0) { -+ gettimeofday (&tv1, NULL); -+ } -+ msgs_delivered += 1; -+ if (msgs_delivered == msgs_wanted) { -+ gettimeofday (&tv2, NULL); -+ timersub (&tv2, &tv1, &tv_elapsed); -+ printf ("%5d Writes ", msgs_delivered); -+ printf ("%5d bytes per write ", msg_size); -+ printf ("%7.3f Seconds runtime ", -+ (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0))); -+ printf ("%9.3f TP/s ", -+ ((float)msgs_delivered) / (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0))); -+ printf ("%7.3f MB/s.\n", -+ ((float)msgs_delivered) * ((float)msg_size) / ((tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)) * 1000000.0)); -+ } -+} -diff -Naurd corosync-0.92/services/testquorum.c corosync-trunk/services/testquorum.c ---- corosync-0.92/services/testquorum.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/services/testquorum.c 2008-12-09 14:48:47.000000000 +0100 -@@ -0,0 +1,153 @@ -+/* -+ * Copyright (c) 2008 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 Red Hat, 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 -+#include -+ -+#include -+ -+LOGSYS_DECLARE_SUBSYS ("TEST", LOG_INFO); -+ -+static void test_init(struct corosync_api_v1 *api, quorum_set_quorate_fn_t report); -+ -+/* -+ * lcrso object definition -+ */ -+static struct quorum_services_api_ver1 test_quorum_iface_ver0 = { -+ .init = test_init -+}; -+ -+static struct lcr_iface corosync_test_quorum_ver0[1] = { -+ { -+ .name = "testquorum", -+ .version = 0, -+ .versions_replace = 0, -+ .versions_replace_count = 0, -+ .dependencies = 0, -+ .dependency_count = 0, -+ .constructor = NULL, -+ .destructor = NULL, -+ .interfaces = (void **)(void *)&test_quorum_iface_ver0, -+ }, -+}; -+ -+static struct lcr_comp test_quorum_comp_ver0 = { -+ .iface_count = 1, -+ .ifaces = corosync_test_quorum_ver0 -+}; -+ -+__attribute__ ((constructor)) static void test_quorum_comp_register (void) { -+ lcr_interfaces_set (&corosync_test_quorum_ver0[0], &test_quorum_iface_ver0); -+ lcr_component_register (&test_quorum_comp_ver0); -+} -+ -+/* -------------------------------------------------- */ -+ -+static quorum_set_quorate_fn_t set_quorum; -+ -+static void key_change_notify(object_change_type_t change_type, -+ unsigned int parent_object_handle, -+ unsigned int object_handle, -+ void *object_name_pt, int object_name_len, -+ void *key_name_pt, int key_len, -+ void *key_value_pt, int key_value_len, -+ void *priv_data_pt) -+{ -+ unsigned int members[1]; -+ struct memb_ring_id ring_id; -+ -+ memset(&ring_id, 0, sizeof(ring_id)); -+ -+ /* If the 'quorum.quorate' key changes, then that changes quorum */ -+ if (strncmp(key_name_pt, "quorate", key_len) == 0) { -+ set_quorum(members, 0, atoi(key_value_pt), &ring_id); -+ } -+} -+ -+static void quorum_callback(int quorate, void *context) -+{ -+ log_printf(LOG_LEVEL_DEBUG, "quorum callback: quorate = %d\n", quorate); -+} -+ -+static void test_init(struct corosync_api_v1 *api, -+ quorum_set_quorate_fn_t report) -+{ -+ -+ unsigned int find_handle; -+ unsigned int quorum_handle = 0; -+ -+ set_quorum = report; -+ -+ /* -+ * Register for objdb changes on quorum { } -+ */ -+ api->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle); -+ api->object_find_next(find_handle, &quorum_handle); -+ api->object_find_destroy(find_handle); -+ -+ api->object_track_start(quorum_handle, -+ 1, -+ key_change_notify, -+ NULL, // object_create_notify -+ NULL, // object_destroy_notify -+ NULL, // object_reload_notify -+ NULL); // priv_data -+ -+ /* Register for quorum changes too! */ -+ api->quorum_register_callback(quorum_callback, NULL); -+} -diff -Naurd corosync-0.92/services/votequorum.c corosync-trunk/services/votequorum.c ---- corosync-0.92/services/votequorum.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/services/votequorum.c 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,1619 @@ -+/* -+ * Copyright (c) 2009 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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 -+#ifndef COROSYNC_BSD -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define VOTEQUORUM_MAJOR_VERSION 6 -+#define VOTEQUORUM_MINOR_VERSION 3 -+#define VOTEQUORUM_PATCH_VERSION 0 -+ -+ /* Silly default to prevent accidents! */ -+#define DEFAULT_EXPECTED 1024 -+#define DEFAULT_QDEV_POLL 10000 -+ -+LOGSYS_DECLARE_SUBSYS ("VOTEQ", LOG_INFO); -+ -+enum quorum_message_req_types { -+ MESSAGE_REQ_EXEC_VOTEQUORUM_NODEINFO = 0, -+ MESSAGE_REQ_EXEC_VOTEQUORUM_RECONFIGURE = 1, -+ MESSAGE_REQ_EXEC_VOTEQUORUM_KILLNODE = 2, -+}; -+ -+#define NODE_FLAGS_BEENDOWN 1 -+#define NODE_FLAGS_SEESDISALLOWED 8 -+#define NODE_FLAGS_HASSTATE 16 -+#define NODE_FLAGS_QDISK 32 -+#define NODE_FLAGS_REMOVED 64 -+#define NODE_FLAGS_US 128 -+ -+ -+typedef enum { NODESTATE_JOINING=1, NODESTATE_MEMBER, -+ NODESTATE_DEAD, NODESTATE_LEAVING, NODESTATE_DISALLOWED } nodestate_t; -+ -+ -+/* This structure is tacked onto the start of a cluster message packet for our -+ * own nefarious purposes. */ -+struct q_protheader { -+ unsigned char tgtport; /* Target port number */ -+ unsigned char srcport; /* Source (originating) port number */ -+ unsigned short pad; -+ unsigned int flags; -+ int srcid; /* Node ID of the sender */ -+ int tgtid; /* Node ID of the target */ -+} __attribute__((packed)); -+ -+struct cluster_node { -+ int flags; -+ int node_id; -+ unsigned int expected_votes; -+ unsigned int votes; -+ time_t join_time; -+ -+ nodestate_t state; -+ -+ struct timeval last_hello; /* Only used for quorum devices */ -+ -+ struct list_head list; -+}; -+ -+static int quorum_flags; -+#define VOTEQUORUM_FLAG_FEATURE_DISALLOWED 1 -+#define VOTEQUORUM_FLAG_FEATURE_TWONODE 1 -+ -+static int quorum; -+static int cluster_is_quorate; -+static int first_trans = 1; -+static unsigned int quorumdev_poll = DEFAULT_QDEV_POLL; -+ -+static struct cluster_node *us; -+static struct cluster_node *quorum_device = NULL; -+static char quorum_device_name[VOTEQUORUM_MAX_QDISK_NAME_LEN]; -+static corosync_timer_handle_t quorum_device_timer; -+static struct list_head cluster_members_list; -+static struct corosync_api_v1 *corosync_api; -+static struct list_head trackers_list; -+static unsigned int quorum_members[PROCESSOR_COUNT_MAX+1]; -+static int quorum_members_entries = 0; -+static struct memb_ring_id quorum_ringid; -+static cs_tpg_handle group_handle; -+ -+#define max(a,b) (((a) > (b)) ? (a) : (b)) -+static struct cluster_node *find_node_by_nodeid(int nodeid); -+static struct cluster_node *allocate_node(int nodeid); -+static char *kill_reason(int reason); -+ -+static struct corosync_tpg_group quorum_group[1] = { -+ { .group = "VOTEQ", .group_len = 5}, -+}; -+ -+#define list_iterate(v, head) \ -+ for (v = (head)->next; v != head; v = v->next) -+ -+struct quorum_pd { -+ unsigned char track_flags; -+ int tracking_enabled; -+ uint64_t tracking_context; -+ struct list_head list; -+ void *conn; -+}; -+ -+/* -+ * Service Interfaces required by service_message_handler struct -+ */ -+ -+static void votequorum_init(struct corosync_api_v1 *api, -+ quorum_set_quorate_fn_t report); -+ -+static void quorum_confchg_fn ( -+ enum totem_configuration_type configuration_type, -+ unsigned int *member_list, int member_list_entries, -+ unsigned int *left_list, int left_list_entries, -+ unsigned int *joined_list, int joined_list_entries, -+ struct memb_ring_id *ring_id); -+ -+static void quorum_deliver_fn(unsigned int nodeid, struct iovec *iovec, int iov_len, -+ int endian_conversion_required); -+ -+static int votequorum_exec_init_fn (struct corosync_api_v1 *corosync_api); -+ -+static int quorum_lib_init_fn (void *conn); -+ -+static int quorum_lib_exit_fn (void *conn); -+ -+static void message_handler_req_exec_quorum_nodeinfo ( -+ void *message, -+ unsigned int nodeid); -+ -+static void message_handler_req_exec_quorum_reconfigure ( -+ void *message, -+ unsigned int nodeid); -+ -+static void message_handler_req_exec_quorum_killnode ( -+ void *message, -+ unsigned int nodeid); -+ -+ -+static void message_handler_req_lib_votequorum_getinfo (void *conn, void *message); -+ -+static void message_handler_req_lib_votequorum_setexpected (void *conn, void *message); -+ -+static void message_handler_req_lib_votequorum_setvotes (void *conn, void *message); -+ -+static void message_handler_req_lib_votequorum_qdisk_register (void *conn, void *message); -+ -+static void message_handler_req_lib_votequorum_qdisk_unregister (void *conn, void *message); -+ -+static void message_handler_req_lib_votequorum_qdisk_poll (void *conn, void *message); -+ -+static void message_handler_req_lib_votequorum_qdisk_getinfo (void *conn, void *message); -+ -+static void message_handler_req_lib_votequorum_setstate (void *conn, void *message); -+ -+static void message_handler_req_lib_votequorum_leaving (void *conn, void *message); -+static void message_handler_req_lib_votequorum_trackstart (void *conn, void *msg); -+static void message_handler_req_lib_votequorum_trackstop (void *conn, void *msg); -+ -+static int quorum_exec_send_nodeinfo(void); -+static int quorum_exec_send_reconfigure(int param, int nodeid, int value); -+static int quorum_exec_send_killnode(int nodeid, unsigned int reason); -+ -+static void add_votequorum_config_notification(unsigned int quorum_object_handle); -+ -+ -+/* -+ * Library Handler Definition -+ */ -+static struct corosync_lib_handler quorum_lib_service[] = -+{ -+ { /* 0 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_getinfo, -+ .response_size = sizeof (struct res_lib_votequorum_getinfo), -+ .response_id = MESSAGE_RES_VOTEQUORUM_GETINFO, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 1 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_setexpected, -+ .response_size = sizeof (struct res_lib_votequorum_status), -+ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 2 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_setvotes, -+ .response_size = sizeof (struct res_lib_votequorum_status), -+ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 3 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_qdisk_register, -+ .response_size = sizeof (struct res_lib_votequorum_status), -+ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 4 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_qdisk_unregister, -+ .response_size = sizeof (struct res_lib_votequorum_status), -+ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 5 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_qdisk_poll, -+ .response_size = sizeof (struct res_lib_votequorum_status), -+ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 6 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_qdisk_getinfo, -+ .response_size = sizeof (struct res_lib_votequorum_qdisk_getinfo), -+ .response_id = MESSAGE_RES_VOTEQUORUM_QDISK_GETINFO, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 7 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_setstate, -+ .response_size = sizeof (struct res_lib_votequorum_status), -+ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 8 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_leaving, -+ .response_size = sizeof (struct res_lib_votequorum_status), -+ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 9 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_trackstart, -+ .response_size = sizeof (struct res_lib_votequorum_status), -+ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ }, -+ { /* 10 */ -+ .lib_handler_fn = message_handler_req_lib_votequorum_trackstop, -+ .response_size = sizeof (struct res_lib_votequorum_status), -+ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED -+ } -+}; -+ -+static quorum_set_quorate_fn_t set_quorum; -+/* -+ * lcrso object definition -+ */ -+static struct quorum_services_api_ver1 votequorum_iface_ver0 = { -+ .init = votequorum_init -+}; -+ -+static struct corosync_service_engine quorum_service_handler = { -+ .name = "corosync votes quorum service v0.90", -+ .id = VOTEQUORUM_SERVICE, -+ .private_data_size = sizeof (struct quorum_pd), -+ .allow_inquorate = CS_LIB_ALLOW_INQUORATE, -+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED, -+ .lib_init_fn = quorum_lib_init_fn, -+ .lib_exit_fn = quorum_lib_exit_fn, -+ .lib_engine = quorum_lib_service, -+ .lib_engine_count = sizeof (quorum_lib_service) / sizeof (struct corosync_lib_handler), -+ .exec_init_fn = votequorum_exec_init_fn, -+ .exec_engine = NULL, -+ .exec_engine_count = 0, -+ .confchg_fn = NULL, -+}; -+ -+/* -+ * Dynamic loader definition -+ */ -+static struct corosync_service_engine *quorum_get_service_handler_ver0 (void); -+ -+static struct corosync_service_engine_iface_ver0 quorum_service_handler_iface = { -+ .corosync_get_service_engine_ver0 = quorum_get_service_handler_ver0 -+}; -+ -+static struct lcr_iface corosync_quorum_ver0[2] = { -+ { -+ .name = "corosync_votequorum", -+ .version = 0, -+ .versions_replace = 0, -+ .versions_replace_count = 0, -+ .dependencies = 0, -+ .dependency_count = 0, -+ .constructor = NULL, -+ .destructor = NULL, -+ .interfaces = (void **)(void *)&votequorum_iface_ver0 -+ }, -+ { -+ .name = "corosync_votequorum_iface", -+ .version = 0, -+ .versions_replace = 0, -+ .versions_replace_count = 0, -+ .dependencies = 0, -+ .dependency_count = 0, -+ .constructor = NULL, -+ .destructor = NULL, -+ .interfaces = NULL -+ } -+}; -+ -+static struct lcr_comp quorum_comp_ver0 = { -+ .iface_count = 2, -+ .ifaces = corosync_quorum_ver0 -+}; -+ -+ -+static struct corosync_service_engine *quorum_get_service_handler_ver0 (void) -+{ -+ return (&quorum_service_handler); -+} -+ -+__attribute__ ((constructor)) static void quorum_comp_register (void) { -+ lcr_interfaces_set (&corosync_quorum_ver0[0], &votequorum_iface_ver0); -+ lcr_interfaces_set (&corosync_quorum_ver0[1], &quorum_service_handler_iface); -+ lcr_component_register (&quorum_comp_ver0); -+} -+ -+static void votequorum_init(struct corosync_api_v1 *api, -+ quorum_set_quorate_fn_t report) -+{ -+ ENTER(); -+ set_quorum = report; -+ -+ /* Load the library-servicing part of this module */ -+ api->service_link_and_init(api, "corosync_votequorum_iface", 0); -+ -+ LEAVE(); -+} -+ -+/* Message types */ -+#define VOTEQUORUM_MSG_NODEINFO 5 -+#define VOTEQUORUM_MSG_KILLNODE 6 -+#define VOTEQUORUM_MSG_RECONFIGURE 8 -+ -+struct req_exec_quorum_nodeinfo { -+ unsigned char cmd; -+ unsigned char first_trans; -+ unsigned int votes; -+ unsigned int expected_votes; -+ -+ unsigned int major_version; /* Not backwards compatible */ -+ unsigned int minor_version; /* Backwards compatible */ -+ unsigned int patch_version; /* Backwards/forwards compatible */ -+ unsigned int config_version; -+ unsigned int flags; -+ -+} __attribute__((packed)); -+ -+/* Parameters for RECONFIG command */ -+#define RECONFIG_PARAM_EXPECTED_VOTES 1 -+#define RECONFIG_PARAM_NODE_VOTES 2 -+#define RECONFIG_PARAM_LEAVING 3 -+ -+struct req_exec_quorum_reconfigure { -+ unsigned char cmd; -+ unsigned char param; -+ unsigned short pad; -+ int nodeid; -+ unsigned int value; -+}; -+ -+struct req_exec_quorum_killnode { -+ unsigned char cmd; -+ unsigned char pad1; -+ uint16_t reason; -+ int nodeid; -+}; -+ -+/* These just make the access a little neater */ -+static inline int objdb_get_string(struct corosync_api_v1 *corosync, unsigned int object_service_handle, -+ char *key, char **value) -+{ -+ int res; -+ -+ *value = NULL; -+ if ( !(res = corosync_api->object_key_get(object_service_handle, -+ key, -+ strlen(key), -+ (void *)value, -+ NULL))) { -+ if (*value) -+ return 0; -+ } -+ return -1; -+} -+ -+static inline void objdb_get_int(struct corosync_api_v1 *corosync, unsigned int object_service_handle, -+ char *key, unsigned int *intvalue, unsigned int default_value) -+{ -+ char *value = NULL; -+ -+ *intvalue = default_value; -+ -+ if (!corosync_api->object_key_get(object_service_handle, key, strlen(key), -+ (void *)&value, NULL)) { -+ if (value) { -+ *intvalue = atoi(value); -+ } -+ } -+} -+ -+static int votequorum_send_message(void *message, int len) -+{ -+ struct iovec iov[2]; -+ struct q_protheader header; -+ -+ header.tgtport = 0; -+ header.srcport = 0; -+ header.flags = 0; -+ header.srcid = us->node_id; -+ header.tgtid = 0; -+ -+ iov[0].iov_base = &header; -+ iov[0].iov_len = sizeof(header); -+ iov[1].iov_base = message; -+ iov[1].iov_len = len; -+ -+ return corosync_api->tpg_joined_mcast(group_handle, iov, 2, TOTEM_AGREED); -+} -+ -+static void read_quorum_config(unsigned int quorum_handle) -+{ -+ unsigned int value = 0; -+ int cluster_members = 0; -+ struct list_head *tmp; -+ struct cluster_node *node; -+ -+ log_printf(LOG_INFO, "Reading configuration\n"); -+ -+ objdb_get_int(corosync_api, quorum_handle, "expected_votes", &us->expected_votes, DEFAULT_EXPECTED); -+ objdb_get_int(corosync_api, quorum_handle, "votes", &us->votes, 1); -+ objdb_get_int(corosync_api, quorum_handle, "quorumdev_poll", &quorumdev_poll, DEFAULT_QDEV_POLL); -+ objdb_get_int(corosync_api, quorum_handle, "disallowed", &value, 0); -+ if (value) -+ quorum_flags |= VOTEQUORUM_FLAG_FEATURE_DISALLOWED; -+ else -+ quorum_flags &= ~VOTEQUORUM_FLAG_FEATURE_DISALLOWED; -+ -+ objdb_get_int(corosync_api, quorum_handle, "two_node", &value, 0); -+ if (value) -+ quorum_flags |= VOTEQUORUM_FLAG_FEATURE_TWONODE; -+ else -+ quorum_flags &= ~VOTEQUORUM_FLAG_FEATURE_TWONODE; -+ -+ /* -+ * two_node mode is invalid if there are more than 2 nodes in the cluster! -+ */ -+ list_iterate(tmp, &cluster_members_list) { -+ node = list_entry(tmp, struct cluster_node, list); -+ cluster_members++; -+ } -+ -+ if (quorum_flags & VOTEQUORUM_FLAG_FEATURE_TWONODE && cluster_members > 2) { -+ log_printf(LOG_WARNING, "quorum.two_node was set but there are more than 2 nodes in the cluster. It will be ignored."); -+ quorum_flags &= ~VOTEQUORUM_FLAG_FEATURE_TWONODE; -+ } -+} -+ -+static int votequorum_exec_init_fn (struct corosync_api_v1 *api) -+{ -+ unsigned int object_handle; -+ unsigned int find_handle; -+ -+ ENTER(); -+ -+ corosync_api = api; -+ -+ list_init(&cluster_members_list); -+ list_init(&trackers_list); -+ -+ /* Allocate a cluster_node for us */ -+ us = allocate_node(corosync_api->totem_nodeid_get()); -+ if (!us) -+ return (1); -+ -+ us->flags |= NODE_FLAGS_US; -+ us->state = NODESTATE_MEMBER; -+ us->expected_votes = DEFAULT_EXPECTED; -+ us->votes = 1; -+ time(&us->join_time); -+ -+ /* Get configuration variables */ -+ corosync_api->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle); -+ -+ if (corosync_api->object_find_next(find_handle, &object_handle) == 0) { -+ read_quorum_config(object_handle); -+ } -+ /* Listen for changes */ -+ add_votequorum_config_notification(object_handle); -+ corosync_api->object_find_destroy(find_handle); -+ -+ api->tpg_init(&group_handle, quorum_deliver_fn, quorum_confchg_fn); -+ api->tpg_join(group_handle, quorum_group, 1); -+ -+ LEAVE(); -+ return (0); -+} -+ -+static int quorum_lib_exit_fn (void *conn) -+{ -+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); -+ -+ ENTER(); -+ if (quorum_pd->tracking_enabled) { -+ list_del (&quorum_pd->list); -+ list_init (&quorum_pd->list); -+ } -+ LEAVE(); -+ return (0); -+} -+ -+ -+static int send_quorum_notification(void *conn, uint64_t context) -+{ -+ struct res_lib_votequorum_notification *res_lib_votequorum_notification; -+ struct list_head *tmp; -+ struct cluster_node *node; -+ int cluster_members = 0; -+ int i = 0; -+ int size; -+ char *buf; -+ -+ ENTER(); -+ list_iterate(tmp, &cluster_members_list) { -+ node = list_entry(tmp, struct cluster_node, list); -+ cluster_members++; -+ } -+ if (quorum_device) -+ cluster_members++; -+ -+ size = sizeof(struct res_lib_votequorum_notification) + sizeof(struct votequorum_node) * cluster_members; -+ buf = alloca(size); -+ if (!buf) { -+ LEAVE(); -+ return -1; -+ } -+ -+ res_lib_votequorum_notification = (struct res_lib_votequorum_notification *)buf; -+ res_lib_votequorum_notification->quorate = cluster_is_quorate; -+ res_lib_votequorum_notification->node_list_entries = cluster_members; -+ res_lib_votequorum_notification->context = context; -+ list_iterate(tmp, &cluster_members_list) { -+ node = list_entry(tmp, struct cluster_node, list); -+ res_lib_votequorum_notification->node_list[i].nodeid = node->node_id; -+ res_lib_votequorum_notification->node_list[i++].state = node->state; -+ } -+ if (quorum_device) { -+ res_lib_votequorum_notification->node_list[i].nodeid = 0; -+ res_lib_votequorum_notification->node_list[i++].state = quorum_device->state | 0x80; -+ } -+ res_lib_votequorum_notification->header.id = MESSAGE_RES_VOTEQUORUM_NOTIFICATION; -+ res_lib_votequorum_notification->header.size = size; -+ res_lib_votequorum_notification->header.error = CS_OK; -+ -+ /* Send it to all interested parties */ -+ if (conn) { -+ int ret = corosync_api->ipc_conn_send_response(conn, buf, size); -+ LEAVE(); -+ return ret; -+ } -+ else { -+ struct quorum_pd *qpd; -+ -+ list_iterate(tmp, &trackers_list) { -+ qpd = list_entry(tmp, struct quorum_pd, list); -+ res_lib_votequorum_notification->context = qpd->tracking_context; -+ corosync_api->ipc_conn_send_response(corosync_api->ipc_conn_partner_get(qpd->conn), buf, size); -+ } -+ } -+ LEAVE(); -+ return 0; -+} -+ -+static void set_quorate(int total_votes) -+{ -+ int quorate; -+ -+ ENTER(); -+ if (quorum > total_votes) { -+ quorate = 0; -+ } -+ else { -+ quorate = 1; -+ } -+ -+ if (cluster_is_quorate && !quorate) -+ log_printf(LOG_INFO, "quorum lost, blocking activity\n"); -+ if (!cluster_is_quorate && quorate) -+ log_printf(LOG_INFO, "quorum regained, resuming activity\n"); -+ -+ /* If we are newly quorate, then kill any DISALLOWED nodes */ -+ if (!cluster_is_quorate && quorate) { -+ struct cluster_node *node = NULL; -+ struct list_head *tmp; -+ -+ list_iterate(tmp, &cluster_members_list) { -+ node = list_entry(tmp, struct cluster_node, list); -+ if (node->state == NODESTATE_DISALLOWED) -+ quorum_exec_send_killnode(node->node_id, VOTEQUORUM_REASON_KILL_REJOIN); -+ } -+ } -+ -+ cluster_is_quorate = quorate; -+ set_quorum(quorum_members, quorum_members_entries, quorate, &quorum_ringid); -+ ENTER(); -+} -+ -+static int calculate_quorum(int allow_decrease, int max_expected, unsigned int *ret_total_votes) -+{ -+ struct list_head *nodelist; -+ struct cluster_node *node; -+ unsigned int total_votes = 0; -+ unsigned int highest_expected = 0; -+ unsigned int newquorum, q1, q2; -+ unsigned int total_nodes = 0; -+ unsigned int leaving = 0; -+ -+ ENTER(); -+ list_iterate(nodelist, &cluster_members_list) { -+ node = list_entry(nodelist, struct cluster_node, list); -+ -+ log_printf(LOG_DEBUG, "node %x state=%d, votes=%d, expected=%d\n", -+ node->node_id, node->state, node->votes, node->expected_votes); -+ -+ if (node->state == NODESTATE_MEMBER) { -+ if (max_expected) -+ node->expected_votes = max_expected; -+ else -+ highest_expected = max(highest_expected, node->expected_votes); -+ total_votes += node->votes; -+ total_nodes++; -+ } -+ if (node->state == NODESTATE_LEAVING) { -+ leaving = 1; -+ } -+ } -+ -+ if (quorum_device && quorum_device->state == NODESTATE_MEMBER) -+ total_votes += quorum_device->votes; -+ -+ if (max_expected > 0) -+ highest_expected = max_expected; -+ -+ /* This quorum calculation is taken from the OpenVMS Cluster Systems -+ * manual, but, then, you guessed that didn't you */ -+ q1 = (highest_expected + 2) / 2; -+ q2 = (total_votes + 2) / 2; -+ newquorum = max(q1, q2); -+ -+ /* Normally quorum never decreases but the system administrator can -+ * force it down by setting expected votes to a maximum value */ -+ if (!allow_decrease) -+ newquorum = max(quorum, newquorum); -+ -+ /* The special two_node mode allows each of the two nodes to retain -+ * quorum if the other fails. Only one of the two should live past -+ * fencing (as both nodes try to fence each other in split-brain.) -+ * Also: if there are more than two nodes, force us inquorate to avoid -+ * any damage or confusion. -+ */ -+ if ((quorum_flags & VOTEQUORUM_FLAG_FEATURE_TWONODE) && total_nodes <= 2) -+ newquorum = 1; -+ -+ if (ret_total_votes) -+ *ret_total_votes = total_votes; -+ -+ LEAVE(); -+ return newquorum; -+} -+ -+/* Recalculate cluster quorum, set quorate and notify changes */ -+static void recalculate_quorum(int allow_decrease) -+{ -+ unsigned int total_votes; -+ -+ ENTER(); -+ quorum = calculate_quorum(allow_decrease, 0, &total_votes); -+ set_quorate(total_votes); -+ send_quorum_notification(NULL, 0L); -+ LEAVE(); -+} -+ -+static int have_disallowed(void) -+{ -+ struct cluster_node *node; -+ struct list_head *tmp; -+ -+ list_iterate(tmp, &cluster_members_list) { -+ node = list_entry(tmp, struct cluster_node, list); -+ if (node->state == NODESTATE_DISALLOWED) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static void node_add_ordered(struct cluster_node *newnode) -+{ -+ struct cluster_node *node = NULL; -+ struct list_head *tmp; -+ struct list_head *newlist = &newnode->list; -+ -+ list_iterate(tmp, &cluster_members_list) { -+ node = list_entry(tmp, struct cluster_node, list); -+ -+ if (newnode->node_id < node->node_id) -+ break; -+ } -+ -+ if (!node) -+ list_add(&newnode->list, &cluster_members_list); -+ else { -+ newlist->prev = tmp->prev; -+ newlist->next = tmp; -+ tmp->prev->next = newlist; -+ tmp->prev = newlist; -+ } -+} -+ -+static struct cluster_node *allocate_node(int nodeid) -+{ -+ struct cluster_node *cl; -+ -+ cl = malloc(sizeof(struct cluster_node)); -+ if (cl) { -+ memset(cl, 0, sizeof(struct cluster_node)); -+ cl->node_id = nodeid; -+ if (nodeid) -+ node_add_ordered(cl); -+ } -+ return cl; -+} -+ -+static struct cluster_node *find_node_by_nodeid(int nodeid) -+{ -+ struct cluster_node *node; -+ struct list_head *tmp; -+ -+ list_iterate(tmp, &cluster_members_list) { -+ node = list_entry(tmp, struct cluster_node, list); -+ if (node->node_id == nodeid) -+ return node; -+ } -+ return NULL; -+} -+ -+ -+static int quorum_exec_send_nodeinfo() -+{ -+ struct req_exec_quorum_nodeinfo req_exec_quorum_nodeinfo; -+ int ret; -+ -+ ENTER(); -+ -+ req_exec_quorum_nodeinfo.cmd = VOTEQUORUM_MSG_NODEINFO; -+ req_exec_quorum_nodeinfo.expected_votes = us->expected_votes; -+ req_exec_quorum_nodeinfo.votes = us->votes; -+ req_exec_quorum_nodeinfo.major_version = VOTEQUORUM_MAJOR_VERSION; -+ req_exec_quorum_nodeinfo.minor_version = VOTEQUORUM_MINOR_VERSION; -+ req_exec_quorum_nodeinfo.patch_version = VOTEQUORUM_PATCH_VERSION; -+ req_exec_quorum_nodeinfo.flags = us->flags; -+ req_exec_quorum_nodeinfo.first_trans = first_trans; -+ if (have_disallowed()) -+ req_exec_quorum_nodeinfo.flags |= NODE_FLAGS_SEESDISALLOWED; -+ -+ ret = votequorum_send_message(&req_exec_quorum_nodeinfo, sizeof(req_exec_quorum_nodeinfo)); -+ LEAVE(); -+ return ret; -+} -+ -+ -+static int quorum_exec_send_reconfigure(int param, int nodeid, int value) -+{ -+ struct req_exec_quorum_reconfigure req_exec_quorum_reconfigure; -+ int ret; -+ -+ ENTER(); -+ -+ req_exec_quorum_reconfigure.cmd = VOTEQUORUM_MSG_RECONFIGURE; -+ req_exec_quorum_reconfigure.param = param; -+ req_exec_quorum_reconfigure.nodeid = nodeid; -+ req_exec_quorum_reconfigure.value = value; -+ -+ ret = votequorum_send_message(&req_exec_quorum_reconfigure, sizeof(req_exec_quorum_reconfigure)); -+ LEAVE(); -+ return ret; -+} -+ -+static int quorum_exec_send_killnode(int nodeid, unsigned int reason) -+{ -+ struct req_exec_quorum_killnode req_exec_quorum_killnode; -+ int ret; -+ -+ ENTER(); -+ -+ req_exec_quorum_killnode.cmd = VOTEQUORUM_MSG_KILLNODE; -+ req_exec_quorum_killnode.nodeid = nodeid; -+ req_exec_quorum_killnode.reason = reason; -+ -+ ret = votequorum_send_message(&req_exec_quorum_killnode, sizeof(req_exec_quorum_killnode)); -+ LEAVE(); -+ return ret; -+} -+ -+static void quorum_confchg_fn ( -+ enum totem_configuration_type configuration_type, -+ unsigned int *member_list, int member_list_entries, -+ unsigned int *left_list, int left_list_entries, -+ unsigned int *joined_list, int joined_list_entries, -+ struct memb_ring_id *ring_id) -+{ -+ int i; -+ int leaving = 0; -+ struct cluster_node *node; -+ -+ ENTER(); -+ if (member_list_entries > 1) -+ first_trans = 0; -+ -+ if (left_list_entries) { -+ for (i = 0; i< left_list_entries; i++) { -+ node = find_node_by_nodeid(left_list[i]); -+ if (node) { -+ if (node->state == NODESTATE_LEAVING) -+ leaving = 1; -+ node->state = NODESTATE_DEAD; -+ node->flags |= NODE_FLAGS_BEENDOWN; -+ } -+ } -+ recalculate_quorum(leaving); -+ } -+ -+ if (member_list_entries) { -+ memcpy(quorum_members, member_list, sizeof(unsigned int) * member_list_entries); -+ quorum_members_entries = member_list_entries; -+ if (quorum_device) { -+ quorum_members[quorum_members_entries++] = 0; -+ } -+ quorum_exec_send_nodeinfo(); -+ } -+ -+ memcpy(&quorum_ringid, ring_id, sizeof(*ring_id)); -+ LEAVE(); -+} -+ -+static void exec_quorum_nodeinfo_endian_convert (void *msg) -+{ -+ struct req_exec_quorum_nodeinfo *nodeinfo = (struct req_exec_quorum_nodeinfo *)msg; -+ -+ nodeinfo->votes = swab32(nodeinfo->votes); -+ nodeinfo->expected_votes = swab32(nodeinfo->expected_votes); -+ nodeinfo->major_version = swab32(nodeinfo->major_version); -+ nodeinfo->minor_version = swab32(nodeinfo->minor_version); -+ nodeinfo->patch_version = swab32(nodeinfo->patch_version); -+ nodeinfo->config_version = swab32(nodeinfo->config_version); -+ nodeinfo->flags = swab32(nodeinfo->flags); -+} -+ -+static void exec_quorum_reconfigure_endian_convert (void *msg) -+{ -+ struct req_exec_quorum_reconfigure *reconfigure = (struct req_exec_quorum_reconfigure *)msg; -+ reconfigure->nodeid = swab32(reconfigure->nodeid); -+ reconfigure->value = swab32(reconfigure->value); -+} -+ -+static void exec_quorum_killnode_endian_convert (void *msg) -+{ -+ struct req_exec_quorum_killnode *killnode = (struct req_exec_quorum_killnode *)msg; -+ killnode->reason = swab16(killnode->reason); -+ killnode->nodeid = swab32(killnode->nodeid); -+} -+ -+static void quorum_deliver_fn(unsigned int nodeid, struct iovec *iovec, int iov_len, -+ int endian_conversion_required) -+{ -+ struct q_protheader *header = iovec->iov_base; -+ char *buf; -+ -+ ENTER(); -+ -+ if (endian_conversion_required) { -+ header->srcid = swab32(header->srcid); -+ header->tgtid = swab32(header->tgtid); -+ header->flags = swab32(header->flags); -+ } -+ -+ /* Only pass on messages for us or everyone */ -+ if (header->tgtport == 0 && -+ (header->tgtid == us->node_id || -+ header->tgtid == 0)) { -+ buf = iovec->iov_base + sizeof(struct q_protheader); -+ switch (*buf) { -+ -+ case VOTEQUORUM_MSG_NODEINFO: -+ if (endian_conversion_required) -+ exec_quorum_nodeinfo_endian_convert(buf); -+ message_handler_req_exec_quorum_nodeinfo (buf, header->srcid); -+ break; -+ case VOTEQUORUM_MSG_RECONFIGURE: -+ if (endian_conversion_required) -+ exec_quorum_reconfigure_endian_convert(buf); -+ message_handler_req_exec_quorum_reconfigure (buf, header->srcid); -+ break; -+ case VOTEQUORUM_MSG_KILLNODE: -+ if (endian_conversion_required) -+ exec_quorum_killnode_endian_convert(buf); -+ message_handler_req_exec_quorum_killnode (buf, header->srcid); -+ break; -+ -+ /* Just ignore other messages */ -+ } -+ } -+ LEAVE(); -+} -+ -+static void message_handler_req_exec_quorum_nodeinfo ( -+ void *message, -+ unsigned int nodeid) -+{ -+ struct req_exec_quorum_nodeinfo *req_exec_quorum_nodeinfo = (struct req_exec_quorum_nodeinfo *)message; -+ struct cluster_node *node; -+ int old_votes; -+ int old_expected; -+ nodestate_t old_state; -+ int new_node = 0; -+ -+ ENTER(); -+ log_printf(LOG_LEVEL_DEBUG, "got nodeinfo message from cluster node %d\n", nodeid); -+ -+ node = find_node_by_nodeid(nodeid); -+ if (!node) { -+ node = allocate_node(nodeid); -+ new_node = 1; -+ } -+ if (!node) { -+ corosync_api->error_memory_failure(); -+ return; -+ } -+ -+ /* -+ * If the node sending the message sees disallowed nodes and we don't, then -+ * we have to leave -+ */ -+ if (req_exec_quorum_nodeinfo->flags & NODE_FLAGS_SEESDISALLOWED && !have_disallowed()) { -+ /* Must use syslog directly here or the message will never arrive */ -+ syslog(LOG_CRIT, "[VOTEQ]: Joined a cluster with disallowed nodes. must die"); -+ corosync_api->fatal_error(2, __FILE__, __LINE__); -+ exit(2); -+ } -+ old_votes = node->votes; -+ old_expected = node->expected_votes; -+ old_state = node->state; -+ -+ /* Update node state */ -+ if (req_exec_quorum_nodeinfo->minor_version >= 2) -+ node->votes = req_exec_quorum_nodeinfo->votes; -+ node->expected_votes = req_exec_quorum_nodeinfo->expected_votes; -+ node->state = NODESTATE_MEMBER; -+ -+ /* Check flags for disallowed (if enabled) */ -+ if (quorum_flags & VOTEQUORUM_FLAG_FEATURE_DISALLOWED) { -+ if ((req_exec_quorum_nodeinfo->flags & NODE_FLAGS_HASSTATE && node->flags & NODE_FLAGS_BEENDOWN) || -+ (req_exec_quorum_nodeinfo->flags & NODE_FLAGS_HASSTATE && req_exec_quorum_nodeinfo->first_trans && !(node->flags & NODE_FLAGS_US))) { -+ if (node->state != NODESTATE_DISALLOWED) { -+ if (cluster_is_quorate) { -+ log_printf(LOG_CRIT, "Killing node %d because it has rejoined the cluster with existing state", node->node_id); -+ node->state = NODESTATE_DISALLOWED; -+ quorum_exec_send_killnode(nodeid, VOTEQUORUM_REASON_KILL_REJOIN); -+ } -+ else { -+ log_printf(LOG_CRIT, "Node %d not joined to quorum because it has existing state", node->node_id); -+ node->state = NODESTATE_DISALLOWED; -+ } -+ } -+ } -+ } -+ node->flags &= ~NODE_FLAGS_BEENDOWN; -+ -+ if (new_node || old_votes != node->votes || old_expected != node->expected_votes || old_state != node->state) -+ recalculate_quorum(0); -+ LEAVE(); -+} -+ -+static void message_handler_req_exec_quorum_killnode ( -+ void *message, -+ unsigned int nodeid) -+{ -+ struct req_exec_quorum_killnode *req_exec_quorum_killnode = (struct req_exec_quorum_killnode *)message; -+ -+ if (req_exec_quorum_killnode->nodeid == corosync_api->totem_nodeid_get()) { -+ log_printf(LOG_CRIT, "Killed by node %d: %s\n", nodeid, kill_reason(req_exec_quorum_killnode->reason)); -+ -+ corosync_api->fatal_error(1, __FILE__, __LINE__); -+ exit(1); -+ } -+} -+ -+static void message_handler_req_exec_quorum_reconfigure ( -+ void *message, -+ unsigned int nodeid) -+{ -+ struct req_exec_quorum_reconfigure *req_exec_quorum_reconfigure = (struct req_exec_quorum_reconfigure *)message; -+ struct cluster_node *node; -+ struct list_head *nodelist; -+ -+ log_printf(LOG_LEVEL_DEBUG, "got reconfigure message from cluster node %d\n", nodeid); -+ -+ node = find_node_by_nodeid(req_exec_quorum_reconfigure->nodeid); -+ if (!node) -+ return; -+ -+ switch(req_exec_quorum_reconfigure->param) -+ { -+ case RECONFIG_PARAM_EXPECTED_VOTES: -+ node->expected_votes = req_exec_quorum_reconfigure->value; -+ -+ list_iterate(nodelist, &cluster_members_list) { -+ node = list_entry(nodelist, struct cluster_node, list); -+ if (node->state == NODESTATE_MEMBER && -+ node->expected_votes > req_exec_quorum_reconfigure->value) { -+ node->expected_votes = req_exec_quorum_reconfigure->value; -+ } -+ } -+ recalculate_quorum(1); /* Allow decrease */ -+ break; -+ -+ case RECONFIG_PARAM_NODE_VOTES: -+ node->votes = req_exec_quorum_reconfigure->value; -+ recalculate_quorum(1); /* Allow decrease */ -+ break; -+ -+ case RECONFIG_PARAM_LEAVING: -+ node->state = NODESTATE_LEAVING; -+ break; -+ } -+} -+ -+static int quorum_lib_init_fn (void *conn) -+{ -+ struct quorum_pd *pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); -+ -+ ENTER(); -+ -+ list_init (&pd->list); -+ pd->conn = conn; -+ -+ LEAVE(); -+ return (0); -+} -+ -+/* Message from the library */ -+static void message_handler_req_lib_votequorum_getinfo (void *conn, void *message) -+{ -+ struct req_lib_votequorum_getinfo *req_lib_votequorum_getinfo = (struct req_lib_votequorum_getinfo *)message; -+ struct res_lib_votequorum_getinfo res_lib_votequorum_getinfo; -+ struct cluster_node *node; -+ unsigned int highest_expected = 0; -+ unsigned int total_votes = 0; -+ cs_error_t error = CS_OK; -+ -+ log_printf(LOG_LEVEL_DEBUG, "got getinfo request on %p for node %d\n", conn, req_lib_votequorum_getinfo->nodeid); -+ -+ if (req_lib_votequorum_getinfo->nodeid) { -+ node = find_node_by_nodeid(req_lib_votequorum_getinfo->nodeid); -+ } -+ else { -+ node = us; -+ } -+ -+ if (node) { -+ struct cluster_node *iternode; -+ struct list_head *nodelist; -+ -+ list_iterate(nodelist, &cluster_members_list) { -+ iternode = list_entry(nodelist, struct cluster_node, list); -+ -+ if (node->state == NODESTATE_MEMBER) { -+ highest_expected = -+ max(highest_expected, node->expected_votes); -+ total_votes += node->votes; -+ } -+ } -+ -+ if (quorum_device && quorum_device->state == NODESTATE_MEMBER) { -+ total_votes += quorum_device->votes; -+ } -+ -+ res_lib_votequorum_getinfo.votes = us->votes; -+ res_lib_votequorum_getinfo.expected_votes = us->expected_votes; -+ res_lib_votequorum_getinfo.highest_expected = highest_expected; -+ -+ res_lib_votequorum_getinfo.quorum = quorum; -+ res_lib_votequorum_getinfo.total_votes = total_votes; -+ res_lib_votequorum_getinfo.flags = 0; -+ res_lib_votequorum_getinfo.nodeid = node->node_id; -+ -+ if (us->flags & NODE_FLAGS_HASSTATE) -+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_FLAG_HASSTATE; -+ if (quorum_flags & VOTEQUORUM_FLAG_FEATURE_TWONODE) -+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_FLAG_TWONODE; -+ if (cluster_is_quorate) -+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_FLAG_QUORATE; -+ if (us->flags & NODE_FLAGS_SEESDISALLOWED) -+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_FLAG_DISALLOWED; -+ } -+ else { -+ error = CS_ERR_NOT_EXIST; -+ } -+ -+ res_lib_votequorum_getinfo.header.size = sizeof(res_lib_votequorum_getinfo); -+ res_lib_votequorum_getinfo.header.id = MESSAGE_RES_VOTEQUORUM_GETINFO; -+ res_lib_votequorum_getinfo.header.error = error; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_getinfo, sizeof(res_lib_votequorum_getinfo)); -+ log_printf(LOG_LEVEL_DEBUG, "getinfo response error: %d\n", error); -+} -+ -+/* Message from the library */ -+static void message_handler_req_lib_votequorum_setexpected (void *conn, void *message) -+{ -+ struct req_lib_votequorum_setexpected *req_lib_votequorum_setexpected = (struct req_lib_votequorum_setexpected *)message; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ cs_error_t error = CS_OK; -+ unsigned int newquorum; -+ unsigned int total_votes; -+ -+ ENTER(); -+ -+ /* -+ * If there are disallowed nodes, then we can't allow the user -+ * to bypass them by fiddling with expected votes. -+ */ -+ if (quorum_flags & VOTEQUORUM_FLAG_FEATURE_DISALLOWED && have_disallowed()) { -+ error = CS_ERR_EXIST; -+ goto error_exit; -+ } -+ -+ /* Validate new expected votes */ -+ newquorum = calculate_quorum(1, req_lib_votequorum_setexpected->expected_votes, &total_votes); -+ if (newquorum < total_votes / 2 -+ || newquorum > total_votes) { -+ error = CS_ERR_INVALID_PARAM; -+ goto error_exit; -+ } -+ -+ quorum_exec_send_reconfigure(RECONFIG_PARAM_EXPECTED_VOTES, us->node_id, req_lib_votequorum_setexpected->expected_votes); -+ -+ /* send status */ -+error_exit: -+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); -+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; -+ res_lib_votequorum_status.header.error = error; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); -+ LEAVE(); -+} -+ -+/* Message from the library */ -+static void message_handler_req_lib_votequorum_setvotes (void *conn, void *message) -+{ -+ struct req_lib_votequorum_setvotes *req_lib_votequorum_setvotes = (struct req_lib_votequorum_setvotes *)message; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ struct cluster_node *node; -+ unsigned int newquorum; -+ unsigned int total_votes; -+ unsigned int saved_votes; -+ cs_error_t error = CS_OK; -+ -+ ENTER(); -+ -+ node = find_node_by_nodeid(req_lib_votequorum_setvotes->nodeid); -+ if (!node) { -+ error = CS_ERR_NAME_NOT_FOUND; -+ goto error_exit; -+ } -+ -+ /* Check votes is valid */ -+ saved_votes = node->votes; -+ node->votes = req_lib_votequorum_setvotes->votes; -+ -+ newquorum = calculate_quorum(1, 0, &total_votes); -+ -+ if (newquorum < total_votes / 2 || newquorum > total_votes) { -+ node->votes = saved_votes; -+ error = CS_ERR_INVALID_PARAM; -+ goto error_exit; -+ } -+ -+ if (!req_lib_votequorum_setvotes->nodeid) -+ req_lib_votequorum_setvotes->nodeid = corosync_api->totem_nodeid_get(); -+ -+ quorum_exec_send_reconfigure(RECONFIG_PARAM_NODE_VOTES, req_lib_votequorum_setvotes->nodeid, req_lib_votequorum_setvotes->votes); -+ -+error_exit: -+ /* send status */ -+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); -+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; -+ res_lib_votequorum_status.header.error = error; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); -+ LEAVE(); -+} -+ -+static void message_handler_req_lib_votequorum_leaving (void *conn, void *message) -+{ -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ cs_error_t error = CS_OK; -+ -+ ENTER(); -+ -+ quorum_exec_send_reconfigure(RECONFIG_PARAM_LEAVING, us->node_id, 0); -+ -+ /* send status */ -+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); -+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; -+ res_lib_votequorum_status.header.error = error; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); -+ LEAVE(); -+} -+ -+static void quorum_device_timer_fn(void *arg) -+{ -+ struct timeval now; -+ -+ ENTER(); -+ if (!quorum_device || quorum_device->state == NODESTATE_DEAD) -+ return; -+ gettimeofday(&now, NULL); -+ if (quorum_device->last_hello.tv_sec + quorumdev_poll/1000 < now.tv_sec) { -+ quorum_device->state = NODESTATE_DEAD; -+ log_printf(LOG_INFO, "lost contact with quorum device\n"); -+ recalculate_quorum(0); -+ } -+ else { -+ corosync_api->timer_add_duration((unsigned long long)quorumdev_poll*1000000, quorum_device, -+ quorum_device_timer_fn, &quorum_device_timer); -+ } -+ LEAVE(); -+} -+ -+ -+static void message_handler_req_lib_votequorum_qdisk_register (void *conn, void *message) -+{ -+ struct req_lib_votequorum_qdisk_register *req_lib_votequorum_qdisk_register = (struct req_lib_votequorum_qdisk_register *)message; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ cs_error_t error = CS_OK; -+ -+ ENTER(); -+ -+ if (quorum_device) { -+ error = CS_ERR_EXIST; -+ } -+ else { -+ quorum_device = allocate_node(0); -+ quorum_device->state = NODESTATE_DEAD; -+ quorum_device->votes = req_lib_votequorum_qdisk_register->votes; -+ strcpy(quorum_device_name, req_lib_votequorum_qdisk_register->name); -+ list_add(&quorum_device->list, &cluster_members_list); -+ } -+ -+ /* send status */ -+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); -+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; -+ res_lib_votequorum_status.header.error = error; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); -+ LEAVE(); -+} -+ -+static void message_handler_req_lib_votequorum_qdisk_unregister (void *conn, void *message) -+{ -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ cs_error_t error = CS_OK; -+ -+ ENTER(); -+ -+ if (quorum_device) { -+ struct cluster_node *node = quorum_device; -+ -+ quorum_device = NULL; -+ list_del(&node->list); -+ free(node); -+ recalculate_quorum(0); -+ } -+ else { -+ error = CS_ERR_NOT_EXIST; -+ } -+ -+ /* send status */ -+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); -+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; -+ res_lib_votequorum_status.header.error = error; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); -+ LEAVE(); -+} -+ -+static void message_handler_req_lib_votequorum_qdisk_poll (void *conn, void *message) -+{ -+ struct req_lib_votequorum_qdisk_poll *req_lib_votequorum_qdisk_poll = (struct req_lib_votequorum_qdisk_poll *)message; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ cs_error_t error = CS_OK; -+ -+ ENTER(); -+ -+ if (quorum_device) { -+ if (req_lib_votequorum_qdisk_poll->state) { -+ gettimeofday(&quorum_device->last_hello, NULL); -+ if (quorum_device->state == NODESTATE_DEAD) { -+ quorum_device->state = NODESTATE_MEMBER; -+ recalculate_quorum(0); -+ -+ corosync_api->timer_add_duration((unsigned long long)quorumdev_poll*1000000, quorum_device, -+ quorum_device_timer_fn, &quorum_device_timer); -+ } -+ } -+ else { -+ if (quorum_device->state == NODESTATE_MEMBER) { -+ quorum_device->state = NODESTATE_DEAD; -+ recalculate_quorum(0); -+ corosync_api->timer_delete(quorum_device_timer); -+ } -+ } -+ } -+ else { -+ error = CS_ERR_NOT_EXIST; -+ } -+ -+ /* send status */ -+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); -+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; -+ res_lib_votequorum_status.header.error = error; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); -+ -+ LEAVE(); -+} -+ -+static void message_handler_req_lib_votequorum_qdisk_getinfo (void *conn, void *message) -+{ -+ struct res_lib_votequorum_qdisk_getinfo res_lib_votequorum_qdisk_getinfo; -+ cs_error_t error = CS_OK; -+ -+ ENTER(); -+ -+ if (quorum_device) { -+ log_printf(LOG_LEVEL_DEBUG, "got qdisk_getinfo state %d\n", quorum_device->state); -+ res_lib_votequorum_qdisk_getinfo.votes = quorum_device->votes; -+ if (quorum_device->state == NODESTATE_MEMBER) -+ res_lib_votequorum_qdisk_getinfo.state = 1; -+ else -+ res_lib_votequorum_qdisk_getinfo.state = 0; -+ strcpy(res_lib_votequorum_qdisk_getinfo.name, quorum_device_name); -+ } -+ else { -+ error = CS_ERR_NOT_EXIST; -+ } -+ -+ /* send status */ -+ res_lib_votequorum_qdisk_getinfo.header.size = sizeof(res_lib_votequorum_qdisk_getinfo); -+ res_lib_votequorum_qdisk_getinfo.header.id = MESSAGE_RES_VOTEQUORUM_GETINFO; -+ res_lib_votequorum_qdisk_getinfo.header.error = error; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_qdisk_getinfo, sizeof(res_lib_votequorum_qdisk_getinfo)); -+ -+ LEAVE(); -+} -+ -+static void message_handler_req_lib_votequorum_setstate (void *conn, void *message) -+{ -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ cs_error_t error = CS_OK; -+ -+ ENTER(); -+ -+ us->flags |= NODE_FLAGS_HASSTATE; -+ -+ /* send status */ -+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); -+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; -+ res_lib_votequorum_status.header.error = error; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); -+ -+ LEAVE(); -+} -+ -+static void message_handler_req_lib_votequorum_trackstart (void *conn, void *msg) -+{ -+ struct req_lib_votequorum_trackstart *req_lib_votequorum_trackstart = (struct req_lib_votequorum_trackstart *)msg; -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); -+ -+ ENTER(); -+ /* -+ * If an immediate listing of the current cluster membership -+ * is requested, generate membership list -+ */ -+ if (req_lib_votequorum_trackstart->track_flags & CS_TRACK_CURRENT || -+ req_lib_votequorum_trackstart->track_flags & CS_TRACK_CHANGES) { -+ log_printf(LOG_LEVEL_DEBUG, "sending initial status to %p\n", conn); -+ send_quorum_notification(corosync_api->ipc_conn_partner_get (conn), req_lib_votequorum_trackstart->context); -+ } -+ -+ /* -+ * Record requests for tracking -+ */ -+ if (req_lib_votequorum_trackstart->track_flags & CS_TRACK_CHANGES || -+ req_lib_votequorum_trackstart->track_flags & CS_TRACK_CHANGES_ONLY) { -+ -+ quorum_pd->track_flags = req_lib_votequorum_trackstart->track_flags; -+ quorum_pd->tracking_enabled = 1; -+ quorum_pd->tracking_context = req_lib_votequorum_trackstart->context; -+ -+ list_add (&quorum_pd->list, &trackers_list); -+ } -+ -+ /* Send status */ -+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); -+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; -+ res_lib_votequorum_status.header.error = CS_OK; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); -+ -+ LEAVE(); -+} -+ -+static void message_handler_req_lib_votequorum_trackstop (void *conn, void *msg) -+{ -+ struct res_lib_votequorum_status res_lib_votequorum_status; -+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); -+ int error = CS_OK; -+ -+ ENTER(); -+ -+ if (quorum_pd->tracking_enabled) { -+ error = CS_OK; -+ quorum_pd->tracking_enabled = 0; -+ list_del (&quorum_pd->list); -+ list_init (&quorum_pd->list); -+ } else { -+ error = CS_ERR_NOT_EXIST; -+ } -+ -+ /* send status */ -+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); -+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; -+ res_lib_votequorum_status.header.error = error; -+ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); -+ -+ LEAVE(); -+} -+ -+ -+static char *kill_reason(int reason) -+{ -+ static char msg[1024]; -+ -+ switch (reason) -+ { -+ case VOTEQUORUM_REASON_KILL_REJECTED: -+ return "our membership application was rejected"; -+ -+ case VOTEQUORUM_REASON_KILL_APPLICATION: -+ return "we were killed by an application request"; -+ -+ case VOTEQUORUM_REASON_KILL_REJOIN: -+ return "we rejoined the cluster without a full restart"; -+ -+ default: -+ sprintf(msg, "we got kill message number %d", reason); -+ return msg; -+ } -+} -+ -+static void reread_config(unsigned int object_handle) -+{ -+ unsigned int old_votes; -+ unsigned int old_expected; -+ -+ old_votes = us->votes; -+ old_expected = us->expected_votes; -+ -+ /* -+ * Reload the configuration -+ */ -+ read_quorum_config(object_handle); -+ -+ /* -+ * Check for fundamental changes that we need to propogate -+ */ -+ if (old_votes != us->votes) { -+ quorum_exec_send_reconfigure(RECONFIG_PARAM_NODE_VOTES, us->node_id, us->votes); -+ } -+ if (old_expected != us->expected_votes) { -+ quorum_exec_send_reconfigure(RECONFIG_PARAM_EXPECTED_VOTES, us->node_id, us->expected_votes); -+ } -+} -+ -+static void quorum_key_change_notify(object_change_type_t change_type, -+ unsigned int parent_object_handle, -+ unsigned int object_handle, -+ void *object_name_pt, int object_name_len, -+ void *key_name_pt, int key_len, -+ void *key_value_pt, int key_value_len, -+ void *priv_data_pt) -+{ -+ if (memcmp(object_name_pt, "quorum", object_name_len) == 0) -+ reread_config(object_handle); -+} -+ -+ -+/* Called when the objdb is reloaded */ -+static void votequorum_objdb_reload_notify( -+ objdb_reload_notify_type_t type, int flush, -+ void *priv_data_pt) -+{ -+ /* -+ * A new quorum {} key might exist, cancel the -+ * existing notification at the start of reload, -+ * and start a new one on the new object when -+ * it's all settled. -+ */ -+ -+ if (type == OBJDB_RELOAD_NOTIFY_START) { -+ corosync_api->object_track_stop( -+ quorum_key_change_notify, -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ } -+ -+ if (type == OBJDB_RELOAD_NOTIFY_END || -+ type == OBJDB_RELOAD_NOTIFY_FAILED) { -+ unsigned int find_handle; -+ unsigned int object_handle; -+ -+ corosync_api->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle); -+ if (corosync_api->object_find_next(find_handle, &object_handle) == 0) { -+ add_votequorum_config_notification(object_handle); -+ -+ reread_config(object_handle); -+ } -+ else { -+ log_printf(LOG_LEVEL_ERROR, "votequorum objdb tracking stopped, cannot find quorum{} handle in objdb\n"); -+ } -+ } -+} -+ -+ -+static void add_votequorum_config_notification( -+ unsigned int quorum_object_handle) -+{ -+ -+ corosync_api->object_track_start(quorum_object_handle, -+ 1, -+ quorum_key_change_notify, -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ -+ /* -+ * Reload notify must be on the parent object -+ */ -+ corosync_api->object_track_start(OBJECT_PARENT_HANDLE, -+ 1, -+ NULL, -+ NULL, -+ NULL, -+ votequorum_objdb_reload_notify, -+ NULL); -+} -diff -Naurd corosync-0.92/test/cpgbench.c corosync-trunk/test/cpgbench.c ---- corosync-0.92/test/cpgbench.c 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/test/cpgbench.c 2008-11-06 22:49:07.000000000 +0100 -@@ -50,7 +50,7 @@ - #include - #include - --#include -+#include - #include - - #ifdef COROSYNC_SOLARIS -@@ -121,12 +121,12 @@ - if (flow_control_state == CPG_FLOW_CONTROL_DISABLED) { - retry: - res = cpg_mcast_joined (handle, CPG_TYPE_AGREED, &iov, 1); -- if (res == CPG_ERR_TRY_AGAIN) { -+ if (res == CS_ERR_TRY_AGAIN) { - goto retry; - } - } -- res = cpg_dispatch (handle, CPG_DISPATCH_ALL); -- if (res != CPG_OK) { -+ res = cpg_dispatch (handle, CS_DISPATCH_ALL); -+ if (res != CS_OK) { - printf ("cpg dispatch returned error %d\n", res); - exit (1); - } -@@ -162,13 +162,13 @@ - - signal (SIGALRM, sigalrm_handler); - res = cpg_initialize (&handle, &callbacks); -- if (res != CPG_OK) { -+ if (res != CS_OK) { - printf ("cpg_initialize failed with result %d\n", res); - exit (1); - } - - res = cpg_join (handle, &group_name); -- if (res != CPG_OK) { -+ if (res != CS_OK) { - printf ("cpg_join failed with result %d\n", res); - exit (1); - } -@@ -179,7 +179,7 @@ - } - - res = cpg_finalize (handle); -- if (res != CPG_OK) { -+ if (res != CS_OK) { - printf ("cpg_join failed with result %d\n", res); - exit (1); - } -diff -Naurd corosync-0.92/test/evsbench.c corosync-trunk/test/evsbench.c ---- corosync-0.92/test/evsbench.c 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/test/evsbench.c 2008-11-06 22:49:07.000000000 +0100 -@@ -49,7 +49,7 @@ - #include - #include - --#include -+#include - #include - - #ifdef COROSYNC_SOLARIS -@@ -124,7 +124,7 @@ - int write_size) - { - struct timeval tv1, tv2, tv_elapsed; -- evs_error_t result; -+ cs_error_t result; - int write_count = 0; - - /* -@@ -139,12 +139,12 @@ - if (outstanding < 10) { - result = evs_mcast_joined (handle, EVS_TYPE_AGREED, &iov, 1); - -- if (result != EVS_ERR_TRY_AGAIN) { -+ if (result != CS_ERR_TRY_AGAIN) { - write_count += 1; - outstanding++; - } - } -- result = evs_dispatch (handle, EVS_DISPATCH_ALL); -+ result = evs_dispatch (handle, CS_DISPATCH_ALL); - } while (alarm_notice == 0); - gettimeofday (&tv2, NULL); - timersub (&tv2, &tv1, &tv_elapsed); -@@ -174,7 +174,7 @@ - int main (void) { - int size; - int i; -- evs_error_t result; -+ cs_error_t result; - evs_handle_t handle; - - signal (SIGALRM, sigalrm_handler); -diff -Naurd corosync-0.92/test/evsverify.c corosync-trunk/test/evsverify.c ---- corosync-0.92/test/evsverify.c 2008-09-25 07:31:42.000000000 +0200 -+++ corosync-trunk/test/evsverify.c 2008-11-06 22:49:07.000000000 +0100 -@@ -39,6 +39,7 @@ - #include - #include - #include -+#include - #include - #include "../exec/crypto.h" - -@@ -112,22 +113,22 @@ - - struct msg msg; - --char buffer[200000]; -+unsigned char buffer[200000]; - int main (void) - { - evs_handle_t handle; -- evs_error_t result; -+ cs_error_t result; - unsigned int i = 0, j; - int fd; - unsigned int member_list[32]; - unsigned int local_nodeid; -- int member_list_entries = 32; -+ unsigned int member_list_entries = 32; - struct msg msg; - hash_state sha1_hash; - struct iovec iov[2]; - - result = evs_initialize (&handle, &callbacks); -- if (result != EVS_OK) { -+ if (result != CS_OK) { - printf ("Couldn't initialize EVS service %d\n", result); - exit (0); - } -@@ -169,10 +170,10 @@ - try_again_one: - result = evs_mcast_joined (handle, EVS_TYPE_AGREED, - iov, 2); -- if (result == EVS_ERR_TRY_AGAIN) { -+ if (result == CS_ERR_TRY_AGAIN) { - goto try_again_one; - } -- result = evs_dispatch (handle, EVS_DISPATCH_ALL); -+ result = evs_dispatch (handle, CS_DISPATCH_ALL); - } - - evs_fd_get (handle, &fd); -diff -Naurd corosync-0.92/test/logsysbench.c corosync-trunk/test/logsysbench.c ---- corosync-0.92/test/logsysbench.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/test/logsysbench.c 2008-10-30 23:25:56.000000000 +0100 -@@ -0,0 +1,171 @@ -+/* -+ * Copyright (c) 2008 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 -+ -+LOGSYS_DECLARE_SYSTEM ("logtest_rec", -+ LOG_MODE_OUTPUT_STDERR | LOG_MODE_THREADED, -+ NULL, -+ LOG_DAEMON, -+ "[%6s] %b", -+ 100000); -+ -+LOGSYS_DECLARE_NOSUBSYS(LOG_LEVEL_INFO); -+ -+#define LOGREC_ID_CHECKPOINT_CREATE 2 -+#define LOGREC_ARGS_CHECKPOINT_CREATE 2 -+#define ITERATIONS 1000000 -+ -+struct timeval tv1, tv2, tv_elapsed; -+ -+#define timersub(a, b, result) \ -+do { \ -+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ -+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ -+ if ((result)->tv_usec < 0) { \ -+ --(result)->tv_sec; \ -+ (result)->tv_usec += 1000000; \ -+ } \ -+} while (0) -+ -+void bm_start (void) -+{ -+ gettimeofday (&tv1, NULL); -+} -+void bm_finish (char *operation) -+{ -+ gettimeofday (&tv2, NULL); -+ timersub (&tv2, &tv1, &tv_elapsed); -+ -+ if (strlen (operation) > 22) { -+ printf ("%s\t\t", operation); -+ } else { -+ printf ("%s\t\t\t", operation); -+ } -+ printf ("%9.3f operations/sec\n", -+ ((float)ITERATIONS) / (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0))); -+} -+ -+char buffer[256]; -+int main (void) -+{ -+ int i; -+ char buf[1024]; -+ -+ -+ printf ("heating up cache with logrec functionality\n"); -+ for (i = 0; i < ITERATIONS; i++) { -+ log_rec (LOGREC_ID_CHECKPOINT_CREATE, -+ "recordA", 8, "recordB", 8, LOG_REC_END); -+ } -+ bm_start(); -+ for (i = 0; i < ITERATIONS; i++) { -+ log_rec (LOGREC_ID_CHECKPOINT_CREATE, -+ buffer, 7, LOG_REC_END); -+ } -+ bm_finish ("log_rec 1 arguments:"); -+ bm_start(); -+ for (i = 0; i < ITERATIONS; i++) { -+ log_rec (LOGREC_ID_CHECKPOINT_CREATE, -+ "recordA", 8, LOG_REC_END); -+ } -+ bm_finish ("log_rec 2 arguments:"); -+ bm_start(); -+ for (i = 0; i < 10; i++) { -+ log_rec (LOGREC_ID_CHECKPOINT_CREATE, -+ "recordA", 8, "recordB", 8, LOG_REC_END); -+ } -+ bm_start(); -+ for (i = 0; i < ITERATIONS; i++) { -+ log_rec (LOGREC_ID_CHECKPOINT_CREATE, -+ "recordA", 8, "recordB", 8, "recordC", 8, LOG_REC_END); -+ } -+ bm_finish ("log_rec 3 arguments:"); -+ bm_start(); -+ for (i = 0; i < ITERATIONS; i++) { -+ log_rec (LOGREC_ID_CHECKPOINT_CREATE, -+ "recordA", 8, "recordB", 8, "recordC", 8, "recordD", 8, LOG_REC_END); -+ } -+ bm_finish ("log_rec 4 arguments:"); -+ -+ /* -+ * sprintf testing -+ */ -+ printf ("heating up cache with sprintf functionality\n"); -+ for (i = 0; i < ITERATIONS; i++) { -+ sprintf (buf, "Some logging information %s", "recordA"); -+ } -+ bm_start(); -+ for (i = 0; i < ITERATIONS; i++) { -+ sprintf (buf, "Some logging information %s", "recordA"); -+ } -+ bm_finish ("sprintf 1 argument:"); -+ bm_start(); -+ for (i = 0; i < ITERATIONS; i++) { -+ sprintf (buf, "Some logging information %s %s", "recordA", "recordB"); -+ } -+ bm_finish ("sprintf 2 arguments:"); -+ bm_start(); -+ for (i = 0; i < ITERATIONS; i++) { -+ sprintf (buf, "Some logging information %s %s %s", "recordA", "recordB", "recordC"); -+ } -+ bm_finish ("sprintf 3 arguments:"); -+ bm_start(); -+ for (i = 0; i < ITERATIONS; i++) { -+ sprintf (buf, "Some logging information %s %s %s %s", "recordA", "recordB", "recordC", "recordD"); -+ } -+ bm_finish ("sprintf 4 arguments:"); -+ bm_start(); -+ for (i = 0; i < ITERATIONS; i++) { -+ sprintf (buf, "Some logging information %s %s %s %d", "recordA", "recordB", "recordC", i); -+ } -+ bm_finish ("sprintf 4 arguments (1 int):"); -+ -+ logsys_log_rec_store ("fdata"); -+/* TODO -+ currently fails under some circumstances -+ -+ bm_start(); -+ for (i = 0; i < ITERATIONS; i++) { -+ log_printf (LOG_LEVEL_NOTICE, "test %d", i); -+ } -+ bm_finish("log_printf"); -+*/ -+ -+ return (0); -+} -diff -Naurd corosync-0.92/test/logsysrec.c corosync-trunk/test/logsysrec.c ---- corosync-0.92/test/logsysrec.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/test/logsysrec.c 2008-10-30 23:25:56.000000000 +0100 -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (c) 2008 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 -+ -+LOGSYS_DECLARE_SYSTEM ("logtest_rec", -+ LOG_MODE_OUTPUT_STDERR | LOG_MODE_THREADED, -+ NULL, -+ LOG_DAEMON, -+ "[%6s] %b", -+ 100000); -+ -+LOGSYS_DECLARE_NOSUBSYS(LOG_LEVEL_INFO); -+ -+#define LOGREC_ID_CHECKPOINT_CREATE 2 -+#define LOGREC_ARGS_CHECKPOINT_CREATE 2 -+ -+int main(int argc, char **argv) -+{ -+ int i; -+ -+ for (i = 0; i < 10; i++) { -+ log_printf (LOG_LEVEL_NOTICE, "This is a test of %s\n", "stringparse"); -+ -+ log_rec (LOGREC_ID_CHECKPOINT_CREATE, "record1", 8, "record22", 9, "record333", 10, "record444", 11, LOG_REC_END); -+ } -+ logsys_log_rec_store ("fdata"); -+ -+ return 0; -+} -diff -Naurd corosync-0.92/test/logsys_s.c corosync-trunk/test/logsys_s.c ---- corosync-0.92/test/logsys_s.c 2008-05-12 15:48:06.000000000 +0200 -+++ corosync-trunk/test/logsys_s.c 2008-10-30 23:25:56.000000000 +0100 -@@ -38,7 +38,9 @@ - LOGSYS_DECLARE_SYSTEM ("logsystestsubsystems", - LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED, - NULL, -- LOG_DAEMON); -+ LOG_DAEMON, -+ "[%8s] %b", -+ 100000); - - extern void logsys_s1_print (void); - extern void logsys_s2_print (void); -diff -Naurd corosync-0.92/test/logsys_t1.c corosync-trunk/test/logsys_t1.c ---- corosync-0.92/test/logsys_t1.c 2008-06-20 08:04:03.000000000 +0200 -+++ corosync-trunk/test/logsys_t1.c 2008-10-30 23:25:56.000000000 +0100 -@@ -38,7 +38,9 @@ - LOGSYS_DECLARE_SYSTEM ("logsystestNOsubsystems", - LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED, - NULL, -- LOG_DAEMON); -+ LOG_DAEMON, -+ "%6s %b", -+ 100000); - - LOGSYS_DECLARE_NOSUBSYS(LOG_LEVEL_DEBUG); - -diff -Naurd corosync-0.92/test/logsys_t2.c corosync-trunk/test/logsys_t2.c ---- corosync-0.92/test/logsys_t2.c 2008-06-20 08:04:03.000000000 +0200 -+++ corosync-trunk/test/logsys_t2.c 2008-10-30 23:25:56.000000000 +0100 -@@ -36,9 +36,11 @@ - #include "../exec/logsys.h" - - LOGSYS_DECLARE_SYSTEM ("logtest_t2", -- LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED | LOG_MODE_BUFFER_BEFORE_CONFIG, -+ LOG_MODE_OUTPUT_STDERR | LOG_MODE_THREADED, - NULL, -- LOG_DAEMON); -+ LOG_DAEMON, -+ "[%6s] %b" -+ 100000); - - LOGSYS_DECLARE_NOSUBSYS(LOG_LEVEL_INFO); - -@@ -48,7 +50,7 @@ - /* - * fork could occur here and the file to output to could be set - */ -- logsys_config_mode_set (LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED | LOG_MODE_FLUSH_AFTER_CONFIG); -+ logsys_config_mode_set (LOG_MODE_OUTPUT_STDERR | LOG_MODE_THREADED); - - log_printf(LOG_NOTICE, "Hello, world!\n"); - log_printf(LOG_DEBUG, "If you see this, the logger's busted\n"); -diff -Naurd corosync-0.92/test/Makefile corosync-trunk/test/Makefile ---- corosync-0.92/test/Makefile 2008-09-25 07:31:42.000000000 +0200 -+++ corosync-trunk/test/Makefile 2009-01-26 11:46:08.000000000 +0100 -@@ -42,9 +42,10 @@ - override LDFLAGS += -lnsl -lsocket -lrt - endif - --LIBRARIES= ../lib/libevs.a ../lib/libcpg.a ../lib/libcfg.a ../lib/libconfdb.a -+LIBRARIES= ../lib/libevs.a ../lib/libcpg.a ../lib/libcfg.a ../lib/libconfdb.a ../lib/libquorum.a ../lib/libvotequorum.a - LIBS = $(LIBRARIES) --BINARIES= testevs evsbench evsverify testcpg testcpg2 cpgbench testconfdb -+BINARIES= testevs evsbench evsverify testcpg testcpg2 cpgbench testconfdb logsysbench logsysrec testquorum \ -+ testvotequorum1 testvotequorum2 - - override CFLAGS += -I../include - override LDFLAGS += -L../lib -@@ -75,12 +76,33 @@ - testcpg2: testcpg2.o $(LIBRARIES) - $(CC) $(LDFLAGS) -o testcpg2 testcpg2.o $(LIBS) - -+testquorum: testquorum.o $(LIBRARIES) -+ $(CC) $(LDFLAGS) -o testquorum testquorum.o $(LIBS) -+ - cpgbench: cpgbench.o $(LIBRARIES) - $(CC) $(LDFLAGS) -o cpgbench cpgbench.o $(LIBS) - - testconfdb: testconfdb.o $(LIBRARIES) - $(CC) $(LDFLAGS) -o testconfdb testconfdb.o $(LIBS) -rdynamic - -+logsysbench: logsysbench.o ../exec/liblogsys.a -+ $(CC) -o logsysbench logsysbench.o ../exec/liblogsys.a $(LDFLAGS) -+ -+logsysrec: logsysrec.o ../exec/liblogsys.a -+ $(CC) -o logsysrec logsysrec.o ../exec/liblogsys.a $(LDFLAGS) -+ -+testquorum1: testquorum1.o $(LIBRARIES) -+ $(CC) $(LDFLAGS) -o testquorum1 testquorum1.o $(LIBS) -+ -+testquorum2: testquorum2.o $(LIBRARIES) -+ $(CC) $(LDFLAGS) -o testquorum2 testquorum2.o $(LIBS) -+ -+testvotequorum1: testvotequorum1.o $(LIBRARIES) -+ $(CC) $(LDFLAGS) -o testvotequorum1 testvotequorum1.o $(LIBS) -+ -+testvotequorum2: testvotequorum2.o $(LIBRARIES) -+ $(CC) $(LDFLAGS) -o testvotequorum2 testvotequorum2.o $(LIBS) -+ - logsys_s: logsys_s.o logsys_s1.o logsys_s2.o ../exec/liblogsys.a - $(CC) -o logsys_s logsys_s.o logsys_s1.o logsys_s2.o ../exec/liblogsys.a $(LDFLAGS) - -diff -Naurd corosync-0.92/test/sa_error.c corosync-trunk/test/sa_error.c ---- corosync-0.92/test/sa_error.c 2006-01-24 08:19:11.000000000 +0100 -+++ corosync-trunk/test/sa_error.c 2008-11-06 22:49:07.000000000 +0100 -@@ -6,39 +6,39 @@ - - const char *sa_error_list[] = { - "OUT_OF_RANGE", -- "SA_AIS_OK", -- "SA_AIS_ERR_LIBRARY", -- "SA_AIS_ERR_VERSION", -- "SA_AIS_ERR_INIT", -- "SA_AIS_ERR_TIMEOUT", -- "SA_AIS_ERR_TRY_AGAIN", -- "SA_AIS_ERR_INVALID_PARAM", -- "SA_AIS_ERR_NO_MEMORY", -- "SA_AIS_ERR_BAD_HANDLE", -- "SA_AIS_ERR_BUSY", -- "SA_AIS_ERR_ACCESS", -- "SA_AIS_ERR_NOT_EXIST", -- "SA_AIS_ERR_NAME_TOO_LONG", -- "SA_AIS_ERR_EXIST", -- "SA_AIS_ERR_NO_SPACE", -- "SA_AIS_ERR_INTERRUPT", -- "SA_AIS_ERR_NAME_NOT_FOUND", -- "SA_AIS_ERR_NO_RESOURCES", -- "SA_AIS_ERR_NOT_SUPPORTED", -- "SA_AIS_ERR_BAD_OPERATION", -- "SA_AIS_ERR_FAILED_OPERATION", -- "SA_AIS_ERR_MESSAGE_ERROR", -- "SA_AIS_ERR_QUEUE_FULL", -- "SA_AIS_ERR_QUEUE_NOT_AVAILABLE", -- "SA_AIS_ERR_BAD_CHECKPOINT", -- "SA_AIS_ERR_BAD_FLAGS", -- "SA_AIS_ERR_NO_SECTIONS", -+ "CS_OK", -+ "CS_ERR_LIBRARY", -+ "CS_ERR_VERSION", -+ "CS_ERR_INIT", -+ "CS_ERR_TIMEOUT", -+ "CS_ERR_TRY_AGAIN", -+ "CS_ERR_INVALID_PARAM", -+ "CS_ERR_NO_MEMORY", -+ "CS_ERR_BAD_HANDLE", -+ "CS_ERR_BUSY", -+ "CS_ERR_ACCESS", -+ "CS_ERR_NOT_EXIST", -+ "CS_ERR_NAME_TOO_LONG", -+ "CS_ERR_EXIST", -+ "CS_ERR_NO_SPACE", -+ "CS_ERR_INTERRUPT", -+ "CS_ERR_NAME_NOT_FOUND", -+ "CS_ERR_NO_RESOURCES", -+ "CS_ERR_NOT_SUPPORTED", -+ "CS_ERR_BAD_OPERATION", -+ "CS_ERR_FAILED_OPERATION", -+ "CS_ERR_MESSAGE_ERROR", -+ "CS_ERR_QUEUE_FULL", -+ "CS_ERR_QUEUE_NOT_AVAILABLE", -+ "CS_ERR_BAD_CHECKPOINT", -+ "CS_ERR_BAD_FLAGS", -+ "CS_ERR_NO_SECTIONS", - }; - --int get_sa_error(SaAisErrorT error, char *str, int len) -+int get_sa_error(cs_error_t error, char *str, int len) - { -- if (error < SA_AIS_OK || -- error > SA_AIS_ERR_NO_SECTIONS || -+ if (error < CS_OK || -+ error > CS_ERR_NO_SECTIONS || - len < strlen(sa_error_list[error])) { - errno = EINVAL; - return -1; -@@ -47,11 +47,11 @@ - return 0; - } - --char *get_sa_error_b (SaAisErrorT error) { -+char *get_sa_error_b (cs_error_t error) { - return ((char *)sa_error_list[error]); - } - --char *get_test_output (SaAisErrorT result, SaAisErrorT expected) { -+char *get_test_output (cs_error_t result, cs_error_t expected) { - static char test_result[256]; - - if (result == expected) { -diff -Naurd corosync-0.92/test/sa_error.h corosync-trunk/test/sa_error.h ---- corosync-0.92/test/sa_error.h 2006-01-24 08:19:11.000000000 +0100 -+++ corosync-trunk/test/sa_error.h 2008-11-06 22:49:07.000000000 +0100 -@@ -1,5 +1,5 @@ --extern int get_sa_error(SaAisErrorT error, char *str, int len); -+extern int get_sa_error(cs_error_t error, char *str, int len); - --extern char *get_sa_error_b (SaAisErrorT error); -+extern char *get_sa_error_b (cs_error_t error); - --extern char *get_test_output (SaAisErrorT result, SaAisErrorT expected); -+extern char *get_test_output (cs_error_t result, cs_error_t expected); -diff -Naurd corosync-0.92/test/testconfdb.c corosync-trunk/test/testconfdb.c ---- corosync-0.92/test/testconfdb.c 2008-09-03 09:58:08.000000000 +0200 -+++ corosync-trunk/test/testconfdb.c 2008-11-06 22:49:07.000000000 +0100 -@@ -41,7 +41,7 @@ - #include - #include - --#include -+#include - #include - - #define INCDEC_VALUE 45 -@@ -68,13 +68,13 @@ - - /* Show the keys */ - res = confdb_key_iter_start(handle, parent_object_handle); -- if (res != SA_AIS_OK) { -+ if (res != CS_OK) { - printf( "error resetting key iterator for object %d: %d\n", parent_object_handle, res); - return; - } - - while ( (res = confdb_key_iter(handle, parent_object_handle, key_name, &key_name_len, -- key_value, &key_value_len)) == SA_AIS_OK) { -+ key_value, &key_value_len)) == CS_OK) { - key_name[key_name_len] = '\0'; - key_value[key_value_len] = '\0'; - for (i=0; i - #include - -+#include - #include - - void deliver( -@@ -70,17 +71,17 @@ - int fd; - - printf ("All of the nodeids should match on a single node configuration\n for the test to pass."); -- assert(CPG_OK==cpg_initialize(&handle, &cb)); -- assert(CPG_OK==cpg_local_get(handle,&nodeid)); -+ assert(CS_OK==cpg_initialize(&handle, &cb)); -+ assert(CS_OK==cpg_local_get(handle,&nodeid)); - printf("local_get: %x\n", nodeid); -- assert(CPG_OK==cpg_join(handle, &group)); -+ assert(CS_OK==cpg_join(handle, &group)); - struct iovec msg={"hello", 5}; -- assert(CPG_OK==cpg_mcast_joined(handle,CPG_TYPE_AGREED,&msg,1)); -+ assert(CS_OK==cpg_mcast_joined(handle,CPG_TYPE_AGREED,&msg,1)); - cpg_fd_get (handle, &fd); - pfd.fd = fd; - pfd.events = POLLIN; - - poll (&pfd, 1, 1000); -- cpg_dispatch(handle, CPG_DISPATCH_ALL); -+ cpg_dispatch(handle, CS_DISPATCH_ALL); - return (0); - } -diff -Naurd corosync-0.92/test/testcpg.c corosync-trunk/test/testcpg.c ---- corosync-0.92/test/testcpg.c 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/test/testcpg.c 2008-11-06 22:49:07.000000000 +0100 -@@ -45,7 +45,7 @@ - #include - #include - --#include -+#include - #include - - static int quit = 0; -@@ -206,25 +206,25 @@ - } - - result = cpg_initialize (&handle, &callbacks); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not initialize Cluster Process Group API instance error %d\n", result); - exit (1); - } - result = cpg_local_get (handle, &nodeid); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not get local node id\n"); - exit (1); - } - - printf ("Local node id is %x\n", nodeid); - result = cpg_join(handle, &group_name); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not join process group, error %d\n", result); - exit (1); - } - - cpg_groups_get(handle, &num_groups); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not get list of groups, error %d\n", result); - exit (1); - } -@@ -255,7 +255,7 @@ - } - } - if (FD_ISSET (select_fd, &read_fds)) { -- if (cpg_dispatch (handle, CPG_DISPATCH_ALL) != SA_AIS_OK) -+ if (cpg_dispatch (handle, CS_DISPATCH_ALL) != CS_OK) - exit(1); - } - } while (result && !quit); -diff -Naurd corosync-0.92/test/testevs.c corosync-trunk/test/testevs.c ---- corosync-0.92/test/testevs.c 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/test/testevs.c 2008-11-06 22:49:07.000000000 +0100 -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - #include - - char *delivery_string; -@@ -99,7 +100,7 @@ - int main (void) - { - evs_handle_t handle; -- evs_error_t result; -+ cs_error_t result; - int i = 0; - int fd; - unsigned int member_list[32]; -@@ -107,7 +108,7 @@ - unsigned int member_list_entries = 32; - - result = evs_initialize (&handle, &callbacks); -- if (result != EVS_OK) { -+ if (result != CS_OK) { - printf ("Couldn't initialize EVS service %d\n", result); - exit (0); - } -@@ -142,15 +143,15 @@ - try_again_one: - result = evs_mcast_joined (handle, EVS_TYPE_AGREED, - &iov, 1); -- if (result == EVS_ERR_TRY_AGAIN) { -+ if (result == CS_ERR_TRY_AGAIN) { - //printf ("try again\n"); - goto try_again_one; - } -- result = evs_dispatch (handle, EVS_DISPATCH_ALL); -+ result = evs_dispatch (handle, CS_DISPATCH_ALL); - } - - do { -- result = evs_dispatch (handle, EVS_DISPATCH_ALL); -+ result = evs_dispatch (handle, CS_DISPATCH_ALL); - } while (deliveries < 20); - /* - * Demonstrate evs_mcast_joined -@@ -161,17 +162,17 @@ - try_again_two: - result = evs_mcast_groups (handle, EVS_TYPE_AGREED, - &groups[1], 1, &iov, 1); -- if (result == EVS_ERR_TRY_AGAIN) { -+ if (result == CS_ERR_TRY_AGAIN) { - goto try_again_two; - } - -- result = evs_dispatch (handle, EVS_DISPATCH_ALL); -+ result = evs_dispatch (handle, CS_DISPATCH_ALL); - } - /* - * Flush any pending callbacks - */ - do { -- result = evs_dispatch (handle, EVS_DISPATCH_ALL); -+ result = evs_dispatch (handle, CS_DISPATCH_ALL); - } while (deliveries < 500); - - evs_fd_get (handle, &fd); -diff -Naurd corosync-0.92/test/testquorum.c corosync-trunk/test/testquorum.c ---- corosync-0.92/test/testquorum.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/test/testquorum.c 2008-11-06 22:49:07.000000000 +0100 -@@ -0,0 +1,58 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static quorum_handle_t handle; -+ -+static void quorum_notification_fn( -+ quorum_handle_t handle, -+ uint32_t quorate, -+ uint64_t ring_id, -+ uint32_t view_list_entries, -+ uint32_t *view_list) -+{ -+ int i; -+ -+ printf("quorum notification called \n"); -+ printf(" quorate = %d\n", quorate); -+ printf(" ring id = %lld\n", ring_id); -+ printf(" num nodes = %d ", view_list_entries); -+ -+ for (i=0; i -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static votequorum_handle_t handle; -+ -+static char *node_state(int state) -+{ -+ switch (state) { -+ case NODESTATE_JOINING: -+ return "Joining"; -+ break; -+ case NODESTATE_MEMBER: -+ return "Member"; -+ break; -+ case NODESTATE_DEAD: -+ return "Dead"; -+ break; -+ case NODESTATE_LEAVING: -+ return "Leaving"; -+ break; -+ case NODESTATE_DISALLOWED: -+ return "Disallowed"; -+ break; -+ default: -+ return "UNKNOWN"; -+ break; -+ } -+} -+ -+static void votequorum_notification_fn( -+ votequorum_handle_t handle, -+ uint64_t context, -+ uint32_t quorate, -+ uint32_t node_list_entries, -+ votequorum_node_t node_list[] -+ ) -+{ -+ int i; -+ -+ printf("votequorum notification called \n"); -+ printf(" quorate = %d\n", quorate); -+ printf(" number of nodes = %d\n", node_list_entries); -+ -+ for (i = 0; i< node_list_entries; i++) { -+ printf(" %d: %s\n", node_list[i].nodeid, node_state(node_list[i].state)); -+ } -+ printf("\n"); -+} -+ -+ -+int main(int argc, char *argv[]) -+{ -+ struct votequorum_info info; -+ votequorum_callbacks_t callbacks; -+ int err; -+ -+ if (argc > 1 && strcmp(argv[1], "-h")==0) { -+ fprintf(stderr, "usage: %s [new-expected] [new-votes]\n", argv[0]); -+ return 0; -+ } -+ -+ callbacks.votequorum_notify_fn = votequorum_notification_fn; -+ if ( (err=votequorum_initialize(&handle, &callbacks)) != CS_OK) -+ fprintf(stderr, "votequorum_initialize FAILED: %d\n", err); -+ -+ if ( (err = votequorum_trackstart(handle, handle, CS_TRACK_CHANGES)) != CS_OK) -+ fprintf(stderr, "votequorum_trackstart FAILED: %d\n", err); -+ -+ if ( (err=votequorum_getinfo(handle, 0, &info)) != CS_OK) -+ fprintf(stderr, "votequorum_getinfo FAILED: %d\n", err); -+ else { -+ printf("node votes %d\n", info.node_votes); -+ printf("expected votes %d\n", info.node_expected_votes); -+ printf("highest expected %d\n", info.highest_expected); -+ printf("total votes %d\n", info.total_votes); -+ printf("quorum %d\n", info.quorum); -+ printf("flags "); -+ if (info.flags & VOTEQUORUM_INFO_FLAG_HASSTATE) printf("HasState "); -+ if (info.flags & VOTEQUORUM_INFO_FLAG_DISALLOWED) printf("Disallowed "); -+ if (info.flags & VOTEQUORUM_INFO_FLAG_TWONODE) printf("2Node "); -+ if (info.flags & VOTEQUORUM_INFO_FLAG_QUORATE) printf("Quorate "); -+ printf("\n"); -+ } -+ -+ if (argc >= 2 && atoi(argv[1])) { -+ if ( (err=votequorum_setexpected(handle, atoi(argv[1]))) != CS_OK) -+ fprintf(stderr, "set expected votes FAILED: %d\n", err); -+ } -+ if (argc >= 3 && atoi(argv[2])) { -+ if ( (err=votequorum_setvotes(handle, 0, atoi(argv[2]))) != CS_OK) -+ fprintf(stderr, "set votes FAILED: %d\n", err); -+ } -+ -+ if (argc >= 2) { -+ if ( (err=votequorum_getinfo(handle, 0, &info)) != CS_OK) -+ fprintf(stderr, "votequorum_getinfo2 FAILED: %d\n", err); -+ else { -+ printf("-------------------\n"); -+ printf("node votes %d\n", info.node_votes); -+ printf("expected votes %d\n", info.node_expected_votes); -+ printf("highest expected %d\n", info.highest_expected); -+ printf("total votes %d\n", info.total_votes); -+ printf("votequorum %d\n", info.quorum); -+ printf("flags "); -+ if (info.flags & VOTEQUORUM_INFO_FLAG_HASSTATE) printf("HasState "); -+ if (info.flags & VOTEQUORUM_INFO_FLAG_DISALLOWED) printf("Disallowed "); -+ if (info.flags & VOTEQUORUM_INFO_FLAG_TWONODE) printf("2Node "); -+ if (info.flags & VOTEQUORUM_INFO_FLAG_QUORATE) printf("Quorate "); -+ printf("\n"); -+ } -+ } -+ -+ printf("Waiting for votequorum events, press ^C to finish\n"); -+ printf("-------------------\n"); -+ -+ while (1) -+ votequorum_dispatch(handle, CS_DISPATCH_ALL); -+ -+ return 0; -+} -diff -Naurd corosync-0.92/test/testvotequorum2.c corosync-trunk/test/testvotequorum2.c ---- corosync-0.92/test/testvotequorum2.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/test/testvotequorum2.c 2009-01-26 11:46:08.000000000 +0100 -@@ -0,0 +1,96 @@ -+/* -+ * Copyright (c) 2009 Red Hat, Inc. -+ * -+ * All rights reserved. -+ * -+ * Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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 -+ -+static votequorum_handle_t handle; -+ -+ -+static void print_info(int ok_to_fail) -+{ -+ struct votequorum_qdisk_info qinfo; -+ int err; -+ -+ if ( (err=votequorum_qdisk_getinfo(handle, &qinfo)) != CS_OK) -+ fprintf(stderr, "votequorum_qdisk_getinfo error %d: %s\n", err, ok_to_fail?"OK":"FAILED"); -+ else { -+ printf("qdisk votes %d\n", qinfo.votes); -+ printf("state %d\n", qinfo.state); -+ printf("name %s\n", qinfo.name); -+ printf("\n"); -+ } -+} -+ -+int main(int argc, char *argv[]) -+{ -+ int pollcount=0, polltime=1; -+ int err; -+ -+ if ( (err=votequorum_initialize(&handle, NULL)) != CS_OK) { -+ fprintf(stderr, "votequorum_initialize FAILED: %d\n", err); -+ return -1; -+ } -+ -+ print_info(1); -+ -+ if (argc >= 2 && atoi(argv[1])) { -+ pollcount = atoi(argv[1]); -+ } -+ if (argc >= 3 && atoi(argv[2])) { -+ polltime = atoi(argv[2]); -+ } -+ -+ if (argc >= 2) { -+ if ( (err=votequorum_qdisk_register(handle, "QDISK", 4)) != CS_OK) -+ fprintf(stderr, "qdisk_register FAILED: %d\n", err); -+ -+ while (pollcount--) { -+ print_info(0); -+ if ((err=votequorum_qdisk_poll(handle, 1)) != CS_OK) -+ fprintf(stderr, "qdisk poll FAILED: %d\n", err); -+ print_info(0); -+ sleep(polltime); -+ } -+ if ((err= votequorum_qdisk_unregister(handle)) != CS_OK) -+ fprintf(stderr, "qdisk unregister FAILED: %d\n", err); -+ } -+ print_info(1); -+ -+ return 0; -+} -diff -Naurd corosync-0.92/tools/corosync-cfgtool.c corosync-trunk/tools/corosync-cfgtool.c ---- corosync-0.92/tools/corosync-cfgtool.c 2008-08-14 18:54:46.000000000 +0200 -+++ corosync-trunk/tools/corosync-cfgtool.c 2009-01-19 09:31:21.000000000 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2006-2007 Red Hat, Inc. -+ * Copyright (c) 2006-2009 Red Hat, Inc. - * - * All rights reserved. - * -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -45,12 +46,13 @@ - #include - #include - --#include -+#include -+#include - #include - - static void ringstatusget_do (void) - { -- SaAisErrorT result; -+ cs_error_t result; - corosync_cfg_handle_t handle; - unsigned int interface_count; - char **interface_names; -@@ -59,84 +61,199 @@ - - printf ("Printing ring status.\n"); - result = corosync_cfg_initialize (&handle, NULL); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not initialize corosync configuration API error %d\n", result); - exit (1); - } - -- corosync_cfg_ring_status_get (handle, -- &interface_names, -- &interface_status, -- &interface_count); -- -- for (i = 0; i < interface_count; i++) { -- printf ("RING ID %d\n", i); -- printf ("\tid\t= %s\n", interface_names[i]); -- printf ("\tstatus\t= %s\n", interface_status[i]); -+ result = corosync_cfg_ring_status_get (handle, -+ &interface_names, -+ &interface_status, -+ &interface_count); -+ if (result != CS_OK) { -+ printf ("Could not get the ring status, the error is: %d\n", result); -+ } else { -+ for (i = 0; i < interface_count; i++) { -+ printf ("RING ID %d\n", i); -+ printf ("\tid\t= %s\n", interface_names[i]); -+ printf ("\tstatus\t= %s\n", interface_status[i]); -+ } - } -- -- corosync_cfg_finalize (handle); -+ (void)corosync_cfg_finalize (handle); - } - - static void ringreenable_do (void) - { -- SaAisErrorT result; -+ cs_error_t result; - corosync_cfg_handle_t handle; - - printf ("Re-enabling all failed rings.\n"); - result = corosync_cfg_initialize (&handle, NULL); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not initialize corosync configuration API error %d\n", result); - exit (1); - } - - result = corosync_cfg_ring_reenable (handle); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not reenable ring error %d\n", result); - } - -- corosync_cfg_finalize (handle); -+ (void)corosync_cfg_finalize (handle); - } - - void service_load_do (char *service, unsigned int version) - { -- SaAisErrorT result; -+ cs_error_t result; - corosync_cfg_handle_t handle; - - printf ("Loading service '%s' version '%d'\n", service, version); - result = corosync_cfg_initialize (&handle, NULL); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not initialize corosync configuration API error %d\n", result); - exit (1); - } - result = corosync_cfg_service_load (handle, service, version); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not load service (error = %d)\n", result); - } -- corosync_cfg_finalize (handle); -+ (void)corosync_cfg_finalize (handle); - } - - void service_unload_do (char *service, unsigned int version) - { -- SaAisErrorT result; -+ cs_error_t result; - corosync_cfg_handle_t handle; - - printf ("Unloading service '%s' version '%d'\n", service, version); - result = corosync_cfg_initialize (&handle, NULL); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not initialize corosync configuration API error %d\n", result); - exit (1); - } - result = corosync_cfg_service_unload (handle, service, version); -- if (result != SA_AIS_OK) { -+ if (result != CS_OK) { - printf ("Could not unload service (error = %d)\n", result); - } -- corosync_cfg_finalize (handle); -+ (void)corosync_cfg_finalize (handle); -+} -+ -+void shutdown_callback (corosync_cfg_handle_t cfg_handle, corosync_cfg_shutdown_flags_t flags) -+{ -+ printf("shutdown callback called, flags = %d\n",flags); -+ -+ (void)corosync_cfg_replyto_shutdown (cfg_handle, COROSYNC_CFG_SHUTDOWN_FLAG_YES); -+} -+ -+void *shutdown_dispatch_thread(void *arg) -+{ -+ int res = CS_OK; -+ corosync_cfg_handle_t *handle = arg; -+ -+ while (res == CS_OK) { -+ res = corosync_cfg_dispatch(*handle, CS_DISPATCH_ALL); -+ if (res != CS_OK) -+ printf ("Could not dispatch cfg messages: %d\n", res); -+ } -+ return NULL; -+} -+ -+void shutdown_do() -+{ -+ cs_error_t result; -+ corosync_cfg_handle_t handle; -+ corosync_cfg_callbacks_t callbacks; -+ corosync_cfg_state_notification_t notification_buffer; -+ pthread_t dispatch_thread; -+ -+ printf ("Shutting down corosync\n"); -+ callbacks.corosync_cfg_shutdown_callback = shutdown_callback; -+ -+ result = corosync_cfg_initialize (&handle, &callbacks); -+ if (result != CS_OK) { -+ printf ("Could not initialize corosync configuration API error %d\n", result); -+ exit (1); -+ } -+ -+ pthread_create(&dispatch_thread, NULL, shutdown_dispatch_thread, &handle); -+ -+ result = corosync_cfg_state_track (handle, -+ 0, -+ ¬ification_buffer); -+ if (result != CS_OK) { -+ printf ("Could not start corosync cfg tracking error %d\n", result); -+ exit (1); -+ } -+ -+ result = corosync_cfg_try_shutdown (handle, COROSYNC_CFG_SHUTDOWN_FLAG_REQUEST); -+ if (result != CS_OK) { -+ printf ("Could not shutdown (error = %d)\n", result); -+ } -+ -+ (void)corosync_cfg_finalize (handle); - } - -+void showaddrs_do(int nodeid) -+{ -+ cs_error_t result; -+ corosync_cfg_handle_t handle; -+ corosync_cfg_callbacks_t callbacks; -+ int numaddrs; -+ int i; -+ corosync_cfg_node_address_t addrs[INTERFACE_MAX]; -+ -+ -+ result = corosync_cfg_initialize (&handle, &callbacks); -+ if (result != CS_OK) { -+ printf ("Could not initialize corosync configuration API error %d\n", result); -+ exit (1); -+ } -+ -+ if (!corosync_cfg_get_node_addrs(handle, nodeid, INTERFACE_MAX, &numaddrs, addrs) == CS_OK) { -+ for (i=0; iss_family == AF_INET6) -+ saddr = &sin6->sin6_addr; -+ else -+ saddr = &sin->sin_addr; -+ -+ inet_ntop(ss->ss_family, saddr, buf, sizeof(buf)); -+ printf("%s", buf); -+ } -+ printf("\n"); -+ } -+ -+ -+ (void)corosync_cfg_finalize (handle); -+} -+ -+void killnode_do(unsigned int nodeid) -+{ -+ cs_error_t result; -+ corosync_cfg_handle_t handle; -+ -+ printf ("Killing node %d\n", nodeid); -+ result = corosync_cfg_initialize (&handle, NULL); -+ if (result != CS_OK) { -+ printf ("Could not initialize corosync configuration API error %d\n", result); -+ exit (1); -+ } -+ result = corosync_cfg_kill_node (handle, nodeid, "Killed by corosync-cfgtool"); -+ if (result != CS_OK) { -+ printf ("Could not kill node (error = %d)\n", result); -+ } -+ (void)corosync_cfg_finalize (handle); -+} -+ -+ - void usage_do (void) - { -- printf ("corosync-cfgtool [-s] [-r] [-l] [-u] [service_name] [-v] [version]\n\n"); -+ printf ("corosync-cfgtool [-s] [-r] [-l] [-u] [service_name] [-v] [version] [-k] [nodeid] [-a] [nodeid]\n\n"); - printf ("A tool for displaying and configuring active parameters within corosync.\n"); - printf ("options:\n"); - printf ("\t-s\tDisplays the status of the current rings on this node.\n"); -@@ -144,15 +261,19 @@ - printf ("\t\tre-enable redundant ring operation.\n"); - printf ("\t-l\tLoad a service identified by name.\n"); - printf ("\t-u\tUnload a service identified by name.\n"); -+ printf ("\t-a\tDisplay the IP address(es) of a node\n"); -+ printf ("\t-k\tKill a node identified by node id.\n"); -+ printf ("\t-h\tShutdown corosync cleanly on this node.\n"); - } - - int main (int argc, char *argv[]) { -- const char *options = "srl:u:v:"; -+ const char *options = "srl:u:v:k:a:h"; - int opt; - int service_load = 0; -+ unsigned int nodeid; - int service_unload = 0; -- char *service; -- unsigned int version; -+ char *service = NULL; -+ unsigned int version = 0; - - if (argc == 1) { - usage_do (); -@@ -173,17 +294,28 @@ - service_unload = 1; - service = strdup (optarg); - break; -+ case 'k': -+ nodeid = atoi (optarg); -+ killnode_do(nodeid); -+ break; -+ case 'h': -+ shutdown_do(); -+ break; -+ case 'a': -+ showaddrs_do( atoi(optarg) ); -+ break; - case 'v': - version = atoi (optarg); -+ break; - } - } - - if (service_load) { - service_load_do (service, version); -- } else -+ } else - if (service_unload) { - service_unload_do (service, version); - } -- -+ - return (0); - } -diff -Naurd corosync-0.92/tools/corosync-fplay.c corosync-trunk/tools/corosync-fplay.c ---- corosync-0.92/tools/corosync-fplay.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/tools/corosync-fplay.c 2008-11-11 18:25:22.000000000 +0100 -@@ -0,0 +1,485 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+unsigned int flt_data_size = 1000000; -+ -+unsigned int *flt_data; -+#define FDHEAD_INDEX (flt_data_size) -+#define FDTAIL_INDEX (flt_data_size + 1) -+ -+#define TOTEMIP_ADDRLEN (sizeof(struct in6_addr)) -+ -+struct totem_ip_address { -+ unsigned int nodeid; -+ unsigned short family; -+ unsigned char addr[TOTEMIP_ADDRLEN]; -+} __attribute__((packed)); -+ -+struct memb_ring_id { -+ struct totem_ip_address rep; -+ unsigned long long seq; -+} __attribute__((packed)); -+ -+const char *totemip_print(struct totem_ip_address *addr) -+{ -+ static char buf[INET6_ADDRSTRLEN]; -+ -+ return inet_ntop(addr->family, addr->addr, buf, sizeof(buf)); -+} -+ -+char *print_string_len (unsigned char *str, unsigned int len) -+{ -+ unsigned int i; -+ static char buf[1024]; -+ memset (buf, 0, sizeof (buf)); -+ for (i = 0; i < len; i++) { -+ buf[i] = str[i]; -+ } -+ return (buf); -+} -+ -+void sync_printer_confchg_set_sync (void **record) -+{ -+ unsigned int *my_should_sync = record[0]; -+ printf ("Setting my_should_sync to %d\n", *my_should_sync); -+} -+ -+void sync_printer_set_sync_state (void **record) -+{ -+ unsigned int *my_sync_state = record[0]; -+ printf ("Setting my_sync_state to %d\n", *my_sync_state); -+} -+ -+void sync_printer_process_currentstate (void **record) -+{ -+ unsigned int *my_sync_state = record[0]; -+ printf ("Retrieving my_sync_state %d\n", *my_sync_state); -+} -+ -+void sync_printer_process_get_shouldsync (void **record) -+{ -+ unsigned int *my_should_sync = record[0]; -+ printf ("Getting my_should_sync %d\n", *my_should_sync); -+} -+ -+void sync_printer_checkpoint_release (void **record) -+{ -+ unsigned char *name = record[0]; -+ uint16_t *name_len = record[1]; -+ unsigned int *ckpt_id = record[2]; -+ unsigned int *from = record[3]; -+ -+ printf ("Checkpoint release name=[%s] id=[%d] from=[%d] len=[%d]\n", -+ print_string_len (name, *name_len), -+ *ckpt_id, -+ *from, -+ *name_len); -+} -+ -+void sync_printer_checkpoint_transmit (void **record) -+{ -+ unsigned char *name = record[0]; -+ uint16_t *name_len = record[1]; -+ unsigned int *ckpt_id = record[2]; -+ unsigned int *xmit_id = record[3]; -+ -+ printf ("xmit_id=[%d] Checkpoint transmit name=[%s] id=[%d]\n", -+ *xmit_id, print_string_len (name, *name_len), -+ *ckpt_id); -+} -+ -+void sync_printer_section_transmit (void **record) -+{ -+ unsigned char *ckpt_name = record[0]; -+ uint16_t *name_len = record[1]; -+ unsigned int *ckpt_id = record[2]; -+ unsigned int *xmit_id = record[3]; -+ unsigned char *section_name = record[4]; -+ uint16_t *section_name_len = record[5]; -+ -+ printf ("xmit_id=[%d] Section transmit checkpoint name=[%s] id=[%d] ", -+ *xmit_id, print_string_len (ckpt_name, *name_len), -+ *ckpt_id); -+ printf ("section=[%s]\n", -+ print_string_len (section_name, *section_name_len)); -+} -+void sync_printer_checkpoint_receive (void **record) -+{ -+ unsigned char *ckpt_name = record[0]; -+ uint16_t *name_len = record[1]; -+ unsigned int *ckpt_id = record[2]; -+ unsigned int *xmit_id = record[3]; -+ -+ printf ("xmit_id=[%d] Checkpoint receive checkpoint name=[%s] id=[%d]\n", -+ *xmit_id, print_string_len (ckpt_name, *name_len), *ckpt_id); -+} -+ -+void sync_printer_section_receive (void **record) -+{ -+ unsigned char *ckpt_name = record[0]; -+ uint16_t *name_len = record[1]; -+ unsigned int *ckpt_id = record[2]; -+ unsigned int *xmit_id = record[3]; -+ unsigned char *section_name = record[4]; -+ unsigned int *section_name_len = record[5]; -+ -+ printf ("xmit_id=[%d] Section receive checkpoint name=[%s] id=[%d] ", -+ *xmit_id, print_string_len (ckpt_name, *name_len), -+ *ckpt_id); -+ -+ printf ("section=[%s]\n", -+ print_string_len (section_name, *section_name_len)); -+} -+ -+void sync_printer_nada (void **record) -+{ -+printf ("nada\n"); -+} -+void sync_printer_confchg_fn (void **record) -+{ -+ unsigned int i; -+ -+ unsigned int *members = record[0]; -+ unsigned int *member_count = record[1]; -+ struct memb_ring_id *ring_id = record[2]; -+ struct in_addr addr; -+ -+ printf ("sync confchg fn ringid [ip=%s seq=%lld]\n", -+ totemip_print (&ring_id->rep), -+ ring_id->seq); -+ printf ("members [%d]:\n", *member_count); -+ for (i = 0; i < *member_count; i++) { -+ addr.s_addr = members[i]; -+ printf ("\tmember [%s]\n", inet_ntoa (addr)); -+ } -+} -+ -+void printer_totemsrp_mcast (void **record) -+{ -+ unsigned int *msgid = record[0]; -+ -+ printf ("totemsrp_mcast %d\n", *msgid); -+} -+ -+void printer_totemsrp_delv (void **record) -+{ -+ unsigned int *msgid = record[0]; -+ -+ printf ("totemsrp_delv %d\n", *msgid); -+} -+ -+void printer_totempg_mcast_fits (void **record) -+{ -+ unsigned int *index = record[0]; -+ unsigned int *iov_len = record[1]; -+ unsigned int *copy_len = record[2]; -+ unsigned int *fragment_size = record[3]; -+ unsigned int *max_packet_size = record[4]; -+ unsigned int *copy_base = record[5]; -+ unsigned char *next_fragment = record[6]; -+ -+ printf ("totempg_mcast index=[%d] iov_len=[%d] copy_len=[%d] fragment_size=[%d] max_packet_size=[%d] copy_base=[%d] next_fragment[%d]\n", -+ *index, *iov_len, *copy_len, *fragment_size, *max_packet_size, *copy_base, *next_fragment); -+} -+ -+void sync_printer_service_process (void **record) -+{ -+ struct memb_ring_id *ring_id = record[0]; -+ struct memb_ring_id *sync_ring_id = record[1]; -+ -+ printf ("sync service process callback ringid [ip=%s seq=%lld] ", -+ totemip_print (&ring_id->rep), -+ ring_id->seq); -+ printf ("sync ringid [ip=%s seq=%lld]\n", -+ totemip_print (&sync_ring_id->rep), -+ sync_ring_id->seq); -+} -+ -+struct printer_subsys_record_print { -+ int ident; -+ void (*print_fn)(void **record); -+ int record_length; -+}; -+ -+struct printer_subsys { -+ char *subsys; -+ struct printer_subsys_record_print *record_printers; -+ int record_printers_count; -+}; -+ -+#define LOGREC_ID_SYNC_CONFCHG_FN 0 -+#define LOGREC_ID_SYNC_SERVICE_PROCESS 1 -+ -+/* -+ * CKPT subsystem -+ */ -+#define LOGREC_ID_CONFCHG_SETSYNC 0 -+#define LOGREC_ID_SETSYNCSTATE 1 -+#define LOGREC_ID_SYNC_PROCESS_CURRENTSTATE 2 -+#define LOGREC_ID_SYNC_PROCESS_GETSHOULDSYNC 3 -+#define LOGREC_ID_SYNC_CHECKPOINT_TRANSMIT 4 -+#define LOGREC_ID_SYNC_SECTION_TRANSMIT 5 -+#define LOGREC_ID_SYNC_CHECKPOINT_RECEIVE 6 -+#define LOGREC_ID_SYNC_SECTION_RECEIVE 7 -+#define LOGREC_ID_SYNC_CHECKPOINT_RELEASE 8 -+ -+#define LOGREC_ID_TOTEMSRP_MCAST 0 -+#define LOGREC_ID_TOTEMSRP_DELV 1 -+#define LOGREC_ID_TOTEMPG_MCAST_FITS 2 -+ -+ -+struct printer_subsys_record_print record_print_sync[] = { -+ { -+ .ident = LOGREC_ID_SYNC_CONFCHG_FN, -+ .print_fn = sync_printer_confchg_fn, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_SYNC_SERVICE_PROCESS, -+ .print_fn = sync_printer_service_process, -+ .record_length = 28 -+ } -+}; -+ -+struct printer_subsys_record_print record_print_ckpt[] = { -+ { -+ .ident = LOGREC_ID_CONFCHG_SETSYNC, -+ .print_fn = sync_printer_confchg_set_sync, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_SETSYNCSTATE, -+ .print_fn = sync_printer_set_sync_state, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_SYNC_PROCESS_CURRENTSTATE, -+ .print_fn = sync_printer_process_currentstate, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_SYNC_PROCESS_GETSHOULDSYNC, -+ .print_fn = sync_printer_process_get_shouldsync, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_SYNC_CHECKPOINT_TRANSMIT, -+ .print_fn = sync_printer_checkpoint_transmit, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_SYNC_SECTION_TRANSMIT, -+ .print_fn = sync_printer_section_transmit, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_SYNC_CHECKPOINT_RECEIVE, -+ .print_fn = sync_printer_checkpoint_receive, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_SYNC_SECTION_RECEIVE, -+ .print_fn = sync_printer_section_receive, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_SYNC_CHECKPOINT_RELEASE, -+ .print_fn = sync_printer_checkpoint_release, -+ .record_length = 28 -+ } -+ -+}; -+struct printer_subsys_record_print record_print_totem[] = { -+ { -+ .ident = LOGREC_ID_TOTEMSRP_MCAST, -+ .print_fn = printer_totemsrp_mcast, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_TOTEMSRP_DELV, -+ .print_fn = printer_totemsrp_delv, -+ .record_length = 28 -+ }, -+ { -+ .ident = LOGREC_ID_TOTEMPG_MCAST_FITS, -+ .print_fn = printer_totempg_mcast_fits, -+ .record_length = 28 -+ } -+}; -+ -+struct printer_subsys printer_subsystems[] = { -+ { -+ .subsys = "SYNC", -+ .record_printers = record_print_sync, -+ .record_printers_count = sizeof (record_print_sync) / sizeof (struct printer_subsys_record_print) -+ }, -+ { -+ .subsys = "CKPT", -+ .record_printers = record_print_ckpt, -+ .record_printers_count = sizeof (record_print_ckpt) / sizeof (struct printer_subsys_record_print) -+ }, -+ { -+ .subsys = "TOTEM", -+ .record_printers = record_print_totem, -+ .record_printers_count = sizeof (record_print_totem) / sizeof (struct printer_subsys_record_print) -+ } -+}; -+ -+unsigned int printer_subsys_count = sizeof (printer_subsystems) / sizeof (struct printer_subsys); -+ -+unsigned int records_printed = 1; -+ -+unsigned int record[10000]; -+ -+/* -+ * Copy record, dealing with wrapping -+ */ -+int logsys_rec_get (int rec_idx) { -+ unsigned int rec_size; -+ int firstcopy, secondcopy; -+ -+ rec_size = flt_data[rec_idx]; -+ -+ firstcopy = rec_size; -+ secondcopy = 0; -+ if (firstcopy + rec_idx > flt_data_size) { -+ firstcopy = flt_data_size - rec_idx; -+ secondcopy -= firstcopy - rec_size; -+ } -+ memcpy (&record[0], &flt_data[rec_idx], firstcopy<<2); -+ if (secondcopy) { -+ memcpy (&record[firstcopy], &flt_data[0], secondcopy<<2); -+ } -+ return ((rec_idx + rec_size) % flt_data_size); -+} -+ -+void logsys_rec_print (void *record) -+{ -+ unsigned int *buf_uint32t = (unsigned int *)record; -+ unsigned int rec_size; -+ unsigned int rec_ident; -+ unsigned int line; -+ unsigned int arg_size_idx; -+ unsigned int i; -+ unsigned int j; -+ unsigned int rec_idx = 0; -+ unsigned int record_number; -+ unsigned int words_processed; -+ unsigned int found; -+ void *arguments[64]; -+ int arg_count = 0; -+ -+ rec_size = buf_uint32t[rec_idx]; -+ rec_ident = buf_uint32t[rec_idx+1]; -+ line = buf_uint32t[rec_idx+2]; -+ record_number = buf_uint32t[rec_idx+3]; -+ -+printf ("rec=[%d] ", record_number); -+ arg_size_idx = rec_idx + 4; -+ words_processed = 4; -+ for (i = 0; words_processed < rec_size; i++) { -+ arguments[arg_count++] = &buf_uint32t[arg_size_idx + 1]; -+ words_processed += buf_uint32t[arg_size_idx] + 1; -+ arg_size_idx += buf_uint32t[arg_size_idx] + 1; -+ -+ } -+ -+ found = 0; -+ for (i = 0; i < printer_subsys_count; i++) { -+ if (strcmp ((char *)arguments[0], printer_subsystems[i].subsys) == 0) { -+ for (j = 0; j < printer_subsystems[i].record_printers_count; j++) { -+ if (rec_ident == printer_subsystems[i].record_printers[j].ident) { -+ printer_subsystems[i].record_printers[j].print_fn (&arguments[3]); -+ found = 1; -+ } -+ } -+ } -+ } -+ if (rec_ident & LOGSYS_TAG_LOG) { -+ printf ("Log Message=%s\n", (char *)arguments[3]); -+ found = 1; -+ } -+ if (rec_ident & LOGSYS_TAG_ENTER) { -+ printf ("ENTERING function [%s] line [%d]\n", (char *)arguments[2], line); -+ found = 1; -+ } -+ if (rec_ident & LOGSYS_TAG_LEAVE) { -+ printf ("LEAVING function [%s] line [%d]\n", (char *)arguments[2], line); -+ found = 1; -+ } -+ if (found == 0) { -+ printf ("Unknown record type found subsys=[%s] ident=[%d]\n", -+ (char *)arguments[0], rec_ident); -+ } -+ -+ -+ if (rec_ident == 999) { -+ printf ("ENTERING function [%s] line [%d]\n", (char *)arguments[2], line); -+ found = 1; -+ } -+ if (rec_ident == 1000) { -+ printf ("LEAVING function [%s] line [%d]\n", (char *)arguments[2], line); -+ found = 1; -+ } -+ if (found == 0) { -+ printf ("Unknown record type found subsys=[%s] ident=[%d]\n", -+ (char *)arguments[0], rec_ident); -+ } -+ -+ -+#ifdef COMPILE_OUT -+printf ("\n"); -+#endif -+} -+ -+int main (void) -+{ -+ unsigned int fd; -+ int rec_idx; -+ int end_rec; -+ int record_count = 1; -+ int size_read; -+ -+ flt_data = malloc ((flt_data_size + 2) * sizeof (unsigned int)); -+ fd = open ("/var/lib/corosync/fdata", O_RDONLY); -+ size_read = (int)read (fd, flt_data, (flt_data_size + 2) * sizeof (unsigned int)); -+ -+ if (size_read != (flt_data_size + 2) * sizeof (unsigned int)) { -+ printf ("Warning: read %d bytes, but expected %d\n", -+ size_read, (flt_data_size + 2) * sizeof (unsigned int)); -+ } -+ -+ rec_idx = flt_data[FDTAIL_INDEX]; -+ end_rec = flt_data[FDHEAD_INDEX]; -+ -+ printf ("Starting replay: head [%d] tail [%d]\n", -+ flt_data[FDHEAD_INDEX], -+ flt_data[FDTAIL_INDEX]); -+ -+ for (;;) { -+ rec_idx = logsys_rec_get (rec_idx); -+ logsys_rec_print (record); -+ if (rec_idx == end_rec) { -+ break; -+ } -+ record_count += 1; -+ } -+ -+ printf ("Finishing replay: records found [%d]\n", record_count); -+ return (0); -+} -diff -Naurd corosync-0.92/tools/corosync-keygen.c corosync-trunk/tools/corosync-keygen.c ---- corosync-0.92/tools/corosync-keygen.c 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/tools/corosync-keygen.c 2008-11-11 19:13:47.000000000 +0100 -@@ -44,7 +44,7 @@ - int authkey_fd; - int random_fd; - unsigned char key[128]; -- int res; -+ ssize_t res; - - printf ("Corosync Cluster Engine Authentication key generator.\n"); - if (geteuid() != 0) { -@@ -80,7 +80,7 @@ - /* - * Set security of authorization key to uid = 0 uid = 0 mode = 0400 - */ -- res = fchown (authkey_fd, 0, 0); -+ fchown (authkey_fd, 0, 0); - fchmod (authkey_fd, 0400); - - printf ("Writing corosync key to /etc/ais/authkey.\n"); -diff -Naurd corosync-0.92/tools/corosync-objctl.c corosync-trunk/tools/corosync-objctl.c ---- corosync-0.92/tools/corosync-objctl.c 2008-08-14 18:44:26.000000000 +0200 -+++ corosync-trunk/tools/corosync-objctl.c 2008-12-08 17:11:07.000000000 +0100 -@@ -32,6 +32,7 @@ - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -+#include - #include - #include - #include -@@ -41,7 +42,7 @@ - #include - #include - --#include -+#include - #include - - #define SEPERATOR '.' -@@ -104,12 +105,12 @@ - int key_name_len; - char key_value[OBJ_NAME_SIZE]; - int key_value_len; -- confdb_error_t res; -+ cs_error_t res; - int children_printed; - - /* Show the keys */ - res = confdb_key_iter_start(handle, parent_object_handle); -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - fprintf(stderr, "error resetting key iterator for object %d: %d\n", parent_object_handle, res); - exit(EXIT_FAILURE); - } -@@ -120,7 +121,7 @@ - key_name, - &key_name_len, - key_value, -- &key_value_len)) == CONFDB_OK) { -+ &key_value_len)) == CS_OK) { - key_name[key_name_len] = '\0'; - key_value[key_value_len] = '\0'; - if (parent_name != NULL) -@@ -133,7 +134,7 @@ - - /* Show sub-objects */ - res = confdb_object_iter_start(handle, parent_object_handle); -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - fprintf(stderr, "error resetting object iterator for object %d: %d\n", parent_object_handle, res); - exit(EXIT_FAILURE); - } -@@ -142,7 +143,7 @@ - parent_object_handle, - &object_handle, - object_name, -- &object_name_len)) == CONFDB_OK) { -+ &object_name_len)) == CS_OK) { - - object_name[object_name_len] = '\0'; - if (parent_name != NULL) { -@@ -165,7 +166,7 @@ - int result; - - result = confdb_initialize (&handle, &callbacks); -- if (result != CONFDB_OK) { -+ if (result != CS_OK) { - fprintf (stderr, "Could not initialize objdb library. Error %d\n", result); - return 1; - } -@@ -181,22 +182,23 @@ - static int print_help(void) - { - printf("\n"); -- printf ("usage: corosync-objctl object%ckey ...\n", SEPERATOR); -- printf (" corosync-objctl -c object%cchild_obj ...\n", SEPERATOR); -- printf (" corosync-objctl -d object%cchild_obj ...\n", SEPERATOR); -- printf (" corosync-objctl -w object%cchild_obj.key=value ...\n", SEPERATOR); -- printf (" corosync-objctl -a (print all objects)\n"); -+ printf ("usage: corosync-objctl object%ckey ... Print an object\n", SEPERATOR); -+ printf (" corosync-objctl -c object%cchild_obj ... Create Object\n", SEPERATOR); -+ printf (" corosync-objctl -d object%cchild_obj ... Delete object\n", SEPERATOR); -+ printf (" corosync-objctl -w object%cchild_obj.key=value ... Create a key\n", SEPERATOR); -+ printf (" corosync-objctl -t object%cchild_obj ... Track changes\n", SEPERATOR); -+ printf (" corosync-objctl -a Print all objects\n"); - printf("\n"); - return 0; - } - --static confdb_error_t validate_name(char * obj_name_pt) -+static cs_error_t validate_name(char * obj_name_pt) - { - if ((strchr (obj_name_pt, SEPERATOR) == NULL) && - (strchr (obj_name_pt, '=') == NULL)) -- return CONFDB_OK; -+ return CS_OK; - else -- return CONFDB_ERR_INVALID_PARAM; -+ return CS_ERR_INVALID_PARAM; - } - - void get_child_name(char * name_pt, char * child_name) -@@ -251,7 +253,7 @@ - strcpy(key_name, tmp+1); - } - --static confdb_error_t find_object (confdb_handle_t handle, -+static cs_error_t find_object (confdb_handle_t handle, - char * name_pt, - find_object_of_type_t type, - uint32_t * out_handle) -@@ -261,21 +263,21 @@ - uint32_t obj_handle; - confdb_handle_t parent_object_handle = OBJECT_PARENT_HANDLE; - char tmp_name[OBJ_NAME_SIZE]; -- confdb_error_t res; -+ cs_error_t res; - - strncpy (tmp_name, name_pt, OBJ_NAME_SIZE); - obj_name_pt = strtok_r(tmp_name, SEPERATOR_STR, &save_pt); - - while (obj_name_pt != NULL) { - res = confdb_object_find_start(handle, parent_object_handle); -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - fprintf (stderr, "Could not start object_find %d\n", res); - exit (EXIT_FAILURE); - } - - res = confdb_object_find(handle, parent_object_handle, - obj_name_pt, strlen (obj_name_pt), &obj_handle); -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - return res; - } - -@@ -291,11 +293,11 @@ - { - char parent_name[OBJ_NAME_SIZE]; - uint32_t obj_handle; -- confdb_error_t res; -+ cs_error_t res; - - get_parent_name(name_pt, parent_name); - res = find_object (handle, name_pt, FIND_OBJECT_OR_KEY, &obj_handle); -- if (res == CONFDB_OK) { -+ if (res == CS_OK) { - print_config_tree(handle, obj_handle, parent_name); - } - } -@@ -308,19 +310,19 @@ - char key_value[OBJ_NAME_SIZE]; - char old_key_value[OBJ_NAME_SIZE]; - int old_key_value_len; -- confdb_error_t res; -+ cs_error_t res; - - /* find the parent object */ - get_parent_name(path_pt, parent_name); - get_key(path_pt, key_name, key_value); - -- if (validate_name(key_name) != CONFDB_OK) { -+ if (validate_name(key_name) != CS_OK) { - fprintf(stderr, "Incorrect key name, can not have \"=\" or \"%c\"\n", SEPERATOR); - exit(EXIT_FAILURE); - } - res = find_object (handle, parent_name, FIND_OBJECT_ONLY, &obj_handle); - -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - fprintf(stderr, "Can't find parent object of \"%s\"\n", path_pt); - exit(EXIT_FAILURE); - } -@@ -333,7 +335,7 @@ - old_key_value, - &old_key_value_len); - -- if (res == CONFDB_OK) { -+ if (res == CS_OK) { - /* replace the current value */ - res = confdb_key_replace (handle, - obj_handle, -@@ -344,7 +346,7 @@ - key_value, - strlen(key_value)); - -- if (res != CONFDB_OK) -+ if (res != CS_OK) - fprintf(stderr, "Failed to replace the key %s=%s. Error %d\n", key_name, key_value, res); - } else { - /* not there, create a new key */ -@@ -354,7 +356,7 @@ - strlen(key_name), - key_value, - strlen(key_value)); -- if (res != CONFDB_OK) -+ if (res != CS_OK) - fprintf(stderr, "Failed to create the key %s=%s. Error %d\n", key_name, key_value, res); - } - -@@ -367,23 +369,23 @@ - uint32_t obj_handle; - uint32_t parent_object_handle = OBJECT_PARENT_HANDLE; - char tmp_name[OBJ_NAME_SIZE]; -- confdb_error_t res; -+ cs_error_t res; - - strncpy (tmp_name, name_pt, OBJ_NAME_SIZE); - obj_name_pt = strtok_r(tmp_name, SEPERATOR_STR, &save_pt); - - while (obj_name_pt != NULL) { - res = confdb_object_find_start(handle, parent_object_handle); -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - fprintf (stderr, "Could not start object_find %d\n", res); - exit (EXIT_FAILURE); - } - - res = confdb_object_find(handle, parent_object_handle, - obj_name_pt, strlen (obj_name_pt), &obj_handle); -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - -- if (validate_name(obj_name_pt) != CONFDB_OK) { -+ if (validate_name(obj_name_pt) != CS_OK) { - fprintf(stderr, "Incorrect object name \"%s\", \"=\" not allowed.\n", - obj_name_pt); - exit(EXIT_FAILURE); -@@ -393,7 +395,7 @@ - obj_name_pt, - strlen (obj_name_pt), - &obj_handle); -- if (res != CONFDB_OK) -+ if (res != CS_OK) - fprintf(stderr, "Failed to create object \"%s\". Error %d.\n", - obj_name_pt, res); - } -@@ -449,10 +451,13 @@ - int result; - fd_set read_fds; - int select_fd; -- SaBoolT quit = SA_FALSE; -+ int quit = CS_FALSE; - - FD_ZERO (&read_fds); -- confdb_fd_get(handle, &select_fd); -+ if (confdb_fd_get (handle, &select_fd) != CS_OK) { -+ printf ("can't get the confdb selector object.\n"); -+ return; -+ } - printf ("Type \"q\" to finish\n"); - do { - FD_SET (select_fd, &read_fds); -@@ -464,35 +469,36 @@ - if (FD_ISSET (STDIN_FILENO, &read_fds)) { - char inbuf[3]; - -- fgets(inbuf, sizeof(inbuf), stdin); -- if (strncmp(inbuf, "q", 1) == 0) -- quit = SA_TRUE; -+ if (fgets(inbuf, sizeof(inbuf), stdin) == NULL) -+ quit = CS_TRUE; -+ else if (strncmp(inbuf, "q", 1) == 0) -+ quit = CS_TRUE; - } - if (FD_ISSET (select_fd, &read_fds)) { -- if (confdb_dispatch (handle, CONFDB_DISPATCH_ALL) != CONFDB_OK) -+ if (confdb_dispatch (handle, CONFDB_DISPATCH_ALL) != CS_OK) - exit(1); - } -- } while (result && quit == SA_FALSE); -+ } while (result && quit == CS_FALSE); - -- confdb_stop_track_changes(handle); -+ (void)confdb_stop_track_changes(handle); - - } - - static void track_object(confdb_handle_t handle, char * name_pt) - { -- confdb_error_t res; -+ cs_error_t res; - uint32_t obj_handle; - - res = find_object (handle, name_pt, FIND_OBJECT_ONLY, &obj_handle); - -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - fprintf (stderr, "Could not find object \"%s\". Error %d\n", - name_pt, res); - return; - } - - res = confdb_track_changes (handle, obj_handle, CONFDB_TRACK_DEPTH_RECURSIVE); -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - fprintf (stderr, "Could not enable tracking on object \"%s\". Error %d\n", - name_pt, res); - return; -@@ -501,10 +507,10 @@ - - static void stop_tracking(confdb_handle_t handle) - { -- confdb_error_t res; -+ cs_error_t res; - - res = confdb_stop_track_changes (handle); -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - fprintf (stderr, "Could not stop tracking. Error %d\n", res); - return; - } -@@ -512,14 +518,14 @@ - - static void delete_object(confdb_handle_t handle, char * name_pt) - { -- confdb_error_t res; -+ cs_error_t res; - uint32_t obj_handle; - res = find_object (handle, name_pt, FIND_OBJECT_ONLY, &obj_handle); - -- if (res == CONFDB_OK) { -+ if (res == CS_OK) { - res = confdb_object_destroy (handle, obj_handle); - -- if (res != CONFDB_OK) -+ if (res != CS_OK) - fprintf(stderr, "Failed to find object \"%s\" to delete. Error %d\n", name_pt, res); - } else { - char parent_name[OBJ_NAME_SIZE]; -@@ -531,7 +537,7 @@ - get_key(name_pt, key_name, key_value); - res = find_object (handle, parent_name, FIND_OBJECT_ONLY, &obj_handle); - -- if (res != CONFDB_OK) { -+ if (res != CS_OK) { - fprintf(stderr, "Failed to find the key's parent object \"%s\". Error %d\n", parent_name, res); - exit (EXIT_FAILURE); - } -@@ -543,7 +549,7 @@ - key_value, - strlen(key_value)); - -- if (res != CONFDB_OK) -+ if (res != CS_OK) - fprintf(stderr, "Failed to delete key \"%s=%s\" from object \"%s\". Error %d\n", - key_name, key_value, parent_name, res); - } -@@ -552,8 +558,8 @@ - - int main (int argc, char *argv[]) { - confdb_handle_t handle; -- confdb_error_t result; -- char c; -+ cs_error_t result; -+ int c; - - action = ACTION_READ; - -@@ -603,7 +609,7 @@ - } - - result = confdb_initialize (&handle, &callbacks); -- if (result != CONFDB_OK) { -+ if (result != CS_OK) { - fprintf (stderr, "Failed to initialize the objdb API. Error %d\n", result); - exit (EXIT_FAILURE); - } -@@ -633,7 +639,7 @@ - } - - result = confdb_finalize (handle); -- if (result != CONFDB_OK) { -+ if (result != CS_OK) { - fprintf (stderr, "Error finalizing objdb API. Error %d\n", result); - exit(EXIT_FAILURE); - } -diff -Naurd corosync-0.92/tools/corosync-pload.c corosync-trunk/tools/corosync-pload.c ---- corosync-0.92/tools/corosync-pload.c 1970-01-01 01:00:00.000000000 +0100 -+++ corosync-trunk/tools/corosync-pload.c 2008-11-06 22:49:07.000000000 +0100 -@@ -0,0 +1,76 @@ -+/* -+ * Copyright (c) 2008 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 -+ -+#define timersub(a, b, result) \ -+do { \ -+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ -+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ -+ if ((result)->tv_usec < 0) { \ -+ --(result)->tv_sec; \ -+ (result)->tv_usec += 1000000; \ -+ } \ -+} while (0) -+ -+int main (void) { -+ pload_error_t result; -+ pload_handle_t handle; -+ -+ result = pload_initialize (&handle, NULL); -+ printf ("Init result %d\n", result); -+ result = pload_start ( -+ handle, -+ 0, /* code */ -+ 150000000, /* count */ -+ 300); /* size */ -+ return (0); -+} -diff -Naurd corosync-0.92/tools/Makefile corosync-trunk/tools/Makefile ---- corosync-0.92/tools/Makefile 2008-08-15 08:15:26.000000000 +0200 -+++ corosync-trunk/tools/Makefile 2008-11-11 18:28:22.000000000 +0100 -@@ -41,8 +41,8 @@ - override LDFLAGS += -lnsl -lsocket -lrt - endif - --LIBS = ../lib/libconfdb.a ../lib/libcfg.a --BINARIES=corosync-objctl corosync-cfgtool corosync-keygen -+LIBS = ../lib/libconfdb.a ../lib/libcfg.a ../lib/libpload.a -+BINARIES=corosync-objctl corosync-cfgtool corosync-keygen corosync-fplay corosync-pload - APPS_SRC=$(addsuffix .c,$(BINARIES)) - EXTRA_CFLAGS = -I$(srcdir)include - -@@ -57,9 +57,22 @@ - corosync-keygen: corosync-keygen.o - $(CC) $(LDFLAGS) -o $@ $< - -+corosync-fplay: corosync-fplay.o -+ $(CC) $(LDFLAGS) -o $@ $< -+ -+corosync-pload: corosync-pload.o -+ $(CC) $(LDFLAGS) -o $@ $< $(LIBS) -+ - clean: - rm -f *.o $(BINARIES) - -+lint: -+ -splint $(LINT_FLAGS) $(CFLAGS) corosync-objctl.c -+ -splint $(LINT_FLAGS) $(CFLAGS) corosync-cfgtool.c -+ -splint $(LINT_FLAGS) $(CFLAGS) corosync-keygen.c -+ -splint $(LINT_FLAGS) $(CFLAGS) corosync-fplay.c -+ -splint $(LINT_FLAGS) $(CFLAGS) corosync-pload.c -+ - %.o: %.c - $(CC) $(CFLAGS) $(CPPFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< - diff --git a/corosync-trunk.diff b/corosync-trunk.diff new file mode 100644 index 0000000..8018dc6 --- /dev/null +++ b/corosync-trunk.diff @@ -0,0 +1,22706 @@ +diff -Naurd corosync-0.92/exec/apidef.c corosync-trunk/exec/apidef.c +--- corosync-0.92/exec/apidef.c 2008-09-17 21:15:00.000000000 +0200 ++++ corosync-trunk/exec/apidef.c 2008-12-08 16:55:41.000000000 +0100 +@@ -46,6 +46,7 @@ + #include "main.h" + #include "ipc.h" + #include "sync.h" ++#include "quorum.h" + #include + #include "service.h" + #include +@@ -55,11 +56,16 @@ + /* + * Remove compile warnings about type name changes + */ +-typedef int (*typedef_tpg_join) (corosync_tpg_handle, struct corosync_tpg_group *, int); +-typedef int (*typedef_tpg_leave) (corosync_tpg_handle, struct corosync_tpg_group *, int); +-typedef int (*typedef_tpg_groups_mcast) (corosync_tpg_handle, int, struct corosync_tpg_group *, int groups_cnt, struct iovec *, int); +-typedef int (*typedef_tpg_groups_send_ok) (corosync_tpg_handle, struct corosync_tpg_group *, int groups_cnt, struct iovec *, int); ++typedef int (*typedef_tpg_join) (cs_tpg_handle, struct corosync_tpg_group *, int); ++typedef int (*typedef_tpg_leave) (cs_tpg_handle, struct corosync_tpg_group *, int); ++typedef int (*typedef_tpg_groups_mcast) (cs_tpg_handle, int, struct corosync_tpg_group *, int groups_cnt, struct iovec *, int); ++typedef int (*typedef_tpg_groups_send_ok) (cs_tpg_handle, struct corosync_tpg_group *, int groups_cnt, struct iovec *, int); + ++static inline void _corosync_public_exit_error ( ++ cs_fatal_error_t err, const char *file, unsigned int line) ++{ ++ _corosync_exit_error (err, file, line); ++} + + static struct corosync_api_v1 apidef_corosync_api_v1 = { + .timer_add_duration = corosync_timer_add_duration, +@@ -68,16 +74,16 @@ + .timer_time_get = NULL, + .ipc_source_set = message_source_set, + .ipc_source_is_local = message_source_is_local, +- .ipc_private_data_get = corosync_conn_private_data_get, ++ .ipc_private_data_get = cs_conn_private_data_get, + .ipc_response_send = NULL, +- .ipc_response_no_fcc = corosync_conn_send_response_no_fcc, ++ .ipc_response_no_fcc = cs_conn_send_response_no_fcc, + .ipc_dispatch_send = NULL, +- .ipc_conn_send_response = corosync_conn_send_response, +- .ipc_conn_partner_get = corosync_conn_partner_get, +- .ipc_refcnt_inc = corosync_ipc_flow_control_local_increment, +- .ipc_refcnt_dec = corosync_ipc_flow_control_local_decrement, +- .ipc_fc_create = corosync_ipc_flow_control_create, +- .ipc_fc_destroy = corosync_ipc_flow_control_destroy, ++ .ipc_conn_send_response = cs_conn_send_response, ++ .ipc_conn_partner_get = cs_conn_partner_get, ++ .ipc_refcnt_inc = cs_ipc_flow_control_local_increment, ++ .ipc_refcnt_dec = cs_ipc_flow_control_local_decrement, ++ .ipc_fc_create = cs_ipc_flow_control_create, ++ .ipc_fc_destroy = cs_ipc_flow_control_destroy, + .totem_nodeid_get = totempg_my_nodeid_get, + .totem_family_get = totempg_my_family_get, + .totem_ring_reenable = totempg_ring_reenable, +@@ -86,6 +92,7 @@ + .totem_ifaces_get = totempg_ifaces_get, + .totem_ifaces_print = totempg_ifaces_print, + .totem_ip_print = totemip_print, ++ .totem_callback_token_create = totempg_callback_token_create, + .tpg_init = totempg_groups_initialize, + .tpg_exit = NULL, /* missing from totempg api */ + .tpg_join = (typedef_tpg_join)totempg_groups_join, +@@ -95,12 +102,16 @@ + .tpg_groups_mcast = (typedef_tpg_groups_mcast)totempg_groups_mcast_groups, + .tpg_groups_send_ok = (typedef_tpg_groups_send_ok)totempg_groups_send_ok_groups, + .sync_request = sync_request, ++ .quorum_is_quorate = corosync_quorum_is_quorate, ++ .quorum_register_callback = corosync_quorum_register_callback, ++ .quorum_unregister_callback = corosync_quorum_unregister_callback, ++ .quorum_initialize = corosync_quorum_initialize, + .service_link_and_init = corosync_service_link_and_init, + .service_unlink_and_exit = corosync_service_unlink_and_exit, + .plugin_interface_reference = lcr_ifact_reference, + .plugin_interface_release = lcr_ifact_release, + .error_memory_failure = _corosync_out_of_memory_error, +- .fatal_error = _corosync_exit_error ++ .fatal_error = _corosync_public_exit_error + }; + + void apidef_init (struct objdb_iface_ver0 *objdb) { +diff -Naurd corosync-0.92/exec/coropoll.c corosync-trunk/exec/coropoll.c +--- corosync-0.92/exec/coropoll.c 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/exec/coropoll.c 2009-01-20 18:59:10.000000000 +0100 +@@ -59,6 +59,7 @@ + struct timerlist timerlist; + void (*serialize_lock_fn) (void); + void (*serialize_unlock_fn) (void); ++ int stop_requested; + }; + + /* +@@ -92,6 +93,7 @@ + poll_instance->poll_entries = 0; + poll_instance->ufds = 0; + poll_instance->poll_entry_count = 0; ++ poll_instance->stop_requested = 0; + poll_instance->serialize_lock_fn = serialize_lock_fn; + poll_instance->serialize_unlock_fn = serialize_unlock_fn; + timerlist_init (&poll_instance->timerlist); +@@ -291,18 +293,18 @@ + struct poll_instance *poll_instance; + int res = 0; + ++ if (timer_handle_out == NULL) { ++ res -ENOENT; ++ goto error_exit; ++ } ++ + res = hdb_handle_get (&poll_instance_database, handle, + (void *)&poll_instance); + if (res != 0) { + res = -ENOENT; +- + goto error_exit; + } + +- if (timer_handle_out == 0) { +- res = -ENOENT; +- } +- + timerlist_add_duration (&poll_instance->timerlist, + timer_fn, data, ((unsigned long long)msec_duration) * 1000000ULL, timer_handle_out); + +@@ -336,6 +338,27 @@ + return (res); + } + ++int poll_stop ( ++ poll_handle handle) ++{ ++ struct poll_instance *poll_instance; ++ unsigned int res; ++ ++ res = hdb_handle_get (&poll_instance_database, handle, ++ (void *)&poll_instance); ++ if (res != 0) { ++ res = -ENOENT; ++ goto error_exit; ++ } ++ ++ poll_instance->stop_requested = 1; ++ ++ hdb_handle_put (&poll_instance_database, handle); ++error_exit: ++ return (res); ++} ++ ++ + int poll_run ( + poll_handle handle) + { +@@ -366,6 +389,10 @@ + retry_poll: + res = poll (poll_instance->ufds, + poll_instance->poll_entry_count, expire_timeout_msec); ++ if (poll_instance->stop_requested) { ++ printf ("poll should stop\n"); ++ return (0); ++ } + if (errno == EINTR && res == -1) { + goto retry_poll; + } else +@@ -403,9 +430,6 @@ + return (-1); + } + +-int poll_stop ( +- poll_handle handle); +- + #ifdef COMPILE_OUT + void poll_print_state ( + poll_handle handle, +diff -Naurd corosync-0.92/exec/crypto.c corosync-trunk/exec/crypto.c +--- corosync-0.92/exec/crypto.c 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/exec/crypto.c 2009-01-26 21:22:28.000000000 +0100 +@@ -20,13 +20,14 @@ + #endif + #include + #include ++#include + + #include "crypto.h" + + #define CONST64(n) n ## ULL + +-typedef unsigned long ulong32; +-typedef unsigned long long ulong64; ++typedef uint32_t ulong32; ++typedef uint64_t ulong64; + + #if __BYTE_ORDER == __LITTLE_ENDIAN + #define ENDIAN_LITTLE +@@ -41,10 +42,10 @@ + #endif + + #if defined(COROSYNC_LINUX) +-#if __WORDIZE == 64 ++#if __WORDSIZE == 64 + #define ENDIAN_64BITWORD + #endif +-#if __WORDIZE == 32 ++#if __WORDSIZE == 32 + #define ENDIAN_32BITWORD + #endif + #else +@@ -844,7 +845,7 @@ + assert ((len & 3) == 0); + + for (i = 0; i < len; i += 4) { +- k = BYTE2WORD((unsigned char *)&buf[i]); ++ k = BYTE2WORD((unsigned char*)&buf[i]); + ADDKEY(k); + cycle(c->R); + XORNL(nltap(c)); +@@ -1250,11 +1251,11 @@ + void (*callback)(void)) + { + int fd; +- int rb; ++ unsigned long rb; + + fd = open ("/dev/urandom", O_RDONLY); + +- rb = read (fd, buf, len); ++ rb = (unsigned long)read (fd, buf, len); + + close (fd); + +diff -Naurd corosync-0.92/exec/crypto.h corosync-trunk/exec/crypto.h +--- corosync-0.92/exec/crypto.h 2004-09-15 22:20:07.000000000 +0200 ++++ corosync-trunk/exec/crypto.h 2009-01-26 21:22:28.000000000 +0100 +@@ -1,6 +1,8 @@ + #ifndef CRYPTO_H_DEFINED + #define CRYPTO_H_DEFINED + ++#include ++ + #define DIGEST_SHA1 0 + #define PRNG_SOBER 0 + +@@ -88,7 +90,7 @@ + unsigned char *dst, unsigned long *dstlen); + + struct sober128_prng { +- unsigned long R[17], /* Working storage for the shift register */ ++ uint32_t R[17], /* Working storage for the shift register */ + initR[17], /* saved register contents */ + konst, /* key dependent constant */ + sbuf; /* partial word encryption buffer */ +diff -Naurd corosync-0.92/exec/flow.c corosync-trunk/exec/flow.c +--- corosync-0.92/exec/flow.c 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/exec/flow.c 2008-11-06 22:49:07.000000000 +0100 +@@ -34,9 +34,9 @@ + + /* + * New messages are allowed from the library ONLY when the processor has not +- * received a COROSYNC_FLOW_CONTROL_STATE_ENABLED from any processor. If a +- * COROSYNC_FLOW_CONTROL_STATE_ENABLED message is sent, it must later be +- * cancelled by a COROSYNC_FLOW_CONTROL_STATE_DISABLED message. A configuration ++ * received a CS_FLOW_CONTROL_STATE_ENABLED from any processor. If a ++ * CS_FLOW_CONTROL_STATE_ENABLED message is sent, it must later be ++ * cancelled by a CS_FLOW_CONTROL_STATE_DISABLED message. A configuration + * change with the flow controlled processor leaving the configuration will + * also cancel flow control. + */ +@@ -68,12 +68,12 @@ + unsigned int service __attribute__((aligned(8))); + char id[1024] __attribute__((aligned(8))); + unsigned int id_len __attribute__((aligned(8))); +- enum corosync_flow_control_state flow_control_state __attribute__((aligned(8))); ++ enum cs_flow_control_state flow_control_state __attribute__((aligned(8))); + }; + + struct flow_control_node_state { + unsigned int nodeid; +- enum corosync_flow_control_state flow_control_state; ++ enum cs_flow_control_state flow_control_state; + }; + + struct flow_control_service { +@@ -81,10 +81,10 @@ + unsigned int service; + char id[1024]; + unsigned int id_len; +- void (*flow_control_state_set_fn) (void *context, enum corosync_flow_control_state flow_control_state); ++ void (*flow_control_state_set_fn) (void *context, enum cs_flow_control_state flow_control_state); + void *context; + unsigned int processor_count; +- enum corosync_flow_control_state flow_control_state; ++ enum cs_flow_control_state flow_control_state; + struct list_head list; + struct list_head list_all; + }; +@@ -108,7 +108,7 @@ + + static inline int flow_control_xmit ( + struct flow_control_service *flow_control_service, +- enum corosync_flow_control_state flow_control_state) ++ enum cs_flow_control_state flow_control_state) + { + struct flow_control_message flow_control_message; + struct iovec iovec; +@@ -165,11 +165,11 @@ + * Determine if any flow control is enabled on any nodes and set + * the internal variable appropriately + */ +- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_DISABLED; ++ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_DISABLED; + flow_control_service->flow_control_state_set_fn (flow_control_service->context, flow_control_service->flow_control_state); + for (i = 0; i < flow_control_service->processor_count; i++) { +- if (flow_control_service->flow_control_node_state[i].flow_control_state == COROSYNC_FLOW_CONTROL_STATE_ENABLED) { +- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_ENABLED; ++ if (flow_control_service->flow_control_node_state[i].flow_control_state == CS_FLOW_CONTROL_STATE_ENABLED) { ++ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_ENABLED; + flow_control_service->flow_control_state_set_fn (flow_control_service->context, flow_control_service->flow_control_state); + } + } +@@ -204,7 +204,7 @@ + */ + for (i = 0; i < member_list_entries; i++) { + flow_control_node_state_temp[i].nodeid = member_list[i]; +- flow_control_node_state_temp[i].flow_control_state = COROSYNC_FLOW_CONTROL_STATE_DISABLED; ++ flow_control_node_state_temp[i].flow_control_state = CS_FLOW_CONTROL_STATE_DISABLED; + + /* + * Determine if previous state was set for this processor +@@ -231,10 +231,10 @@ + * Turn on all flow control after a configuration change + */ + flow_control_service->processor_count = flow_control_member_list_entries; +- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_DISABLED; ++ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_DISABLED; + for (i = 0; i < member_list_entries; i++) { +- if (flow_control_service->flow_control_node_state[i].flow_control_state == COROSYNC_FLOW_CONTROL_STATE_ENABLED) { +- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_ENABLED; ++ if (flow_control_service->flow_control_node_state[i].flow_control_state == CS_FLOW_CONTROL_STATE_ENABLED) { ++ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_ENABLED; + flow_control_service->flow_control_state_set_fn (flow_control_service->context, flow_control_service->flow_control_state); + } + } +@@ -244,7 +244,7 @@ + /* + * External API + */ +-unsigned int corosync_flow_control_initialize (void) ++unsigned int cs_flow_control_initialize (void) + { + unsigned int res; + +@@ -271,7 +271,7 @@ + return (0); + } + +-unsigned int corosync_flow_control_ipc_init ( ++unsigned int cs_flow_control_ipc_init ( + unsigned int *flow_control_handle, + unsigned int service) + { +@@ -301,19 +301,19 @@ + + } + +-unsigned int corosync_flow_control_ipc_exit ( ++unsigned int cs_flow_control_ipc_exit ( + unsigned int flow_control_handle) + { + hdb_handle_destroy (&flow_control_hdb, flow_control_handle); + return (0); + } + +-unsigned int corosync_flow_control_create ( ++unsigned int cs_flow_control_create ( + unsigned int flow_control_handle, + unsigned int service, + void *id, + unsigned int id_len, +- void (*flow_control_state_set_fn) (void *context, enum corosync_flow_control_state flow_control_state), ++ void (*flow_control_state_set_fn) (void *context, enum cs_flow_control_state flow_control_state), + void *context) + { + struct flow_control_service *flow_control_service; +@@ -337,7 +337,7 @@ + */ + memset (flow_control_service, 0, sizeof (struct flow_control_service)); + +- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_DISABLED; ++ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_DISABLED; + flow_control_service->service = service; + memcpy (flow_control_service->id, id, id_len); + flow_control_service->id_len = id_len; +@@ -363,7 +363,7 @@ + return (res); + } + +-unsigned int corosync_flow_control_destroy ( ++unsigned int cs_flow_control_destroy ( + unsigned int flow_control_identifier, + unsigned int service, + unsigned char *id, +@@ -389,7 +389,7 @@ + if ((flow_control_service->id_len == id_len) && + (memcmp (flow_control_service->id, id, id_len) == 0)) { + flow_control_xmit (flow_control_service, +- COROSYNC_FLOW_CONTROL_STATE_DISABLED); ++ CS_FLOW_CONTROL_STATE_DISABLED); + list_del (&flow_control_service->list); + list_del (&flow_control_service->list_all); + free (flow_control_service); +@@ -406,7 +406,7 @@ + * Disable the ability for new messages to be sent for this service + * with the handle id of length id_len + */ +-unsigned int corosync_flow_control_disable ( ++unsigned int cs_flow_control_disable ( + unsigned int flow_control_handle) + { + struct flow_control_instance *instance; +@@ -425,8 +425,8 @@ + list = list->next) { + + flow_control_service = list_entry (list, struct flow_control_service, list); +- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_DISABLED; +- flow_control_xmit (flow_control_service, COROSYNC_FLOW_CONTROL_STATE_DISABLED); ++ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_DISABLED; ++ flow_control_xmit (flow_control_service, CS_FLOW_CONTROL_STATE_DISABLED); + } + hdb_handle_put (&flow_control_hdb, flow_control_handle); + +@@ -438,7 +438,7 @@ + * Enable the ability for new messagess to be sent for this service + * with the handle id of length id_len + */ +-unsigned int corosync_flow_control_enable ( ++unsigned int cs_flow_control_enable ( + unsigned int flow_control_handle) + { + struct flow_control_instance *instance; +@@ -458,8 +458,8 @@ + + + flow_control_service = list_entry (list, struct flow_control_service, list); +- flow_control_service->flow_control_state = COROSYNC_FLOW_CONTROL_STATE_ENABLED; +- flow_control_xmit (flow_control_service, COROSYNC_FLOW_CONTROL_STATE_ENABLED); ++ flow_control_service->flow_control_state = CS_FLOW_CONTROL_STATE_ENABLED; ++ flow_control_xmit (flow_control_service, CS_FLOW_CONTROL_STATE_ENABLED); + } + hdb_handle_put (&flow_control_hdb, flow_control_handle); + +diff -Naurd corosync-0.92/exec/flow.h corosync-trunk/exec/flow.h +--- corosync-0.92/exec/flow.h 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/exec/flow.h 2008-11-06 22:49:07.000000000 +0100 +@@ -37,38 +37,38 @@ + #define FLOW_H_DEFINED + + #define COROSYNC_FLOW_CONTROL_STATE +-enum corosync_flow_control_state { +- COROSYNC_FLOW_CONTROL_STATE_DISABLED, +- COROSYNC_FLOW_CONTROL_STATE_ENABLED ++enum cs_flow_control_state { ++ CS_FLOW_CONTROL_STATE_DISABLED, ++ CS_FLOW_CONTROL_STATE_ENABLED + }; + +-unsigned int corosync_flow_control_initialize (void); ++unsigned int cs_flow_control_initialize (void); + +-unsigned int corosync_flow_control_ipc_init ( ++unsigned int cs_flow_control_ipc_init ( + unsigned int *flow_control_identifier, + unsigned int service); + +-unsigned int corosync_flow_control_ipc_exit ( ++unsigned int cs_flow_control_ipc_exit ( + unsigned int flow_control_identifier); + +-unsigned int corosync_flow_control_create ( ++unsigned int cs_flow_control_create ( + unsigned int flow_control_handle, + unsigned int service, + void *id, + unsigned int id_len, +- void (*flow_control_state_set_fn) (void *context, enum corosync_flow_control_state flow_control_state), ++ void (*flow_control_state_set_fn) (void *context, enum cs_flow_control_state flow_control_state), + void *context); + +-unsigned int corosync_flow_control_destroy ( ++unsigned int cs_flow_control_destroy ( + unsigned int flow_control_identifier, + unsigned int service, + unsigned char *id, + unsigned int id_len); + +-unsigned int corosync_flow_control_disable ( ++unsigned int cs_flow_control_disable ( + unsigned int flow_control_identifier); + +-unsigned int corosync_flow_control_enable ( ++unsigned int cs_flow_control_enable ( + unsigned int flow_control_identifier); + + #endif /* FLOW_H_DEFINED */ +diff -Naurd corosync-0.92/exec/ipc.c corosync-trunk/exec/ipc.c +--- corosync-0.92/exec/ipc.c 2008-09-17 21:15:00.000000000 +0200 ++++ corosync-trunk/exec/ipc.c 2008-12-28 10:25:17.000000000 +0100 +@@ -62,7 +62,7 @@ + #endif + + #include +-#include ++#include + #include + #include + #include +@@ -72,6 +72,7 @@ + #include + #include + ++#include "quorum.h" + #include "poll.h" + #include "totemsrp.h" + #include "mempool.h" +@@ -153,7 +154,7 @@ + unsigned int flow_control_handle; /* flow control identifier */ + unsigned int flow_control_enabled; /* flow control enabled bit */ + unsigned int flow_control_local_count; /* flow control local count */ +- enum corosync_lib_flow_control flow_control; /* Does this service use IPC flow control */ ++ enum cs_lib_flow_control flow_control; /* Does this service use IPC flow control */ + pthread_mutex_t flow_control_mutex; + int (*lib_exit_fn) (void *conn); + struct timerlist timerlist; +@@ -193,26 +194,26 @@ + struct conn_info *conn_info, + void *message) + { +- SaAisErrorT error = SA_AIS_ERR_ACCESS; ++ cs_error_t error = CS_ERR_ACCESS; + uintptr_t cinfo = (uintptr_t)conn_info; + mar_req_lib_response_init_t *req_lib_response_init = (mar_req_lib_response_init_t *)message; + mar_res_lib_response_init_t res_lib_response_init; + + if (conn_info->authenticated) { + conn_info->service = req_lib_response_init->resdis_header.service; +- error = SA_AIS_OK; ++ error = CS_OK; + } + res_lib_response_init.header.size = sizeof (mar_res_lib_response_init_t); + res_lib_response_init.header.id = MESSAGE_RES_INIT; + res_lib_response_init.header.error = error; + res_lib_response_init.conn_info = (mar_uint64_t)cinfo; + +- corosync_conn_send_response ( ++ cs_conn_send_response ( + conn_info, + &res_lib_response_init, + sizeof (res_lib_response_init)); + +- if (error == SA_AIS_ERR_ACCESS) { ++ if (error == CS_ERR_ACCESS) { + libais_disconnect_security (conn_info); + return (-1); + } +@@ -223,7 +224,7 @@ + struct conn_info *conn_info, + void *message) + { +- SaAisErrorT error = SA_AIS_ERR_ACCESS; ++ cs_error_t error = CS_ERR_ACCESS; + uintptr_t cinfo; + mar_req_lib_dispatch_init_t *req_lib_dispatch_init = (mar_req_lib_dispatch_init_t *)message; + mar_res_lib_dispatch_init_t res_lib_dispatch_init; +@@ -232,9 +233,9 @@ + if (conn_info->authenticated) { + conn_info->service = req_lib_dispatch_init->resdis_header.service; + if (!ais_service[req_lib_dispatch_init->resdis_header.service]) +- error = SA_AIS_ERR_NOT_SUPPORTED; ++ error = CS_ERR_NOT_SUPPORTED; + else +- error = SA_AIS_OK; ++ error = CS_OK; + + cinfo = (uintptr_t)req_lib_dispatch_init->conn_info; + conn_info->conn_info_partner = (struct conn_info *)cinfo; +@@ -252,7 +253,7 @@ + msg_conn_info = (struct conn_info *)cinfo; + msg_conn_info->conn_info_partner = conn_info; + +- if (error == SA_AIS_OK) { ++ if (error == CS_OK) { + int private_data_size; + + private_data_size = ais_service[req_lib_dispatch_init->resdis_header.service]->private_data_size; +@@ -261,7 +262,7 @@ + + conn_info->conn_info_partner->private_data = conn_info->private_data; + if (conn_info->private_data == NULL) { +- error = SA_AIS_ERR_NO_MEMORY; ++ error = CS_ERR_NO_MEMORY; + } else { + memset (conn_info->private_data, 0, private_data_size); + } +@@ -276,16 +277,16 @@ + res_lib_dispatch_init.header.id = MESSAGE_RES_INIT; + res_lib_dispatch_init.header.error = error; + +- corosync_conn_send_response ( ++ cs_conn_send_response ( + conn_info, + &res_lib_dispatch_init, + sizeof (res_lib_dispatch_init)); + +- if (error == SA_AIS_ERR_ACCESS) { ++ if (error == CS_ERR_ACCESS) { + libais_disconnect_security (conn_info); + return (-1); + } +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (-1); + } + +@@ -296,8 +297,8 @@ + + conn_info->flow_control = ais_service[conn_info->service]->flow_control; + conn_info->conn_info_partner->flow_control = ais_service[conn_info->service]->flow_control; +- if (ais_service[conn_info->service]->flow_control == COROSYNC_LIB_FLOW_CONTROL_REQUIRED) { +- corosync_flow_control_ipc_init ( ++ if (ais_service[conn_info->service]->flow_control == CS_LIB_FLOW_CONTROL_REQUIRED) { ++ cs_flow_control_ipc_init ( + &conn_info->flow_control_handle, + conn_info->service); + +@@ -448,7 +449,7 @@ + conn_info->state = CONN_STATE_DISCONNECTED; + conn_info->conn_info_partner->state = CONN_STATE_DISCONNECTED; + if (conn_info->flow_control_enabled == 1) { +- corosync_flow_control_disable (conn_info->flow_control_handle); ++ cs_flow_control_disable (conn_info->flow_control_handle); + } + return (0); + } +@@ -486,6 +487,7 @@ + struct sched_param sched_param; + int res; + pthread_mutex_t *rel_mutex; ++ pthread_mutex_t *rel2_mutex; + unsigned int service; + struct conn_info *cinfo_partner; + void *private_data; +@@ -523,11 +525,12 @@ + + case CONN_STATE_DISCONNECTED: + rel_mutex = conn_info->shared_mutex; ++ rel2_mutex = &conn_info->mutex; + private_data = conn_info->private_data; + cinfo_partner = conn_info->conn_info_partner; + conn_info_destroy (conn); + if (service == SOCKET_SERVICE_INIT) { +- pthread_mutex_unlock (&conn_info->mutex); ++ pthread_mutex_unlock (rel2_mutex); + } else { + pthread_mutex_unlock (rel_mutex); + } +@@ -633,34 +636,37 @@ + /* + * IPC group-wide flow control + */ +- if (conn_info->flow_control == COROSYNC_LIB_FLOW_CONTROL_REQUIRED) { ++ if (conn_info->flow_control == CS_LIB_FLOW_CONTROL_REQUIRED) { + if (conn_info->flow_control_enabled == 0 && + ((fcc + FLOW_CONTROL_ENTRIES_ENABLE) > SIZEQUEUE)) { + + log_printf (LOG_LEVEL_NOTICE, "Enabling flow control [%d/%d] - [%d].\n", + entries_usedhw, SIZEQUEUE, + flow_control_local_count); +- corosync_flow_control_enable (conn_info->flow_control_handle); ++ cs_flow_control_enable (conn_info->flow_control_handle); + conn_info->flow_control_enabled = 1; +- conn_info->conn_info_partner->flow_control_enabled = 1; ++ if (conn_info->conn_info_partner) { ++ conn_info->conn_info_partner->flow_control_enabled = 1; ++ } + } + if (conn_info->flow_control_enabled == 1 && +- + fcc <= FLOW_CONTROL_ENTRIES_DISABLE) { + + log_printf (LOG_LEVEL_NOTICE, "Disabling flow control [%d/%d] - [%d].\n", + entries_usedhw, SIZEQUEUE, + flow_control_local_count); +- corosync_flow_control_disable (conn_info->flow_control_handle); ++ cs_flow_control_disable (conn_info->flow_control_handle); + conn_info->flow_control_enabled = 0; +- conn_info->conn_info_partner->flow_control_enabled = 0; ++ if (conn_info->conn_info_partner) { ++ conn_info->conn_info_partner->flow_control_enabled = 0; ++ } + } + } + } + + static int conn_info_outq_flush (struct conn_info *conn_info) { + struct queue *outq; +- int res = 0; ++ ssize_t res = 0; + struct outq_item *queue_item; + struct msghdr msg_send; + struct iovec iov_send; +@@ -731,14 +737,15 @@ + + + +-struct res_overlay { ++struct ipc_res_overlay { + mar_res_header_t header __attribute((aligned(8))); + char buf[4096]; + }; + + static void libais_deliver (struct conn_info *conn_info) + { +- int res; ++ ssize_t res; ++ int dispatch_res; + mar_req_header_t *header; + int service; + struct msghdr msg_recv; +@@ -752,7 +759,7 @@ + int send_ok = 0; + int send_ok_joined = 0; + struct iovec send_ok_joined_iovec; +- struct res_overlay res_overlay; ++ struct ipc_res_overlay res_overlay; + + msg_recv.msg_iov = &iov_recv; + msg_recv.msg_iovlen = 1; +@@ -841,7 +848,7 @@ + #ifdef COROSYNC_LINUX + if (conn_info->authenticated == 0) { + cmsg = CMSG_FIRSTHDR (&msg_recv); +- assert (cmsg); ++ assert (cmsg != NULL); + cred = (struct ucred *)CMSG_DATA (cmsg); + if (cred) { + if (cred->uid == 0 || cred->gid == g_gid_valid) { +@@ -861,7 +868,8 @@ + conn_info->inb_inuse += res; + conn_info->inb_start += res; + +- while (conn_info->inb_inuse >= sizeof (mar_req_header_t) && res != -1) { ++ dispatch_res = 0; ++ while (conn_info->inb_inuse >= sizeof (mar_req_header_t) && dispatch_res != -1) { + header = (mar_req_header_t *)&conn_info->inb[conn_info->inb_start - conn_info->inb_inuse]; + + if (header->size > conn_info->inb_inuse) { +@@ -874,7 +882,7 @@ + * else handle message using service service + */ + if (service == SOCKET_SERVICE_INIT) { +- res = ais_init_service[header->id] (conn_info, header); ++ dispatch_res = ais_init_service[header->id] (conn_info, header); + } else { + /* + * Not an init service, but a standard service +@@ -897,11 +905,11 @@ + &send_ok_joined_iovec, 1); + + send_ok = +- (sync_primary_designated() == 1) && ( +- (ais_service[service]->lib_engine[header->id].flow_control == COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED) || +- ((ais_service[service]->lib_engine[header->id].flow_control == COROSYNC_LIB_FLOW_CONTROL_REQUIRED) && ++ (corosync_quorum_is_quorate() == 1 || ais_service[service]->allow_inquorate == CS_LIB_ALLOW_INQUORATE) && ( ++ (ais_service[service]->lib_engine[header->id].flow_control == CS_LIB_FLOW_CONTROL_NOT_REQUIRED) || ++ ((ais_service[service]->lib_engine[header->id].flow_control == CS_LIB_FLOW_CONTROL_REQUIRED) && + (send_ok_joined) && +- (sync_in_process() == 0))); ++ (sync_in_process() == 0))); + + if (send_ok) { + ais_service[service]->lib_engine[header->id].lib_handler_fn(conn_info, header); +@@ -914,8 +922,8 @@ + ais_service[service]->lib_engine[header->id].response_size; + res_overlay.header.id = + ais_service[service]->lib_engine[header->id].response_id; +- res_overlay.header.error = SA_AIS_ERR_TRY_AGAIN; +- corosync_conn_send_response ( ++ res_overlay.header.error = CS_ERR_TRY_AGAIN; ++ cs_conn_send_response ( + conn_info, + &res_overlay, + res_overlay.header.size); +@@ -1030,7 +1038,7 @@ + { + } + +-void corosync_ipc_init ( ++void cs_ipc_init ( + void (*serialize_lock_fn) (void), + void (*serialize_unlock_fn) (void), + unsigned int gid_valid) +@@ -1102,7 +1110,7 @@ + /* + * Get the conn info private data + */ +-void *corosync_conn_private_data_get (void *conn) ++void *cs_conn_private_data_get (void *conn) + { + struct conn_info *conn_info = (struct conn_info *)conn; + +@@ -1116,7 +1124,7 @@ + /* + * Get the conn info partner connection + */ +-void *corosync_conn_partner_get (void *conn) ++void *cs_conn_partner_get (void *conn) + { + struct conn_info *conn_info = (struct conn_info *)conn; + +@@ -1127,25 +1135,27 @@ + } + } + +-int corosync_conn_send_response_no_fcc ( ++int cs_conn_send_response_no_fcc ( + void *conn, + void *msg, + int mlen) + { ++ int ret; + dont_call_flow_control = 1; +- corosync_conn_send_response ( ++ ret = cs_conn_send_response ( + conn, msg, mlen); + dont_call_flow_control = 0; ++ return ret; + } + +-int corosync_conn_send_response ( ++int cs_conn_send_response ( + void *conn, + void *msg, + int mlen) + { + struct queue *outq; + char *cmsg; +- int res = 0; ++ ssize_t res = 0; + int queue_empty; + struct outq_item *queue_item; + struct outq_item queue_item_out; +@@ -1282,17 +1292,17 @@ + return (0); + } + +-void corosync_ipc_flow_control_create ( ++void cs_ipc_flow_control_create ( + void *conn, + unsigned int service, + char *id, + int id_len, +- void (*flow_control_state_set_fn) (void *conn, enum corosync_flow_control_state), ++ void (*flow_control_state_set_fn) (void *conn, enum cs_flow_control_state), + void *context) + { + struct conn_info *conn_info = (struct conn_info *)conn; + +- corosync_flow_control_create ( ++ cs_flow_control_create ( + conn_info->flow_control_handle, + service, + id, +@@ -1302,7 +1312,7 @@ + conn_info->conn_info_partner->flow_control_handle = conn_info->flow_control_handle; + } + +-void corosync_ipc_flow_control_destroy ( ++void cs_ipc_flow_control_destroy ( + void *conn, + unsigned int service, + unsigned char *id, +@@ -1310,14 +1320,14 @@ + { + struct conn_info *conn_info = (struct conn_info *)conn; + +- corosync_flow_control_destroy ( ++ cs_flow_control_destroy ( + conn_info->flow_control_handle, + service, + id, + id_len); + } + +-void corosync_ipc_flow_control_local_increment ( ++void cs_ipc_flow_control_local_increment ( + void *conn) + { + struct conn_info *conn_info = (struct conn_info *)conn; +@@ -1329,7 +1339,7 @@ + pthread_mutex_unlock (&conn_info->flow_control_mutex); + } + +-void corosync_ipc_flow_control_local_decrement ( ++void cs_ipc_flow_control_local_decrement ( + void *conn) + { + struct conn_info *conn_info = (struct conn_info *)conn; +diff -Naurd corosync-0.92/exec/ipc.h corosync-trunk/exec/ipc.h +--- corosync-0.92/exec/ipc.h 2008-09-17 21:15:00.000000000 +0200 ++++ corosync-trunk/exec/ipc.h 2008-11-06 22:49:07.000000000 +0100 +@@ -46,52 +46,52 @@ + + extern int message_source_is_local (mar_message_source_t *source); + +-extern void *corosync_conn_partner_get (void *conn); ++extern void *cs_conn_partner_get (void *conn); + +-extern void *corosync_conn_private_data_get (void *conn); ++extern void *cs_conn_private_data_get (void *conn); + +-extern int corosync_conn_send_response (void *conn, void *msg, int mlen); ++extern int cs_conn_send_response (void *conn, void *msg, int mlen); + +-extern int corosync_conn_send_response_no_fcc (void *conn, void *msg,int mlen); ++extern int cs_conn_send_response_no_fcc (void *conn, void *msg,int mlen); + +-extern void corosync_ipc_init ( ++extern void cs_ipc_init ( + void (*serialize_lock_fn) (void), + void (*serialize_unlock_fn) (void), + unsigned int gid_valid); + +-extern int corosync_ipc_timer_add ( ++extern int cs_ipc_timer_add ( + void *conn, + void (*timer_fn) (void *data), + void *data, + unsigned int msec_in_future, + timer_handle *handle); + +-extern void corosync_ipc_timer_del ( ++extern void cs_ipc_timer_del ( + void *conn, + timer_handle timer_handle); + +-extern void corosync_ipc_timer_del_data ( ++extern void cs_ipc_timer_del_data ( + void *conn, + timer_handle timer_handle); + +-extern void corosync_ipc_flow_control_create ( ++extern void cs_ipc_flow_control_create ( + void *conn, + unsigned int service, + char *id, + int id_len, +- void (*flow_control_state_set_fn) (void *context, enum corosync_flow_control_state flow_control_state_set), ++ void (*flow_control_state_set_fn) (void *context, enum cs_flow_control_state flow_control_state_set), + void *context); + +-extern void corosync_ipc_flow_control_destroy ( ++extern void cs_ipc_flow_control_destroy ( + void *conn, + unsigned int service, + unsigned char *id, + int id_len); + +-extern void corosync_ipc_flow_control_local_increment ( ++extern void cs_ipc_flow_control_local_increment ( + void *conn); + +-extern void corosync_ipc_flow_control_local_decrement ( ++extern void cs_ipc_flow_control_local_decrement ( + void *conn); + + #endif /* IPC_H_DEFINED */ +diff -Naurd corosync-0.92/exec/logsys.c corosync-trunk/exec/logsys.c +--- corosync-0.92/exec/logsys.c 2008-09-17 20:22:58.000000000 +0200 ++++ corosync-trunk/exec/logsys.c 2009-01-23 15:25:30.000000000 +0100 +@@ -1,6 +1,6 @@ + /* + * Copyright (c) 2002-2004 MontaVista Software, Inc. +- * Copyright (c) 2006-2007 Red Hat, Inc. ++ * Copyright (c) 2006-2009 Red Hat, Inc. + * + * Author: Steven Dake (sdake@redhat.com) + * Author: Lon Hohberger (lhh@redhat.com) +@@ -35,13 +35,17 @@ + */ + #include + #include ++#include + #include + #include + #include ++#include ++#include + #include + #include + #include + #include ++#include + #if defined(COROSYNC_LINUX) + #include + #endif +@@ -54,14 +58,53 @@ + #include + + #include +-#include "wthread.h" ++ ++/* similar to syslog facilities/priorities tables, ++ * make a tag table for internal use ++ */ ++ ++#ifdef SYSLOG_NAMES ++CODE tagnames[] = ++ { ++ { "log", LOGSYS_TAG_LOG }, ++ { "enter", LOGSYS_TAG_ENTER }, ++ { "leave", LOGSYS_TAG_LEAVE }, ++ { "trace1", LOGSYS_TAG_TRACE1 }, ++ { "trace2", LOGSYS_TAG_TRACE2 }, ++ { "trace3", LOGSYS_TAG_TRACE3 }, ++ { "trace4", LOGSYS_TAG_TRACE4 }, ++ { "trace5", LOGSYS_TAG_TRACE5 }, ++ { "trace6", LOGSYS_TAG_TRACE6 }, ++ { "trace7", LOGSYS_TAG_TRACE7 }, ++ { "trace8", LOGSYS_TAG_TRACE8 }, ++ { NULL, -1 } ++ }; ++#endif ++ ++/* ++ * These are not static so they can be read from the core file ++ */ ++int *flt_data; ++ ++int flt_data_size; ++ ++#define SUBSYS_MAX 32 ++ ++#define COMBINE_BUFFER_SIZE 2048 ++ ++struct logsys_logger { ++ char subsys[64]; ++ unsigned int priority; ++ unsigned int tags; ++ unsigned int mode; ++}; + + /* + * Configuration parameters for logging system + */ + static char *logsys_name = NULL; + +-static unsigned int logsys_mode = 0; ++static unsigned int logsys_mode = LOG_MODE_NOSUBSYS; + + static char *logsys_file = NULL; + +@@ -69,35 +112,44 @@ + + static int logsys_facility = LOG_DAEMON; + +-static int logsys_wthread_active = 0; ++static char *logsys_format = NULL; ++ ++/* ++ * operating global variables ++ */ ++static struct logsys_logger logsys_loggers[SUBSYS_MAX]; ++ ++static int wthread_active = 0; ++ ++static int wthread_should_exit = 0; + + static pthread_mutex_t logsys_config_mutex = PTHREAD_MUTEX_INITIALIZER; + +-static pthread_mutex_t logsys_new_log_mutex = PTHREAD_MUTEX_INITIALIZER; ++static unsigned int records_written = 1; + +-static struct worker_thread_group log_thread_group; ++static pthread_t logsys_thread_id; + +-static unsigned int dropped_log_entries = 0; ++static pthread_cond_t logsys_cond; + +-#ifndef MAX_LOGGERS +-#define MAX_LOGGERS 32 +-#endif +-struct logsys_logger logsys_loggers[MAX_LOGGERS]; ++static pthread_mutex_t logsys_cond_mutex; + +-int logsys_single_id = 0; ++static pthread_spinlock_t logsys_idx_spinlock; ++ ++static unsigned int log_rec_idx; + ++static int logsys_buffer_full = 0; + +-struct log_entry { +- char *file; +- int line; +- int priority; +- char str[128]; +- struct log_entry *next; +-}; ++static char *format_buffer="[%6s] %b"; + +-static struct log_entry *head; ++static int log_requests_pending = 0; + +-static struct log_entry *tail; ++static int log_requests_lost = 0; ++ ++void *logsys_rec_end; ++ ++#define FDHEAD_INDEX (flt_data_size) ++ ++#define FDTAIL_INDEX (flt_data_size + 1) + + struct log_data { + unsigned int syslog_pos; +@@ -105,324 +157,674 @@ + char *log_string; + }; + +-enum logsys_config_mutex_state { +- LOGSYS_CONFIG_MUTEX_LOCKED, +- LOGSYS_CONFIG_MUTEX_UNLOCKED +-}; +- + static void logsys_atexit (void); + +-#define LEVELMASK 0x07 /* 3 bits */ +-#define LOG_LEVEL(p) ((p) & LEVELMASK) +-#define LOGSYS_IDMASK (0x3f << 3) /* 6 bits */ +-#define LOG_ID(p) (((p) & LOGSYS_IDMASK) >> 3) +- +-static void logsys_buffer_flush (void); ++/* ++ * Helpers for _logsys_log_rec functionality ++ */ ++static inline void my_memcpy_32bit (int *dest, int *src, unsigned int words) ++{ ++ unsigned int word_idx; ++ for (word_idx = 0; word_idx < words; word_idx++) { ++ dest[word_idx] = src[word_idx]; ++ } ++} + +-void _logsys_nosubsys_set (void) ++static inline void my_memcpy_8bit (char *dest, char *src, unsigned int bytes) + { +- logsys_mode |= LOG_MODE_NOSUBSYS; ++ unsigned int byte_idx; ++ ++ for (byte_idx = 0; byte_idx < bytes; byte_idx++) { ++ dest[byte_idx] = src[byte_idx]; ++ } + } + +-int logsys_facility_id_get (const char *name) ++/* ++ * Before any write operation, a reclaim on the buffer area must be executed ++ */ ++static inline void records_reclaim (unsigned int idx, unsigned int words) + { +- unsigned int i; ++ unsigned int should_reclaim; + +- for (i = 0; facilitynames[i].c_name != NULL; i++) { +- if (strcasecmp(name, facilitynames[i].c_name) == 0) { +- return (facilitynames[i].c_val); ++ should_reclaim = 0; ++ ++ if ((idx + words) >= flt_data_size) { ++ logsys_buffer_full = 1; ++ } ++ if (logsys_buffer_full == 0) { ++ return; ++ } ++ ++ pthread_spin_lock (&logsys_idx_spinlock); ++ if (flt_data[FDTAIL_INDEX] > flt_data[FDHEAD_INDEX]) { ++ if (idx + words >= flt_data[FDTAIL_INDEX]) { ++ should_reclaim = 1; ++ } ++ } else { ++ if ((idx + words) >= (flt_data[FDTAIL_INDEX] + flt_data_size)) { ++ should_reclaim = 1; + } + } +- return (-1); ++ ++ if (should_reclaim) { ++ int words_needed = 0; ++ ++ words_needed = words + 1; ++ do { ++ unsigned int old_tail; ++ ++ words_needed -= flt_data[flt_data[FDTAIL_INDEX]]; ++ old_tail = flt_data[FDTAIL_INDEX]; ++ flt_data[FDTAIL_INDEX] = ++ (flt_data[FDTAIL_INDEX] + ++ flt_data[flt_data[FDTAIL_INDEX]]) % (flt_data_size); ++ if (log_rec_idx == old_tail) { ++ log_requests_lost += 1; ++ log_rec_idx = flt_data[FDTAIL_INDEX]; ++ } ++ } while (words_needed > 0); ++ } ++ pthread_spin_unlock (&logsys_idx_spinlock); + } + +-const char *logsys_facility_name_get (unsigned int facility) ++#define idx_word_step(idx) \ ++do { \ ++ if (idx > (flt_data_size - 1)) { \ ++ idx = 0; \ ++ } \ ++} while (0); ++ ++#define idx_buffer_step(idx) \ ++do { \ ++ if (idx > (flt_data_size - 1)) { \ ++ idx = ((idx) % (flt_data_size)); \ ++ } \ ++} while (0); ++ ++/* ++ * Internal threaded logging implementation ++ */ ++static inline int strcpy_cutoff (char *dest, char *src, int cutoff) + { +- unsigned int i; ++ unsigned int len; + +- for (i = 0; facilitynames[i].c_name != NULL; i++) { +- if (facility == facilitynames[i].c_val) { +- return (facilitynames[i].c_name); ++ if (cutoff == -1) { ++ strcpy (dest, src); ++ return (strlen (dest)); ++ } else { ++ assert (cutoff > 0); ++ strncpy (dest, src, cutoff); ++ dest[cutoff] = '\0'; ++ len = strlen (dest); ++ if (len != cutoff) { ++ memset (&dest[len], ' ', cutoff - len); + } + } +- return (NULL); ++ return (cutoff); + } + +-int logsys_priority_id_get (const char *name) ++/* ++ * %s SUBSYSTEM ++ * %n FUNCTION NAME ++ * %f FILENAME ++ * %l FILELINE ++ * %p PRIORITY ++ * %t TIMESTAMP ++ * %b BUFFER ++ * ++ * any number between % and character specify field length to pad or chop ++*/ ++static void log_printf_to_logs ( ++ char *subsys, ++ char *function_name, ++ char *file_name, ++ int file_line, ++ unsigned int level, ++ char *buffer) + { +- unsigned int i; ++ char output_buffer[COMBINE_BUFFER_SIZE]; ++ char char_time[128]; ++ char line_no[30]; ++ unsigned int format_buffer_idx = 0; ++ unsigned int output_buffer_idx = 0; ++ struct timeval tv; ++ int cutoff; ++ unsigned int len; ++ ++ while (format_buffer[format_buffer_idx]) { ++ cutoff = -1; ++ if (format_buffer[format_buffer_idx] == '%') { ++ format_buffer_idx += 1; ++ if (isdigit (format_buffer[format_buffer_idx])) { ++ cutoff = atoi (&format_buffer[format_buffer_idx]); ++ } ++ while (isdigit (format_buffer[format_buffer_idx])) { ++ format_buffer_idx += 1; ++ } ++ ++ switch (format_buffer[format_buffer_idx]) { ++ case 's': ++ len = strcpy_cutoff (&output_buffer[output_buffer_idx], subsys, cutoff); ++ output_buffer_idx += len; ++ break; + +- for (i = 0; prioritynames[i].c_name != NULL; i++) { +- if (strcasecmp(name, prioritynames[i].c_name) == 0) { +- return (prioritynames[i].c_val); ++ case 'n': ++ len = strcpy_cutoff (&output_buffer[output_buffer_idx], function_name, cutoff); ++ output_buffer_idx += len; ++ break; ++ ++ case 'l': ++ sprintf (line_no, "%d", file_line); ++ len = strcpy_cutoff (&output_buffer[output_buffer_idx], line_no, cutoff); ++ output_buffer_idx += len; ++ break; ++ ++ case 'p': ++ break; ++ ++ case 't': ++ gettimeofday (&tv, NULL); ++ (void)strftime (char_time, sizeof (char_time), "%b %e %k:%M:%S", localtime ((time_t *)&tv.tv_sec)); ++ len = strcpy_cutoff (&output_buffer[output_buffer_idx], char_time, cutoff); ++ output_buffer_idx += len; ++ break; ++ ++ case 'b': ++ len = strcpy_cutoff (&output_buffer[output_buffer_idx], buffer, cutoff); ++ output_buffer_idx += len; ++ break; ++ } ++ format_buffer_idx += 1; ++ } else { ++ output_buffer[output_buffer_idx++] = format_buffer[format_buffer_idx++]; + } + } +- return (-1); ++ ++ output_buffer[output_buffer_idx] = '\0'; ++ ++ /* ++ * Output to syslog ++ */ ++ if (logsys_mode & LOG_MODE_OUTPUT_SYSLOG) { ++ syslog (level, "%s", output_buffer); ++ } ++ ++ /* ++ * Terminate string with \n \0 ++ */ ++ if (logsys_mode & (LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_STDERR)) { ++ output_buffer[output_buffer_idx++] = '\n'; ++ output_buffer[output_buffer_idx] = '\0'; ++ } ++ ++ /* ++ * Output to configured file ++ */ ++ if ((logsys_mode & LOG_MODE_OUTPUT_FILE) && logsys_file_fp) { ++ /* ++ * Output to a file ++ */ ++ (void)fwrite (output_buffer, strlen (output_buffer), 1, logsys_file_fp); ++ fflush (logsys_file_fp); ++ } ++ ++ /* ++ * Output to stderr ++ */ ++ if (logsys_mode & LOG_MODE_OUTPUT_STDERR) { ++ (void)write (STDERR_FILENO, output_buffer, strlen (output_buffer)); ++ } + } + +-const char *logsys_priority_name_get (unsigned int priority) ++static void record_print (char *buf) + { ++ int *buf_uint32t = (int *)buf; ++ unsigned int rec_size = buf_uint32t[0]; ++ unsigned int rec_ident = buf_uint32t[1]; ++ unsigned int file_line = buf_uint32t[2]; ++ unsigned int level = rec_ident >> 28; + unsigned int i; ++ unsigned int words_processed; ++ unsigned int arg_size_idx; ++ void *arguments[64]; ++ unsigned int arg_count; + +- for (i = 0; prioritynames[i].c_name != NULL; i++) { +- if (priority == prioritynames[i].c_val) { +- return (prioritynames[i].c_name); +- } ++ arg_size_idx = 4; ++ words_processed = 4; ++ arg_count = 0; ++ ++ for (i = 0; words_processed < rec_size; i++) { ++ arguments[arg_count++] = &buf_uint32t[arg_size_idx + 1]; ++ arg_size_idx += buf_uint32t[arg_size_idx] + 1; ++ words_processed += buf_uint32t[arg_size_idx] + 1; + } +- return (NULL); ++ log_printf_to_logs ( ++ (char *)arguments[0], ++ (char *)arguments[1], ++ (char *)arguments[2], ++ file_line, ++ level, ++ (char *)arguments[3]); + } ++ ++static int record_read (char *buf, int rec_idx, int *log_msg) { ++ unsigned int rec_size; ++ unsigned int rec_ident; ++ int firstcopy, secondcopy; + +-unsigned int logsys_config_subsys_set ( +- const char *subsys, +- unsigned int tags, +- unsigned int priority) +-{ +- int i; ++ rec_size = flt_data[rec_idx]; ++ rec_ident = flt_data[(rec_idx + 1) % flt_data_size]; + +- pthread_mutex_lock (&logsys_config_mutex); +- for (i = 0; i < MAX_LOGGERS; i++) { +- if (strcmp (logsys_loggers[i].subsys, subsys) == 0) { +- logsys_loggers[i].tags = tags; +- logsys_loggers[i].priority = priority; ++ /* ++ * Not a log record ++ */ ++ if ((rec_ident & LOGSYS_TAG_LOG) == 0) { ++ *log_msg = 0; ++ return ((rec_idx + rec_size) % flt_data_size); ++ } + +- break; +- } ++ /* ++ * A log record ++ */ ++ *log_msg = 1; ++ ++ firstcopy = rec_size; ++ secondcopy = 0; ++ if (firstcopy + rec_idx > flt_data_size) { ++ firstcopy = flt_data_size - rec_idx; ++ secondcopy -= firstcopy - rec_size; ++ } ++ memcpy (&buf[0], &flt_data[rec_idx], firstcopy << 2); ++ if (secondcopy) { ++ memcpy (&buf[(firstcopy << 2)], &flt_data[0], secondcopy << 2); ++ } ++ return ((rec_idx + rec_size) % flt_data_size); ++} ++ ++static inline void wthread_signal (void) ++{ ++ if (wthread_active == 0) { ++ return; + } ++ pthread_mutex_lock (&logsys_cond_mutex); ++ pthread_cond_signal (&logsys_cond); ++ pthread_mutex_unlock (&logsys_cond_mutex); ++} + +- if (i == MAX_LOGGERS) { +- for (i = 0; i < MAX_LOGGERS; i++) { +- if (strcmp (logsys_loggers[i].subsys, "") == 0) { +- strncpy (logsys_loggers[i].subsys, subsys, +- sizeof(logsys_loggers[i].subsys)); +- logsys_loggers[i].tags = tags; +- logsys_loggers[i].priority = priority; ++static inline void wthread_wait (void) ++{ ++ pthread_mutex_lock (&logsys_cond_mutex); ++ pthread_cond_wait (&logsys_cond, &logsys_cond_mutex); ++ pthread_mutex_unlock (&logsys_cond_mutex); ++} ++ ++static inline void wthread_wait_locked (void) ++{ ++ pthread_cond_wait (&logsys_cond, &logsys_cond_mutex); ++ pthread_mutex_unlock (&logsys_cond_mutex); ++} ++ ++static void *logsys_worker_thread (void *data) ++{ ++ int log_msg; ++ char buf[COMBINE_BUFFER_SIZE]; ++ ++ /* ++ * Signal wthread_create that the initialization process may continue ++ */ ++ wthread_signal (); ++ pthread_spin_lock (&logsys_idx_spinlock); ++ log_rec_idx = flt_data[FDTAIL_INDEX]; ++ pthread_spin_unlock (&logsys_idx_spinlock); ++ ++ for (;;) { ++ wthread_wait (); ++ /* ++ * Read and copy the logging record index position ++ * It may have been updated by records_reclaim if ++ * messages were lost or or log_rec on the first new ++ * logging record available ++ */ ++ /* ++ * Process any pending log messages here ++ */ ++ for (;;) { ++ pthread_spin_lock (&logsys_idx_spinlock); ++ if (log_requests_lost > 0) { ++ printf ("lost %d log requests\n", log_requests_lost); ++ log_requests_pending -= log_requests_lost; ++ log_requests_lost = 0; ++ } ++ if (log_requests_pending == 0) { ++ pthread_spin_unlock (&logsys_idx_spinlock); + break; + } ++ log_rec_idx = record_read (buf, log_rec_idx, &log_msg); ++ if (log_msg) { ++ log_requests_pending -= 1; ++ } ++ pthread_spin_unlock (&logsys_idx_spinlock); ++ ++ /* ++ * print the stored buffer ++ */ ++ if (log_msg) { ++ record_print (buf); ++ } ++ } ++ ++ if (wthread_should_exit) { ++ pthread_exit (NULL); + } + } +- assert(i < MAX_LOGGERS); ++} + +- pthread_mutex_unlock (&logsys_config_mutex); +- return i; ++static void wthread_create (void) ++{ ++ int res; ++ ++ if (wthread_active) { ++ return; ++ } ++ ++ wthread_active = 1; ++ ++ pthread_mutex_init (&logsys_cond_mutex, NULL); ++ pthread_cond_init (&logsys_cond, NULL); ++ pthread_mutex_lock (&logsys_cond_mutex); ++ res = pthread_create (&logsys_thread_id, NULL, ++ logsys_worker_thread, NULL); ++ ++ ++ /* ++ * Wait for thread to be started ++ */ ++ wthread_wait_locked (); + } + +-inline int logsys_mkpri (int priority, int id) ++/* ++ * Internal API - exported ++ */ ++void _logsys_nosubsys_set (void) + { +- return (((id) << 3) | (priority)); ++ logsys_mode |= LOG_MODE_NOSUBSYS; + } + +-int logsys_config_subsys_get ( ++unsigned int _logsys_subsys_create ( + const char *subsys, +- unsigned int *tags, +- unsigned int *priority) ++ unsigned int priority) + { +- unsigned int i; ++ assert (subsys != NULL); + +- pthread_mutex_lock (&logsys_config_mutex); ++ return logsys_config_subsys_set ( ++ subsys, ++ LOGSYS_TAG_LOG, ++ priority); ++} + +- for (i = 0; i < MAX_LOGGERS; i++) { +- if (strcmp (logsys_loggers[i].subsys, subsys) == 0) { +- *tags = logsys_loggers[i].tags; +- *priority = logsys_loggers[i].priority; +- pthread_mutex_unlock (&logsys_config_mutex); +- return i; ++int _logsys_wthread_create (void) ++{ ++ if ((logsys_mode & LOG_MODE_FORK) == 0) { ++ if (logsys_name != NULL) { ++ openlog (logsys_name, LOG_CONS|LOG_PID, logsys_facility); + } ++ wthread_create(); ++ atexit (logsys_atexit); + } +- +- pthread_mutex_unlock (&logsys_config_mutex); +- +- return (-1); ++ return (0); + } + +-static void buffered_log_printf ( +- char *file, +- int line, +- int priority, +- char *format, +- va_list ap) ++int _logsys_rec_init (unsigned int size) + { +- struct log_entry *entry = malloc(sizeof(struct log_entry)); ++ /* ++ * First record starts at zero ++ * Last record ends at zero ++ */ ++ flt_data = malloc ((size + 2) * sizeof (unsigned int)); ++ assert (flt_data != NULL); ++ flt_data_size = size; ++ assert (flt_data != NULL); ++ flt_data[FDHEAD_INDEX] = 0; ++ flt_data[FDTAIL_INDEX] = 0; ++ pthread_spin_init (&logsys_idx_spinlock, 0); + +- entry->file = file; +- entry->line = line; +- entry->priority = priority; +- entry->next = NULL; +- if (head == NULL) { +- head = tail = entry; +- } else { +- tail->next = entry; +- tail = entry; +- } +- vsnprintf(entry->str, sizeof(entry->str), format, ap); ++ return (0); + } + +-static void log_printf_worker_fn (void *thread_data, void *work_item) ++ ++/* ++ * u32 RECORD SIZE ++ * u32 record ident ++ * u32 arg count ++ * u32 file line ++ * u32 subsys length ++ * buffer null terminated subsys ++ * u32 filename length ++ * buffer null terminated filename ++ * u32 filename length ++ * buffer null terminated function ++ * u32 arg1 length ++ * buffer arg1 ++ * ... repeats length & arg ++ */ ++void _logsys_log_rec ( ++ int subsys, ++ char *function_name, ++ char *file_name, ++ int file_line, ++ unsigned int rec_ident, ++ ...) + { +- struct log_data *log_data = (struct log_data *)work_item; ++ va_list ap; ++ void *buf_args[64]; ++ unsigned int buf_len[64]; ++ unsigned int i; ++ unsigned int idx; ++ unsigned int arguments = 0; ++ unsigned int record_reclaim_size; ++ unsigned int index_start; ++ int words_written; + +- if (logsys_wthread_active) +- pthread_mutex_lock (&logsys_config_mutex); ++ record_reclaim_size = 0; ++ + /* +- * Output the log data ++ * Decode VA Args + */ +- if (logsys_mode & LOG_MODE_OUTPUT_FILE && logsys_file_fp != 0) { +- fprintf (logsys_file_fp, "%s", log_data->log_string); +- fflush (logsys_file_fp); ++ va_start (ap, rec_ident); ++ arguments = 3; ++ for (;;) { ++ assert (arguments < 64); ++ buf_args[arguments] = va_arg (ap, void *); ++ if (buf_args[arguments] == LOG_REC_END) { ++ break; ++ } ++ buf_len[arguments] = va_arg (ap, int); ++ record_reclaim_size += ((buf_len[arguments] + 3) >> 2) + 1; ++ arguments++; + } +- if (logsys_mode & LOG_MODE_OUTPUT_STDERR) { +- fprintf (stderr, "%s", log_data->log_string); +- fflush (stdout); ++ va_end (ap); ++ ++ /* ++ * Encode logsys subsystem identity, filename, and function ++ */ ++ buf_args[0] = logsys_loggers[subsys].subsys; ++ buf_len[0] = strlen (logsys_loggers[subsys].subsys) + 1; ++ buf_args[1] = file_name; ++ buf_len[1] = strlen (file_name) + 1; ++ buf_args[2] = function_name; ++ buf_len[2] = strlen (function_name) + 1; ++ for (i = 0; i < 3; i++) { ++ record_reclaim_size += ((buf_len[i] + 3) >> 2) + 1; + } + +- /* release mutex here in case syslog blocks */ +- if (logsys_wthread_active) +- pthread_mutex_unlock (&logsys_config_mutex); ++ idx = flt_data[FDHEAD_INDEX]; ++ index_start = idx; + +- if ((logsys_mode & LOG_MODE_OUTPUT_SYSLOG_THREADED) && +- (!((logsys_mode & LOG_MODE_FILTER_DEBUG_FROM_SYSLOG) && +- (log_data->priority == LOG_LEVEL_DEBUG)))) { +- syslog (log_data->priority, +- &log_data->log_string[log_data->syslog_pos]); +- } +- free (log_data->log_string); +-} ++ /* ++ * Reclaim data needed for record including 4 words for the header ++ */ ++ records_reclaim (idx, record_reclaim_size + 4); + +-static void _log_printf ( +- enum logsys_config_mutex_state config_mutex_state, +- char *file, +- int line, +- int priority, +- int id, +- char *format, +- va_list ap) +-{ +- char newstring[4096]; +- char log_string[4096]; +- char char_time[512]; +- char *p = NULL; +- struct timeval tv; +- int i = 0; +- int len; +- struct log_data log_data; +- unsigned int res = 0; ++ /* ++ * Write record size of zero and rest of header information ++ */ ++ flt_data[idx++] = 0; ++ idx_word_step(idx); + +- assert (id < MAX_LOGGERS); ++ flt_data[idx++] = rec_ident; ++ idx_word_step(idx); + +- if (config_mutex_state == LOGSYS_CONFIG_MUTEX_UNLOCKED) { +- pthread_mutex_lock (&logsys_config_mutex); +- } +- pthread_mutex_lock (&logsys_new_log_mutex); ++ flt_data[idx++] = file_line; ++ idx_word_step(idx); ++ ++ flt_data[idx++] = records_written; ++ idx_word_step(idx); + /* +- ** Buffer before log has been configured has been called. +- */ +- if (logsys_mode & LOG_MODE_BUFFER_BEFORE_CONFIG) { +- buffered_log_printf(file, line, logsys_mkpri(priority, id), format, ap); +- pthread_mutex_unlock (&logsys_new_log_mutex); +- if (config_mutex_state == LOGSYS_CONFIG_MUTEX_UNLOCKED) { +- pthread_mutex_unlock (&logsys_config_mutex); +- } +- return; +- } ++ * Encode all of the arguments into the log message ++ */ ++ for (i = 0; i < arguments; i++) { ++ unsigned int bytes; ++ unsigned int full_words; ++ unsigned int total_words; + +- if (((logsys_mode & LOG_MODE_OUTPUT_FILE) || (logsys_mode & LOG_MODE_OUTPUT_STDERR)) && +- (logsys_mode & LOG_MODE_DISPLAY_TIMESTAMP)) { +- gettimeofday (&tv, NULL); +- strftime (char_time, sizeof (char_time), "%b %e %k:%M:%S", +- localtime ((time_t *)&tv.tv_sec)); +- i = sprintf (newstring, "%s.%06ld ", char_time, (long)tv.tv_usec); +- } ++ bytes = buf_len[i]; ++ full_words = bytes >> 2; ++ total_words = (bytes + 3) >> 2; ++ ++ flt_data[idx++] = total_words; ++ idx_word_step(idx); + +- if ((priority == LOG_LEVEL_DEBUG) || (logsys_mode & LOG_MODE_DISPLAY_FILELINE)) { +- if (logsys_mode & LOG_MODE_SHORT_FILELINE) { +- p = strrchr(file, '/'); +- if (p) +- file = ++p; +- } +- sprintf (&newstring[i], "[%s:%04u] %s", file, line, format); +- } else { +- if (logsys_mode & LOG_MODE_NOSUBSYS) { +- sprintf (&newstring[i], "%s", format); +- } else { +- sprintf (&newstring[i], "[%-5s] %s", logsys_loggers[id].subsys, format); +- } +- } +- if (dropped_log_entries) { + /* +- * Get rid of \n if there is one ++ * determine if this is a wrapped write or normal write + */ +- if (newstring[strlen (newstring) - 1] == '\n') { +- newstring[strlen (newstring) - 1] = '\0'; ++ if (idx + total_words < flt_data_size) { ++ /* ++ * dont need to wrap buffer ++ */ ++ my_memcpy_32bit (&flt_data[idx], buf_args[i], full_words); ++ if (bytes % 4) { ++ my_memcpy_8bit ((char *)&flt_data[idx + full_words], ++ ((char *)buf_args[i]) + (full_words << 2), bytes % 4); ++ } ++ } else { ++ /* ++ * need to wrap buffer ++ */ ++ unsigned int first; ++ unsigned int second; ++ ++ first = flt_data_size - idx; ++ if (first > full_words) { ++ first = full_words; ++ } ++ second = full_words - first; ++ my_memcpy_32bit (&flt_data[idx], (int *)buf_args[i], first); ++ my_memcpy_32bit (&flt_data[0], ++ (int *)(((unsigned char *)buf_args[i]) + (first << 2)), ++ second); ++ if (bytes % 4) { ++ my_memcpy_8bit ((char *)&flt_data[0 + second], ++ ((char *)buf_args[i]) + (full_words << 2), bytes % 4); ++ } + } +- len = sprintf (log_string, +- "%s - prior to this log entry, corosync logger dropped '%d' messages because of overflow.", newstring, dropped_log_entries + 1); +- } else { +- len = vsprintf (log_string, newstring, ap); ++ idx += total_words; ++ idx_buffer_step (idx); ++ } ++ words_written = idx - index_start; ++ if (words_written < 0) { ++ words_written += flt_data_size; + } + + /* +- ** add line feed if not done yet +- */ +- if (log_string[len - 1] != '\n') { +- log_string[len] = '\n'; +- log_string[len + 1] = '\0'; +- } ++ * Commit the write of the record size now that the full record ++ * is in the memory buffer ++ */ ++ flt_data[index_start] = words_written; + + /* +- * Create work thread data ++ * If the index of the current head equals the current log_rec_idx, ++ * and this is not a log_printf operation, set the log_rec_idx to ++ * the new head position and commit the new head. + */ +- log_data.syslog_pos = i; +- log_data.priority = priority; +- log_data.log_string = strdup (log_string); +- if (log_data.log_string == NULL) { +- goto drop_log_msg; ++ pthread_spin_lock (&logsys_idx_spinlock); ++ if (rec_ident & LOGSYS_TAG_LOG) { ++ log_requests_pending += 1; + } +- +- if (logsys_wthread_active) { +- res = worker_thread_group_work_add (&log_thread_group, &log_data); +- if (res == 0) { +- dropped_log_entries = 0; +- } else { +- dropped_log_entries += 1; +- } +- } else { +- log_printf_worker_fn (NULL, &log_data); ++ if (log_requests_pending == 0) { ++ log_rec_idx = idx; + } ++ flt_data[FDHEAD_INDEX] = idx; ++ pthread_spin_unlock (&logsys_idx_spinlock); ++ records_written++; ++} + +- pthread_mutex_unlock (&logsys_new_log_mutex); +- if (config_mutex_state == LOGSYS_CONFIG_MUTEX_UNLOCKED) { +- pthread_mutex_unlock (&logsys_config_mutex); ++void _logsys_log_printf ( ++ int subsys, ++ char *function_name, ++ char *file_name, ++ int file_line, ++ unsigned int level, ++ char *format, ++ ...) ++{ ++ char logsys_print_buffer[COMBINE_BUFFER_SIZE]; ++ unsigned int len; ++ va_list ap; ++ ++ if (logsys_mode & LOG_MODE_NOSUBSYS) { ++ subsys = 0; ++ } ++ if (level > logsys_loggers[subsys].priority) { ++ return; ++ } ++ va_start (ap, format); ++ len = vsprintf (logsys_print_buffer, format, ap); ++ va_end (ap); ++ if (logsys_print_buffer[len - 1] == '\n') { ++ logsys_print_buffer[len - 1] = '\0'; ++ len -= 1; + } +- return; + +-drop_log_msg: +- dropped_log_entries++; +- pthread_mutex_unlock (&logsys_new_log_mutex); +- if (config_mutex_state == LOGSYS_CONFIG_MUTEX_UNLOCKED) { +- pthread_mutex_unlock (&logsys_config_mutex); ++ /* ++ * Create a log record ++ */ ++ _logsys_log_rec (subsys, ++ function_name, ++ file_name, ++ file_line, ++ (level+1) << 28, ++ logsys_print_buffer, len + 1, ++ LOG_REC_END); ++ ++ if ((logsys_mode & LOG_MODE_THREADED) == 0) { ++ /* ++ * Output (and block) if the log mode is not threaded otherwise ++ * expect the worker thread to output the log data once signaled ++ */ ++ log_printf_to_logs (logsys_loggers[subsys].subsys, ++ function_name, file_name, file_line, level, ++ logsys_print_buffer); ++ } else { ++ /* ++ * Signal worker thread to display logging output ++ */ ++ wthread_signal (); + } + } + +-unsigned int _logsys_subsys_create ( +- const char *subsys, +- unsigned int priority) ++/* ++ * External Configuration and Initialization API ++ */ ++void logsys_fork_completed (void) + { +- assert (subsys != NULL); +- +- return logsys_config_subsys_set ( +- subsys, +- LOGSYS_TAG_LOG, +- priority); ++ logsys_mode &= ~LOG_MODE_FORK; ++ _logsys_wthread_create (); + } + +- + void logsys_config_mode_set (unsigned int mode) + { + pthread_mutex_lock (&logsys_config_mutex); + logsys_mode = mode; +- if (mode & LOG_MODE_FLUSH_AFTER_CONFIG) { +- _logsys_wthread_create (); +- logsys_buffer_flush (); +- } + pthread_mutex_unlock (&logsys_config_mutex); + } + +@@ -431,22 +833,28 @@ + return logsys_mode; + } + ++static void logsys_close_logfile() ++{ ++ if (logsys_file_fp != NULL) { ++ fclose (logsys_file_fp); ++ logsys_file_fp = NULL; ++ } ++} ++ + int logsys_config_file_set (char **error_string, char *file) + { + static char error_string_response[512]; + + if (file == NULL) { ++ logsys_close_logfile(); + return (0); + } + +- pthread_mutex_lock (&logsys_new_log_mutex); + pthread_mutex_lock (&logsys_config_mutex); + + if (logsys_mode & LOG_MODE_OUTPUT_FILE) { + logsys_file = file; +- if (logsys_file_fp != NULL) { +- fclose (logsys_file_fp); +- } ++ logsys_close_logfile(); + logsys_file_fp = fopen (file, "a+"); + if (logsys_file_fp == 0) { + sprintf (error_string_response, +@@ -454,222 +862,243 @@ + file, strerror (errno)); + *error_string = error_string_response; + pthread_mutex_unlock (&logsys_config_mutex); +- pthread_mutex_unlock (&logsys_new_log_mutex); + return (-1); + } +- } ++ } else ++ logsys_close_logfile(); + + pthread_mutex_unlock (&logsys_config_mutex); +- pthread_mutex_unlock (&logsys_new_log_mutex); + return (0); + } + +-void logsys_config_facility_set (char *name, unsigned int facility) ++void logsys_format_set (char *format) + { +- pthread_mutex_lock (&logsys_new_log_mutex); + pthread_mutex_lock (&logsys_config_mutex); + +- logsys_name = name; +- logsys_facility = facility; ++ logsys_format = format; + + pthread_mutex_unlock (&logsys_config_mutex); +- pthread_mutex_unlock (&logsys_new_log_mutex); + } + +-void _logsys_config_priority_set (unsigned int id, unsigned int priority) ++void logsys_config_facility_set (char *name, unsigned int facility) + { +- pthread_mutex_lock (&logsys_new_log_mutex); ++ pthread_mutex_lock (&logsys_config_mutex); + +- logsys_loggers[id].priority = priority; ++ logsys_name = name; ++ logsys_facility = facility; + +- pthread_mutex_unlock (&logsys_new_log_mutex); ++ pthread_mutex_unlock (&logsys_config_mutex); + } + +-static void child_cleanup (void) ++int logsys_facility_id_get (const char *name) + { +- memset(&log_thread_group, 0, sizeof(log_thread_group)); +- logsys_wthread_active = 0; +- pthread_mutex_init(&logsys_config_mutex, NULL); +- pthread_mutex_init(&logsys_new_log_mutex, NULL); ++ unsigned int i; ++ ++ for (i = 0; facilitynames[i].c_name != NULL; i++) { ++ if (strcasecmp(name, facilitynames[i].c_name) == 0) { ++ return (facilitynames[i].c_val); ++ } ++ } ++ return (-1); + } + +-int _logsys_wthread_create (void) ++const char *logsys_facility_name_get (unsigned int facility) + { +- worker_thread_group_init ( +- &log_thread_group, +- 1, +- 1024, +- sizeof (struct log_data), +- 0, +- NULL, +- log_printf_worker_fn); +- +- logsys_flush(); +- +- atexit (logsys_atexit); +- pthread_atfork(NULL, NULL, child_cleanup); ++ unsigned int i; + +- if (logsys_mode & LOG_MODE_OUTPUT_SYSLOG_THREADED && logsys_name != NULL) { +- openlog (logsys_name, LOG_CONS|LOG_PID, logsys_facility); ++ for (i = 0; facilitynames[i].c_name != NULL; i++) { ++ if (facility == facilitynames[i].c_val) { ++ return (facilitynames[i].c_name); ++ } + } ++ return (NULL); ++} + +- logsys_wthread_active = 1; ++int logsys_priority_id_get (const char *name) ++{ ++ unsigned int i; + +- return (0); ++ for (i = 0; prioritynames[i].c_name != NULL; i++) { ++ if (strcasecmp(name, prioritynames[i].c_name) == 0) { ++ return (prioritynames[i].c_val); ++ } ++ } ++ return (-1); + } + +-void logsys_log_printf ( +- char *file, +- int line, +- int priority, +- char *format, +- ...) ++const char *logsys_priority_name_get (unsigned int priority) + { +- int id = LOG_ID(priority); +- int level = LOG_LEVEL(priority); +- va_list ap; +- +- assert (id < MAX_LOGGERS); ++ unsigned int i; + +- if (LOG_LEVEL(priority) > logsys_loggers[id].priority) { +- return; ++ for (i = 0; prioritynames[i].c_name != NULL; i++) { ++ if (priority == prioritynames[i].c_val) { ++ return (prioritynames[i].c_name); ++ } + } +- +- va_start (ap, format); +- _log_printf (LOGSYS_CONFIG_MUTEX_UNLOCKED, file, line, level, id, +- format, ap); +- va_end(ap); ++ return (NULL); + } + +-static void logsys_log_printf_locked ( +- char *file, +- int line, +- int priority, +- char *format, +- ...) ++int logsys_tag_id_get (const char *name) + { +- int id = LOG_ID(priority); +- int level = LOG_LEVEL(priority); +- va_list ap; +- +- assert (id < MAX_LOGGERS); ++ unsigned int i; + +- if (LOG_LEVEL(priority) > logsys_loggers[id].priority) { +- return; ++ for (i = 0; tagnames[i].c_name != NULL; i++) { ++ if (strcasecmp(name, tagnames[i].c_name) == 0) { ++ return (tagnames[i].c_val); ++ } + } +- +- va_start (ap, format); +- _log_printf (LOGSYS_CONFIG_MUTEX_LOCKED, file, line, level, id, +- format, ap); +- va_end(ap); ++ return (-1); + } + +-void _logsys_log_printf2 ( +- char *file, +- int line, +- int priority, +- int id, +- char *format, ...) ++const char *logsys_tag_name_get (unsigned int tag) + { +- va_list ap; +- +- assert (id < MAX_LOGGERS); ++ unsigned int i; + +- va_start (ap, format); +- _log_printf (LOGSYS_CONFIG_MUTEX_UNLOCKED, file, line, priority, id, +- format, ap); +- va_end(ap); ++ for (i = 0; tagnames[i].c_name != NULL; i++) { ++ if (tag == tagnames[i].c_val) { ++ return (tagnames[i].c_name); ++ } ++ } ++ return (NULL); + } + +-void _logsys_trace (char *file, int line, int tag, int id, char *format, ...) ++unsigned int logsys_config_subsys_set ( ++ const char *subsys, ++ unsigned int tags, ++ unsigned int priority) + { +- assert (id < MAX_LOGGERS); ++ int i; + + pthread_mutex_lock (&logsys_config_mutex); ++ for (i = 0; i < SUBSYS_MAX; i++) { ++ if (strcmp (logsys_loggers[i].subsys, subsys) == 0) { ++ logsys_loggers[i].tags = tags; ++ logsys_loggers[i].priority = priority; + +- if (tag & logsys_loggers[id].tags) { +- va_list ap; ++ break; ++ } ++ } + +- va_start (ap, format); +- _log_printf (LOGSYS_CONFIG_MUTEX_LOCKED, file, line, +- LOG_LEVEL_DEBUG, id, format, ap); +- va_end(ap); ++ if (i == SUBSYS_MAX) { ++ for (i = 0; i < SUBSYS_MAX; i++) { ++ if (strcmp (logsys_loggers[i].subsys, "") == 0) { ++ strncpy (logsys_loggers[i].subsys, subsys, ++ sizeof(logsys_loggers[i].subsys)); ++ logsys_loggers[i].tags = tags; ++ logsys_loggers[i].priority = priority; ++ break; ++ } ++ } + } ++ assert(i < SUBSYS_MAX); ++ + pthread_mutex_unlock (&logsys_config_mutex); ++ return i; + } + +-static void logsys_atexit (void) ++int logsys_config_subsys_get ( ++ const char *subsys, ++ unsigned int *tags, ++ unsigned int *priority) + { +- if (logsys_wthread_active) { +- worker_thread_group_wait (&log_thread_group); +- } +- if (logsys_mode & LOG_MODE_OUTPUT_SYSLOG_THREADED) { +- closelog (); ++ unsigned int i; ++ ++ pthread_mutex_lock (&logsys_config_mutex); ++ ++ for (i = 0; i < SUBSYS_MAX; i++) { ++ if (strcmp (logsys_loggers[i].subsys, subsys) == 0) { ++ *tags = logsys_loggers[i].tags; ++ *priority = logsys_loggers[i].priority; ++ pthread_mutex_unlock (&logsys_config_mutex); ++ return i; ++ } + } ++ ++ pthread_mutex_unlock (&logsys_config_mutex); ++ ++ return (-1); + } + +-static void logsys_buffer_flush (void) ++int logsys_log_rec_store (char *filename) + { +- struct log_entry *entry = head; +- struct log_entry *tmp; ++ int fd; ++ ssize_t written_size; ++ size_t size_to_write = (flt_data_size + 2) * sizeof (unsigned int); + +- if (logsys_mode & LOG_MODE_FLUSH_AFTER_CONFIG) { +- logsys_mode &= ~LOG_MODE_FLUSH_AFTER_CONFIG; ++ fd = open (filename, O_CREAT|O_RDWR, 0700); ++ if (fd == -1) { ++ return (-1); ++ } + +- while (entry) { +- logsys_log_printf_locked ( +- entry->file, +- entry->line, +- entry->priority, +- entry->str); +- tmp = entry; +- entry = entry->next; +- free (tmp); +- } ++ written_size = write (fd, flt_data, size_to_write); ++ if (written_size < 0) { ++ return (-1); ++ } else if ((size_t)written_size != size_to_write) { ++ return (-1); + } ++ return (0); ++} + +- head = tail = NULL; ++static void logsys_atexit (void) ++{ ++ if (wthread_active) { ++ wthread_should_exit = 1; ++ wthread_signal (); ++ pthread_join (logsys_thread_id, NULL); ++ } + } + +-void logsys_flush (void) ++void logsys_atsegv (void) + { +- worker_thread_group_wait (&log_thread_group); ++ if (wthread_active) { ++ wthread_should_exit = 1; ++ wthread_signal (); ++ pthread_join (logsys_thread_id, NULL); ++ } + } + +-int logsys_init (char *name, int mode, int facility, int priority, char *file) ++int logsys_init ( ++ char *name, ++ int mode, ++ int facility, ++ int priority, ++ char *file, ++ char *format, ++ int rec_size) + { + char *errstr; + +- /* logsys_subsys_id will be 0 */ +- logsys_single_id = 1; +- ++ _logsys_nosubsys_set (); ++ _logsys_subsys_create (name, priority); + strncpy (logsys_loggers[0].subsys, name, + sizeof (logsys_loggers[0].subsys)); + logsys_config_mode_set (mode); + logsys_config_facility_set (name, facility); + logsys_config_file_set (&errstr, file); +- _logsys_config_priority_set (0, priority); +- if ((mode & LOG_MODE_BUFFER_BEFORE_CONFIG) == 0) { +- _logsys_wthread_create (); +- } ++ logsys_format_set (format); ++ _logsys_rec_init (rec_size); ++ _logsys_wthread_create (); + return (0); + } + +-int logsys_conf (char *name, int mode, int facility, int priority, char *file) ++int logsys_conf ( ++ char *name, ++ int mode, ++ int facility, ++ int priority, ++ char *file) + { + char *errstr; + ++ _logsys_rec_init (100000); + strncpy (logsys_loggers[0].subsys, name, + sizeof (logsys_loggers[0].subsys)); + logsys_config_mode_set (mode); + logsys_config_facility_set (name, facility); + logsys_config_file_set (&errstr, file); +- _logsys_config_priority_set (0, priority); + return (0); + } + + void logsys_exit (void) + { +- logsys_flush (); + } +- +diff -Naurd corosync-0.92/exec/main.c corosync-trunk/exec/main.c +--- corosync-0.92/exec/main.c 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/exec/main.c 2009-01-23 17:12:13.000000000 +0100 +@@ -34,8 +34,6 @@ + */ + #include + #include +-#include +-#include + #include + #include + #include +@@ -56,7 +54,7 @@ + #include + + #include +-#include ++#include + #include + #include + #include +@@ -66,6 +64,7 @@ + #include + #include + ++#include "quorum.h" + #include "totemsrp.h" + #include "mempool.h" + #include "mainconfig.h" +@@ -83,18 +82,16 @@ + #include "version.h" + + LOGSYS_DECLARE_SYSTEM ("corosync", +- LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED | LOG_MODE_BUFFER_BEFORE_CONFIG, ++ LOG_MODE_OUTPUT_STDERR | LOG_MODE_THREADED | LOG_MODE_FORK, + NULL, +- LOG_DAEMON); ++ LOG_DAEMON, ++ "[%6s] %b", ++ 1000000); + + LOGSYS_DECLARE_SUBSYS ("MAIN", LOG_INFO); + + #define SERVER_BACKLOG 5 + +-static int ais_uid = 0; +- +-static int gid_valid = 0; +- + static unsigned int service_count = 32; + + static pthread_mutex_t serialize_mutex = PTHREAD_MUTEX_INITIALIZER; +@@ -145,7 +142,6 @@ + #endif + + totempg_finalize (); +- logsys_flush (); + + corosync_exit_error (AIS_DONE_EXIT); + +@@ -170,15 +166,17 @@ + + static void sigsegv_handler (int num) + { +- signal (SIGSEGV, SIG_DFL); +- logsys_flush (); ++ (void)signal (SIGSEGV, SIG_DFL); ++ logsys_atsegv(); ++ logsys_log_rec_store ("/var/lib/corosync/fdata"); + raise (SIGSEGV); + } + + static void sigabrt_handler (int num) + { +- signal (SIGABRT, SIG_DFL); +- logsys_flush (); ++ (void)signal (SIGABRT, SIG_DFL); ++ logsys_atsegv(); ++ logsys_log_rec_store ("/var/lib/corosync/fdata"); + raise (SIGABRT); + } + +@@ -271,36 +269,11 @@ + } + } + +-static void aisexec_uid_determine (struct main_config *main_config) +-{ +- struct passwd *passwd; +- +- passwd = getpwnam(main_config->user); +- if (passwd == 0) { +- log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' user is not found in /etc/passwd, please read the documentation.\n", main_config->user); +- corosync_exit_error (AIS_DONE_UID_DETERMINE); +- } +- ais_uid = passwd->pw_uid; +- endpwent (); +-} +- +-static void aisexec_gid_determine (struct main_config *main_config) +-{ +- struct group *group; +- group = getgrnam (main_config->group); +- if (group == 0) { +- log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' group is not found in /etc/group, please read the documentation.\n", group->gr_name); +- corosync_exit_error (AIS_DONE_GID_DETERMINE); +- } +- gid_valid = group->gr_gid; +- endgrent (); +-} +- +-static void aisexec_priv_drop (void) ++static void priv_drop (struct main_config *main_config) + { +-return; +- setuid (ais_uid); +- setegid (ais_uid); ++return; /* TODO: we are still not dropping privs */ ++ setuid (main_config->uid); ++ setegid (main_config->gid); + } + + static void aisexec_mempool_init (void) +@@ -341,7 +314,7 @@ + } + + /* Create new session */ +- setsid(); ++ (void)setsid(); + + /* + * Map stdin/out/err to /dev/null. +@@ -408,7 +381,6 @@ + #endif + } + +- + static void deliver_fn ( + unsigned int nodeid, + struct iovec *iovec, +@@ -448,6 +420,8 @@ + */ + service = header->id >> 16; + fn_id = header->id & 0xffff; ++ if (!ais_service[service]) ++ return; + if (endian_conversion_required) { + assert(ais_service[service]->exec_engine[fn_id].exec_endian_convert_fn != NULL); + ais_service[service]->exec_engine[fn_id].exec_endian_convert_fn +@@ -494,7 +468,6 @@ + char *iface; + int res, ch; + int background, setprio; +- int totem_log_service; + + /* default configuration + */ +@@ -506,7 +479,7 @@ + switch (ch) { + case 'f': + background = 0; +- logsys_config_mode_set (LOG_MODE_OUTPUT_STDERR|LOG_MODE_FLUSH_AFTER_CONFIG); ++ logsys_config_mode_set (LOG_MODE_OUTPUT_STDERR|LOG_MODE_THREADED|LOG_MODE_FORK); + break; + case 'p': + setprio = 0; +@@ -527,11 +500,11 @@ + log_printf (LOG_LEVEL_NOTICE, "Copyright (C) 2002-2006 MontaVista Software, Inc and contributors.\n"); + log_printf (LOG_LEVEL_NOTICE, "Copyright (C) 2006-2008 Red Hat, Inc.\n"); + +- signal (SIGINT, sigintr_handler); +- signal (SIGUSR2, sigusr2_handler); +- signal (SIGSEGV, sigsegv_handler); +- signal (SIGABRT, sigabrt_handler); +- signal (SIGQUIT, sigquit_handler); ++ (void)signal (SIGINT, sigintr_handler); ++ (void)signal (SIGUSR2, sigusr2_handler); ++ (void)signal (SIGSEGV, sigsegv_handler); ++ (void)signal (SIGABRT, sigabrt_handler); ++ (void)signal (SIGQUIT, sigquit_handler); + + corosync_timer_init ( + serialize_mutex_lock, +@@ -635,14 +608,6 @@ + corosync_exit_error (AIS_DONE_MAINCONFIGREAD); + } + +- logsys_config_facility_set ("corosync", main_config.syslog_facility); +- logsys_config_mode_set (main_config.logmode); +- logsys_config_file_set (&error_string, main_config.logfile); +- +- aisexec_uid_determine (&main_config); +- +- aisexec_gid_determine (&main_config); +- + /* + * Set round robin realtime scheduling with priority 99 + * Lock all memory to avoid page faults which may interrupt +@@ -654,13 +619,14 @@ + aisexec_mlockall (); + + totem_config.totem_logging_configuration = totem_logging_configuration; +- totem_log_service = _logsys_subsys_create ("TOTEM", LOG_INFO); +- totem_config.totem_logging_configuration.log_level_security = logsys_mkpri (LOG_LEVEL_SECURITY, totem_log_service); +- totem_config.totem_logging_configuration.log_level_error = logsys_mkpri (LOG_LEVEL_ERROR, totem_log_service); +- totem_config.totem_logging_configuration.log_level_warning = logsys_mkpri (LOG_LEVEL_WARNING, totem_log_service); +- totem_config.totem_logging_configuration.log_level_notice = logsys_mkpri (LOG_LEVEL_NOTICE, totem_log_service); +- totem_config.totem_logging_configuration.log_level_debug = logsys_mkpri (LOG_LEVEL_DEBUG, totem_log_service); +- totem_config.totem_logging_configuration.log_printf = logsys_log_printf; ++ totem_config.totem_logging_configuration.log_subsys_id = ++ _logsys_subsys_create ("TOTEM", LOG_INFO); ++ totem_config.totem_logging_configuration.log_level_security = LOG_LEVEL_SECURITY; ++ totem_config.totem_logging_configuration.log_level_error = LOG_LEVEL_ERROR; ++ totem_config.totem_logging_configuration.log_level_warning = LOG_LEVEL_WARNING; ++ totem_config.totem_logging_configuration.log_level_notice = LOG_LEVEL_NOTICE; ++ totem_config.totem_logging_configuration.log_level_debug = LOG_LEVEL_DEBUG; ++ totem_config.totem_logging_configuration.log_printf = _logsys_log_printf; + + /* + * Sleep for a while to let other nodes in the cluster +@@ -704,11 +670,9 @@ + } + + +- sync_register (corosync_sync_callbacks_retrieve, corosync_sync_completed, +- totem_config.vsf_type); +- ++ sync_register (corosync_sync_callbacks_retrieve, corosync_sync_completed); + +- res = corosync_flow_control_initialize (); ++ res = cs_flow_control_initialize (); + + /* + * Drop root privleges to user 'ais' +@@ -718,14 +682,14 @@ + * CAP_SYS_NICE (setscheduler) + * CAP_IPC_LOCK (mlockall) + */ +- aisexec_priv_drop (); ++ priv_drop (&main_config); + + aisexec_mempool_init (); + +- corosync_ipc_init ( ++ cs_ipc_init ( + serialize_mutex_lock, + serialize_mutex_unlock, +- gid_valid); ++ main_config.gid); + + /* + * Start main processing loop +diff -Naurd corosync-0.92/exec/mainconfig.c corosync-trunk/exec/mainconfig.c +--- corosync-0.92/exec/mainconfig.c 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/exec/mainconfig.c 2009-01-23 17:12:13.000000000 +0100 +@@ -40,8 +40,10 @@ + #include + #include + #include ++#include ++#include + +-#include ++#include + #include + #include + #include +@@ -51,6 +53,12 @@ + #include "mempool.h" + + static char error_string_response[512]; ++static struct objdb_iface_ver0 *global_objdb; ++ ++static void add_logsys_config_notification( ++ struct objdb_iface_ver0 *objdb, ++ struct main_config *main_config); ++ + + /* This just makes the code below a little neater */ + static inline int objdb_get_string ( +@@ -98,7 +106,10 @@ + unsigned int tags; + } logsys_logger; + +-int corosync_main_config_read ( ++ ++ ++ ++int corosync_main_config_read_logging ( + struct objdb_iface_ver0 *objdb, + char **error_string, + struct main_config *main_config) +@@ -109,10 +120,6 @@ + char *error_reason = error_string_response; + unsigned int object_find_handle; + unsigned int object_find_logsys_handle; +- int global_debug = 0; +- +- +- memset (main_config, 0, sizeof (struct main_config)); + + objdb->object_find_create ( + OBJECT_PARENT_HANDLE, +@@ -120,7 +127,7 @@ + strlen ("logging"), + &object_find_handle); + +- main_config->logmode = LOG_MODE_FLUSH_AFTER_CONFIG; ++ main_config->logmode = LOG_MODE_THREADED | LOG_MODE_FORK; + if (objdb->object_find_next ( + object_find_handle, + &object_service_handle) == 0) { +@@ -135,10 +142,10 @@ + } + if (!objdb_get_string (objdb,object_service_handle, "to_syslog", &value)) { + if (strcmp (value, "yes") == 0) { +- main_config->logmode |= LOG_MODE_OUTPUT_SYSLOG_THREADED; ++ main_config->logmode |= LOG_MODE_OUTPUT_SYSLOG; + } else + if (strcmp (value, "no") == 0) { +- main_config->logmode &= ~LOG_MODE_OUTPUT_SYSLOG_THREADED; ++ main_config->logmode &= ~LOG_MODE_OUTPUT_SYSLOG; + } + } + if (!objdb_get_string (objdb,object_service_handle, "to_stderr", &value)) { +@@ -149,18 +156,8 @@ + main_config->logmode &= ~LOG_MODE_OUTPUT_STDERR; + } + } +- +- if (!objdb_get_string (objdb,object_service_handle, "debug", &value)) { +- if (strcmp (value, "on") == 0) { +- global_debug = 1; +- } else +- if (strcmp (value, "off") == 0) { +- global_debug = 0; +- } else { +- goto parse_error; +- } +- } + if (!objdb_get_string (objdb,object_service_handle, "timestamp", &value)) { ++/* todo change format string + if (strcmp (value, "on") == 0) { + main_config->logmode |= LOG_MODE_DISPLAY_TIMESTAMP; + } else +@@ -169,12 +166,20 @@ + } else { + goto parse_error; + } ++*/ ++ } ++ ++ /* free old string on reload */ ++ if (main_config->logfile) { ++ free(main_config->logfile); ++ main_config->logfile = NULL; + } + if (!objdb_get_string (objdb,object_service_handle, "logfile", &value)) { + main_config->logfile = strdup (value); + } + + if (!objdb_get_string (objdb,object_service_handle, "fileline", &value)) { ++/* TODO + if (strcmp (value, "on") == 0) { + main_config->logmode |= LOG_MODE_DISPLAY_FILELINE; + } else +@@ -183,41 +188,21 @@ + } else { + goto parse_error; + } ++*/ + } + + if (!objdb_get_string (objdb,object_service_handle, "syslog_facility", &value)) { +- if (strcmp (value, "daemon") == 0) { +- main_config->syslog_facility = LOG_DAEMON; +- } else +- if (strcmp (value, "local0") == 0) { +- main_config->syslog_facility = LOG_LOCAL0; +- } else +- if (strcmp (value, "local1") == 0) { +- main_config->syslog_facility = LOG_LOCAL1; +- } else +- if (strcmp (value, "local2") == 0) { +- main_config->syslog_facility = LOG_LOCAL2; +- } else +- if (strcmp (value, "local3") == 0) { +- main_config->syslog_facility = LOG_LOCAL3; +- } else +- if (strcmp (value, "local4") == 0) { +- main_config->syslog_facility = LOG_LOCAL4; +- } else +- if (strcmp (value, "local5") == 0) { +- main_config->syslog_facility = LOG_LOCAL5; +- } else +- if (strcmp (value, "local6") == 0) { +- main_config->syslog_facility = LOG_LOCAL6; +- } else +- if (strcmp (value, "local7") == 0) { +- main_config->syslog_facility = LOG_LOCAL7; +- } else { ++ main_config->syslog_facility = logsys_facility_id_get(value); ++ if (main_config->syslog_facility < 0) { + error_reason = "unknown syslog facility specified"; + goto parse_error; + } + } + ++ logsys_config_facility_set ("corosync", main_config->syslog_facility); ++ logsys_config_mode_set (main_config->logmode); ++ logsys_config_file_set (error_string, main_config->logfile); ++ + objdb->object_find_create ( + object_service_handle, + "logger_subsys", +@@ -239,6 +224,13 @@ + error_reason = "subsys required for logger directive"; + goto parse_error; + } ++ if (!objdb_get_string (objdb, object_logger_subsys_handle, "syslog_level", &value)) { ++ logsys_logger.priority = logsys_priority_id_get(value); ++ if (logsys_logger.priority < 0) { ++ error_reason = "unknown syslog priority specified"; ++ goto parse_error; ++ } ++ } + if (!objdb_get_string (objdb, object_logger_subsys_handle, "debug", &value)) { + if (strcmp (value, "on") == 0) { + logsys_logger.priority = LOG_LEVEL_DEBUG; +@@ -253,31 +245,14 @@ + char *token = strtok (value, "|"); + + while (token != NULL) { +- if (strcmp (token, "enter") == 0) { +- logsys_logger.tags |= LOGSYS_TAG_ENTER; +- } else if (strcmp (token, "leave") == 0) { +- logsys_logger.tags |= LOGSYS_TAG_LEAVE; +- } else if (strcmp (token, "trace1") == 0) { +- logsys_logger.tags |= LOGSYS_TAG_TRACE1; +- } else if (strcmp (token, "trace2") == 0) { +- logsys_logger.tags |= LOGSYS_TAG_TRACE2; +- } else if (strcmp (token, "trace3") == 0) { +- logsys_logger.tags |= LOGSYS_TAG_TRACE3; +- } else if (strcmp (token, "trace4") == 0) { +- logsys_logger.tags |= LOGSYS_TAG_TRACE4; +- } else if (strcmp (token, "trace5") == 0) { +- logsys_logger.tags |= LOGSYS_TAG_TRACE5; +- } else if (strcmp (token, "trace6") == 0) { +- logsys_logger.tags |= LOGSYS_TAG_TRACE6; +- } else if (strcmp (token, "trace7") == 0) { +- logsys_logger.tags |= LOGSYS_TAG_TRACE7; +- } else if (strcmp (token, "trace8") == 0) { +- logsys_logger.tags |= LOGSYS_TAG_TRACE8; +- } else { ++ int val; ++ ++ val = logsys_tag_id_get(token); ++ if (val < 0) { + error_reason = "bad tags value"; + goto parse_error; + } +- ++ logsys_logger.tags |= val; + token = strtok(NULL, "|"); + } + } +@@ -295,6 +270,61 @@ + + objdb->object_find_destroy (object_find_handle); + ++ return 0; ++ ++parse_error: ++ sprintf (error_string_response, ++ "parse error in config: %s.\n", ++ error_reason); ++ ++ *error_string = error_string_response; ++ return (-1); ++} ++ ++static int uid_determine (char *req_user) ++{ ++ struct passwd *passwd; ++ int ais_uid = 0; ++ ++ passwd = getpwnam(req_user); ++ if (passwd == 0) { ++ log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' user is not found in /etc/passwd, please read the documentation.\n", req_user); ++ corosync_exit_error (AIS_DONE_UID_DETERMINE); ++ } ++ ais_uid = passwd->pw_uid; ++ endpwent (); ++ return ais_uid; ++} ++ ++static int gid_determine (char *req_group) ++{ ++ struct group *group; ++ int ais_gid = 0; ++ ++ group = getgrnam (req_group); ++ if (group == 0) { ++ log_printf (LOG_LEVEL_ERROR, "ERROR: The '%s' group is not found in /etc/group, please read the documentation.\n", req_group); ++ corosync_exit_error (AIS_DONE_GID_DETERMINE); ++ } ++ ais_gid = group->gr_gid; ++ endgrent (); ++ return ais_gid; ++} ++ ++int corosync_main_config_read ( ++ struct objdb_iface_ver0 *objdb, ++ char **error_string, ++ struct main_config *main_config) ++{ ++ unsigned int object_service_handle; ++ char *value; ++ char *error_reason = error_string_response; ++ unsigned int object_find_handle; ++ ++ memset (main_config, 0, sizeof (struct main_config)); ++ ++ corosync_main_config_read_logging(objdb, error_string, main_config); ++ + objdb->object_find_create ( + OBJECT_PARENT_HANDLE, + "aisexec", +@@ -306,22 +336,18 @@ + &object_service_handle) == 0) { + + if (!objdb_get_string (objdb,object_service_handle, "user", &value)) { +- main_config->user = strdup(value); +- } ++ main_config->uid = uid_determine(value); ++ } else ++ main_config->uid = uid_determine("ais"); ++ + if (!objdb_get_string (objdb,object_service_handle, "group", &value)) { +- main_config->group = strdup(value); +- } ++ main_config->gid = gid_determine(value); ++ } else ++ main_config->gid = gid_determine("ais"); + } + + objdb->object_find_destroy (object_find_handle); + +- /* Default user/group */ +- if (!main_config->user) +- main_config->user = "ais"; +- +- if (!main_config->group) +- main_config->group = "ais"; +- + if ((main_config->logmode & LOG_MODE_OUTPUT_FILE) && + (main_config->logfile == NULL)) { + error_reason = "logmode set to 'file' but no logfile specified"; +@@ -331,6 +357,10 @@ + if (main_config->syslog_facility == 0) + main_config->syslog_facility = LOG_DAEMON; + ++ add_logsys_config_notification(objdb, main_config); ++ ++ logsys_fork_completed (); ++ + return 0; + + parse_error: +@@ -341,3 +371,38 @@ + *error_string = error_string_response; + return (-1); + } ++ ++ ++static void main_objdb_reload_notify(objdb_reload_notify_type_t type, int flush, ++ void *priv_data_pt) ++{ ++ struct main_config *main_config = priv_data_pt; ++ char *error_string; ++ ++ if (type == OBJDB_RELOAD_NOTIFY_END) { ++ ++ /* ++ * Reload the logsys configuration ++ */ ++ corosync_main_config_read_logging(global_objdb, ++ &error_string, ++ main_config); ++ } ++} ++ ++static void add_logsys_config_notification( ++ struct objdb_iface_ver0 *objdb, ++ struct main_config *main_config) ++{ ++ ++ global_objdb = objdb; ++ ++ objdb->object_track_start(OBJECT_PARENT_HANDLE, ++ 1, ++ NULL, ++ NULL, ++ NULL, ++ main_objdb_reload_notify, ++ main_config); ++ ++} +diff -Naurd corosync-0.92/exec/mainconfig.h corosync-trunk/exec/mainconfig.h +--- corosync-0.92/exec/mainconfig.h 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/exec/mainconfig.h 2009-01-23 17:12:13.000000000 +0100 +@@ -61,13 +61,13 @@ + /* + * user/group to run as + */ +- char *user; +- char *group; ++ int uid; ++ int gid; + }; + + extern int corosync_main_config_read ( + struct objdb_iface_ver0 *objdb, + char **error_string, + struct main_config *main_config); +- ++ + #endif /* MAINCONFIG_H_DEFINED */ +diff -Naurd corosync-0.92/exec/main.h corosync-trunk/exec/main.h +--- corosync-0.92/exec/main.h 2008-08-20 02:57:40.000000000 +0200 ++++ corosync-trunk/exec/main.h 2008-11-06 22:49:07.000000000 +0100 +@@ -37,7 +37,7 @@ + + #define TRUE 1 + #define FALSE 0 +-#include ++#include + #include + #include + #include +diff -Naurd corosync-0.92/exec/Makefile corosync-trunk/exec/Makefile +--- corosync-0.92/exec/Makefile 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/exec/Makefile 2008-12-08 16:55:41.000000000 +0100 +@@ -59,14 +59,14 @@ + EXEC_LIBS = libtotem_pg.a liblogsys.a + + # LCR objects +-LCR_SRC = vsf_ykd.c objdb.c coroparse.c +-LCR_OBJS = vsf_ykd.o objdb.o coroparse.o ++LCR_SRC = vsf_ykd.c objdb.c coroparse.c vsf_quorum.c ++LCR_OBJS = vsf_ykd.o objdb.o coroparse.o vsf_quorum.o + + # main executive objects + MAIN_SRC = main.c mempool.c util.c sync.c apidef.c service.c ipc.c flow.c \ +- timer.c totemconfig.c mainconfig.c ++ quorum.c timer.c totemconfig.c mainconfig.c + MAIN_OBJS = main.o mempool.o util.o sync.o apidef.o service.o ipc.o flow.o \ +- timer.o totemconfig.o mainconfig.o ../lcr/lcr_ifact.o ++ quorum.o timer.o totemconfig.o mainconfig.o ../lcr/lcr_ifact.o + + ifeq (${BUILD_DYNAMIC}, 1) + #EXEC_OBJS = $(TOTEM_OBJS) $(LOGSYS_OBJS) $(MAIN_OBJS) +@@ -75,7 +75,7 @@ + + all:libtotem_pg.a libtotem_pg.so.2.0.0 liblogsys.a liblogsys.so.2.0.0 \ + ../lcr/lcr_ifact.o corosync_ \ +- objdb.lcrso vsf_ykd.lcrso coroparse.lcrso ++ objdb.lcrso vsf_ykd.lcrso coroparse.lcrso vsf_quorum.lcrso + else + EXEC_OBJS = $(MAIN_OBJS) $(LCR_OBJS) + all: libtotem_pg.a liblogsys.a corosync +@@ -90,6 +90,9 @@ + vsf_ykd.lcrso: vsf_ykd.o + $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./corosync -bind_at_load vsf_ykd.o -o $@ + ++vsf_quorum.lcrso: vsf_quorum.o ++ $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./corosync -bind_at_load vsf_quorum.o -o $@ ++ + coroparse.lcrso: coroparse.o + $(CC) -bundle -bundle_loader ./corosync -bind_at_load coroparse.o -o $@ + +@@ -98,9 +101,15 @@ + vsf_ykd.lcrso: vsf_ykd.o + $(CC) -shared -Wl,-soname,vsf_ykd.lcrso vsf_ykd.o -o $@ + ++vsf_quorum.lcrso: vsf_quorum.o ++ $(CC) -shared -Wl,-soname,vsf_quorum.lcrso vsf_quorum.o -o $@ ++ + objdb.lcrso: objdb.o + $(CC) -shared -Wl,-soname,objdb.lcrso objdb.o -o $@ + ++testquorum.lcrso: testquorum.o ++ $(CC) -shared -Wl,-soname,testquorum.lcrso objdb.o -o $@ ++ + coroparse.lcrso: coroparse.o + $(CC) -shared -Wl,-soname,coroparse.lcrso coroparse.o -o $@ + endif +@@ -131,6 +140,9 @@ + + endif + ++lint: ++ -splint $(LINT_FLAGS) $(CFLAGS) *.c ++ + clean: + rm -f corosync $(OBJS) *.o *.lcrso libtotem_pg.so* libtotem_pg.a gmon.out + rm -f *.da *.bb *.bbg liblogsys.so* liblogsys.a +@@ -145,9 +157,15 @@ + vsf_ykd.o: vsf_ykd.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + ++vsf_quorum.o: vsf_quorum.c ++ $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< ++ + objdb.o: objdb.c + $(CC) $(CFLAGS) -c -o $@ $< + ++testquorum.o: testquorum.c ++ $(CC) $(CFLAGS) -c -o $@ $< ++ + coroparse.o: coroparse.c + $(CC) $(CFLAGS) -c -o $@ $< + +diff -Naurd corosync-0.92/exec/objdb.c corosync-trunk/exec/objdb.c +--- corosync-0.92/exec/objdb.c 2008-09-03 12:01:31.000000000 +0200 ++++ corosync-trunk/exec/objdb.c 2009-01-23 16:41:06.000000000 +0100 +@@ -1,6 +1,6 @@ + /* + * Copyright (c) 2006 MontaVista Software, Inc. +- * Copyright (c) 2007-2008 Red Hat, Inc. ++ * Copyright (c) 2007-2009 Red Hat, Inc. + * + * All rights reserved. + * +@@ -59,6 +59,7 @@ + object_key_change_notify_fn_t key_change_notify_fn; + object_create_notify_fn_t object_create_notify_fn; + object_destroy_notify_fn_t object_destroy_notify_fn; ++ object_reload_notify_fn_t object_reload_notify_fn; + struct list_head tracker_list; + struct list_head object_list; + }; +@@ -91,6 +92,9 @@ + + struct objdb_iface_ver0 objdb_iface; + struct list_head objdb_trackers_head; ++static pthread_rwlock_t reload_lock; ++static pthread_t lock_thread; ++static pthread_mutex_t meta_lock; + + static struct hdb_handle_database object_instance_database = { + .handle_count = 0, +@@ -107,6 +111,38 @@ + }; + + ++static void objdb_wrlock() ++{ ++ pthread_mutex_lock(&meta_lock); ++ pthread_rwlock_wrlock(&reload_lock); ++ lock_thread = pthread_self(); ++ pthread_mutex_unlock(&meta_lock); ++} ++ ++static void objdb_rdlock() ++{ ++ pthread_mutex_lock(&meta_lock); ++ if (lock_thread != pthread_self()) ++ pthread_rwlock_rdlock(&reload_lock); ++ pthread_mutex_unlock(&meta_lock); ++} ++ ++static void objdb_rdunlock() ++{ ++ pthread_mutex_lock(&meta_lock); ++ if (lock_thread != pthread_self()) ++ pthread_rwlock_unlock(&reload_lock); ++ pthread_mutex_unlock(&meta_lock); ++} ++ ++static void objdb_wrunlock() ++{ ++ pthread_mutex_lock(&meta_lock); ++ pthread_rwlock_unlock(&reload_lock); ++ lock_thread = 0; ++ pthread_mutex_unlock(&meta_lock); ++} ++ + static int objdb_init (void) + { + unsigned int handle; +@@ -135,6 +171,8 @@ + list_init (&instance->child_list); + list_init (&instance->track_head); + list_init (&objdb_trackers_head); ++ pthread_rwlock_init(&reload_lock, NULL); ++ pthread_mutex_init(&meta_lock, NULL); + + hdb_handle_put (&object_instance_database, handle); + return (0); +@@ -293,6 +331,30 @@ + } while (obj_pt->object_handle != OBJECT_PARENT_HANDLE); + } + ++static void object_reload_notification(int startstop, int flush) ++{ ++ struct list_head * list; ++ struct object_instance * obj_pt; ++ struct object_tracker * tracker_pt; ++ unsigned int res; ++ ++ res = hdb_handle_get (&object_instance_database, ++ OBJECT_PARENT_HANDLE, (void *)&obj_pt); ++ ++ for (list = obj_pt->track_head.next; ++ list != &obj_pt->track_head; list = list->next) { ++ ++ tracker_pt = list_entry (list, struct object_tracker, object_list); ++ ++ if (tracker_pt->object_reload_notify_fn != NULL) { ++ tracker_pt->object_reload_notify_fn(startstop, flush, ++ tracker_pt->data_pt); ++ } ++ } ++ hdb_handle_put (&object_instance_database, OBJECT_PARENT_HANDLE); ++} ++ ++ + /* + * object db create/destroy/set + */ +@@ -308,6 +370,7 @@ + int found = 0; + int i; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_instance_database, + parent_object_handle, (void *)&parent_instance); + if (res != 0) { +@@ -380,7 +443,7 @@ + object_instance->parent_handle, + object_instance->object_name, + object_instance->object_name_len); +- ++ objdb_rdunlock(); + return (0); + + error_put_destroy: +@@ -393,6 +456,7 @@ + hdb_handle_put (&object_instance_database, parent_object_handle); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -403,6 +467,8 @@ + int res; + struct object_instance *object_instance; + ++ objdb_rdlock(); ++ + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&object_instance); + if (res != 0) { +@@ -412,9 +478,11 @@ + object_instance->priv = priv; + + hdb_handle_put (&object_instance_database, object_handle); ++ objdb_rdunlock(); + return (0); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -432,6 +500,8 @@ + int i; + unsigned int val; + ++ objdb_rdlock(); ++ + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { +@@ -493,7 +563,7 @@ + list_add_tail (&object_key->list, &instance->key_head); + object_key_changed_notification(object_handle, key_name, key_len, + value, value_len, OBJECT_KEY_CREATED); +- ++ objdb_rdunlock(); + return (0); + + error_put_key: +@@ -506,6 +576,7 @@ + hdb_handle_put (&object_instance_database, object_handle); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -554,9 +625,12 @@ + struct object_instance *instance; + unsigned int res; + ++ objdb_rdlock(); ++ + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { ++ objdb_rdunlock(); + return (res); + } + +@@ -572,6 +646,7 @@ + free(instance->object_name); + free(instance); + ++ objdb_rdunlock(); + return (res); + } + +@@ -583,6 +658,7 @@ + struct object_instance *instance; + unsigned int res; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { +@@ -594,9 +670,11 @@ + + hdb_handle_put (&object_instance_database, object_handle); + ++ objdb_rdunlock(); + return (0); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -608,6 +686,7 @@ + struct object_instance *instance; + unsigned int res; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { +@@ -619,9 +698,11 @@ + + hdb_handle_put (&object_instance_database, object_handle); + ++ objdb_rdunlock(); + return (0); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -638,6 +719,7 @@ + struct object_instance *object_instance; + struct object_find_instance *object_find_instance; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&object_instance); + if (res != 0) { +@@ -662,6 +744,8 @@ + + hdb_handle_put (&object_instance_database, object_handle); + hdb_handle_put (&object_find_instance_database, *object_find_handle); ++ ++ objdb_rdunlock(); + return (0); + + error_destroy: +@@ -671,6 +755,7 @@ + hdb_handle_put (&object_instance_database, object_handle); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -684,6 +769,7 @@ + struct list_head *list; + unsigned int found = 0; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_find_instance_database, + object_find_handle, (void *)&object_find_instance); + if (res != 0) { +@@ -714,16 +800,35 @@ + *object_handle = object_instance->object_handle; + res = 0; + } ++ objdb_rdunlock(); + return (res); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + + static int object_find_destroy ( + unsigned int object_find_handle) + { ++ struct object_find_instance *object_find_instance; ++ unsigned int res; ++ ++ objdb_rdlock(); ++ res = hdb_handle_get (&object_find_instance_database, ++ object_find_handle, (void *)&object_find_instance); ++ if (res != 0) { ++ goto error_exit; ++ } ++ hdb_handle_put(&object_find_instance_database, object_find_handle); ++ hdb_handle_destroy(&object_find_instance_database, object_find_handle); ++ ++ objdb_rdunlock(); + return (0); ++ ++error_exit: ++ objdb_rdunlock(); ++ return (-1); + } + + static int object_key_get ( +@@ -739,6 +844,7 @@ + struct list_head *list; + int found = 0; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { +@@ -766,9 +872,11 @@ + } + + hdb_handle_put (&object_instance_database, object_handle); ++ objdb_rdunlock(); + return (res); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -784,6 +892,7 @@ + struct list_head *list; + int found = 0; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { +@@ -809,9 +918,11 @@ + } + + hdb_handle_put (&object_instance_database, object_handle); ++ objdb_rdunlock(); + return (res); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -827,6 +938,7 @@ + struct list_head *list; + int found = 0; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { +@@ -852,9 +964,11 @@ + } + + hdb_handle_put (&object_instance_database, object_handle); ++ objdb_rdunlock(); + return (res); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -872,6 +986,7 @@ + struct list_head *list; + int found = 0; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { +@@ -906,9 +1021,11 @@ + if (ret == 0) + object_key_changed_notification(object_handle, key_name, key_len, + value, value_len, OBJECT_KEY_DELETED); ++ objdb_rdunlock(); + return (ret); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -928,6 +1045,8 @@ + struct list_head *list; + int found = 0; + ++ objdb_rdlock(); ++ + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { +@@ -950,6 +1069,7 @@ + + if (found) { + int i; ++ int found_validator = 0; + + /* + * Do validation check if validation is configured for the parent object +@@ -962,7 +1082,7 @@ + instance->object_key_valid_list[i].key_name, + key_len) == 0)) { + +- found = 1; ++ found_validator = 1; + break; + } + } +@@ -970,7 +1090,7 @@ + /* + * Item not found in validation list + */ +- if (found == 0) { ++ if (found_validator == 0) { + goto error_put; + } else { + if (instance->object_key_valid_list[i].validate_callback) { +@@ -983,7 +1103,7 @@ + } + } + +- if (new_value_len <= object_key->value_len) { ++ if (new_value_len != object_key->value_len) { + void *replacement_value; + replacement_value = malloc(new_value_len); + if (!replacement_value) +@@ -1003,11 +1123,13 @@ + if (ret == 0) + object_key_changed_notification(object_handle, key_name, key_len, + new_value, new_value_len, OBJECT_KEY_REPLACED); ++ objdb_rdunlock(); + return (ret); + + error_put: + hdb_handle_put (&object_instance_database, object_handle); + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -1018,6 +1140,7 @@ + int res; + struct object_instance *object_instance; + ++ objdb_rdunlock(); + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&object_instance); + if (res != 0) { +@@ -1027,9 +1150,11 @@ + *priv = object_instance->priv; + + hdb_handle_put (&object_instance_database, object_handle); ++ objdb_rdunlock(); + return (0); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -1092,6 +1217,8 @@ + unsigned int res; + struct object_instance *instance; + ++ objdb_rdlock(); ++ + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { +@@ -1100,9 +1227,11 @@ + instance->iter_key_list = &instance->key_head; + + hdb_handle_put (&object_instance_database, object_handle); ++ objdb_rdunlock(); + return (0); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -1119,6 +1248,8 @@ + struct list_head *list; + unsigned int found = 0; + ++ objdb_rdlock(); ++ + res = hdb_handle_get (&object_instance_database, + parent_object_handle, (void *)&instance); + if (res != 0) { +@@ -1145,9 +1276,11 @@ + } + + hdb_handle_put (&object_instance_database, parent_object_handle); ++ objdb_rdunlock(); + return (res); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -1165,6 +1298,8 @@ + struct list_head *list; + unsigned int found = 0; + ++ objdb_rdlock(); ++ + res = hdb_handle_get (&object_instance_database, + parent_object_handle, (void *)&instance); + if (res != 0) { +@@ -1197,9 +1332,11 @@ + } + + hdb_handle_put (&object_instance_database, parent_object_handle); ++ objdb_rdunlock(); + return (res); + + error_exit: ++ objdb_rdunlock(); + return (-1); + } + +@@ -1210,9 +1347,12 @@ + struct object_instance *instance; + unsigned int res; + ++ objdb_rdlock(); ++ + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { ++ objdb_rdunlock(); + return (res); + } + +@@ -1222,6 +1362,7 @@ + *parent_handle = instance->parent_handle; + + hdb_handle_put (&object_instance_database, object_handle); ++ objdb_rdunlock(); + + return (0); + } +@@ -1233,9 +1374,11 @@ + struct object_instance *instance; + unsigned int res; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { ++ objdb_rdunlock(); + return (res); + } + +@@ -1243,6 +1386,7 @@ + *object_name_len = instance->object_name_len; + + hdb_handle_put (&object_instance_database, object_handle); ++ objdb_rdunlock(); + + return (0); + } +@@ -1253,6 +1397,7 @@ + object_key_change_notify_fn_t key_change_notify_fn, + object_create_notify_fn_t object_create_notify_fn, + object_destroy_notify_fn_t object_destroy_notify_fn, ++ object_reload_notify_fn_t object_reload_notify_fn, + void * priv_data_pt) + { + struct object_instance *instance; +@@ -1271,6 +1416,7 @@ + tracker_pt->key_change_notify_fn = key_change_notify_fn; + tracker_pt->object_create_notify_fn = object_create_notify_fn; + tracker_pt->object_destroy_notify_fn = object_destroy_notify_fn; ++ tracker_pt->object_reload_notify_fn = object_reload_notify_fn; + tracker_pt->data_pt = priv_data_pt; + + list_init(&tracker_pt->object_list); +@@ -1287,6 +1433,7 @@ + static void object_track_stop(object_key_change_notify_fn_t key_change_notify_fn, + object_create_notify_fn_t object_create_notify_fn, + object_destroy_notify_fn_t object_destroy_notify_fn, ++ object_reload_notify_fn_t object_reload_notify_fn, + void * priv_data_pt) + { + struct object_instance *instance; +@@ -1305,6 +1452,7 @@ + if (tracker_pt && (tracker_pt->data_pt == priv_data_pt) && + (tracker_pt->object_create_notify_fn == object_create_notify_fn) && + (tracker_pt->object_destroy_notify_fn == object_destroy_notify_fn) && ++ (tracker_pt->object_reload_notify_fn == object_reload_notify_fn) && + (tracker_pt->key_change_notify_fn == key_change_notify_fn)) { + + /* get the object & take this tracker off of it's list. */ +@@ -1337,9 +1485,11 @@ + struct object_instance *instance; + unsigned int res; + ++ objdb_rdlock(); + res = hdb_handle_get (&object_instance_database, + object_handle, (void *)&instance); + if (res != 0) { ++ objdb_rdunlock(); + return (res); + } + +@@ -1347,6 +1497,7 @@ + + hdb_handle_put (&object_instance_database, object_handle); + ++ objdb_rdunlock(); + return (res); + } + +@@ -1358,13 +1509,19 @@ + int res; + + main_get_config_modules(&modules, &num_modules); ++ ++ objdb_wrlock(); ++ + for (i=0; iconfig_writeconfig) { + res = modules[i]->config_writeconfig(&objdb_iface, error_string); +- if (res) ++ if (res) { ++ objdb_wrunlock(); + return res; ++ } + } + } ++ objdb_wrunlock(); + return 0; + } + +@@ -1376,14 +1533,22 @@ + int res; + + main_get_config_modules(&modules, &num_modules); ++ object_reload_notification(OBJDB_RELOAD_NOTIFY_START, flush); ++ ++ objdb_wrlock(); + + for (i=0; iconfig_reloadconfig) { + res = modules[i]->config_reloadconfig(&objdb_iface, flush, error_string); +- if (res) ++ if (res) { ++ object_reload_notification(OBJDB_RELOAD_NOTIFY_FAILED, flush); ++ objdb_wrunlock(); + return res; ++ } + } + } ++ objdb_wrunlock(); ++ object_reload_notification(OBJDB_RELOAD_NOTIFY_END, flush); + return 0; + } + +diff -Naurd corosync-0.92/exec/quorum.c corosync-trunk/exec/quorum.c +--- corosync-0.92/exec/quorum.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/exec/quorum.c 2008-12-09 14:48:47.000000000 +0100 +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (c) 2008 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 "quorum.h" ++#include "main.h" ++#include "sync.h" ++#include "vsf.h" ++ ++LOGSYS_DECLARE_SUBSYS ("QUORUM", LOG_INFO); ++ ++ ++static struct quorum_callin_functions *corosync_quorum_fns = NULL; ++ ++int corosync_quorum_is_quorate (void) ++{ ++ if (corosync_quorum_fns) { ++ return corosync_quorum_fns->quorate(); ++ } ++ else { ++ return 1; ++ } ++} ++ ++int corosync_quorum_register_callback (quorum_callback_fn_t fn, void *context) ++{ ++ if (corosync_quorum_fns) { ++ return corosync_quorum_fns->register_callback(fn, context); ++ } ++ else { ++ return 0; ++ } ++} ++ ++int corosync_quorum_unregister_callback (quorum_callback_fn_t fn, void *context) ++{ ++ if (corosync_quorum_fns) { ++ return corosync_quorum_fns->unregister_callback(fn, context); ++ } ++ else { ++ return 0; ++ } ++} ++ ++int corosync_quorum_initialize (struct quorum_callin_functions *fns, ++ sync_callback_fn_t *sync_callback_fn) ++{ ++ if (corosync_quorum_fns) ++ return -1; ++ ++ corosync_quorum_fns = fns; ++ *sync_callback_fn = sync_primary_callback_fn; ++ return 0; ++} ++ ++int quorum_none(void) ++{ ++ if (corosync_quorum_fns) ++ return 0; ++ else ++ return 1; ++} +diff -Naurd corosync-0.92/exec/quorum.h corosync-trunk/exec/quorum.h +--- corosync-0.92/exec/quorum.h 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/exec/quorum.h 2008-12-08 16:55:41.000000000 +0100 +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (c) 2008 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 Red Hat, 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 QUORUM_H_DEFINED ++#define QUORUM_H_DEFINED ++ ++struct memb_ring_id; ++ ++typedef void (*quorum_callback_fn_t) (int quorate, void *context); ++ ++typedef void (*sync_callback_fn_t) ( ++ unsigned int *view_list, ++ int view_list_entries, ++ int primary_designated, ++ struct memb_ring_id *ring_id); ++ ++struct quorum_callin_functions ++{ ++ int (*quorate) (void); ++ int (*register_callback) (quorum_callback_fn_t, void*); ++ int (*unregister_callback) (quorum_callback_fn_t, void*); ++}; ++ ++extern int corosync_quorum_is_quorate (void); ++ ++extern int corosync_quorum_register_callback (quorum_callback_fn_t fn, void *context); ++ ++extern int corosync_quorum_unregister_callback (quorum_callback_fn_t fn, void *context); ++ ++extern int corosync_quorum_initialize (struct quorum_callin_functions *fns, ++ sync_callback_fn_t *sync_callback_fn); ++ ++ ++extern int quorum_none(void); ++ ++ ++#endif /* QUORUM_H_DEFINED */ +diff -Naurd corosync-0.92/exec/service.c corosync-trunk/exec/service.c +--- corosync-0.92/exec/service.c 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/exec/service.c 2009-01-27 09:59:14.000000000 +0100 +@@ -78,6 +78,10 @@ + .name = "corosync_confdb", + .ver = 0, + }, ++ { ++ .name = "corosync_pload", ++ .ver = 0, ++ } + }; + + struct corosync_service_engine *ais_service[SERVICE_HANDLER_MAXIMUM_COUNT]; +diff -Naurd corosync-0.92/exec/sync.c corosync-trunk/exec/sync.c +--- corosync-0.92/exec/sync.c 2008-09-17 21:04:19.000000000 +0200 ++++ corosync-trunk/exec/sync.c 2008-12-08 16:55:41.000000000 +0100 +@@ -49,16 +49,17 @@ + #include + #include + +-#include ++#include + #include + #include + #include + #include + #include ++#include "quorum.h" + + #include "main.h" + #include "sync.h" +-#include "vsf.h" ++ + + LOGSYS_DECLARE_SUBSYS ("SYNC", LOG_INFO); + +@@ -72,8 +73,6 @@ + + static struct memb_ring_id *sync_ring_id; + +-static int vsf_none = 0; +- + static int (*sync_callbacks_retrieve) (int sync_id, struct sync_callbacks *callack); + + static struct sync_callbacks sync_callbacks; +@@ -93,8 +92,6 @@ + + static struct barrier_data barrier_data_process[PROCESSOR_COUNT_MAX]; + +-static struct corosync_vsf_iface_ver0 *vsf_iface; +- + static int sync_barrier_send (struct memb_ring_id *ring_id); + + static int sync_start_process (enum totem_callback_token_type type, void *data); +@@ -116,12 +113,6 @@ + unsigned int *joined_list, int joined_list_entries, + struct memb_ring_id *ring_id); + +-static void sync_primary_callback_fn ( +- unsigned int *view_list, +- int view_list_entries, +- int primary_designated, +- struct memb_ring_id *ring_id); +- + static struct totempg_group sync_group = { + .group = "sync", + .group_len = 4 +@@ -266,13 +257,10 @@ + + int sync_register ( + int (*callbacks_retrieve) (int sync_id, struct sync_callbacks *callack), +- void (*synchronization_completed) (void), +- char *vsf_type) ++ void (*synchronization_completed) (void)) ++ + { + unsigned int res; +- unsigned int vsf_handle; +- void *vsf_iface_p; +- char corosync_vsf_type[1024]; + + res = totempg_groups_initialize ( + &sync_group_handle, +@@ -292,42 +280,13 @@ + log_printf (LOG_LEVEL_ERROR, "Couldn't join group.\n"); + return (-1); + } +- +- if (strcmp (vsf_type, "none") == 0) { +- log_printf (LOG_LEVEL_NOTICE, +- "Not using a virtual synchrony filter.\n"); +- vsf_none = 1; +- } else { +- vsf_none = 0; +- +- sprintf (corosync_vsf_type, "corosync_vsf_%s", vsf_type); +- res = lcr_ifact_reference ( +- &vsf_handle, +- corosync_vsf_type, +- 0, +- &vsf_iface_p, +- 0); +- +- if (res == -1) { +- log_printf (LOG_LEVEL_NOTICE, +- "Couldn't load virtual synchrony filter %s\n", +- vsf_type); +- return (-1); +- } +- +- log_printf (LOG_LEVEL_NOTICE, +- "Using virtual synchrony filter %s\n", corosync_vsf_type); +- +- vsf_iface = (struct corosync_vsf_iface_ver0 *)vsf_iface_p; +- vsf_iface->init (sync_primary_callback_fn); +- } + + sync_callbacks_retrieve = callbacks_retrieve; + sync_synchronization_completed = synchronization_completed; + return (0); + } + +-static void sync_primary_callback_fn ( ++void sync_primary_callback_fn ( + unsigned int *view_list, + int view_list_entries, + int primary_designated, +@@ -335,13 +294,6 @@ + { + int i; + +- if (primary_designated) { +- log_printf (LOG_LEVEL_NOTICE, "This node is within the primary component and will provide service.\n"); +- } else { +- log_printf (LOG_LEVEL_NOTICE, "This node is within the non-primary component and will NOT provide any services.\n"); +- return; +- } +- + /* + * Execute configuration change for synchronization service + */ +@@ -521,7 +473,7 @@ + * If no virtual synchrony filter configured, then start + * synchronization process + */ +- if (vsf_none == 1) { ++ if (quorum_none() == 1) { + sync_primary_callback_fn ( + member_list, + member_list_entries, +@@ -546,7 +498,7 @@ + struct iovec iovec[2]; + int name_len; + +- ENTER("'%s'", name); ++ ENTER(); + + name_len = strlen (name) + 1; + msg.header.size = sizeof (msg) + name_len; +@@ -589,15 +541,6 @@ + return (sync_processing); + } + +-int sync_primary_designated (void) +-{ +- if (vsf_none == 1) { +- return (1); +- } else { +- return (vsf_iface->primary()); +- } +-} +- + /** + * Execute synchronization upon request for the named service + * @param name +@@ -608,7 +551,7 @@ + { + assert (name != NULL); + +- ENTER("'%s'", name); ++ ENTER(); + + if (sync_processing) { + return -1; +@@ -618,7 +561,7 @@ + TOTEM_CALLBACK_TOKEN_SENT, 0, /* don't delete after callback */ + sync_request_send, name); + +- LEAVE(""); ++ LEAVE(); + + return 0; + } +diff -Naurd corosync-0.92/exec/sync.h corosync-trunk/exec/sync.h +--- corosync-0.92/exec/sync.h 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/exec/sync.h 2008-12-08 16:55:41.000000000 +0100 +@@ -47,10 +47,10 @@ + char *name; + }; + ++struct corosync_api_v1; + int sync_register ( + int (*sync_callbacks_retrieve) (int sync_id, struct sync_callbacks *callbacks), +- void (*synchronization_completed) (void), +- char *vsf_type); ++ void (*synchronization_completed) (void)); + + int sync_in_process (void); + +@@ -64,4 +64,11 @@ + */ + extern int sync_request (char *name); + ++extern void sync_primary_callback_fn ( ++ unsigned int *view_list, ++ int view_list_entries, ++ int primary_designated, ++ struct memb_ring_id *ring_id); ++ ++ + #endif /* SYNC_H_DEFINED */ +diff -Naurd corosync-0.92/exec/timer.c corosync-trunk/exec/timer.c +--- corosync-0.92/exec/timer.c 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/exec/timer.c 2008-11-06 22:49:07.000000000 +0100 +@@ -56,7 +56,7 @@ + #include + + #include +-#include ++#include + #include + #include + #include +diff -Naurd corosync-0.92/exec/totemconfig.c corosync-trunk/exec/totemconfig.c +--- corosync-0.92/exec/totemconfig.c 2008-08-20 02:57:40.000000000 +0200 ++++ corosync-trunk/exec/totemconfig.c 2008-12-12 12:27:27.000000000 +0100 +@@ -76,6 +76,13 @@ + #define RRP_PROBLEM_COUNT_THRESHOLD_MIN 5 + + static char error_string_response[512]; ++static struct objdb_iface_ver0 *global_objdb; ++ ++static void add_totem_config_notification( ++ struct objdb_iface_ver0 *objdb, ++ struct totem_config *totem_config, ++ unsigned int totem_object_handle); ++ + + /* These just makes the code below a little neater */ + static inline int objdb_get_string ( +@@ -163,6 +170,50 @@ + return (0); + } + ++static void totem_volatile_config_read ( ++ struct objdb_iface_ver0 *objdb, ++ struct totem_config *totem_config, ++ unsigned int object_totem_handle) ++{ ++ objdb_get_int (objdb,object_totem_handle, "token", &totem_config->token_timeout); ++ ++ objdb_get_int (objdb,object_totem_handle, "token_retransmit", &totem_config->token_retransmit_timeout); ++ ++ objdb_get_int (objdb,object_totem_handle, "hold", &totem_config->token_hold_timeout); ++ ++ objdb_get_int (objdb,object_totem_handle, "token_retransmits_before_loss_const", &totem_config->token_retransmits_before_loss_const); ++ ++ objdb_get_int (objdb,object_totem_handle, "join", &totem_config->join_timeout); ++ objdb_get_int (objdb,object_totem_handle, "send_join", &totem_config->send_join_timeout); ++ ++ objdb_get_int (objdb,object_totem_handle, "consensus", &totem_config->consensus_timeout); ++ ++ objdb_get_int (objdb,object_totem_handle, "merge", &totem_config->merge_timeout); ++ ++ objdb_get_int (objdb,object_totem_handle, "downcheck", &totem_config->downcheck_timeout); ++ ++ objdb_get_int (objdb,object_totem_handle, "fail_recv_const", &totem_config->fail_to_recv_const); ++ ++ objdb_get_int (objdb,object_totem_handle, "seqno_unchanged_const", &totem_config->seqno_unchanged_const); ++ ++ objdb_get_int (objdb,object_totem_handle, "rrp_token_expired_timeout", &totem_config->rrp_token_expired_timeout); ++ ++ objdb_get_int (objdb,object_totem_handle, "rrp_problem_count_timeout", &totem_config->rrp_problem_count_timeout); ++ ++ objdb_get_int (objdb,object_totem_handle, "rrp_problem_count_threshold", &totem_config->rrp_problem_count_threshold); ++ ++ objdb_get_int (objdb,object_totem_handle, "heartbeat_failures_allowed", &totem_config->heartbeat_failures_allowed); ++ ++ objdb_get_int (objdb,object_totem_handle, "max_network_delay", &totem_config->max_network_delay); ++ ++ objdb_get_int (objdb,object_totem_handle, "window_size", &totem_config->window_size); ++ objdb_get_string (objdb, object_totem_handle, "vsftype", &totem_config->vsf_type); ++ ++ objdb_get_int (objdb,object_totem_handle, "max_messages", &totem_config->max_messages); ++ ++} ++ ++ + extern int totem_config_read ( + struct objdb_iface_ver0 *objdb, + struct totem_config *totem_config, +@@ -222,41 +273,10 @@ + + objdb_get_int (objdb,object_totem_handle, "netmtu", &totem_config->net_mtu); + +- objdb_get_int (objdb,object_totem_handle, "token", &totem_config->token_timeout); +- +- objdb_get_int (objdb,object_totem_handle, "token_retransmit", &totem_config->token_retransmit_timeout); +- +- objdb_get_int (objdb,object_totem_handle, "hold", &totem_config->token_hold_timeout); +- +- objdb_get_int (objdb,object_totem_handle, "token_retransmits_before_loss_const", &totem_config->token_retransmits_before_loss_const); +- +- objdb_get_int (objdb,object_totem_handle, "join", &totem_config->join_timeout); +- objdb_get_int (objdb,object_totem_handle, "send_join", &totem_config->send_join_timeout); +- +- objdb_get_int (objdb,object_totem_handle, "consensus", &totem_config->consensus_timeout); +- +- objdb_get_int (objdb,object_totem_handle, "merge", &totem_config->merge_timeout); +- +- objdb_get_int (objdb,object_totem_handle, "downcheck", &totem_config->downcheck_timeout); +- +- objdb_get_int (objdb,object_totem_handle, "fail_recv_const", &totem_config->fail_to_recv_const); +- +- objdb_get_int (objdb,object_totem_handle, "seqno_unchanged_const", &totem_config->seqno_unchanged_const); +- +- objdb_get_int (objdb,object_totem_handle, "rrp_token_expired_timeout", &totem_config->rrp_token_expired_timeout); +- +- objdb_get_int (objdb,object_totem_handle, "rrp_problem_count_timeout", &totem_config->rrp_problem_count_timeout); +- +- objdb_get_int (objdb,object_totem_handle, "rrp_problem_count_threshold", &totem_config->rrp_problem_count_threshold); +- +- objdb_get_int (objdb,object_totem_handle, "heartbeat_failures_allowed", &totem_config->heartbeat_failures_allowed); +- +- objdb_get_int (objdb,object_totem_handle, "max_network_delay", &totem_config->max_network_delay); +- +- objdb_get_int (objdb,object_totem_handle, "window_size", &totem_config->window_size); +- objdb_get_string (objdb, object_totem_handle, "vsftype", &totem_config->vsf_type); +- +- objdb_get_int (objdb,object_totem_handle, "max_messages", &totem_config->max_messages); ++ /* ++ * Get things that might change in the future ++ */ ++ totem_volatile_config_read (objdb, totem_config, object_totem_handle); + + objdb->object_find_create ( + object_totem_handle, +@@ -297,6 +317,8 @@ + + objdb->object_find_destroy (object_find_interface_handle); + ++ add_totem_config_notification(objdb, totem_config, object_totem_handle); ++ + return 0; + } + +@@ -323,7 +345,7 @@ + error_reason = "No multicast address specified"; + goto parse_error; + } +- ++ + if (totem_config->interfaces[i].ip_port == 0) { + error_reason = "No multicast port specified"; + goto parse_error; +@@ -331,7 +353,7 @@ + + if (totem_config->interfaces[i].mcast_addr.family == AF_INET6 && + totem_config->node_id == 0) { +- ++ + error_reason = "An IPV6 network requires that a node ID be specified."; + goto parse_error; + } +@@ -498,7 +520,7 @@ + totem_config->rrp_token_expired_timeout = + totem_config->token_retransmit_timeout; + } +- ++ + if (totem_config->rrp_token_expired_timeout < MINIMUM_TIMEOUT) { + sprintf (local_error_reason, "The RRP token expired timeout parameter (%d ms) may not be less then (%d ms).", + totem_config->rrp_token_expired_timeout, MINIMUM_TIMEOUT); +@@ -658,3 +680,92 @@ + return (-1); + + } ++ ++static void totem_key_change_notify(object_change_type_t change_type, ++ unsigned int parent_object_handle, ++ unsigned int object_handle, ++ void *object_name_pt, int object_name_len, ++ void *key_name_pt, int key_len, ++ void *key_value_pt, int key_value_len, ++ void *priv_data_pt) ++{ ++ struct totem_config *totem_config = priv_data_pt; ++ ++ if (memcmp(object_name_pt, "totem", object_name_len) == 0) ++ totem_volatile_config_read(global_objdb, ++ totem_config, ++ object_handle); // CHECK ++} ++ ++static void totem_objdb_reload_notify(objdb_reload_notify_type_t type, int flush, ++ void *priv_data_pt) ++{ ++ struct totem_config *totem_config = priv_data_pt; ++ unsigned int totem_object_handle; ++ ++ /* ++ * A new totem {} key might exist, cancel the ++ * existing notification at the start of reload, ++ * and start a new one on the new object when ++ * it's all settled. ++ */ ++ ++ if (type == OBJDB_RELOAD_NOTIFY_START) { ++ global_objdb->object_track_stop( ++ totem_key_change_notify, ++ NULL, ++ NULL, ++ NULL, ++ NULL); ++ } ++ ++ if (type == OBJDB_RELOAD_NOTIFY_END || ++ type == OBJDB_RELOAD_NOTIFY_FAILED) { ++ ++ ++ if (!totem_handle_find(global_objdb, ++ &totem_object_handle)) { ++ add_totem_config_notification(global_objdb, totem_config, totem_object_handle); ++ ++ /* ++ * Reload the configuration ++ */ ++ totem_volatile_config_read(global_objdb, ++ totem_config, ++ totem_object_handle); ++ ++ } ++ else { ++ log_printf(LOG_LEVEL_ERROR, "totem objdb tracking stopped, cannot find totem{} handle on objdb\n"); ++ } ++ } ++} ++ ++ ++static void add_totem_config_notification( ++ struct objdb_iface_ver0 *objdb, ++ struct totem_config *totem_config, ++ unsigned int totem_object_handle) ++{ ++ ++ global_objdb = objdb; ++ objdb->object_track_start(totem_object_handle, ++ 1, ++ totem_key_change_notify, ++ NULL, // object_create_notify, ++ NULL, // object_destroy_notify, ++ NULL, // object_reload_notify ++ totem_config); // priv_data ++ ++ /* ++ * Reload notify must be on the parent object ++ */ ++ objdb->object_track_start(OBJECT_PARENT_HANDLE, ++ 1, ++ NULL, // key_change_notify, ++ NULL, // object_create_notify, ++ NULL, // object_destroy_notify, ++ totem_objdb_reload_notify, // object_reload_notify ++ totem_config); // priv_data ++ ++} +diff -Naurd corosync-0.92/exec/totemconfig.h corosync-trunk/exec/totemconfig.h +--- corosync-0.92/exec/totemconfig.h 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/exec/totemconfig.h 2008-11-06 22:49:07.000000000 +0100 +@@ -36,7 +36,7 @@ + #define TOTEMCONFIG_H_DEFINED + + #include +-#include ++#include + #include + #include + #include +diff -Naurd corosync-0.92/exec/totemip.c corosync-trunk/exec/totemip.c +--- corosync-0.92/exec/totemip.c 2008-09-16 17:35:09.000000000 +0200 ++++ corosync-trunk/exec/totemip.c 2009-01-26 21:46:45.000000000 +0100 +@@ -226,7 +226,7 @@ + sin->sin_len = sizeof(struct sockaddr_in); + #endif + sin->sin_family = ip_addr->family; +- sin->sin_port = port; ++ sin->sin_port = ntohs(port); + memcpy(&sin->sin_addr, ip_addr->addr, sizeof(struct in_addr)); + *addrlen = sizeof(struct sockaddr_in); + ret = 0; +@@ -240,7 +240,7 @@ + sin->sin6_len = sizeof(struct sockaddr_in6); + #endif + sin->sin6_family = ip_addr->family; +- sin->sin6_port = port; ++ sin->sin6_port = ntohs(port); + sin->sin6_scope_id = 2; + memcpy(&sin->sin6_addr, ip_addr->addr, sizeof(struct in6_addr)); + +@@ -376,7 +376,8 @@ + int totemip_iface_check(struct totem_ip_address *bindnet, + struct totem_ip_address *boundto, + int *interface_up, +- int *interface_num) ++ int *interface_num, ++ int mask_high_bit) + { + int fd; + struct { +@@ -472,7 +473,7 @@ + memcpy(&network, RTA_DATA(tb[IFA_BROADCAST]), sizeof(uint32_t)); + memcpy(&addr, bindnet->addr, sizeof(uint32_t)); + +- if (addr == (network & netmask)) { ++ if ((addr & netmask) == (network & netmask)) { + memcpy(ipaddr.addr, RTA_DATA(tb[IFA_ADDRESS]), TOTEMIP_ADDRLEN); + found_if = 1; + } +@@ -514,6 +515,18 @@ + } + } + finished: ++ /* ++ * Mask 32nd bit off to workaround bugs in other poeples code ++ * if configuration requests it. ++ */ ++ if (ipaddr.family == AF_INET && ipaddr.nodeid == 0) { ++ unsigned int nodeid = 0; ++ memcpy (&nodeid, ipaddr.addr, sizeof (int)); ++ if (mask_high_bit) { ++ nodeid &= 0x7FFFFFFF; ++ } ++ ipaddr.nodeid = nodeid; ++ } + totemip_copy (boundto, &ipaddr); + close(fd); + return 0; +diff -Naurd corosync-0.92/exec/totemmrp.c corosync-trunk/exec/totemmrp.c +--- corosync-0.92/exec/totemmrp.c 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/exec/totemmrp.c 2008-12-01 19:44:55.000000000 +0100 +@@ -192,7 +192,7 @@ + return (res); + } + +-int totemmrp_my_nodeid_get (void) ++unsigned int totemmrp_my_nodeid_get (void) + { + return (totemsrp_my_nodeid_get (totemsrp_handle_in)); + } +diff -Naurd corosync-0.92/exec/totemnet.c corosync-trunk/exec/totemnet.c +--- corosync-0.92/exec/totemnet.c 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/exec/totemnet.c 2009-01-25 22:15:25.000000000 +0100 +@@ -137,7 +137,11 @@ + + int totemnet_log_level_debug; + +- void (*totemnet_log_printf) (char *file, int line, int level, char *format, ...) __attribute__((format(printf, 4, 5))); ++ int totemnet_subsys_id; ++ ++ void (*totemnet_log_printf) (int subsys, char *function, char *file, ++ int line, unsigned int level, char *format, ++ ...)__attribute__((format(printf, 6, 7))); + + totemnet_handle handle; + +@@ -226,8 +230,12 @@ + instance->my_memb_entries = 1; + } + +-#define log_printf(level, format, args...) \ +- instance->totemnet_log_printf (__FILE__, __LINE__, level, format, ##args) ++#define log_printf(level, format, args...) \ ++do { \ ++ instance->totemnet_log_printf (instance->totemnet_subsys_id, \ ++ (char *)__FUNCTION__, __FILE__, __LINE__, level, \ ++ format, ##args); \ ++} while (0); + + static int authenticate_and_decrypt ( + struct totemnet_instance *instance, +@@ -691,18 +699,9 @@ + int res; + + res = totemip_iface_check (bindnet, bound_to, +- interface_up, interface_num); ++ interface_up, interface_num, +++ 0); // TODO andrew can address this instance->totem_config->clear_node_high_bit); + +- /* +- * If the desired binding is to an IPV4 network and nodeid isn't +- * specified, retrieve the node id from this_ip network address +- * +- * IPV6 networks must have a node ID specified since the node id +- * field is only 32 bits. +- */ +- if (bound_to->family == AF_INET && bound_to->nodeid == 0) { +- memcpy (&bound_to->nodeid, bound_to->addr, sizeof (int)); +- } + + return (res); + } +@@ -1192,6 +1191,7 @@ + instance->totemnet_log_level_warning = totem_config->totem_logging_configuration.log_level_warning; + instance->totemnet_log_level_notice = totem_config->totem_logging_configuration.log_level_notice; + instance->totemnet_log_level_debug = totem_config->totem_logging_configuration.log_level_debug; ++ instance->totemnet_subsys_id = totem_config->totem_logging_configuration.log_subsys_id; + instance->totemnet_log_printf = totem_config->totem_logging_configuration.log_printf; + + /* +diff -Naurd corosync-0.92/exec/totempg.c corosync-trunk/exec/totempg.c +--- corosync-0.92/exec/totempg.c 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/exec/totempg.c 2009-01-25 22:25:25.000000000 +0100 +@@ -153,7 +153,10 @@ + static int totempg_log_level_warning; + static int totempg_log_level_notice; + static int totempg_log_level_debug; +-static void (*totempg_log_printf) (char *file, int line, int level, char *format, ...) __attribute__((format(printf, 4, 5))) = NULL; ++static int totempg_subsys_id; ++static void (*totempg_log_printf) (int subsys_id, char *function, char *file, ++ int line, unsigned int level, char *format, ++ ...) __attribute__((format(printf, 6, 7))); + + struct totem_config *totempg_totem_config; + +@@ -165,6 +168,13 @@ + struct list_head list; + }; + ++enum throw_away_mode_t { ++ THROW_AWAY_INACTIVE, ++ THROW_AWAY_ACTIVE ++}; ++ ++static enum throw_away_mode_t throw_away_mode = THROW_AWAY_INACTIVE; ++ + DECLARE_LIST_INIT(assembly_list_inuse); + + DECLARE_LIST_INIT(assembly_list_free); +@@ -225,8 +235,11 @@ + + static pthread_mutex_t mcast_msg_mutex = PTHREAD_MUTEX_INITIALIZER; + +-#define log_printf(level, format, args...) \ +- totempg_log_printf (__FILE__, __LINE__, level, format, ##args) ++#define log_printf(level, format, args...) \ ++do { \ ++ totempg_log_printf (totempg_subsys_id, (char *)__FUNCTION__, \ ++ __FILE__, __LINE__, level, format, ##args); \ ++} while (0); + + static struct assembly *assembly_ref (unsigned int nodeid) + { +@@ -558,43 +571,32 @@ + * the continued message. + */ + start = 0; +- if (continuation) { + +- if (continuation != assembly->last_frag_num) { +- log_printf (totempg_log_level_error, +- "Message continuation doesn't match previous frag e: %u - a: %u\n", +- assembly->last_frag_num, continuation); +- continuation = 0; +- } ++ if (throw_away_mode == THROW_AWAY_ACTIVE) { ++ /* Throw away the first msg block */ ++ if (mcast->fragmented == 0 || mcast->fragmented == 1) { ++ throw_away_mode = THROW_AWAY_INACTIVE; + +- if ((assembly->index == 0) || +- (!continuation && assembly->index)) { +- log_printf (totempg_log_level_error, +- "Throwing away broken message: continuation %u, index %u\n", +- continuation, assembly->index); +- continuation = 0; +- } +- +- /* +- * we decided to throw away the first continued message +- * in this buffer, if continuation was set to zero. +- */ +- if (!continuation) { + assembly->index += msg_lens[0]; + iov_delv.iov_base = &assembly->data[assembly->index]; + iov_delv.iov_len = msg_lens[1]; + start = 1; + } +- +- } +- +- for (i = start; i < msg_count; i++) { +- app_deliver_fn(nodeid, &iov_delv, 1, +- endian_conversion_required); +- assembly->index += msg_lens[i]; +- iov_delv.iov_base = &assembly->data[assembly->index]; +- if (i < (msg_count - 1)) { +- iov_delv.iov_len = msg_lens[i + 1]; ++ } else ++ if (throw_away_mode == THROW_AWAY_INACTIVE) { ++ if (continuation == assembly->last_frag_num) { ++ assembly->last_frag_num = mcast->fragmented; ++ for (i = start; i < msg_count; i++) { ++ app_deliver_fn(nodeid, &iov_delv, 1, ++ endian_conversion_required); ++ assembly->index += msg_lens[i]; ++ iov_delv.iov_base = &assembly->data[assembly->index]; ++ if (i < (msg_count - 1)) { ++ iov_delv.iov_len = msg_lens[i + 1]; ++ } ++ } ++ } else { ++ throw_away_mode = THROW_AWAY_ACTIVE; + } + } + +@@ -609,7 +611,6 @@ + /* + * Message is fragmented, keep around assembly list + */ +- assembly->last_frag_num = mcast->fragmented; + if (mcast->msg_count > 1) { + memmove (&assembly->data[0], + &assembly->data[assembly->index], +@@ -686,6 +687,7 @@ + totempg_log_level_notice = totem_config->totem_logging_configuration.log_level_notice; + totempg_log_level_debug = totem_config->totem_logging_configuration.log_level_debug; + totempg_log_printf = totem_config->totem_logging_configuration.log_printf; ++ totempg_subsys_id = totem_config->totem_logging_configuration.log_subsys_id; + + fragmentation_data = malloc (TOTEMPG_PACKET_SIZE); + if (fragmentation_data == 0) { +@@ -721,14 +723,16 @@ + * Multicast a message + */ + static int mcast_msg ( +- struct iovec *iovec, ++ struct iovec *iovec_in, + int iov_len, + int guarantee) + { + int res = 0; + struct totempg_mcast mcast; + struct iovec iovecs[3]; ++ struct iovec iovec[64]; + int i; ++ int dest, src; + int max_packet_size = 0; + int copy_len = 0; + int copy_base = 0; +@@ -737,6 +741,18 @@ + pthread_mutex_lock (&mcast_msg_mutex); + totemmrp_new_msg_signal (); + ++ /* ++ * Remove zero length iovectors from the list ++ */ ++ assert (iov_len < 64); ++ for (dest = 0, src = 0; src < iov_len; src++) { ++ if (iovec_in[src].iov_len) { ++ memcpy (&iovec[dest++], &iovec_in[src], ++ sizeof (struct iovec)); ++ } ++ } ++ iov_len = dest; ++ + max_packet_size = TOTEMPG_PACKET_SIZE - + (sizeof (unsigned short) * (mcast_packed_msg_count + 1)); + +@@ -774,6 +790,7 @@ + iovec[i].iov_base + copy_base, copy_len); + fragment_size += copy_len; + mcast_packed_msg_lens[mcast_packed_msg_count] += copy_len; ++ next_fragment = 1; + copy_len = 0; + copy_base = 0; + i++; +@@ -1243,7 +1260,7 @@ + return (iface_string); + } + +-int totempg_my_nodeid_get (void) ++unsigned int totempg_my_nodeid_get (void) + { + return (totemmrp_my_nodeid_get()); + } +diff -Naurd corosync-0.92/exec/totemrrp.c corosync-trunk/exec/totemrrp.c +--- corosync-0.92/exec/totemrrp.c 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/exec/totemrrp.c 2008-10-30 23:25:56.000000000 +0100 +@@ -194,7 +194,11 @@ + + int totemrrp_log_level_debug; + +- void (*totemrrp_log_printf) (char *file, int line, int level, char *format, ...) __attribute__((format(printf, 4, 5))); ++ int totemrrp_subsys_id; ++ ++ void (*totemrrp_log_printf) (int subsys, char *function, char *file, ++ int line, unsigned int level, char *format, ++ ...)__attribute__((format(printf, 6, 7))); + + totemrrp_handle handle; + +@@ -459,8 +463,14 @@ + .mutex = PTHREAD_MUTEX_INITIALIZER + }; + +-#define log_printf(level, format, args...) \ +- rrp_instance->totemrrp_log_printf (__FILE__, __LINE__, level, format, ##args) ++ ++#define log_printf(level, format, args...) \ ++do { \ ++ rrp_instance->totemrrp_log_printf ( \ ++ rrp_instance->totemrrp_subsys_id, \ ++ (char *)__FUNCTION__, __FILE__, __LINE__, level, \ ++ format, ##args); \ ++} while (0); + + /* + * None Replication Implementation +@@ -1426,6 +1436,7 @@ + instance->totemrrp_log_level_warning = totem_config->totem_logging_configuration.log_level_warning; + instance->totemrrp_log_level_notice = totem_config->totem_logging_configuration.log_level_notice; + instance->totemrrp_log_level_debug = totem_config->totem_logging_configuration.log_level_debug; ++ instance->totemrrp_subsys_id = totem_config->totem_logging_configuration.log_subsys_id; + instance->totemrrp_log_printf = totem_config->totem_logging_configuration.log_printf; + + instance->interfaces = totem_config->interfaces; +diff -Naurd corosync-0.92/exec/totemsrp.c corosync-trunk/exec/totemsrp.c +--- corosync-0.92/exec/totemsrp.c 2008-08-20 03:07:29.000000000 +0200 ++++ corosync-trunk/exec/totemsrp.c 2009-01-20 18:41:45.000000000 +0100 +@@ -429,7 +429,11 @@ + + int totemsrp_log_level_debug; + +- void (*totemsrp_log_printf) (char *file, int line, int level, char *format, ...) __attribute__((format(printf, 4, 5))); ++ int totemsrp_subsys_id; ++ ++ void (*totemsrp_log_printf) (int subsys, char *function, char *file, ++ int line, unsigned int level, char *format, ++ ...)__attribute__((format(printf, 6, 7)));; + + enum memb_state memb_state; + +@@ -607,8 +611,12 @@ + + static char *rundir = NULL; + +-#define log_printf(level, format, args...) \ +- instance->totemsrp_log_printf (__FILE__, __LINE__, level, format, ##args) ++#define log_printf(level, format, args...) \ ++do { \ ++ instance->totemsrp_log_printf (instance->totemsrp_subsys_id, \ ++ (char *)__FUNCTION__, __FILE__, __LINE__, level, \ ++ format, ##args); \ ++} while (0); + + void totemsrp_instance_initialize (struct totemsrp_instance *instance) + { +@@ -618,7 +626,7 @@ + + list_init (&instance->token_callback_sent_listhead); + +- instance->my_received_flg = 0; ++ instance->my_received_flg = 1; + + instance->my_token_seq = SEQNO_START_TOKEN - 1; + +@@ -709,6 +717,7 @@ + instance->totemsrp_log_level_warning = totem_config->totem_logging_configuration.log_level_warning; + instance->totemsrp_log_level_notice = totem_config->totem_logging_configuration.log_level_notice; + instance->totemsrp_log_level_debug = totem_config->totem_logging_configuration.log_level_debug; ++ instance->totemsrp_subsys_id = totem_config->totem_logging_configuration.log_subsys_id; + instance->totemsrp_log_printf = totem_config->totem_logging_configuration.log_printf; + + /* +@@ -904,11 +913,11 @@ + return (res); + } + +-int totemsrp_my_nodeid_get ( ++unsigned int totemsrp_my_nodeid_get ( + totemsrp_handle handle) + { + struct totemsrp_instance *instance; +- int res; ++ unsigned int res; + + res = hdb_handle_get (&totemsrp_instance_database, handle, + (void *)&instance); +@@ -1686,7 +1695,7 @@ + "entering OPERATIONAL state.\n"); + instance->memb_state = MEMB_STATE_OPERATIONAL; + +- instance->my_received_flg = 0; ++ instance->my_received_flg = 1; + + return; + } +@@ -2634,6 +2643,8 @@ + { + struct srp_addr *addr; + struct memb_commit_token_memb_entry *memb_list; ++ unsigned int high_aru; ++ unsigned int i; + + addr = (struct srp_addr *)commit_token->end_of_commit_token; + memb_list = (struct memb_commit_token_memb_entry *)(addr + commit_token->addr_entries); +@@ -2655,9 +2666,40 @@ + instance->my_received_flg = + (instance->my_aru == instance->my_high_seq_received); + +- memb_list[commit_token->memb_index].high_delivered = instance->my_high_delivered; + memb_list[commit_token->memb_index].received_flg = instance->my_received_flg; + ++ memb_list[commit_token->memb_index].high_delivered = instance->my_high_delivered; ++ /* ++ * find high aru up to current memb_index for all matching ring ids ++ * if any ring id matching memb_index has aru less then high aru set ++ * received flag for that entry to false ++ */ ++ high_aru = memb_list[commit_token->memb_index].aru; ++ for (i = 0; i <= commit_token->memb_index; i++) { ++ if (memcmp (&memb_list[commit_token->memb_index].ring_id, ++ &memb_list[i].ring_id, ++ sizeof (struct memb_ring_id)) == 0) { ++ ++ if (sq_lt_compare (high_aru, memb_list[i].aru)) { ++ high_aru = memb_list[i].aru; ++ } ++ } ++ } ++ ++ for (i = 0; i <= commit_token->memb_index; i++) { ++ if (memcmp (&memb_list[commit_token->memb_index].ring_id, ++ &memb_list[i].ring_id, ++ sizeof (struct memb_ring_id)) == 0) { ++ ++ if (sq_lt_compare (memb_list[i].aru, high_aru)) { ++ memb_list[i].received_flg = 0; ++ if (i == commit_token->memb_index) { ++ instance->my_received_flg = 0; ++ } ++ } ++ } ++ } ++ + commit_token->header.nodeid = instance->my_id.addr[0].nodeid; + commit_token->memb_index += 1; + assert (commit_token->memb_index <= commit_token->addr_entries); +@@ -2944,6 +2986,8 @@ + goto error_exit; + } + ++ token_hold_cancel_send (instance); ++ + callback_handle = (struct token_callback_instance *)malloc (sizeof (struct token_callback_instance)); + if (callback_handle == 0) { + return (-1); +diff -Naurd corosync-0.92/exec/totemsrp.h corosync-trunk/exec/totemsrp.h +--- corosync-0.92/exec/totemsrp.h 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/exec/totemsrp.h 2008-12-01 19:44:55.000000000 +0100 +@@ -104,7 +104,7 @@ + char ***status, + unsigned int *iface_count); + +-extern int totemsrp_my_nodeid_get ( ++extern unsigned int totemsrp_my_nodeid_get ( + totemsrp_handle handle); + + extern int totemsrp_my_family_get ( +diff -Naurd corosync-0.92/exec/util.c corosync-trunk/exec/util.c +--- corosync-0.92/exec/util.c 2008-09-17 21:04:19.000000000 +0200 ++++ corosync-trunk/exec/util.c 2008-12-18 09:28:46.000000000 +0100 +@@ -39,7 +39,7 @@ + #include + #include + +-#include ++#include + #include + #include + #include "util.h" +@@ -49,7 +49,7 @@ + /* + * Compare two names. returns non-zero on match. + */ +-int name_match(SaNameT *name1, SaNameT *name2) ++int name_match(cs_name_t *name1, cs_name_t *name2) + { + if (name1->length == name2->length) { + return ((strncmp ((char *)name1->value, (char *)name2->value, +@@ -61,17 +61,17 @@ + /* + * Get the time of day and convert to nanoseconds + */ +-SaTimeT clust_time_now(void) ++cs_time_t clust_time_now(void) + { + struct timeval tv; +- SaTimeT time_now; ++ cs_time_t time_now; + + if (gettimeofday(&tv, 0)) { + return 0ULL; + } + +- time_now = (SaTimeT)(tv.tv_sec) * 1000000000ULL; +- time_now += (SaTimeT)(tv.tv_usec) * 1000ULL; ++ time_now = (cs_time_t)(tv.tv_sec) * 1000000000ULL; ++ time_now += (cs_time_t)(tv.tv_usec) * 1000ULL; + + return time_now; + } +@@ -87,20 +87,19 @@ + { + log_printf (LOG_LEVEL_ERROR, "AIS Executive exiting " + "with status %d at %s:%u.\n", err, file, line); +- logsys_flush(); +- exit (EXIT_FAILURE); ++ exit (err); + } + + #define min(a,b) ((a) < (b) ? (a) : (b)) + +-char *getSaNameT (SaNameT *name) ++char *getcs_name_t (cs_name_t *name) + { +- static char ret_name[SA_MAX_NAME_LENGTH]; ++ static char ret_name[CS_MAX_NAME_LENGTH]; + + /* if string is corrupt (non-terminated), ensure it's displayed safely */ +- if (name->length >= SA_MAX_NAME_LENGTH || name->value[name->length] != '\0') { ++ if (name->length >= CS_MAX_NAME_LENGTH || name->value[name->length] != '\0') { + memset (ret_name, 0, sizeof (ret_name)); +- memcpy (ret_name, name->value, min(name->length, SA_MAX_NAME_LENGTH -1)); ++ memcpy (ret_name, name->value, min(name->length, CS_MAX_NAME_LENGTH -1)); + return (ret_name); + } + return ((char *)name->value); +@@ -134,16 +133,16 @@ + return (end_address); + } + +-void setSaNameT (SaNameT *name, char *str) { +- strncpy ((char *)name->value, str, SA_MAX_NAME_LENGTH); +- if (strlen ((char *)name->value) > SA_MAX_NAME_LENGTH) { +- name->length = SA_MAX_NAME_LENGTH; ++void setcs_name_t (cs_name_t *name, char *str) { ++ strncpy ((char *)name->value, str, CS_MAX_NAME_LENGTH); ++ if (strlen ((char *)name->value) > CS_MAX_NAME_LENGTH) { ++ name->length = CS_MAX_NAME_LENGTH; + } else { + name->length = strlen (str); + } + } + +-int SaNameTisEqual (SaNameT *str1, char *str2) { ++int cs_name_tisEqual (cs_name_t *str1, char *str2) { + if (str1->length == strlen (str2)) { + return ((strncmp ((char *)str1->value, (char *)str2, + str1->length)) == 0); +diff -Naurd corosync-0.92/exec/util.h corosync-trunk/exec/util.h +--- corosync-0.92/exec/util.h 2008-09-17 21:04:19.000000000 +0200 ++++ corosync-trunk/exec/util.h 2008-11-06 22:49:07.000000000 +0100 +@@ -37,12 +37,12 @@ + + #include + #include +-#include ++#include + + /* + * Get the time of day and convert to nanoseconds + */ +-extern SaTimeT clust_time_now(void); ++extern cs_time_t clust_time_now(void); + + enum e_ais_done { + AIS_DONE_EXIT = -1, +@@ -66,15 +66,15 @@ + /* + * Compare two names. returns non-zero on match. + */ +-extern int name_match(SaNameT *name1, SaNameT *name2); ++extern int name_match(cs_name_t *name1, cs_name_t *name2); + extern int mar_name_match(mar_name_t *name1, mar_name_t *name2); + #define corosync_exit_error(err) _corosync_exit_error ((err), __FILE__, __LINE__) + extern void _corosync_exit_error ( + enum e_ais_done err, const char *file, unsigned int line); + void _corosync_out_of_memory_error (void); +-extern char *getSaNameT (SaNameT *name); ++extern char *getcs_name_t (cs_name_t *name); + extern char *strstr_rs (const char *haystack, const char *needle); +-extern void setSaNameT (SaNameT *name, char *str); ++extern void setcs_name_t (cs_name_t *name, char *str); + char *get_mar_name_t (mar_name_t *name); +-extern int SaNameTisEqual (SaNameT *str1, char *str2); ++extern int cs_name_tisEqual (cs_name_t *str1, char *str2); + #endif /* UTIL_H_DEFINED */ +diff -Naurd corosync-0.92/exec/vsf.h corosync-trunk/exec/vsf.h +--- corosync-0.92/exec/vsf.h 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/exec/vsf.h 2008-12-08 16:55:41.000000000 +0100 +@@ -34,12 +34,14 @@ + #ifndef VSF_H_DEFINED + #define VSF_H_DEFINED + ++struct corosync_api_v1; + struct corosync_vsf_iface_ver0 { + + /* + * Executes a callback whenever component changes + */ + int (*init) ( ++ struct corosync_api_v1 *api, + void (*primary_callback_fn) ( + unsigned int *view_list, + int view_list_entries, +diff -Naurd corosync-0.92/exec/vsf_quorum.c corosync-trunk/exec/vsf_quorum.c +--- corosync-0.92/exec/vsf_quorum.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/exec/vsf_quorum.c 2009-01-08 12:12:10.000000000 +0100 +@@ -0,0 +1,468 @@ ++/* ++ * Copyright (c) 2008 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 Red Hat 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++LOGSYS_DECLARE_SUBSYS ("QUORUM", LOG_INFO); ++ ++struct quorum_pd { ++ unsigned char track_flags; ++ int tracking_enabled; ++ struct list_head list; ++ void *conn; ++}; ++ ++struct internal_callback_pd { ++ struct list_head list; ++ quorum_callback_fn_t callback; ++ void *context; ++}; ++ ++static void message_handler_req_lib_quorum_getquorate (void *conn, void *msg); ++static void message_handler_req_lib_quorum_trackstart (void *conn, void *msg); ++static void message_handler_req_lib_quorum_trackstop (void *conn, void *msg); ++static void send_library_notification(void *conn); ++static void send_internal_notification(void); ++static int quorum_exec_init_fn (struct corosync_api_v1 *api); ++static int quorum_lib_init_fn (void *conn); ++static int quorum_lib_exit_fn (void *conn); ++ ++static int primary_designated = 0; ++static struct corosync_api_v1 *corosync_api; ++static struct list_head lib_trackers_list; ++static struct list_head internal_trackers_list; ++static struct memb_ring_id quorum_ring_id; ++static int quorum_view_list_entries = 0; ++static int quorum_view_list[PROCESSOR_COUNT_MAX]; ++struct quorum_services_api_ver1 *quorum_iface = NULL; ++ ++static void (*sync_primary_callback_fn) ( ++ unsigned int *view_list, ++ int view_list_entries, ++ int primary_designated, ++ struct memb_ring_id *ring_id); ++ ++/* Internal quorum API function */ ++static void quorum_api_set_quorum(unsigned int *view_list, ++ int view_list_entries, ++ int quorum, struct memb_ring_id *ring_id) ++{ ++ primary_designated = quorum; ++ ++ if (primary_designated) { ++ log_printf (LOG_LEVEL_NOTICE, "This node is within the primary component and will provide service.\n"); ++ } else { ++ log_printf (LOG_LEVEL_NOTICE, "This node is within the non-primary component and will NOT provide any services.\n"); ++ } ++ ++ memcpy(&quorum_ring_id, ring_id, sizeof (quorum_ring_id)); ++ ++ quorum_view_list_entries = view_list_entries; ++ memcpy(quorum_view_list, view_list, sizeof(unsigned int)*view_list_entries); ++ ++ /* Tell sync() */ ++ sync_primary_callback_fn(view_list, view_list_entries, ++ primary_designated, &quorum_ring_id); ++ ++ /* Tell internal listeners */ ++ send_internal_notification(); ++ ++ /* Tell IPC listeners */ ++ send_library_notification(NULL); ++} ++ ++static struct corosync_lib_handler quorum_lib_service[] = ++{ ++ { /* 0 */ ++ .lib_handler_fn = message_handler_req_lib_quorum_getquorate, ++ .response_size = sizeof (struct res_lib_quorum_getquorate), ++ .response_id = MESSAGE_RES_QUORUM_GETQUORATE, ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 1 */ ++ .lib_handler_fn = message_handler_req_lib_quorum_trackstart, ++ .response_size = sizeof (mar_res_header_t), ++ .response_id = MESSAGE_RES_QUORUM_NOTIFICATION, ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 2 */ ++ .lib_handler_fn = message_handler_req_lib_quorum_trackstop, ++ .response_size = sizeof (mar_res_header_t), ++ .response_id = MESSAGE_RES_QUORUM_TRACKSTOP, ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED ++ } ++}; ++ ++static struct corosync_service_engine quorum_service_handler = { ++ .name = "corosync cluster quorum service v0.1", ++ .id = QUORUM_SERVICE, ++ .private_data_size = sizeof (struct quorum_pd), ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED, ++ .allow_inquorate = CS_LIB_ALLOW_INQUORATE, ++ .lib_init_fn = quorum_lib_init_fn, ++ .lib_exit_fn = quorum_lib_exit_fn, ++ .lib_engine = quorum_lib_service, ++ .exec_init_fn = quorum_exec_init_fn, ++ .lib_engine_count = sizeof (quorum_lib_service) / sizeof (struct corosync_lib_handler), ++}; ++ ++static struct lcr_iface corosync_quorum_ver0[1] = { ++ { ++ .name = "corosync_quorum", ++ .version = 0, ++ .versions_replace = 0, ++ .versions_replace_count = 0, ++ .dependencies = 0, ++ .dependency_count = 0, ++ .constructor = NULL, ++ .destructor = NULL, ++ .interfaces = NULL, ++ }, ++}; ++ ++static struct corosync_service_engine *quorum_get_service_handler_ver0 (void) ++{ ++ return (&quorum_service_handler); ++} ++ ++static struct lcr_comp quorum_comp_ver0 = { ++ .iface_count = 1, ++ .ifaces = corosync_quorum_ver0 ++}; ++ ++static struct corosync_service_engine_iface_ver0 quorum_service_handler_iface = { ++ .corosync_get_service_engine_ver0 = quorum_get_service_handler_ver0 ++}; ++ ++__attribute__ ((constructor)) static void quorum_comp_register (void) { ++ lcr_component_register (&quorum_comp_ver0); ++ lcr_interfaces_set (&corosync_quorum_ver0[0], &quorum_service_handler_iface); ++} ++ ++/* -------------------------------------------------- */ ++ ++ ++/* ++ * Internal API functions for corosync ++ */ ++ ++static int quorum_quorate(void) ++{ ++ return primary_designated; ++} ++ ++ ++static int quorum_register_callback(quorum_callback_fn_t function, void *context) ++{ ++ struct internal_callback_pd *pd = malloc(sizeof(struct internal_callback_pd)); ++ if (!pd) ++ return -1; ++ ++ pd->context = context; ++ pd->callback = function; ++ list_add (&pd->list, &internal_trackers_list); ++ ++ return 0; ++} ++ ++static int quorum_unregister_callback(quorum_callback_fn_t function, void *context) ++{ ++ struct internal_callback_pd *pd; ++ struct list_head *tmp; ++ ++ for (tmp = internal_trackers_list.next; tmp != &internal_trackers_list; tmp = tmp->next) { ++ ++ pd = list_entry(tmp, struct internal_callback_pd, list); ++ if (pd->callback == function && pd->context == context) { ++ list_del(&pd->list); ++ return 0; ++ } ++ } ++ return -1; ++} ++ ++static struct quorum_callin_functions callins = { ++ .quorate = quorum_quorate, ++ .register_callback = quorum_register_callback, ++ .unregister_callback = quorum_unregister_callback ++}; ++ ++/* --------------------------------------------------------------------- */ ++ ++static int quorum_exec_init_fn (struct corosync_api_v1 *api) ++{ ++ unsigned int find_handle; ++ unsigned int quorum_handle = 0; ++ unsigned int q_handle; ++ char *quorum_module; ++ int res; ++ void *quorum_iface_p; ++ ++ corosync_api = api; ++ list_init (&lib_trackers_list); ++ list_init (&internal_trackers_list); ++ ++ /* ++ * Tell corosync we have a quorum engine. ++ */ ++ api->quorum_initialize(&callins, &sync_primary_callback_fn); ++ ++ /* ++ * Look for a quorum provider ++ */ ++ api->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle); ++ api->object_find_next(find_handle, &quorum_handle); ++ api->object_find_destroy(find_handle); ++ ++ if (quorum_handle) { ++ if ( !(res = api->object_key_get(quorum_handle, ++ "provider", ++ strlen("provider"), ++ (void *)&quorum_module, ++ NULL))) { ++ ++ res = lcr_ifact_reference ( ++ &q_handle, ++ quorum_module, ++ 0, ++ &quorum_iface_p, ++ 0); ++ ++ if (res == -1) { ++ log_printf (LOG_LEVEL_NOTICE, ++ "Couldn't load quorum provider %s\n", ++ quorum_module); ++ return (-1); ++ } ++ ++ log_printf (LOG_LEVEL_NOTICE, ++ "Using quorum provider %s\n", quorum_module); ++ ++ quorum_iface = (struct quorum_services_api_ver1 *)quorum_iface_p; ++ quorum_iface->init (api, quorum_api_set_quorum); ++ } ++ } ++ if (!quorum_iface) { ++ /* ++ * With no quorum provider, we are always quorate ++ */ ++ primary_designated = 1; ++ } ++ ++ return (0); ++} ++ ++static int quorum_lib_init_fn (void *conn) ++{ ++ struct quorum_pd *pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); ++ ++ log_printf(LOG_LEVEL_DEBUG, "lib_init_fn: conn=%p\n", conn); ++ ++ list_init (&pd->list); ++ pd->conn = conn; ++ ++ return (0); ++} ++ ++static int quorum_lib_exit_fn (void *conn) ++{ ++ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); ++ ++ log_printf(LOG_LEVEL_DEBUG, "lib_exit_fn: conn=%p\n", conn); ++ ++ if (quorum_pd->tracking_enabled) { ++ list_del (&quorum_pd->list); ++ list_init (&quorum_pd->list); ++ } ++ return (0); ++} ++ ++ ++static void send_internal_notification(void) ++{ ++ struct list_head *tmp; ++ struct internal_callback_pd *pd; ++ ++ for (tmp = internal_trackers_list.next; tmp != &internal_trackers_list; tmp = tmp->next) { ++ ++ pd = list_entry(tmp, struct internal_callback_pd, list); ++ ++ pd->callback(primary_designated, pd->context); ++ } ++} ++ ++static void send_library_notification(void *conn) ++{ ++ int size = sizeof(struct res_lib_quorum_notification) + sizeof(unsigned int)*quorum_view_list_entries; ++ char buf[size]; ++ struct res_lib_quorum_notification *res_lib_quorum_notification = (struct res_lib_quorum_notification *)buf; ++ struct list_head *tmp; ++ int i; ++ ++ log_printf(LOG_LEVEL_DEBUG, "sending quorum notification to %p, length = %d\n", conn, size); ++ ++ res_lib_quorum_notification->quorate = primary_designated; ++ res_lib_quorum_notification->ring_seq = quorum_ring_id.seq; ++ res_lib_quorum_notification->view_list_entries = quorum_view_list_entries; ++ for (i=0; iview_list[i] = quorum_view_list[i]; ++ } ++ ++ res_lib_quorum_notification->header.id = MESSAGE_RES_QUORUM_NOTIFICATION; ++ res_lib_quorum_notification->header.size = size; ++ res_lib_quorum_notification->header.error = CS_OK; ++ ++ /* Send it to all interested parties */ ++ if (conn) { ++ corosync_api->ipc_conn_send_response(conn, res_lib_quorum_notification, size); ++ } ++ else { ++ struct quorum_pd *qpd; ++ ++ for (tmp = lib_trackers_list.next; tmp != &lib_trackers_list; tmp = tmp->next) { ++ ++ qpd = list_entry(tmp, struct quorum_pd, list); ++ ++ corosync_api->ipc_conn_send_response(corosync_api->ipc_conn_partner_get(qpd->conn), ++ res_lib_quorum_notification, size); ++ } ++ } ++ return; ++} ++ ++static void message_handler_req_lib_quorum_getquorate (void *conn, void *msg) ++{ ++ struct res_lib_quorum_getquorate res_lib_quorum_getquorate; ++ ++ log_printf(LOG_LEVEL_DEBUG, "got quorate request on %p\n", conn); ++ ++ /* send status */ ++ res_lib_quorum_getquorate.quorate = primary_designated; ++ res_lib_quorum_getquorate.header.size = sizeof(res_lib_quorum_getquorate); ++ res_lib_quorum_getquorate.header.id = MESSAGE_RES_QUORUM_GETQUORATE; ++ res_lib_quorum_getquorate.header.error = CS_OK; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_quorum_getquorate, sizeof(res_lib_quorum_getquorate)); ++} ++ ++ ++static void message_handler_req_lib_quorum_trackstart (void *conn, void *msg) ++{ ++ struct req_lib_quorum_trackstart *req_lib_quorum_trackstart = (struct req_lib_quorum_trackstart *)msg; ++ mar_res_header_t res; ++ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); ++ ++ log_printf(LOG_LEVEL_DEBUG, "got trackstart request on %p\n", conn); ++ ++ /* ++ * If an immediate listing of the current cluster membership ++ * is requested, generate membership list ++ */ ++ if (req_lib_quorum_trackstart->track_flags & CS_TRACK_CURRENT || ++ req_lib_quorum_trackstart->track_flags & CS_TRACK_CHANGES) { ++ log_printf(LOG_LEVEL_DEBUG, "sending initial status to %p\n", conn); ++ send_library_notification(corosync_api->ipc_conn_partner_get (conn)); ++ } ++ ++ /* ++ * Record requests for tracking ++ */ ++ if (req_lib_quorum_trackstart->track_flags & CS_TRACK_CHANGES || ++ req_lib_quorum_trackstart->track_flags & CS_TRACK_CHANGES_ONLY) { ++ ++ quorum_pd->track_flags = req_lib_quorum_trackstart->track_flags; ++ quorum_pd->tracking_enabled = 1; ++ ++ list_add (&quorum_pd->list, &lib_trackers_list); ++ } ++ ++ /* send status */ ++ res.size = sizeof(res); ++ res.id = MESSAGE_RES_QUORUM_TRACKSTART; ++ res.error = CS_OK; ++ corosync_api->ipc_conn_send_response(conn, &res, sizeof(mar_res_header_t)); ++} ++ ++static void message_handler_req_lib_quorum_trackstop (void *conn, void *msg) ++{ ++ mar_res_header_t res; ++ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); ++ ++ log_printf(LOG_LEVEL_DEBUG, "got trackstop request on %p\n", conn); ++ ++ if (quorum_pd->tracking_enabled) { ++ res.error = CS_OK; ++ quorum_pd->tracking_enabled = 0; ++ list_del (&quorum_pd->list); ++ list_init (&quorum_pd->list); ++ } else { ++ res.error = CS_ERR_NOT_EXIST; ++ } ++ ++ /* send status */ ++ res.size = sizeof(res); ++ res.id = MESSAGE_RES_QUORUM_TRACKSTOP; ++ res.error = CS_OK; ++ corosync_api->ipc_conn_send_response(conn, &res, sizeof(mar_res_header_t)); ++} ++ +diff -Naurd corosync-0.92/exec/vsf_ykd.c corosync-trunk/exec/vsf_ykd.c +--- corosync-0.92/exec/vsf_ykd.c 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/exec/vsf_ykd.c 2008-12-08 16:55:41.000000000 +0100 +@@ -56,12 +56,12 @@ + #include + + #include ++#include ++#include ++#include + #include + #include + +-#include "main.h" +-#include "vsf.h" +- + LOGSYS_DECLARE_SUBSYS ("YKD", LOG_INFO); + + #define YKD_PROCESSOR_COUNT_MAX 32 +@@ -108,7 +108,7 @@ + + struct ykd_state ykd_state; + +-static totempg_groups_handle ykd_group_handle; ++static cs_tpg_handle ykd_group_handle; + + static struct state_received state_received_confchg[YKD_PROCESSOR_COUNT_MAX]; + +@@ -140,6 +140,8 @@ + + static void *ykd_state_send_callback_token_handle = 0; + ++static struct corosync_api_v1 *api; ++ + static void (*ykd_primary_callback_fn) ( + unsigned int *view_list, + int view_list_entries, +@@ -168,15 +170,15 @@ + iovec[1].iov_base = (char *)&ykd_state; + iovec[1].iov_len = sizeof (struct ykd_state); + +- res = totempg_groups_mcast_joined (ykd_group_handle, iovec, 2, +- TOTEMPG_AGREED); ++ res = api->tpg_joined_mcast (ykd_group_handle, iovec, 2, ++ TOTEM_AGREED); + + return (res); + } + + static void ykd_state_send (void) + { +- totempg_callback_token_create ( ++ api->totem_callback_token_create ( + &ykd_state_send_callback_token_handle, + TOTEM_CALLBACK_TOKEN_SENT, + 1, /* delete after callback */ +@@ -195,15 +197,15 @@ + iovec.iov_base = (char *)&header; + iovec.iov_len = sizeof (struct ykd_header); + +- res = totempg_groups_mcast_joined (ykd_group_handle, &iovec, 1, +- TOTEMPG_AGREED); ++ res = api->tpg_joined_mcast (ykd_group_handle, &iovec, 1, ++ TOTEM_AGREED); + + return (res); + } + + static void ykd_attempt_send (void) + { +- totempg_callback_token_create ( ++ api->totem_callback_token_create ( + &ykd_attempt_send_callback_token_handle, + TOTEM_CALLBACK_TOKEN_SENT, + 1, /* delete after callback */ +@@ -460,7 +462,7 @@ + memcpy (&ykd_ring_id, ring_id, sizeof (struct memb_ring_id)); + + if (first_run) { +- ykd_state.last_primary.member_list[0] = totempg_my_nodeid_get(); ++ ykd_state.last_primary.member_list[0] = api->totem_nodeid_get(); + ykd_state.last_primary.member_list_entries = 1; + ykd_state.last_primary.session_id = 0; + first_run = 0; +@@ -493,53 +495,41 @@ + ykd_state_send (); + } + +-struct totempg_group ykd_group = { ++struct corosync_tpg_group ykd_group = { + .group = "ykd", + .group_len = 3 + }; + +-static int ykd_init ( +- void (*primary_callback_fn) ( +- unsigned int *view_list, +- int view_list_entries, +- int primary_designated, +- struct memb_ring_id *ring_id)) ++static void ykd_init ( ++ struct corosync_api_v1 *corosync_api, ++ quorum_set_quorate_fn_t set_primary) + { +- ykd_primary_callback_fn = primary_callback_fn; ++ ykd_primary_callback_fn = set_primary; ++ api = corosync_api; + +- totempg_groups_initialize ( ++ api->tpg_init ( + &ykd_group_handle, + ykd_deliver_fn, + ykd_confchg_fn); + +- totempg_groups_join ( ++ api->tpg_join ( + ykd_group_handle, + &ykd_group, + 1); + + ykd_state_init (); +- +- return (0); +-} +- +-/* +- * Returns 1 if this processor is in the primary +- */ +-static int ykd_primary (void) { +- return (primary_designated); + } + + /* + * lcrso object definition + */ +-static struct corosync_vsf_iface_ver0 vsf_ykd_iface_ver0 = { ++static struct quorum_services_api_ver1 vsf_ykd_iface_ver0 = { + .init = ykd_init, +- .primary = ykd_primary + }; + + static struct lcr_iface corosync_vsf_ykd_ver0[1] = { + { +- .name = "corosync_vsf_ykd", ++ .name = "corosync_quorum_ykd", + .version = 0, + .versions_replace = 0, + .versions_replace_count = 0, +diff -Naurd corosync-0.92/include/corosync/ais_util.h corosync-trunk/include/corosync/ais_util.h +--- corosync-0.92/include/corosync/ais_util.h 2008-08-14 16:59:50.000000000 +0200 ++++ corosync-trunk/include/corosync/ais_util.h 2008-11-06 22:49:07.000000000 +0100 +@@ -67,71 +67,71 @@ + + struct saVersionDatabase { + int versionCount; +- SaVersionT *versionsSupported; ++ cs_version_t *versionsSupported; + }; + +-SaAisErrorT saSendMsgRetry ( ++cs_error_t saSendMsgRetry ( + int s, + struct iovec *iov, + int iov_len); + +-SaAisErrorT saSendMsgReceiveReply ( ++cs_error_t saSendMsgReceiveReply ( + int s, + struct iovec *iov, + int iov_len, + void *responseMessage, + int responseLen); + +-SaAisErrorT saSendReceiveReply ( ++cs_error_t saSendReceiveReply ( + int s, + void *requestMessage, + int requestLen, + void *responseMessage, + int responseLen); + +-SaAisErrorT ++cs_error_t + saPollRetry ( + struct pollfd *ufds, + unsigned int nfds, + int timeout); + +-SaAisErrorT ++cs_error_t + saHandleCreate ( + struct saHandleDatabase *handleDatabase, + int instanceSize, +- SaUint64T *handleOut); ++ uint64_t *handleOut); + +-SaAisErrorT ++cs_error_t + saHandleDestroy ( + struct saHandleDatabase *handleDatabase, +- SaUint64T handle); ++ uint64_t handle); + +-SaAisErrorT ++cs_error_t + saHandleInstanceGet ( + struct saHandleDatabase *handleDatabase, +- SaUint64T handle, ++ uint64_t handle, + void **instance); + +-SaAisErrorT ++cs_error_t + saHandleInstancePut ( + struct saHandleDatabase *handleDatabase, +- SaUint64T handle); ++ uint64_t handle); + +-SaAisErrorT ++cs_error_t + saVersionVerify ( + struct saVersionDatabase *versionDatabase, +- SaVersionT *version); ++ cs_version_t *version); + + #define offset_of(type,member) (int)(&(((type *)0)->member)) + +-SaTimeT ++cs_time_t + clustTimeNow(void); + +-extern SaAisErrorT saServiceConnect ( ++extern cs_error_t saServiceConnect ( + int *responseOut, int *callbackOut, enum service_types service); + +-extern SaAisErrorT saRecvRetry (int s, void *msg, size_t len); ++extern cs_error_t saRecvRetry (int s, void *msg, size_t len); + +-extern SaAisErrorT saSendRetry (int s, const void *msg, size_t len); ++extern cs_error_t saSendRetry (int s, const void *msg, size_t len); + + #endif /* AIS_UTIL_H_DEFINED */ +diff -Naurd corosync-0.92/include/corosync/cfg.h corosync-trunk/include/corosync/cfg.h +--- corosync-0.92/include/corosync/cfg.h 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/include/corosync/cfg.h 2009-01-29 10:17:43.000000000 +0100 +@@ -1,6 +1,6 @@ + /* + * Copyright (c) 2005 MontaVista Software, Inc. +- * Copyright (c) 2006 Red Hat, Inc. ++ * Copyright (c) 2006-2009 Red Hat, Inc. + * + * All rights reserved. + * +@@ -36,33 +36,33 @@ + #define AIS_COROSYNCCFG_H_DEFINED + + #include +-#include "saAis.h" ++#include + +-typedef SaUint64T corosync_cfg_handle_t; ++typedef uint64_t corosync_cfg_handle_t; + + typedef enum { + COROSYNC_CFG_ADMINISTRATIVETARGET_SERVICEUNIT = 0, + COROSYNC_CFG_ADMINISTRATIVETARGET_SERVICEGROUP = 1, + COROSYNC_CFG_ADMINISTRATIVETARGET_COMPONENTSERVICEINSTANCE = 2, + COROSYNC_CFG_ADMINISTRATIVETARGET_NODE = 3 +-} CorosyncCfgAdministrativeTargetT; ++} corosync_cfg_administrative_target_t; + + typedef enum { + COROSYNC_CFG_ADMINISTRATIVESTATE_UNLOCKED = 0, + COROSYNC_CFG_ADMINISTRATIVESTATE_LOCKED = 1, + COROSYNC_CFG_ADMINISTRATIVESTATE_STOPPING = 2 +-} CorosyncCfgAdministrativeStateT; ++} corosync_cfg_administrative_state_t; + + typedef enum { + COROSYNC_CFG_OPERATIONALSTATE_ENABLED = 1, + COROSYNC_CFG_OPERATIONALSTATE_DISABLED = 2 +-} CorosyncCfgOperationalStateT; ++} corosync_cfg_operational_state_t; + + typedef enum { + COROSYNC_CFG_READINESSSTATE_OUTOFSERVICE = 1, + COROSYNC_CFG_READINESSSTATE_INSERVICE = 2, + COROSYNC_CFG_READINESSSTATE_STOPPING = 3 +-} CorosyncCfgReadinessStateT; ++} corosync_cfg_readiness_state_t; + + typedef enum { + COROSYNC_CFG_PRESENCESTATE_UNINSTANTIATED = 1, +@@ -72,7 +72,7 @@ + COROSYNC_CFG_PRESENCESTATE_RESTARTING = 5, + COROSYNC_CFG_PRESENCESTATE_INSTANTIATION_FAILED = 6, + COROSYNC_CFG_PRESENCESTATE_TERMINATION_FAILED = 7 +-} CorosyncCfgPresenceStateT; ++} corosync_cfg_presence_state_t; + + typedef enum { + COROSYNC_CFG_STATETYPE_OPERATIONAL = 0, +@@ -80,27 +80,63 @@ + COROSYNC_CFG_STATETYPE_READINESS = 2, + COROSYNC_CFG_STATETYPE_HA = 3, + COROSYNC_CFG_STATETYPE_PRESENCE = 4 +-} CorosyncCfgStateTypeT; ++} corosync_cfg_state_type_t; ++ ++/* Shutdown types. ++ REQUEST is the normal shutdown. other daemons will be consulted ++ REGARDLESS will tell other daemons but ignore their opinions ++ IMMEDIATE will shut down straight away (but still tell other nodes) ++*/ ++typedef enum { ++ COROSYNC_CFG_SHUTDOWN_FLAG_REQUEST = 0, ++ COROSYNC_CFG_SHUTDOWN_FLAG_REGARDLESS = 1, ++ COROSYNC_CFG_SHUTDOWN_FLAG_IMMEDIATE = 2, ++} corosync_cfg_shutdown_flags_t; ++ ++typedef enum { ++ COROSYNC_CFG_SHUTDOWN_FLAG_NO = 0, ++ COROSYNC_CFG_SHUTDOWN_FLAG_YES = 1, ++} corosync_cfg_shutdown_reply_flags_t; + + typedef struct { +- SaNameT name; +- CorosyncCfgStateTypeT stateType; +- CorosyncCfgAdministrativeStateT administrativeState; +-} CorosyncCfgStateNotificationT; ++ cs_name_t name; ++ corosync_cfg_state_type_t state_type; ++ corosync_cfg_administrative_state_t administrative_state; ++} corosync_cfg_state_notification_t; + + typedef struct { +- SaUint32T numberOfItems; +- CorosyncCfgStateNotificationT *notification; +-} CorosyncCfgStateNotificationBufferT; ++ uint32_t number_of_items; ++ corosync_cfg_state_notification_t *notification; ++} corosync_cfg_state_notification_buffer_t; + +-typedef void (*CorosyncCfgStateTrackCallbackT) ( +- CorosyncCfgStateNotificationBufferT *notificationBuffer, +- SaAisErrorT error); ++typedef void (*corosync_cfg_state_track_callback_t) ( ++ corosync_cfg_state_notification_buffer_t *notification_buffer, ++ cs_error_t error); ++ ++typedef void (*corosync_cfg_shutdown_callback_t) ( ++ corosync_cfg_handle_t cfg_handle, ++ corosync_cfg_shutdown_flags_t flags); + + typedef struct { +- CorosyncCfgStateTrackCallbackT +- corosyncCfgStateTrackCallback; +-} CorosyncCfgCallbacksT; ++ corosync_cfg_state_track_callback_t corosync_cfg_state_track_callback; ++ corosync_cfg_shutdown_callback_t corosync_cfg_shutdown_callback; ++} corosync_cfg_callbacks_t; ++ ++/* ++ * A node address. This is a complete sockaddr_in[6] ++ * To explain: ++ * If you cast cna_address to a 'struct sockaddr', the sa_family field ++ * will be AF_INET or AF_INET6. Armed with that knowledge you can then ++ * cast it to a sockaddr_in or sockaddr_in6 and pull out the address. ++ * No other sockaddr fields are valid. ++ * Also, you must ignore any part of the sockaddr beyond the length supplied ++ */ ++typedef struct ++{ ++ int address_length; ++ char address[sizeof(struct sockaddr_in6)]; ++} corosync_cfg_node_address_t; ++ + + /* + * Interfaces +@@ -109,70 +145,97 @@ + extern "C" { + #endif + +-SaAisErrorT ++cs_error_t + corosync_cfg_initialize ( + corosync_cfg_handle_t *cfg_handle, +- const CorosyncCfgCallbacksT *cfgCallbacks); ++ const corosync_cfg_callbacks_t *cfg_callbacks); + +-SaAisErrorT ++cs_error_t + corosync_cfg_fd_get ( + corosync_cfg_handle_t cfg_handle, +- SaSelectionObjectT *selectionObject); ++ int32_t *selection_fd); + +-SaAisErrorT ++cs_error_t + corosync_cfg_dispatch ( + corosync_cfg_handle_t cfg_handle, +- SaDispatchFlagsT dispatchFlags); ++ cs_dispatch_flags_t dispatch_flags); + +-SaAisErrorT ++cs_error_t + corosync_cfg_finalize ( + corosync_cfg_handle_t cfg_handle); + +-SaAisErrorT ++cs_error_t + corosync_cfg_ring_status_get ( + corosync_cfg_handle_t cfg_handle, + char ***interface_names, + char ***status, + unsigned int *interface_count); + +-SaAisErrorT ++cs_error_t + corosync_cfg_ring_reenable ( + corosync_cfg_handle_t cfg_handle); + +-SaAisErrorT ++cs_error_t + corosync_cfg_service_load ( + corosync_cfg_handle_t cfg_handle, + char *service_name, + unsigned int service_ver); + +-SaAisErrorT ++cs_error_t + corosync_cfg_service_unload ( + corosync_cfg_handle_t cfg_handle, + char *service_name, + unsigned int service_ver); + +-SaAisErrorT ++cs_error_t + corosync_cfg_administrative_state_get ( + corosync_cfg_handle_t cfg_handle, +- CorosyncCfgAdministrativeTargetT administrativeTarget, +- CorosyncCfgAdministrativeStateT *administrativeState); ++ corosync_cfg_administrative_target_t administrative_target, ++ corosync_cfg_administrative_state_t *administrative_state); + +-SaAisErrorT ++cs_error_t + corosync_cfg_administrative_state_set ( + corosync_cfg_handle_t cfg_handle, +- CorosyncCfgAdministrativeTargetT administrativeTarget, +- CorosyncCfgAdministrativeStateT administrativeState); ++ corosync_cfg_administrative_target_t administrative_target, ++ corosync_cfg_administrative_state_t administrative_state); + +-SaAisErrorT ++cs_error_t ++corosync_cfg_kill_node ( ++ corosync_cfg_handle_t cfg_handle, ++ unsigned int nodeid, ++ char *reason); ++ ++cs_error_t ++corosync_cfg_try_shutdown ( ++ corosync_cfg_handle_t cfg_handle, ++ corosync_cfg_shutdown_flags_t flags); ++ ++ ++cs_error_t ++corosync_cfg_replyto_shutdown ( ++ corosync_cfg_handle_t cfg_handle, ++ corosync_cfg_shutdown_reply_flags_t flags); ++ ++cs_error_t + corosync_cfg_state_track ( + corosync_cfg_handle_t cfg_handle, +- SaUint8T trackFlags, +- const CorosyncCfgStateNotificationT *notificationBuffer); ++ uint8_t track_flags, ++ const corosync_cfg_state_notification_t *notification_buffer); + +-SaAisErrorT ++cs_error_t + corosync_cfg_state_track_stop ( + corosync_cfg_handle_t cfg_handle); + ++ ++cs_error_t ++corosync_cfg_get_node_addrs ( ++ corosync_cfg_handle_t cfg_handle, ++ int nodeid, ++ int max_addrs, ++ int *num_addrs, ++ corosync_cfg_node_address_t *addrs); ++ ++ + #ifdef __cplusplus + } + #endif +diff -Naurd corosync-0.92/include/corosync/confdb.h corosync-trunk/include/corosync/confdb.h +--- corosync-0.92/include/corosync/confdb.h 2008-09-03 09:58:08.000000000 +0200 ++++ corosync-trunk/include/corosync/confdb.h 2008-11-06 22:49:07.000000000 +0100 +@@ -34,6 +34,7 @@ + #ifndef COROSYNC_CONFDB_H_DEFINED + #define COROSYNC_CONFDB_H_DEFINED + ++#include + /** + * @addtogroup confdb_corosync + * +@@ -44,33 +45,11 @@ + #define OBJECT_PARENT_HANDLE 0 + + typedef enum { +- CONFDB_DISPATCH_ONE, +- CONFDB_DISPATCH_ALL, +- CONFDB_DISPATCH_BLOCKING +-} confdb_dispatch_t; +- +-typedef enum { + CONFDB_TRACK_DEPTH_ONE, + CONFDB_TRACK_DEPTH_RECURSIVE + } confdb_track_depth_t; + + typedef enum { +- CONFDB_OK = 1, +- CONFDB_ERR_LIBRARY = 2, +- CONFDB_ERR_TIMEOUT = 5, +- CONFDB_ERR_TRY_AGAIN = 6, +- CONFDB_ERR_INVALID_PARAM = 7, +- CONFDB_ERR_NO_MEMORY = 8, +- CONFDB_ERR_BAD_HANDLE = 9, +- CONFDB_ERR_ACCESS = 11, +- CONFDB_ERR_NOT_EXIST = 12, +- CONFDB_ERR_EXIST = 14, +- CONFDB_ERR_CONTEXT_NOT_FOUND = 17, +- CONFDB_ERR_NOT_SUPPORTED = 20, +- CONFDB_ERR_SECURITY = 29, +-} confdb_error_t; +- +-typedef enum { + OBJECT_KEY_CREATED, + OBJECT_KEY_REPLACED, + OBJECT_KEY_DELETED +@@ -112,28 +91,28 @@ + /* + * Create a new confdb connection + */ +-confdb_error_t confdb_initialize ( ++cs_error_t confdb_initialize ( + confdb_handle_t *handle, + confdb_callbacks_t *callbacks); + + /* + * Close the confdb handle + */ +-confdb_error_t confdb_finalize ( ++cs_error_t confdb_finalize ( + confdb_handle_t handle); + + + /* + * Write back the configuration + */ +-confdb_error_t confdb_write ( ++cs_error_t confdb_write ( + confdb_handle_t handle, + char *error_text); + + /* + * Reload the configuration + */ +-confdb_error_t confdb_reload ( ++cs_error_t confdb_reload ( + confdb_handle_t handle, + int flush, + char *error_text); +@@ -142,43 +121,43 @@ + * Get a file descriptor on which to poll. confdb_handle_t is NOT a + * file descriptor and may not be used directly. + */ +-confdb_error_t confdb_fd_get ( ++cs_error_t confdb_fd_get ( + confdb_handle_t handle, + int *fd); + + /* + * Dispatch configuration changes + */ +-confdb_error_t confdb_dispatch ( ++cs_error_t confdb_dispatch ( + confdb_handle_t handle, +- confdb_dispatch_t dispatch_types); ++ cs_dispatch_flags_t dispatch_types); + + /* + * Change notification + */ +-confdb_error_t confdb_track_changes ( ++cs_error_t confdb_track_changes ( + confdb_handle_t handle, + unsigned int object_handle, + unsigned int flags); + +-confdb_error_t confdb_stop_track_changes ( ++cs_error_t confdb_stop_track_changes ( + confdb_handle_t handle); + + /* + * Manipulate objects + */ +-confdb_error_t confdb_object_create ( ++cs_error_t confdb_object_create ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *object_name, + int object_name_len, + unsigned int *object_handle); + +-confdb_error_t confdb_object_destroy ( ++cs_error_t confdb_object_destroy ( + confdb_handle_t handle, + unsigned int object_handle); + +-confdb_error_t confdb_object_parent_get ( ++cs_error_t confdb_object_parent_get ( + confdb_handle_t handle, + unsigned int object_handle, + unsigned int *parent_object_handle); +@@ -186,7 +165,7 @@ + /* + * Manipulate keys + */ +-confdb_error_t confdb_key_create ( ++cs_error_t confdb_key_create ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +@@ -194,7 +173,7 @@ + void *value, + int value_len); + +-confdb_error_t confdb_key_delete ( ++cs_error_t confdb_key_delete ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +@@ -205,7 +184,7 @@ + /* + * Key queries + */ +-confdb_error_t confdb_key_get ( ++cs_error_t confdb_key_get ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +@@ -213,7 +192,7 @@ + void *value, + int *value_len); + +-confdb_error_t confdb_key_replace ( ++cs_error_t confdb_key_replace ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +@@ -223,14 +202,14 @@ + void *new_value, + int new_value_len); + +-confdb_error_t confdb_key_increment ( ++cs_error_t confdb_key_increment ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, + int key_name_len, + unsigned int *value); + +-confdb_error_t confdb_key_decrement ( ++cs_error_t confdb_key_decrement ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +@@ -243,44 +222,44 @@ + * a quick way of finding a specific object, + * "iter" returns each object in sequence. + */ +-confdb_error_t confdb_object_find_start ( ++cs_error_t confdb_object_find_start ( + confdb_handle_t handle, + unsigned int parent_object_handle); + +-confdb_error_t confdb_object_find ( ++cs_error_t confdb_object_find ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *object_name, + int object_name_len, + unsigned int *object_handle); + +-confdb_error_t confdb_object_find_destroy( ++cs_error_t confdb_object_find_destroy( + confdb_handle_t handle, + unsigned int parent_object_handle); + +-confdb_error_t confdb_object_iter_start ( ++cs_error_t confdb_object_iter_start ( + confdb_handle_t handle, + unsigned int parent_object_handle); + +-confdb_error_t confdb_object_iter ( ++cs_error_t confdb_object_iter ( + confdb_handle_t handle, + unsigned int parent_object_handle, + unsigned int *object_handle, + void *object_name, + int *object_name_len); + +-confdb_error_t confdb_object_iter_destroy( ++cs_error_t confdb_object_iter_destroy( + confdb_handle_t handle, + unsigned int parent_object_handle); + + /* + * Key iterator + */ +-confdb_error_t confdb_key_iter_start ( ++cs_error_t confdb_key_iter_start ( + confdb_handle_t handle, + unsigned int object_handle); + +-confdb_error_t confdb_key_iter ( ++cs_error_t confdb_key_iter ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +diff -Naurd corosync-0.92/include/corosync/corotypes.h corosync-trunk/include/corosync/corotypes.h +--- corosync-0.92/include/corosync/corotypes.h 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/include/corosync/corotypes.h 2008-11-07 02:34:43.000000000 +0100 +@@ -0,0 +1,178 @@ ++/* ++ * Copyright (c) 2008 Allied Telesis Labs. ++ * ++ * All rights reserved. ++ * ++ * Author: Angus Salkeld (ahsalkeld@gmail.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 COROTYPES_H_DEFINED ++#define COROTYPES_H_DEFINED ++ ++#ifndef COROSYNC_SOLARIS ++#include ++#else ++#include ++#endif ++ ++typedef int64_t cs_time_t; ++ ++#define CS_FALSE 0 ++#define CS_TRUE !CS_FALSE ++#define CS_MAX_NAME_LENGTH 256 ++#define CS_TIME_END ((cs_time_t)0x7FFFFFFFFFFFFFFFULL) ++ ++typedef struct { ++ uint16_t length; ++ uint8_t value[CS_MAX_NAME_LENGTH]; ++} cs_name_t; ++ ++typedef struct { ++ char releaseCode; ++ unsigned char majorVersion; ++ unsigned char minorVersion; ++} cs_version_t; ++ ++typedef enum { ++ CS_DISPATCH_ONE = 1, ++ CS_DISPATCH_ALL = 2, ++ CS_DISPATCH_BLOCKING = 3 ++} cs_dispatch_flags_t; ++ ++#define CS_TRACK_CURRENT 0x01 ++#define CS_TRACK_CHANGES 0x02 ++#define CS_TRACK_CHANGES_ONLY 0x04 ++ ++typedef enum { ++ CS_OK = 1, ++ CS_ERR_LIBRARY = 2, ++ CS_ERR_VERSION = 3, ++ CS_ERR_INIT = 4, ++ CS_ERR_TIMEOUT = 5, ++ CS_ERR_TRY_AGAIN = 6, ++ CS_ERR_INVALID_PARAM = 7, ++ CS_ERR_NO_MEMORY = 8, ++ CS_ERR_BAD_HANDLE = 9, ++ CS_ERR_BUSY = 10, ++ CS_ERR_ACCESS = 11, ++ CS_ERR_NOT_EXIST = 12, ++ CS_ERR_NAME_TOO_LONG = 13, ++ CS_ERR_EXIST = 14, ++ CS_ERR_NO_SPACE = 15, ++ CS_ERR_INTERRUPT = 16, ++ CS_ERR_NAME_NOT_FOUND = 17, ++ CS_ERR_NO_RESOURCES = 18, ++ CS_ERR_NOT_SUPPORTED = 19, ++ CS_ERR_BAD_OPERATION = 20, ++ CS_ERR_FAILED_OPERATION = 21, ++ CS_ERR_MESSAGE_ERROR = 22, ++ CS_ERR_QUEUE_FULL = 23, ++ CS_ERR_QUEUE_NOT_AVAILABLE = 24, ++ CS_ERR_BAD_FLAGS = 25, ++ CS_ERR_TOO_BIG = 26, ++ CS_ERR_NO_SECTIONS = 27, ++ CS_ERR_CONTEXT_NOT_FOUND = 28, ++ CS_ERR_TOO_MANY_GROUPS = 30 ++} cs_error_t; ++ ++ ++/* ++ * DEPRECATED ++ */ ++#define EVS_DISPATCH_ONE CS_DISPATCH_ONE ++#define EVS_DISPATCH_ALL CS_DISPATCH_ALL ++#define EVS_DISPATCH_BLOCKING CS_DISPATCH_BLOCKING ++#define EVS_OK CS_OK ++#define EVS_ERR_LIBRARY CS_ERR_ERR_LIBRARY ++#define EVS_ERR_TIMEOUT CS_ERR_TIMEOUT ++#define EVS_ERR_TRY_AGAIN CS_ERR_TRY_AGAIN ++#define EVS_ERR_INVALID_PARAM CS_ERR_INVALID_PARAM ++#define EVS_ERR_NO_MEMORY CS_ERR_NO_MEMORY ++#define EVS_ERR_BAD_HANDLE CS_ERR_BAD_HANDLE ++#define EVS_ERR_ACCESS CS_ERR_ACCESS ++#define EVS_ERR_NOT_EXIST CS_ERR_NOT_EXIST ++#define EVS_ERR_EXIST CS_ERR_EXIST ++#define EVS_ERR_NOT_SUPPORTED CS_ERR_NOT_SUPPORTED ++#define EVS_ERR_SECURITY CS_ERR_SECURITY ++#define EVS_ERR_TOO_MANY_GROUPS CS_ERR_TOO_MANY_GROUPS ++#define evs_error_t cs_error_t ++ ++#define CPG_DISPATCH_ONE CS_DISPATCH_ONE ++#define CPG_DISPATCH_ALL CS_DISPATCH_ALL ++#define CPG_DISPATCH_BLOCKING CS_DISPATCH_BLOCKING ++#define CPG_OK CS_OK ++#define CPG_ERR_LIBRARY CS_ERR_ERR_LIBRARY ++#define CPG_ERR_TIMEOUT CS_ERR_TIMEOUT ++#define CPG_ERR_TRY_AGAIN CS_ERR_TRY_AGAIN ++#define CPG_ERR_INVALID_PARAM CS_ERR_INVALID_PARAM ++#define CPG_ERR_NO_MEMORY CS_ERR_NO_MEMORY ++#define CPG_ERR_BAD_HANDLE CS_ERR_BAD_HANDLE ++#define CPG_ERR_ACCESS CS_ERR_ACCESS ++#define CPG_ERR_NOT_EXIST CS_ERR_NOT_EXIST ++#define CPG_ERR_EXIST CS_ERR_EXIST ++#define CPG_ERR_NOT_SUPPORTED CS_ERR_NOT_SUPPORTED ++#define CPG_ERR_SECURITY CS_ERR_SECURITY ++#define cpg_error_t cs_error_t ++ ++#define CONFDB_DISPATCH_ONE CS_DISPATCH_ONE ++#define CONFDB_DISPATCH_ALL CS_DISPATCH_ALL ++#define CONFDB_DISPATCH_BLOCKING CS_DISPATCH_BLOCKING ++#define CONFDB_OK CS_OK ++#define CONFDB_ERR_LIBRARY CS_ERR_ERR_LIBRARY ++#define CONFDB_ERR_TIMEOUT CS_ERR_TIMEOUT ++#define CONFDB_ERR_TRY_AGAIN CS_ERR_TRY_AGAIN ++#define CONFDB_ERR_INVALID_PARAM CS_ERR_INVALID_PARAM ++#define CONFDB_ERR_NO_MEMORY CS_ERR_NO_MEMORY ++#define CONFDB_ERR_BAD_HANDLE CS_ERR_BAD_HANDLE ++#define CONFDB_ERR_ACCESS CS_ERR_ACCESS ++#define CONFDB_ERR_NOT_EXIST CS_ERR_NOT_EXIST ++#define CONFDB_ERR_EXIST CS_ERR_EXIST ++#define CONFDB_ERR_NOT_SUPPORTED CS_ERR_NOT_SUPPORTED ++#define CONFDB_ERR_SECURITY CS_ERR_SECURITY ++#define confdb_error_t cs_error_t ++ ++#define QUORUM_DISPATCH_ONE CS_DISPATCH_ONE ++#define QUORUM_DISPATCH_ALL CS_DISPATCH_ALL ++#define QUORUM_DISPATCH_BLOCKING CS_DISPATCH_BLOCKING ++#define QUORUM_OK CS_OK ++#define QUORUM_ERR_LIBRARY CS_ERR_ERR_LIBRARY ++#define QUORUM_ERR_TIMEOUT CS_ERR_TIMEOUT ++#define QUORUM_ERR_TRY_AGAIN CS_ERR_TRY_AGAIN ++#define QUORUM_ERR_INVALID_PARAM CS_ERR_INVALID_PARAM ++#define QUORUM_ERR_NO_MEMORY CS_ERR_NO_MEMORY ++#define QUORUM_ERR_BAD_HANDLE CS_ERR_BAD_HANDLE ++#define QUORUM_ERR_ACCESS CS_ERR_ACCESS ++#define QUORUM_ERR_NOT_EXIST CS_ERR_NOT_EXIST ++#define QUORUM_ERR_EXIST CS_ERR_EXIST ++#define QUORUM_ERR_NOT_SUPPORTED CS_ERR_NOT_SUPPORTED ++#define QUORUM_ERR_SECURITY CS_ERR_SECURITY ++#define quorum_error_t cs_error_t ++ ++#endif ++ +diff -Naurd corosync-0.92/include/corosync/cpg.h corosync-trunk/include/corosync/cpg.h +--- corosync-0.92/include/corosync/cpg.h 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/include/corosync/cpg.h 2008-11-06 22:49:07.000000000 +0100 +@@ -35,6 +35,7 @@ + #define COROSYNC_CPG_H_DEFINED + + #include ++#include + + /** + * @addtogroup cpg_corosync +@@ -44,12 +45,6 @@ + typedef uint64_t cpg_handle_t; + + typedef enum { +- CPG_DISPATCH_ONE, +- CPG_DISPATCH_ALL, +- CPG_DISPATCH_BLOCKING +-} cpg_dispatch_t; +- +-typedef enum { + CPG_TYPE_UNORDERED, /* not implemented */ + CPG_TYPE_FIFO, /* same as agreed */ + CPG_TYPE_AGREED, +@@ -61,21 +56,6 @@ + CPG_FLOW_CONTROL_ENABLED /* flow control is enabled - new messages should not be sent */ + } cpg_flow_control_state_t; + +-typedef enum { +- CPG_OK = 1, +- CPG_ERR_LIBRARY = 2, +- CPG_ERR_TIMEOUT = 5, +- CPG_ERR_TRY_AGAIN = 6, +- CPG_ERR_INVALID_PARAM = 7, +- CPG_ERR_NO_MEMORY = 8, +- CPG_ERR_BAD_HANDLE = 9, +- CPG_ERR_ACCESS = 11, +- CPG_ERR_NOT_EXIST = 12, +- CPG_ERR_EXIST = 14, +- CPG_ERR_NOT_SUPPORTED = 20, +- CPG_ERR_SECURITY = 29, +- CPG_ERR_TOO_MANY_GROUPS=30 +-} cpg_error_t; + + typedef enum { + CPG_REASON_JOIN = 1, +@@ -132,32 +112,32 @@ + /* + * Create a new cpg connection + */ +-cpg_error_t cpg_initialize ( ++cs_error_t cpg_initialize ( + cpg_handle_t *handle, + cpg_callbacks_t *callbacks); + + /* + * Close the cpg handle + */ +-cpg_error_t cpg_finalize ( ++cs_error_t cpg_finalize ( + cpg_handle_t handle); + + /* + * Get a file descriptor on which to poll. cpg_handle_t is NOT a + * file descriptor and may not be used directly. + */ +-cpg_error_t cpg_fd_get ( ++cs_error_t cpg_fd_get ( + cpg_handle_t handle, + int *fd); + + /* + * Get and set contexts for a CPG handle + */ +-cpg_error_t cpg_context_get ( ++cs_error_t cpg_context_get ( + cpg_handle_t handle, + void **context); + +-cpg_error_t cpg_context_set ( ++cs_error_t cpg_context_set ( + cpg_handle_t handle, + void *context); + +@@ -165,9 +145,9 @@ + /* + * Dispatch messages and configuration changes + */ +-cpg_error_t cpg_dispatch ( ++cs_error_t cpg_dispatch ( + cpg_handle_t handle, +- cpg_dispatch_t dispatch_types); ++ cs_dispatch_flags_t dispatch_types); + + /* + * Join one or more groups. +@@ -175,14 +155,14 @@ + * group that has been joined on handle handle. Any message multicasted + * to a group that has been previously joined will be delivered in cpg_dispatch + */ +-cpg_error_t cpg_join ( ++cs_error_t cpg_join ( + cpg_handle_t handle, + struct cpg_name *group); + + /* + * Leave one or more groups + */ +-cpg_error_t cpg_leave ( ++cs_error_t cpg_leave ( + cpg_handle_t handle, + struct cpg_name *group); + +@@ -191,7 +171,7 @@ + * The iovec described by iovec will be multicasted to all groups joined with + * the cpg_join interface for handle. + */ +-cpg_error_t cpg_mcast_joined ( ++cs_error_t cpg_mcast_joined ( + cpg_handle_t handle, + cpg_guarantee_t guarantee, + struct iovec *iovec, +@@ -200,21 +180,21 @@ + /* + * Get membership information from cpg + */ +-cpg_error_t cpg_membership_get ( ++cs_error_t cpg_membership_get ( + cpg_handle_t handle, + struct cpg_name *groupName, + struct cpg_address *member_list, + int *member_list_entries); + +-cpg_error_t cpg_local_get ( ++cs_error_t cpg_local_get ( + cpg_handle_t handle, + unsigned int *local_nodeid); + +-cpg_error_t cpg_groups_get ( ++cs_error_t cpg_groups_get ( + cpg_handle_t handle, + unsigned int *num_groups); + +-cpg_error_t cpg_flow_control_state_get ( ++cs_error_t cpg_flow_control_state_get ( + cpg_handle_t handle, + cpg_flow_control_state_t *flow_control_enabled); + +diff -Naurd corosync-0.92/include/corosync/engine/coroapi.h corosync-trunk/include/corosync/engine/coroapi.h +--- corosync-0.92/include/corosync/engine/coroapi.h 2008-09-17 21:15:00.000000000 +0200 ++++ corosync-trunk/include/corosync/engine/coroapi.h 2009-01-20 14:19:05.000000000 +0100 +@@ -41,7 +41,7 @@ + + typedef void * corosync_timer_handle_t; + +-typedef unsigned int corosync_tpg_handle; ++typedef unsigned int cs_tpg_handle; + + struct corosync_tpg_group { + void *group; +@@ -88,17 +88,36 @@ + }; + #endif + +-enum corosync_lib_flow_control { +- COROSYNC_LIB_FLOW_CONTROL_REQUIRED = 1, +- COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED = 2 ++#if !defined(TOTEM_CALLBACK_TOKEN_TYPE) ++enum totem_callback_token_type { ++ TOTEM_CALLBACK_TOKEN_RECEIVED = 1, ++ TOTEM_CALLBACK_TOKEN_SENT = 2 ++}; ++#endif ++ ++enum cs_lib_flow_control { ++ CS_LIB_FLOW_CONTROL_REQUIRED = 1, ++ CS_LIB_FLOW_CONTROL_NOT_REQUIRED = 2 ++}; ++#define corosync_lib_flow_control cs_lib_flow_control ++#define COROSYNC_LIB_FLOW_CONTROL_REQUIRED CS_LIB_FLOW_CONTROL_REQUIRED ++#define COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED CS_LIB_FLOW_CONTROL_NOT_REQUIRED ++ ++enum cs_lib_allow_inquorate { ++ CS_LIB_DISALLOW_INQUORATE = 0, /* default */ ++ CS_LIB_ALLOW_INQUORATE = 1 + }; + + #if !defined (COROSYNC_FLOW_CONTROL_STATE) +-enum corosync_flow_control_state { +- COROSYNC_FLOW_CONTROL_STATE_DISABLED, +- COROSYNC_FLOW_CONTROL_STATE_ENABLED ++enum cs_flow_control_state { ++ CS_FLOW_CONTROL_STATE_DISABLED, ++ CS_FLOW_CONTROL_STATE_ENABLED + }; +-#endif ++#define corosync_flow_control_state cs_flow_control_state ++#define CS_FLOW_CONTROL_STATE_DISABLED CS_FLOW_CONTROL_STATE_DISABLED ++#define CS_FLOW_CONTROL_STATE_ENABLED CS_FLOW_CONTROL_STATE_ENABLED ++ ++#endif /* COROSYNC_FLOW_CONTROL_STATE */ + + typedef enum { + COROSYNC_FATAL_ERROR_EXIT = -1, +@@ -109,7 +128,8 @@ + COROSYNC_DYNAMICLOAD = -12, + COROSYNC_OUT_OF_MEMORY = -15, + COROSYNC_FATAL_ERR = -16 +-} corosync_fatal_error_t; ++} cs_fatal_error_t; ++#define corosync_fatal_error_t cs_fatal_error_t; + + #ifndef OBJECT_PARENT_HANDLE + +@@ -125,6 +145,7 @@ + int key_len; + int (*validate_callback) (void *key, int key_len, void *value, int value_len); + }; ++/* deprecated */ + + typedef enum { + OBJECT_TRACK_DEPTH_ONE, +@@ -137,6 +158,12 @@ + OBJECT_KEY_DELETED + } object_change_type_t; + ++typedef enum { ++ OBJDB_RELOAD_NOTIFY_START, ++ OBJDB_RELOAD_NOTIFY_END, ++ OBJDB_RELOAD_NOTIFY_FAILED ++} objdb_reload_notify_type_t; ++ + typedef void (*object_key_change_notify_fn_t)(object_change_type_t change_type, + unsigned int parent_object_handle, + unsigned int object_handle, +@@ -159,8 +186,30 @@ + object_change_type_t type, + void * priv_data_pt); + ++typedef void (*object_reload_notify_fn_t) (objdb_reload_notify_type_t, int flush, ++ void *priv_data_pt); ++ + #endif /* OBJECT_PARENT_HANDLE_DEFINED */ + ++#ifndef QUORUM_H_DEFINED ++typedef void (*quorum_callback_fn_t) (int quorate, void *context); ++ ++struct quorum_callin_functions ++{ ++ int (*quorate) (void); ++ int (*register_callback) (quorum_callback_fn_t callback_fn, void *context); ++ int (*unregister_callback) (quorum_callback_fn_t callback_fn, void *context); ++}; ++ ++typedef void (*sync_callback_fn_t) ( ++ unsigned int *view_list, ++ int view_list_entries, ++ int primary_designated, ++ struct memb_ring_id *ring_id); ++ ++#endif /* QUORUM_H_DEFINED */ ++ ++ + struct corosync_api_v1 { + /* + * Object and configuration APIs +@@ -280,12 +329,14 @@ + object_key_change_notify_fn_t key_change_notify_fn, + object_create_notify_fn_t object_create_notify_fn, + object_destroy_notify_fn_t object_destroy_notify_fn, ++ object_reload_notify_fn_t object_reload_notify_fn, + void * priv_data_pt); + + void (*object_track_stop) ( + object_key_change_notify_fn_t key_change_notify_fn, + object_create_notify_fn_t object_create_notify_fn, + object_destroy_notify_fn_t object_destroy_notify_fn, ++ object_reload_notify_fn_t object_reload_notify_fn, + void * priv_data_pt); + + int (*object_write_config) (char **error_string); +@@ -357,7 +408,7 @@ + int id_len, + void (*flow_control_state_set_fn) + (void *context, +- enum corosync_flow_control_state flow_control_state_set), ++ enum cs_flow_control_state flow_control_state_set), + void *context); + + void (*ipc_fc_destroy) ( +@@ -373,7 +424,7 @@ + /* + * Totem APIs + */ +- int (*totem_nodeid_get) (void); ++ unsigned int (*totem_nodeid_get) (void); + + int (*totem_family_get) (void); + +@@ -393,12 +444,20 @@ + + char *(*totem_ip_print) (struct totem_ip_address *addr); + ++ ++ int (*totem_callback_token_create) ( ++ void **handle_out, ++ enum totem_callback_token_type type, ++ int delete, ++ int (*callback_fn) (enum totem_callback_token_type type, void *), ++ void *data); ++ + /* + * Totem open process groups API for those service engines + * wanting their own groups + */ + int (*tpg_init) ( +- corosync_tpg_handle *handle, ++ cs_tpg_handle *handle, + + void (*deliver_fn) ( + unsigned int nodeid, +@@ -414,31 +473,31 @@ + struct memb_ring_id *ring_id)); + + int (*tpg_exit) ( +- corosync_tpg_handle handle); ++ cs_tpg_handle handle); + + int (*tpg_join) ( +- corosync_tpg_handle handle, ++ cs_tpg_handle handle, + struct corosync_tpg_group *groups, + int gruop_cnt); + + int (*tpg_leave) ( +- corosync_tpg_handle handle, ++ cs_tpg_handle handle, + struct corosync_tpg_group *groups, + int gruop_cnt); + + int (*tpg_joined_mcast) ( +- corosync_tpg_handle handle, ++ cs_tpg_handle handle, + struct iovec *iovec, + int iov_len, + int guarantee); + + int (*tpg_joined_send_ok) ( +- corosync_tpg_handle handle, ++ cs_tpg_handle handle, + struct iovec *iovec, + int iov_len); + + int (*tpg_groups_mcast) ( +- corosync_tpg_handle handle, ++ cs_tpg_handle handle, + int guarantee, + struct corosync_tpg_group *groups, + int groups_cnt, +@@ -446,7 +505,7 @@ + int iov_len); + + int (*tpg_groups_send_ok) ( +- corosync_tpg_handle handle, ++ cs_tpg_handle handle, + struct corosync_tpg_group *groups, + int groups_cnt, + struct iovec *iovec, +@@ -456,6 +515,19 @@ + char *service_name); + + /* ++ * User plugin-callable functions for quorum ++ */ ++ int (*quorum_is_quorate) (void); ++ int (*quorum_register_callback) (quorum_callback_fn_t callback_fn, void *context); ++ int (*quorum_unregister_callback) (quorum_callback_fn_t callback_fn, void *context); ++ ++ /* ++ * This one is for the quorum management plugin's use ++ */ ++ int (*quorum_initialize)(struct quorum_callin_functions *fns, ++ sync_callback_fn_t *sync_callback_fn); ++ ++ /* + * Plugin loading and unloading + */ + int (*plugin_interface_reference) ( +@@ -485,7 +557,7 @@ + */ + void (*error_memory_failure) (void); + #define corosync_fatal_error(err) api->fatal_error ((err), __FILE__, __LINE__) +- void (*fatal_error) (corosync_fatal_error_t err, const char *file, unsigned int line); ++ void (*fatal_error) (cs_fatal_error_t err, const char *file, unsigned int line); + }; + + #define SERVICE_ID_MAKE(a,b) ( ((a)<<16) | (b) ) +@@ -496,7 +568,7 @@ + void (*lib_handler_fn) (void *conn, void *msg); + int response_size; + int response_id; +- enum corosync_lib_flow_control flow_control; ++ enum cs_lib_flow_control flow_control; + }; + + struct corosync_exec_handler { +@@ -512,7 +584,8 @@ + char *name; + unsigned short id; + unsigned int private_data_size; +- enum corosync_lib_flow_control flow_control; ++ enum cs_lib_flow_control flow_control; ++ enum cs_lib_allow_inquorate allow_inquorate; + int (*exec_init_fn) (struct corosync_api_v1 *); + int (*exec_exit_fn) (void); + void (*exec_dump_fn) (void); +diff -Naurd corosync-0.92/include/corosync/engine/logsys.h corosync-trunk/include/corosync/engine/logsys.h +--- corosync-0.92/include/corosync/engine/logsys.h 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/include/corosync/engine/logsys.h 2009-01-16 09:59:09.000000000 +0100 +@@ -1,6 +1,6 @@ + /* + * Copyright (c) 2002-2004 MontaVista Software, Inc. +- * Copyright (c) 2006-2007 Red Hat, Inc. ++ * Copyright (c) 2006-2008 Red Hat, Inc. + * + * Author: Steven Dake (sdake@redhat.com) + * Author: Lon Hohberger (lhh@redhat.com) +@@ -41,21 +41,14 @@ + #include + + /* +- * MODE_OUTPUT_SYSLOG_* modes are mutually exclusive ++ * All of the LOG_MODE's can be ORed together for combined behavior + */ + #define LOG_MODE_OUTPUT_FILE (1<<0) + #define LOG_MODE_OUTPUT_STDERR (1<<1) +-#define LOG_MODE_OUTPUT_SYSLOG_THREADED (1<<2) +-#define LOG_MODE_OUTPUT_SYSLOG_LOSSY (1<<3) +-#define LOG_MODE_OUTPUT_SYSLOG_BLOCKING (1<<4) +-#define LOG_MODE_DISPLAY_PRIORITY (1<<5) +-#define LOG_MODE_DISPLAY_FILELINE (1<<6) +-#define LOG_MODE_DISPLAY_TIMESTAMP (1<<7) +-#define LOG_MODE_BUFFER_BEFORE_CONFIG (1<<8) +-#define LOG_MODE_FLUSH_AFTER_CONFIG (1<<9) +-#define LOG_MODE_SHORT_FILELINE (1<<10) +-#define LOG_MODE_NOSUBSYS (1<<11) +-#define LOG_MODE_FILTER_DEBUG_FROM_SYSLOG (1<<12) ++#define LOG_MODE_OUTPUT_SYSLOG (1<<3) ++#define LOG_MODE_NOSUBSYS (1<<4) ++#define LOG_MODE_FORK (1<<5) ++#define LOG_MODE_THREADED (1<<6) + + /* + * Log priorities, compliant with syslog and SA Forum Log spec. +@@ -71,37 +64,23 @@ + #define LOG_LEVEL_DEBUG LOG_DEBUG + + /* +-** Log tags, used by _logsys_trace macros, uses 32 bits => 32 different tags +-*/ +-#define LOGSYS_TAG_LOG (1<<0) +-#define LOGSYS_TAG_ENTER (1<<1) +-#define LOGSYS_TAG_LEAVE (1<<2) +-#define LOGSYS_TAG_TRACE1 (1<<3) +-#define LOGSYS_TAG_TRACE2 (1<<4) +-#define LOGSYS_TAG_TRACE3 (1<<5) +-#define LOGSYS_TAG_TRACE4 (1<<6) +-#define LOGSYS_TAG_TRACE5 (1<<7) +-#define LOGSYS_TAG_TRACE6 (1<<8) +-#define LOGSYS_TAG_TRACE7 (1<<9) +-#define LOGSYS_TAG_TRACE8 (1<<10) ++ * The tag masks are all mutually exclusive ++ */ ++#define LOGSYS_TAG_LOG (0xff<<28) ++#define LOGSYS_TAG_ENTER (1<<27) ++#define LOGSYS_TAG_LEAVE (1<<26) ++#define LOGSYS_TAG_TRACE1 (1<<25) ++#define LOGSYS_TAG_TRACE2 (1<<24) ++#define LOGSYS_TAG_TRACE3 (1<<23) ++#define LOGSYS_TAG_TRACE4 (1<<22) ++#define LOGSYS_TAG_TRACE5 (1<<21) ++#define LOGSYS_TAG_TRACE6 (1<<20) ++#define LOGSYS_TAG_TRACE7 (1<<19) ++#define LOGSYS_TAG_TRACE8 (1<<18) + + /* + * External API + */ +- +-struct logsys_logger { +- char subsys[6]; +- unsigned int priority; +- unsigned int tags; +- unsigned int mode; +-}; +- +-extern struct logsys_logger logsys_loggers[]; +- +-extern int logsys_single_id; +- +-extern inline int logsys_mkpri (int priority, int id); +- + extern void logsys_config_mode_set ( + unsigned int mode); + +@@ -115,6 +94,9 @@ + char *name, + unsigned int facility); + ++extern void logsys_format_set ( ++ char *format); ++ + extern unsigned int logsys_config_subsys_set ( + const char *subsys, + unsigned int tags, +@@ -137,33 +119,60 @@ + extern const char *logsys_priority_name_get ( + unsigned int priority); + ++extern int logsys_tag_id_get ( ++ const char *name); ++ ++extern const char *logsys_tag_name_get ( ++ unsigned int tag); ++ ++extern void logsys_fork_completed (void); ++ + extern void logsys_flush (void); + + extern void logsys_atsegv (void); + ++extern int logsys_log_rec_store (char *filename); ++ + /* + * Internal APIs that must be globally exported + */ +-extern unsigned int _logsys_subsys_create (const char *ident, ++extern unsigned int _logsys_subsys_create ( ++ const char *ident, + unsigned int priority); + + extern void _logsys_nosubsys_set (void); + +-extern int _logsys_wthread_create (void); ++extern int _logsys_rec_init (unsigned int size); + +-extern void logsys_log_printf (char *file, int line, int priority, +- char *format, ...) __attribute__((format(printf, 4, 5))); ++extern void _logsys_log_printf ( ++ int subsys, ++ char *function_name, ++ char *file_name, ++ int file_line, ++ unsigned int level, ++ char *format, ++ ...) __attribute__((format(printf, 6, 7))); + +-extern void _logsys_log_printf2 (char *file, int line, int priority, +- int id, char *format, ...) __attribute__((format(printf, 5, 6))); ++extern void _logsys_log_rec ( ++ int subsys, ++ char *function_name, ++ char *file_name, ++ int file_line, ++ unsigned int rec_ident, ++ ...); + +-extern void _logsys_trace (char *file, int line, int tag, int id, +- char *format, ...) __attribute__((format(printf, 5, 6))); ++extern int _logsys_wthread_create (void); + ++static unsigned int logsys_subsys_id __attribute__((unused)) = -1; ++ + /* + * External definitions + */ +-#define LOGSYS_DECLARE_SYSTEM(name,mode,file,facility) \ ++extern void *logsys_rec_end; ++ ++#define LOG_REC_END (&logsys_rec_end) ++ ++#define LOGSYS_DECLARE_SYSTEM(name,mode,file,facility,format,rec_size) \ + __attribute__ ((constructor)) static void logsys_system_init (void) \ + { \ + char *error_string; \ +@@ -171,13 +180,11 @@ + logsys_config_mode_set (mode); \ + logsys_config_file_set (&error_string, (file)); \ + logsys_config_facility_set (name, (facility)); \ +- if (((mode) & LOG_MODE_BUFFER_BEFORE_CONFIG) == 0) { \ +- _logsys_wthread_create (); \ +- } \ ++ logsys_format_set (format); \ ++ _logsys_rec_init (rec_size); \ ++ _logsys_wthread_create(); \ + } + +-static unsigned int logsys_subsys_id __attribute__((unused)) = -1; \ +- + #define LOGSYS_DECLARE_NOSUBSYS(priority) \ + __attribute__ ((constructor)) static void logsys_nosubsys_init (void) \ + { \ +@@ -206,161 +213,88 @@ + _logsys_subsys_create ((subsys), (priority)); \ + } + +-#define log_printf(lvl, format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if ((lvl) <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_log_printf2 (__FILE__, __LINE__, lvl, \ +- logsys_subsys_id, (format), ##args); \ +- } \ +-} while(0) +- +-#define dprintf(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_log_printf2 (__FILE__, __LINE__, LOG_DEBUG, \ +- logsys_subsys_id, (format), ##args); \ +- } \ +-} while(0) +- +-#define ENTER_VOID() do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_ENTER, \ +- logsys_subsys_id, ">%s\n", __FUNCTION__); \ +- } \ ++#define log_rec(rec_ident, args...) \ ++do { \ ++ _logsys_log_rec (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, rec_ident, ##args); \ + } while(0) + +-#define ENTER(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_ENTER, \ +- logsys_subsys_id, ">%s: " format, __FUNCTION__, \ +- ##args); \ +- } \ ++#define log_printf(lvl, format, args...) \ ++ do { \ ++ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, lvl, format, ##args); \ + } while(0) + +-#define LEAVE_VOID() do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_LEAVE, \ +- logsys_subsys_id, "<%s\n", __FUNCTION__); \ +- } \ ++#define ENTER() do { \ ++ _logsys_log_rec (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, LOGSYS_TAG_ENTER, LOG_REC_END); \ + } while(0) + +-#define LEAVE(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_LEAVE, \ +- logsys_subsys_id, "<%s: " format, \ +- __FUNCTION__, ##args); \ +- } \ ++#define LEAVE() do { \ ++ _logsys_log_rec (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, LOGSYS_TAG_LEAVE, LOG_REC_END); \ + } while(0) + + #define TRACE1(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE1, \ +- logsys_subsys_id, (format), ##args); \ +- } \ ++ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, LOGSYS_TAG_TRACE1, format, ##args);\ + } while(0) + + #define TRACE2(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE2, \ +- logsys_subsys_id, (format), ##args); \ +- } \ ++ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, LOGSYS_TAG_TRACE2, format, ##args);\ + } while(0) + +-#define TRACE3(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE3, \ +- logsys_subsys_id, (format), ##args); \ +- } \ ++#define TRACE3(format, args...) do { \ ++ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, LOGSYS_TAG_TRACE3, format, ##args);\ + } while(0) + +-#define TRACE4(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE4, \ +- logsys_subsys_id, (format), ##args); \ +- } \ ++#define TRACE4(format, args...) do { \ ++ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, LOGSYS_TAG_TRACE4, format, ##args);\ + } while(0) + + #define TRACE5(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE5, \ +- logsys_subsys_id, (format), ##args); \ +- } \ ++ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, LOGSYS_TAG_TRACE5, format, ##args);\ + } while(0) + + #define TRACE6(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE6, \ +- logsys_subsys_id, (format), ##args); \ +- } \ ++ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, LOGSYS_TAG_TRACE6, format, ##args);\ + } while(0) + + #define TRACE7(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE7, \ +- logsys_subsys_id, (format), ##args); \ +- } \ ++ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, LOGSYS_TAG_TRACE7, format, ##args);\ + } while(0) + + #define TRACE8(format, args...) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- if (LOG_LEVEL_DEBUG <= logsys_loggers[logsys_subsys_id].priority) { \ +- _logsys_trace (__FILE__, __LINE__, LOGSYS_TAG_TRACE8, \ +- logsys_subsys_id, (format), ##args); \ +- } \ ++ _logsys_log_printf (logsys_subsys_id, (char *) __FUNCTION__, \ ++ __FILE__, __LINE__, LOGSYS_TAG_TRACE8, format, ##args);\ + } while(0) + +-extern void _logsys_config_priority_set (unsigned int id, unsigned int priority); +- +-#define logsys_config_priority_set(priority) do { \ +- if (logsys_single_id) \ +- logsys_subsys_id = 0; \ +- assert (logsys_subsys_id != -1); \ +- _logsys_config_priority_set (logsys_subsys_id, priority); \ +-} while(0) ++/* ++ * For one-time programmatic initialization and configuration of logsys ++ * instead of using the DECLARE macros. These APIs do not allow subsystems ++ */ ++int logsys_init ( ++ char *name, ++ int mode, ++ int facility, ++ int priority, ++ char *file, ++ char *format, ++ int rec_size); + +-/* simple, function-based api */ ++int logsys_conf ( ++ char *name, ++ int mode, ++ int facility, ++ int priority, ++ char *file); + +-int logsys_init (char *name, int mode, int facility, int priority, char *file); +-int logsys_conf (char *name, int mode, int facility, int priority, char *file); + void logsys_exit (void); + + #endif /* LOGSYS_H_DEFINED */ +diff -Naurd corosync-0.92/include/corosync/engine/objdb.h corosync-trunk/include/corosync/engine/objdb.h +--- corosync-0.92/include/corosync/engine/objdb.h 2008-09-03 09:58:08.000000000 +0200 ++++ corosync-trunk/include/corosync/engine/objdb.h 2008-10-27 09:25:53.000000000 +0100 +@@ -51,6 +51,13 @@ + OBJECT_KEY_DELETED + } object_change_type_t; + ++typedef enum { ++ OBJDB_RELOAD_NOTIFY_START, ++ OBJDB_RELOAD_NOTIFY_END, ++ OBJDB_RELOAD_NOTIFY_FAILED ++} objdb_reload_notify_type_t; ++ ++ + typedef void (*object_key_change_notify_fn_t)(object_change_type_t change_type, + unsigned int parent_object_handle, + unsigned int object_handle, +@@ -68,6 +75,9 @@ + void *name_pt, int name_len, + void *priv_data_pt); + ++typedef void (*object_reload_notify_fn_t) (objdb_reload_notify_type_t, int flush, ++ void *priv_data_pt); ++ + struct object_valid { + char *object_name; + int object_len; +@@ -198,12 +208,14 @@ + object_key_change_notify_fn_t key_change_notify_fn, + object_create_notify_fn_t object_create_notify_fn, + object_destroy_notify_fn_t object_destroy_notify_fn, ++ object_reload_notify_fn_t object_reload_notify_fn, + void * priv_data_pt); + + void (*object_track_stop) ( + object_key_change_notify_fn_t key_change_notify_fn, + object_create_notify_fn_t object_create_notify_fn, + object_destroy_notify_fn_t object_destroy_notify_fn, ++ object_reload_notify_fn_t object_reload_notify_fn, + void * priv_data_pt); + + int (*object_write_config) (char **error_string); +diff -Naurd corosync-0.92/include/corosync/engine/quorum.h corosync-trunk/include/corosync/engine/quorum.h +--- corosync-0.92/include/corosync/engine/quorum.h 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/include/corosync/engine/quorum.h 2008-12-09 14:51:23.000000000 +0100 +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 2008 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 Red Hat 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 QUORUM_H_DEFINED ++#define QUORUM_H_DEFINED ++ ++typedef void (*quorum_set_quorate_fn_t) (unsigned int *view_list, int view_list_entries, ++ int quorate, struct memb_ring_id *); ++ ++struct quorum_services_api_ver1 { ++ void (*init) (struct corosync_api_v1 *api, quorum_set_quorate_fn_t); ++}; ++#endif /* QUORUM_H_DEFINED */ +diff -Naurd corosync-0.92/include/corosync/evs.h corosync-trunk/include/corosync/evs.h +--- corosync-0.92/include/corosync/evs.h 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/include/corosync/evs.h 2008-11-06 22:49:07.000000000 +0100 +@@ -36,6 +36,7 @@ + + #include + #include ++#include + + /** + * @defgroup corosync Other API services provided by corosync +@@ -49,34 +50,12 @@ + typedef uint64_t evs_handle_t; + + typedef enum { +- EVS_DISPATCH_ONE, +- EVS_DISPATCH_ALL, +- EVS_DISPATCH_BLOCKING +-} evs_dispatch_t; +- +-typedef enum { + EVS_TYPE_UNORDERED, /* not implemented */ + EVS_TYPE_FIFO, /* same as agreed */ + EVS_TYPE_AGREED, + EVS_TYPE_SAFE /* not implemented */ + } evs_guarantee_t; + +-typedef enum { +- EVS_OK = 1, +- EVS_ERR_LIBRARY = 2, +- EVS_ERR_TIMEOUT = 5, +- EVS_ERR_TRY_AGAIN = 6, +- EVS_ERR_INVALID_PARAM = 7, +- EVS_ERR_NO_MEMORY = 8, +- EVS_ERR_BAD_HANDLE = 9, +- EVS_ERR_ACCESS = 11, +- EVS_ERR_NOT_EXIST = 12, +- EVS_ERR_EXIST = 14, +- EVS_ERR_NOT_SUPPORTED = 20, +- EVS_ERR_SECURITY = 29, +- EVS_ERR_TOO_MANY_GROUPS=30 +-} evs_error_t; +- + #define TOTEMIP_ADDRLEN (sizeof(struct in6_addr)) + + /** These are the things that get passed around */ +@@ -110,30 +89,30 @@ + /* + * Create a new evs connection + */ +-evs_error_t evs_initialize ( ++cs_error_t evs_initialize ( + evs_handle_t *handle, + evs_callbacks_t *callbacks); + + /* + * Close the evs handle + */ +-evs_error_t evs_finalize ( ++cs_error_t evs_finalize ( + evs_handle_t handle); + + /* + * Get a file descriptor on which to poll. evs_handle_t is NOT a + * file descriptor and may not be used directly. + */ +-evs_error_t evs_fd_get ( ++cs_error_t evs_fd_get ( + evs_handle_t handle, + int *fd); + + /* + * Dispatch messages and configuration changes + */ +-evs_error_t evs_dispatch ( ++cs_error_t evs_dispatch ( + evs_handle_t handle, +- evs_dispatch_t dispatch_types); ++ cs_dispatch_flags_t dispatch_types); + + /* + * Join one or more groups. +@@ -141,7 +120,7 @@ + * group that has been joined on handle handle. Any message multicasted + * to a group that has been previously joined will be delivered in evs_dispatch + */ +-evs_error_t evs_join ( ++cs_error_t evs_join ( + evs_handle_t handle, + struct evs_group *groups, + int group_cnt); +@@ -149,7 +128,7 @@ + /* + * Leave one or more groups + */ +-evs_error_t evs_leave ( ++cs_error_t evs_leave ( + evs_handle_t handle, + struct evs_group *groups, + int group_cnt); +@@ -159,7 +138,7 @@ + * The iovec described by iovec will be multicasted to all groups joined with + * the evs_join interface for handle. + */ +-evs_error_t evs_mcast_joined ( ++cs_error_t evs_mcast_joined ( + evs_handle_t handle, + evs_guarantee_t guarantee, + struct iovec *iovec, +@@ -170,7 +149,7 @@ + * Messages will be multicast to groups specified in the api call and not those + * that have been joined (unless they are in the groups parameter). + */ +-evs_error_t evs_mcast_groups ( ++cs_error_t evs_mcast_groups ( + evs_handle_t handle, + evs_guarantee_t guarantee, + struct evs_group *groups, +@@ -181,7 +160,7 @@ + /* + * Get membership information from evs + */ +-evs_error_t evs_membership_get ( ++cs_error_t evs_membership_get ( + evs_handle_t handle, + unsigned int *local_nodeid, + unsigned int *member_list, +diff -Naurd corosync-0.92/include/corosync/ipc_cfg.h corosync-trunk/include/corosync/ipc_cfg.h +--- corosync-0.92/include/corosync/ipc_cfg.h 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/include/corosync/ipc_cfg.h 2009-01-19 09:31:21.000000000 +0100 +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 2005 MontaVista Software, Inc. ++ * Copyright (c) 2009 Red Hat, Inc. + * + * All rights reserved. + * +@@ -35,8 +36,8 @@ + #define AIS_IPC_CFG_H_DEFINED + + #include ++#include + #include "ipc_gen.h" +-#include "saAis.h" + #include "cfg.h" + + enum req_lib_cfg_types { +@@ -47,7 +48,11 @@ + MESSAGE_REQ_CFG_ADMINISTRATIVESTATESET = 4, + MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET = 5, + MESSAGE_REQ_CFG_SERVICELOAD = 6, +- MESSAGE_REQ_CFG_SERVICEUNLOAD = 7 ++ MESSAGE_REQ_CFG_SERVICEUNLOAD = 7, ++ MESSAGE_REQ_CFG_KILLNODE = 8, ++ MESSAGE_REQ_CFG_TRYSHUTDOWN = 9, ++ MESSAGE_REQ_CFG_REPLYTOSHUTDOWN = 10, ++ MESSAGE_REQ_CFG_GET_NODE_ADDRS = 11 + }; + + enum res_lib_cfg_types { +@@ -58,13 +63,17 @@ + MESSAGE_RES_CFG_ADMINISTRATIVESTATESET = 4, + MESSAGE_RES_CFG_ADMINISTRATIVESTATEGET = 5, + MESSAGE_RES_CFG_SERVICELOAD = 6, +- MESSAGE_RES_CFG_SERVICEUNLOAD = 7 ++ MESSAGE_RES_CFG_SERVICEUNLOAD = 7, ++ MESSAGE_RES_CFG_KILLNODE = 8, ++ MESSAGE_RES_CFG_TRYSHUTDOWN = 9, ++ MESSAGE_RES_CFG_TESTSHUTDOWN = 10, ++ MESSAGE_RES_CFG_GET_NODE_ADDRS = 11 + }; + + struct req_lib_cfg_statetrack { + mar_req_header_t header; +- SaUint8T trackFlags; +- CorosyncCfgStateNotificationT *notificationBufferAddress; ++ uint8_t track_flags; ++ corosync_cfg_state_notification_t *notification_buffer_address; + }; + + struct res_lib_cfg_statetrack { +@@ -81,9 +90,9 @@ + + struct req_lib_cfg_administrativestateset { + mar_req_header_t header; +- SaNameT compName; +- CorosyncCfgAdministrativeTargetT administrativeTarget; +- CorosyncCfgAdministrativeStateT administrativeState; ++ cs_name_t comp_name; ++ corosync_cfg_administrative_target_t administrative_target; ++ corosync_cfg_administrative_state_t administrative_state; + }; + + struct res_lib_cfg_administrativestateset { +@@ -92,9 +101,9 @@ + + struct req_lib_cfg_administrativestateget { + mar_req_header_t header; +- SaNameT compName; +- CorosyncCfgAdministrativeTargetT administrativeTarget; +- CorosyncCfgAdministrativeStateT administrativeState; ++ cs_name_t comp_name; ++ corosync_cfg_administrative_target_t administrative_target; ++ corosync_cfg_administrative_state_t administrative_state; + }; + + struct res_lib_cfg_administrativestateget { +@@ -122,7 +131,7 @@ + + struct req_lib_cfg_serviceload { + mar_res_header_t header __attribute__((aligned(8))); +- char *service_name[256] __attribute__((aligned(8))); ++ char service_name[256] __attribute__((aligned(8))); + unsigned int service_ver; + }; + +@@ -132,7 +141,7 @@ + + struct req_lib_cfg_serviceunload { + mar_res_header_t header __attribute__((aligned(8))); +- char *service_name[256] __attribute__((aligned(8))); ++ char service_name[256] __attribute__((aligned(8))); + unsigned int service_ver; + }; + +@@ -140,17 +149,65 @@ + mar_res_header_t header __attribute__((aligned(8))); + }; + ++struct req_lib_cfg_killnode { ++ mar_req_header_t header __attribute__((aligned(8))); ++ unsigned int nodeid __attribute__((aligned(8))); ++ cs_name_t reason __attribute__((aligned(8))); ++}; ++ ++struct res_lib_cfg_killnode { ++ mar_res_header_t header __attribute__((aligned(8))); ++}; ++ ++struct req_lib_cfg_tryshutdown { ++ mar_req_header_t header __attribute__((aligned(8))); ++ unsigned int flags; ++}; ++ ++struct res_lib_cfg_tryshutdown { ++ mar_res_header_t header __attribute__((aligned(8))); ++}; ++ ++struct req_lib_cfg_replytoshutdown { ++ mar_res_header_t header __attribute__((aligned(8))); ++ unsigned int response; ++}; ++ ++struct res_lib_cfg_testshutdown { ++ mar_res_header_t header __attribute__((aligned(8))); ++ unsigned int flags; ++}; ++ ++struct req_lib_cfg_get_node_addrs { ++ mar_req_header_t header __attribute__((aligned(8))); ++ unsigned int nodeid; ++}; ++ ++struct res_lib_cfg_get_node_addrs { ++ mar_res_header_t header __attribute__((aligned(8))); ++ unsigned int family; ++ unsigned int num_addrs; ++ char addrs[TOTEMIP_ADDRLEN][0]; ++}; ++ + typedef enum { + AIS_AMF_ADMINISTRATIVETARGET_SERVICEUNIT = 0, + AIS_AMF_ADMINISTRATIVETARGET_SERVICEGROUP = 1, + AIS_AMF_ADMINISTRATIVETARGET_COMPONENTSERVICEINSTANCE = 2, + AIS_AMF_ADMINISTRATIVETARGET_NODE = 3 +-} corosyncAdministrativeTarget; ++} corosync_administrative_target_t; + + typedef enum { + AIS_AMF_ADMINISTRATIVESTATE_UNLOCKED = 0, + AIS_AMF_ADMINISTRATIVESTATE_LOCKED = 1, + AIS_AMF_ADMINISTRATIVESTATE_STOPPING = 2 +-} corosyncAdministrativeState; ++} corosync_administrative_state_t; ++ ++typedef enum { ++ CFG_SHUTDOWN_FLAG_REQUEST = 0, ++ CFG_SHUTDOWN_FLAG_REGARDLESS = 1, ++ CFG_SHUTDOWN_FLAG_IMMEDIATE = 2, ++} corosync_shutdown_flags_t; ++ + + #endif /* AIS_IPC_CFG_H_DEFINED */ +diff -Naurd corosync-0.92/include/corosync/ipc_confdb.h corosync-trunk/include/corosync/ipc_confdb.h +--- corosync-0.92/include/corosync/ipc_confdb.h 2008-09-03 09:58:08.000000000 +0200 ++++ corosync-trunk/include/corosync/ipc_confdb.h 2008-11-06 22:49:07.000000000 +0100 +@@ -35,7 +35,7 @@ + #define IPC_CONFDB_H_DEFINED + + #include +-#include "saAis.h" ++#include + #include "ipc_gen.h" + + enum req_confdb_types { +diff -Naurd corosync-0.92/include/corosync/ipc_cpg.h corosync-trunk/include/corosync/ipc_cpg.h +--- corosync-0.92/include/corosync/ipc_cpg.h 2008-09-17 21:15:00.000000000 +0200 ++++ corosync-trunk/include/corosync/ipc_cpg.h 2009-01-08 07:29:16.000000000 +0100 +@@ -35,7 +35,7 @@ + #define IPC_CPG_H_DEFINED + + #include +-#include "saAis.h" ++#include + #include "ipc_gen.h" + #include "mar_cpg.h" + +@@ -143,7 +143,7 @@ + + struct req_lib_cpg_membership { + mar_req_header_t header __attribute__((aligned(8))); +- mar_cpg_name_t group_name __attribute__((aligned(8))); ++// mar_cpg_name_t group_name __attribute__((aligned(8))); + }; + + struct res_lib_cpg_confchg_callback { +diff -Naurd corosync-0.92/include/corosync/ipc_evs.h corosync-trunk/include/corosync/ipc_evs.h +--- corosync-0.92/include/corosync/ipc_evs.h 2008-08-14 16:59:50.000000000 +0200 ++++ corosync-trunk/include/corosync/ipc_evs.h 2008-11-06 22:49:07.000000000 +0100 +@@ -34,8 +34,7 @@ + #ifndef IPC_EVS_H_DEFINED + #define IPC_EVS_H_DEFINED + +-//#include +-#include "saAis.h" ++#include + #include "evs.h" + #include "ipc_gen.h" + +diff -Naurd corosync-0.92/include/corosync/ipc_gen.h corosync-trunk/include/corosync/ipc_gen.h +--- corosync-0.92/include/corosync/ipc_gen.h 2008-08-14 16:59:50.000000000 +0200 ++++ corosync-trunk/include/corosync/ipc_gen.h 2008-11-06 22:49:07.000000000 +0100 +@@ -46,7 +46,9 @@ + MSG_SERVICE = 6, + CFG_SERVICE = 7, + CPG_SERVICE = 8, +- CONFDB_SERVICE = 10 ++ CONFDB_SERVICE = 10, ++ QUORUM_SERVICE = 11, ++ PLOAD_SERVICE = 12 + }; + + enum req_init_types { +@@ -72,7 +74,7 @@ + typedef struct { + int size; __attribute__((aligned(8))) + int id __attribute__((aligned(8))); +- SaAisErrorT error __attribute__((aligned(8))); ++ cs_error_t error __attribute__((aligned(8))); + } mar_res_header_t __attribute__((aligned(8))); + + typedef struct { +diff -Naurd corosync-0.92/include/corosync/ipc_pload.h corosync-trunk/include/corosync/ipc_pload.h +--- corosync-0.92/include/corosync/ipc_pload.h 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/include/corosync/ipc_pload.h 2008-11-06 22:49:07.000000000 +0100 +@@ -0,0 +1,71 @@ ++/* ++ * Copyright (c) 2008 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 IPC_PLOAD_H_DEFINED ++#define IPC_PLOAD_H_DEFINED ++ ++#include ++#include "pload.h" ++#include "ipc_gen.h" ++ ++enum req_lib_evs_types { ++ MESSAGE_REQ_PLOAD_START = 0, ++}; ++ ++enum res_lib_evs_types { ++ MESSAGE_RES_PLOAD_START = 0, ++}; ++ ++struct res_lib_pload_start { ++ mar_res_header_t header; ++ unsigned int dataset[1024]; ++}; ++ ++struct res_lib_pload_mcast { ++ mar_res_header_t header; ++}; ++ ++struct req_lib_pload_start { ++ mar_req_header_t header; ++ unsigned int msg_code; ++ unsigned int msg_size; ++ unsigned int msg_count; ++ unsigned int time_interval; ++}; ++ ++struct req_lib_pload_mcast { ++ mar_req_header_t header; ++ unsigned int code; ++}; ++ ++#endif /* IPC_PLOAD_H_DEFINED */ +diff -Naurd corosync-0.92/include/corosync/ipc_quorum.h corosync-trunk/include/corosync/ipc_quorum.h +--- corosync-0.92/include/corosync/ipc_quorum.h 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/include/corosync/ipc_quorum.h 2008-11-06 22:49:07.000000000 +0100 +@@ -0,0 +1,73 @@ ++/* ++ * Copyright (c) 2008 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 IPC_QUORUM_H_DEFINED ++#define IPC_QUORUM_H_DEFINED ++ ++#include ++#include ++#include "corosync/ipc_gen.h" ++ ++enum req_quorum_types { ++ MESSAGE_REQ_QUORUM_GETQUORATE = 0, ++ MESSAGE_REQ_QUORUM_TRACKSTART, ++ MESSAGE_REQ_QUORUM_TRACKSTOP ++}; ++ ++enum res_quorum_types { ++ MESSAGE_RES_QUORUM_GETQUORATE = 0, ++ MESSAGE_RES_QUORUM_TRACKSTART, ++ MESSAGE_RES_QUORUM_TRACKSTOP, ++ MESSAGE_RES_QUORUM_NOTIFICATION ++}; ++ ++struct req_lib_quorum_trackstart { ++ mar_req_header_t header __attribute__((aligned(8))); ++ unsigned int track_flags; ++}; ++ ++ ++struct res_lib_quorum_getquorate { ++ mar_res_header_t header __attribute__((aligned(8))); ++ mar_uint32_t quorate; ++}; ++ ++struct res_lib_quorum_notification { ++ mar_res_header_t header __attribute__((aligned(8))); ++ mar_int32_t quorate __attribute__((aligned(8))); ++ mar_uint64_t ring_seq __attribute__((aligned(8))); ++ mar_uint32_t view_list_entries __attribute__((aligned(8))); ++ mar_uint32_t view_list[]; ++}; ++ ++#endif +diff -Naurd corosync-0.92/include/corosync/ipc_votequorum.h corosync-trunk/include/corosync/ipc_votequorum.h +--- corosync-0.92/include/corosync/ipc_votequorum.h 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/include/corosync/ipc_votequorum.h 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,149 @@ ++/* ++ * Copyright (c) 2009 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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 IPC_VOTEQUORUM_H_DEFINED ++#define IPC_VOTEQUORUM_H_DEFINED ++ ++#include "corosync/corotypes.h" ++#include "corosync/ipc_gen.h" ++ ++// ILLEGAL value!! ++#define VOTEQUORUM_SERVICE 15 ++ ++#define VOTEQUORUM_MAX_QDISK_NAME_LEN 255 ++ ++ ++enum req_votequorum_types { ++ MESSAGE_REQ_VOTEQUORUM_GETINFO = 0, ++ MESSAGE_REQ_VOTEQUORUM_SETEXPECTED, ++ MESSAGE_REQ_VOTEQUORUM_SETVOTES, ++ MESSAGE_REQ_VOTEQUORUM_QDISK_REGISTER, ++ MESSAGE_REQ_VOTEQUORUM_QDISK_UNREGISTER, ++ MESSAGE_REQ_VOTEQUORUM_QDISK_POLL, ++ MESSAGE_REQ_VOTEQUORUM_QDISK_GETINFO, ++ MESSAGE_REQ_VOTEQUORUM_SETSTATE, ++ MESSAGE_REQ_VOTEQUORUM_LEAVING, ++ MESSAGE_REQ_VOTEQUORUM_TRACKSTART, ++ MESSAGE_REQ_VOTEQUORUM_TRACKSTOP ++}; ++ ++enum res_votequorum_types { ++ MESSAGE_RES_VOTEQUORUM_STATUS = 0, ++ MESSAGE_RES_VOTEQUORUM_GETINFO, ++ MESSAGE_RES_VOTEQUORUM_QDISK_GETINFO, ++ MESSAGE_RES_VOTEQUORUM_TRACKSTART, ++ MESSAGE_RES_VOTEQUORUM_NOTIFICATION ++}; ++ ++struct req_lib_votequorum_setvotes { ++ mar_req_header_t header __attribute__((aligned(8))); ++ unsigned int votes; ++ int nodeid; ++}; ++ ++struct req_lib_votequorum_qdisk_register { ++ mar_req_header_t header __attribute__((aligned(8))); ++ unsigned int votes; ++ char name[VOTEQUORUM_MAX_QDISK_NAME_LEN]; ++}; ++ ++struct req_lib_votequorum_qdisk_poll { ++ mar_req_header_t header __attribute__((aligned(8))); ++ int state; ++}; ++ ++struct req_lib_votequorum_setexpected { ++ mar_req_header_t header __attribute__((aligned(8))); ++ unsigned int expected_votes; ++}; ++ ++struct req_lib_votequorum_trackstart { ++ mar_req_header_t header __attribute__((aligned(8))); ++ uint64_t context; ++ unsigned int track_flags; ++}; ++ ++struct req_lib_votequorum_general { ++ mar_req_header_t header __attribute__((aligned(8))); ++}; ++ ++#define VOTEQUORUM_REASON_KILL_REJECTED 1 ++#define VOTEQUORUM_REASON_KILL_APPLICATION 2 ++#define VOTEQUORUM_REASON_KILL_REJOIN 3 ++ ++struct req_lib_votequorum_getinfo { ++ mar_req_header_t header __attribute__((aligned(8))); ++ int nodeid; ++}; ++ ++struct res_lib_votequorum_status { ++ mar_res_header_t header __attribute__((aligned(8))); ++}; ++ ++#define VOTEQUORUM_INFO_FLAG_HASSTATE 1 ++#define VOTEQUORUM_INFO_FLAG_DISALLOWED 2 ++#define VOTEQUORUM_INFO_FLAG_TWONODE 4 ++#define VOTEQUORUM_INFO_FLAG_QUORATE 8 ++ ++struct res_lib_votequorum_getinfo { ++ mar_res_header_t header __attribute__((aligned(8))); ++ int nodeid; ++ unsigned int votes; ++ unsigned int expected_votes; ++ unsigned int highest_expected; ++ unsigned int total_votes; ++ unsigned int quorum; ++ unsigned int flags; ++}; ++ ++struct res_lib_votequorum_qdisk_getinfo { ++ mar_res_header_t header __attribute__((aligned(8))); ++ unsigned int votes; ++ unsigned int state; ++ char name[VOTEQUORUM_MAX_QDISK_NAME_LEN]; ++}; ++ ++struct votequorum_node { ++ mar_uint32_t nodeid; ++ mar_uint32_t state; ++}; ++ ++struct res_lib_votequorum_notification { ++ mar_res_header_t header __attribute__((aligned(8))); ++ mar_uint32_t quorate __attribute__((aligned(8))); ++ mar_uint64_t context __attribute__((aligned(8))); ++ mar_uint32_t node_list_entries __attribute__((aligned(8))); ++ struct votequorum_node node_list[] __attribute__((aligned(8))); ++}; ++ ++#endif +diff -Naurd corosync-0.92/include/corosync/mar_gen.h corosync-trunk/include/corosync/mar_gen.h +--- corosync-0.92/include/corosync/mar_gen.h 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/include/corosync/mar_gen.h 2008-11-06 22:49:07.000000000 +0100 +@@ -43,7 +43,7 @@ + #endif + #include + +-#include ++#include + #include + + typedef int8_t mar_int8_t; +@@ -98,7 +98,7 @@ + + typedef struct { + mar_uint16_t length __attribute__((aligned(8))); +- mar_uint8_t value[SA_MAX_NAME_LENGTH] __attribute__((aligned(8))); ++ mar_uint8_t value[CS_MAX_NAME_LENGTH] __attribute__((aligned(8))); + } mar_name_t; + + static inline char *get_mar_name_t (mar_name_t *name) { +@@ -121,19 +121,19 @@ + } + + static inline void marshall_from_mar_name_t ( +- SaNameT *dest, ++ cs_name_t *dest, + mar_name_t *src) + { + dest->length = src->length; +- memcpy (dest->value, src->value, SA_MAX_NAME_LENGTH); ++ memcpy (dest->value, src->value, CS_MAX_NAME_LENGTH); + } + + static inline void marshall_to_mar_name_t ( + mar_name_t *dest, +- SaNameT *src) ++ cs_name_t *src) + { + dest->length = src->length; +- memcpy (dest->value, src->value, SA_MAX_NAME_LENGTH); ++ memcpy (dest->value, src->value, CS_MAX_NAME_LENGTH); + } + + typedef enum { +@@ -148,7 +148,7 @@ + swab_mar_uint64_t (to_swab); + } + +-#define MAR_TIME_END ((SaTimeT)0x7fffffffffffffffull) ++#define MAR_TIME_END ((int64_t)0x7fffffffffffffffull) + #define MAR_TIME_BEGIN 0x0ULL + #define MAR_TIME_UNKNOWN 0x8000000000000000ULL + +@@ -158,7 +158,7 @@ + #define MAR_TIME_ONE_MINUTE 60000000000ULL + #define MAR_TIME_ONE_HOUR 3600000000000ULL + #define MAR_TIME_ONE_DAY 86400000000000ULL +-#define MAR_TIME_MAX SA_TIME_END ++#define MAR_TIME_MAX CS_TIME_END + + #define MAR_TRACK_CURRENT 0x01 + #define MAR_TRACK_CHANGES 0x02 +diff -Naurd corosync-0.92/include/corosync/pload.h corosync-trunk/include/corosync/pload.h +--- corosync-0.92/include/corosync/pload.h 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/include/corosync/pload.h 2008-10-30 23:41:34.000000000 +0100 +@@ -0,0 +1,100 @@ ++/* ++ * Copyright (c) 2008 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 COROSYNC_PLOAD_H_DEFINED ++#define COROSYNC_PLOAD_H_DEFINED ++ ++#include ++#include ++ ++/** ++ * @defgroup corosync Other API services provided by corosync ++ */ ++/** ++ * @addtogroup pload_corosync ++ * ++ * @{ ++ */ ++ ++typedef uint64_t pload_handle_t; ++ ++typedef enum { ++ PLOAD_OK = 1, ++ PLOAD_ERR_LIBRARY = 2, ++ PLOAD_ERR_TIMEOUT = 5, ++ PLOAD_ERR_TRY_AGAIN = 6, ++ PLOAD_ERR_INVALID_PARAM = 7, ++ PLOAD_ERR_NO_MEMORY = 8, ++ PLOAD_ERR_BAD_HANDLE = 9, ++ PLOAD_ERR_ACCESS = 11, ++ PLOAD_ERR_NOT_EXIST = 12, ++ PLOAD_ERR_EXIST = 14, ++ PLOAD_ERR_NOT_SUPPORTED = 20, ++ PLOAD_ERR_SECURITY = 29, ++ PLOAD_ERR_TOO_MANY_GROUPS=30 ++} pload_error_t; ++ ++typedef struct { ++ int callback; ++} pload_callbacks_t; ++ ++/** @} */ ++ ++/* ++ * Create a new pload connection ++ */ ++pload_error_t pload_initialize ( ++ pload_handle_t *handle, ++ pload_callbacks_t *callbacks); ++ ++/* ++ * Close the pload handle ++ */ ++pload_error_t pload_finalize ( ++ pload_handle_t handle); ++ ++/* ++ * Get a file descriptor on which to poll. pload_handle_t is NOT a ++ * file descriptor and may not be used directly. ++ */ ++pload_error_t pload_fd_get ( ++ pload_handle_t handle, ++ int *fd); ++ ++unsigned int pload_start ( ++ pload_handle_t handle, ++ unsigned int code, ++ unsigned int msg_count, ++ unsigned int msg_size); ++ ++#endif /* COROSYNC_PLOAD_H_DEFINED */ +diff -Naurd corosync-0.92/include/corosync/quorum.h corosync-trunk/include/corosync/quorum.h +--- corosync-0.92/include/corosync/quorum.h 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/include/corosync/quorum.h 2009-01-30 14:31:40.000000000 +0100 +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (c) 2008 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfi@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 Red Hat, 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 COROSYNC_QUORUM_H_DEFINED ++#define COROSYNC_QUORUM_H_DEFINED ++ ++#include ++ ++typedef uint64_t quorum_handle_t; ++ ++typedef struct { ++ uint32_t nodeid; ++ uint32_t state; ++} quorum_node_t; ++ ++typedef void (*quorum_notification_fn_t) ( ++ quorum_handle_t handle, ++ uint32_t quorate, ++ uint64_t ring_seq, ++ uint32_t view_list_entries, ++ uint32_t *view_list ++ ); ++ ++typedef struct { ++ quorum_notification_fn_t quorum_notify_fn; ++} quorum_callbacks_t; ++ ++ ++/* ++ * Create a new quorum connection ++ */ ++cs_error_t quorum_initialize ( ++ quorum_handle_t *handle, ++ quorum_callbacks_t *callbacks); ++ ++/* ++ * Close the quorum handle ++ */ ++cs_error_t quorum_finalize ( ++ quorum_handle_t handle); ++ ++ ++/* ++ * Get a file descriptor on which to poll. quorum_handle_t is NOT a ++ * file descriptor and may not be used directly. ++ */ ++cs_error_t quorum_fd_get ( ++ quorum_handle_t handle, ++ int *fd); ++ ++/* ++ * Dispatch messages and configuration changes ++ */ ++cs_error_t quorum_dispatch ( ++ quorum_handle_t handle, ++ cs_dispatch_flags_t dispatch_types); ++ ++ ++/* ++ * Get quorum information. ++ */ ++cs_error_t quorum_getquorate ( ++ quorum_handle_t handle, ++ int *quorate); ++ ++/* Track node and quorum changes */ ++cs_error_t quorum_trackstart ( ++ quorum_handle_t handle, ++ unsigned int flags ); ++ ++cs_error_t quorum_trackstop ( ++ quorum_handle_t handle); ++ ++ ++#endif /* COROSYNC_QUORUM_H_DEFINED */ +diff -Naurd corosync-0.92/include/corosync/saAis.h corosync-trunk/include/corosync/saAis.h +--- corosync-0.92/include/corosync/saAis.h 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/include/corosync/saAis.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,152 +0,0 @@ +-/* +- * Copyright (c) 2002-2003 MontaVista Software, Inc. +- * Copyright (c) 2006-2008 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 AIS_TYPES_H_DEFINED +-#define AIS_TYPES_H_DEFINED +- +-/** +- * @defgroup saf Service Availability Forum Application Interface Specification +- */ +- +-typedef enum { +- SA_FALSE = 0, +- SA_TRUE = 1 +-} SaBoolT; +- +-#ifndef COROSYNC_SOLARIS +-#include +-#else +-#include +-#endif +- +-typedef int8_t SaInt8T; +-typedef int16_t SaInt16T; +-typedef int32_t SaInt32T; +-typedef int64_t SaInt64T; +- +-typedef uint8_t SaUint8T; +-typedef uint16_t SaUint16T; +-typedef uint32_t SaUint32T; +-typedef uint64_t SaUint64T; +- +-typedef float SaFloatT; +-typedef double SaDoubleT; +-typedef char * SaStringT; +-typedef SaInt64T SaTimeT; +- +-#define SA_TIME_END ((SaTimeT)0x7FFFFFFFFFFFFFFFULL) +-#define SA_TIME_BEGIN 0x0ULL +-#define SA_TIME_UNKNOWN 0x8000000000000000ULL +- +-#define SA_TIME_ONE_MICROSECOND 1000ULL +-#define SA_TIME_ONE_MILLISECOND 1000000ULL +-#define SA_TIME_ONE_SECOND 1000000000ULL +-#define SA_TIME_ONE_MINUTE 60000000000ULL +-#define SA_TIME_ONE_HOUR 3600000000000ULL +-#define SA_TIME_ONE_DAY 86400000000000ULL +-#define SA_TIME_MAX SA_TIME_END +- +-#define SA_MAX_NAME_LENGTH 256 +- +-typedef struct { +- SaUint16T length; +- SaUint8T value[SA_MAX_NAME_LENGTH]; +-} SaNameT; +- +-typedef struct { +- char releaseCode; +- unsigned char majorVersion; +- unsigned char minorVersion; +-} SaVersionT; +- +-typedef SaUint64T SaNtfIdentifierT; +- +-#define SA_TRACK_CURRENT 0x01 +-#define SA_TRACK_CHANGES 0x02 +-#define SA_TRACK_CHANGES_ONLY 0x04 +- +-typedef enum { +- SA_DISPATCH_ONE = 1, +- SA_DISPATCH_ALL = 2, +- SA_DISPATCH_BLOCKING = 3 +-} SaDispatchFlagsT; +- +-typedef enum { +- SA_AIS_OK = 1, +- SA_AIS_ERR_LIBRARY = 2, +- SA_AIS_ERR_VERSION = 3, +- SA_AIS_ERR_INIT = 4, +- SA_AIS_ERR_TIMEOUT = 5, +- SA_AIS_ERR_TRY_AGAIN = 6, +- SA_AIS_ERR_INVALID_PARAM = 7, +- SA_AIS_ERR_NO_MEMORY = 8, +- SA_AIS_ERR_BAD_HANDLE = 9, +- SA_AIS_ERR_BUSY = 10, +- SA_AIS_ERR_ACCESS = 11, +- SA_AIS_ERR_NOT_EXIST = 12, +- SA_AIS_ERR_NAME_TOO_LONG = 13, +- SA_AIS_ERR_EXIST = 14, +- SA_AIS_ERR_NO_SPACE = 15, +- SA_AIS_ERR_INTERRUPT = 16, +- SA_AIS_ERR_NAME_NOT_FOUND = 17, +- SA_AIS_ERR_NO_RESOURCES = 18, +- SA_AIS_ERR_NOT_SUPPORTED = 19, +- SA_AIS_ERR_BAD_OPERATION = 20, +- SA_AIS_ERR_FAILED_OPERATION = 21, +- SA_AIS_ERR_MESSAGE_ERROR = 22, +- SA_AIS_ERR_QUEUE_FULL = 23, +- SA_AIS_ERR_QUEUE_NOT_AVAILABLE = 24, +- SA_AIS_ERR_BAD_FLAGS = 25, +- SA_AIS_ERR_TOO_BIG = 26, +- SA_AIS_ERR_NO_SECTIONS = 27 +-} SaAisErrorT; +- +-typedef union { +- SaInt64T int64Value; +- SaUint64T uint64Value; +- SaTimeT timeValue; +- SaFloatT floatValue; +- SaDoubleT doubleValue; +-} SaLimitValueT; +- +-typedef SaUint64T SaSelectionObjectT; +- +-typedef SaUint64T SaInvocationT; +- +-typedef SaUint64T SaSizeT; +- +-#define SA_HANDLE_INVALID 0x0ULL +- +-#endif /* AIS_TYPES_H_DEFINED */ +diff -Naurd corosync-0.92/include/corosync/totem/totem.h corosync-trunk/include/corosync/totem/totem.h +--- corosync-0.92/include/corosync/totem/totem.h 2008-08-20 02:57:40.000000000 +0200 ++++ corosync-trunk/include/corosync/totem/totem.h 2008-10-30 23:41:34.000000000 +0100 +@@ -50,26 +50,6 @@ + #define SEND_THREADS_MAX 16 + #define INTERFACE_MAX 2 + +-/* +- * Array location of various timeouts as +- * specified in corosync.conf. The last enum +- * specifies the size of the timeouts array and +- * needs to remain the last item in the list. +- */ +-enum { +- TOTEM_RETRANSMITS_BEFORE_LOSS, +- TOTEM_TOKEN, +- TOTEM_RETRANSMIT_TOKEN, +- TOTEM_HOLD_TOKEN, +- TOTEM_JOIN, +- TOTEM_CONSENSUS, +- TOTEM_MERGE, +- TOTEM_DOWNCHECK, +- TOTEM_FAIL_RECV_CONST, +- +- MAX_TOTEM_TIMEOUTS /* Last item */ +-} totem_timeout_types; +- + struct totem_interface { + struct totem_ip_address bindnet; + struct totem_ip_address boundto; +@@ -78,12 +58,21 @@ + }; + + struct totem_logging_configuration { +- void (*log_printf) (char *, int, int, char *, ...) __attribute__((format(printf, 4, 5))); ++ void (*log_printf) ( ++ int subsys, ++ char *function_name, ++ char *file_name, ++ int file_line, ++ unsigned int level, ++ char *format, ++ ...) __attribute__((format(printf, 6, 7))); ++ + int log_level_security; + int log_level_error; + int log_level_warning; + int log_level_notice; + int log_level_debug; ++ int log_subsys_id; + }; + + struct totem_config { +@@ -161,6 +150,7 @@ + TOTEM_CONFIGURATION_TRANSITIONAL + }; + ++#define TOTEM_CALLBACK_TOKEN_TYPE + enum totem_callback_token_type { + TOTEM_CALLBACK_TOKEN_RECEIVED = 1, + TOTEM_CALLBACK_TOKEN_SENT = 2 +diff -Naurd corosync-0.92/include/corosync/totem/totemip.h corosync-trunk/include/corosync/totem/totemip.h +--- corosync-0.92/include/corosync/totem/totemip.h 2008-08-14 16:59:50.000000000 +0200 ++++ corosync-trunk/include/corosync/totem/totemip.h 2009-01-25 22:15:25.000000000 +0100 +@@ -72,7 +72,7 @@ + extern int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr, + uint16_t port, struct sockaddr_storage *saddr, int *addrlen); + extern int totemip_parse(struct totem_ip_address *totemip, char *addr, int family); +-extern int totemip_iface_check(struct totem_ip_address *bindnet, struct totem_ip_address *boundto, int *interface_up, int *interface_num); ++extern int totemip_iface_check(struct totem_ip_address *bindnet, struct totem_ip_address *boundto, int *interface_up, int *interface_num, int mask_high_bit); + + /* These two simulate a zero in_addr by clearing the family field */ + static inline void totemip_zero_set(struct totem_ip_address *addr) +diff -Naurd corosync-0.92/include/corosync/totem/totempg.h corosync-trunk/include/corosync/totem/totempg.h +--- corosync-0.92/include/corosync/totem/totempg.h 2008-08-14 16:59:50.000000000 +0200 ++++ corosync-trunk/include/corosync/totem/totempg.h 2008-12-01 19:44:55.000000000 +0100 +@@ -139,7 +139,7 @@ + + extern char *totempg_ifaces_print (unsigned int nodeid); + +-extern int totempg_my_nodeid_get (void); ++extern unsigned int totempg_my_nodeid_get (void); + + extern int totempg_my_family_get (void); + +diff -Naurd corosync-0.92/include/corosync/votequorum.h corosync-trunk/include/corosync/votequorum.h +--- corosync-0.92/include/corosync/votequorum.h 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/include/corosync/votequorum.h 2009-01-30 14:31:40.000000000 +0100 +@@ -0,0 +1,205 @@ ++/* ++ * Copyright (c) 2009 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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 COROSYNC_VOTEQUORUM_H_DEFINED ++#define COROSYNC_VOTEQUORUM_H_DEFINED ++ ++typedef uint64_t votequorum_handle_t; ++ ++ ++#define VOTEQUORUM_MAX_QDISK_NAME_LEN 255 ++ ++#define VOTEQUORUM_INFO_FLAG_HASSTATE 1 ++#define VOTEQUORUM_INFO_FLAG_DISALLOWED 2 ++#define VOTEQUORUM_INFO_FLAG_TWONODE 4 ++#define VOTEQUORUM_INFO_FLAG_QUORATE 8 ++ ++#define NODESTATE_JOINING 1 ++#define NODESTATE_MEMBER 2 ++#define NODESTATE_DEAD 3 ++#define NODESTATE_LEAVING 4 ++#define NODESTATE_DISALLOWED 5 ++ ++ ++/** @} */ ++ ++struct votequorum_info { ++ unsigned int node_id; ++ unsigned int node_votes; ++ unsigned int node_expected_votes; ++ unsigned int highest_expected; ++ unsigned int total_votes; ++ unsigned int quorum; ++ unsigned int flags; ++}; ++ ++struct votequorum_qdisk_info { ++ unsigned int votes; ++ unsigned int state; ++ char name[VOTEQUORUM_MAX_QDISK_NAME_LEN]; ++}; ++ ++typedef struct { ++ uint32_t nodeid; ++ uint32_t state; ++} votequorum_node_t; ++ ++ ++typedef void (*votequorum_notification_fn_t) ( ++ votequorum_handle_t handle, ++ uint64_t context, ++ uint32_t quorate, ++ uint32_t node_list_entries, ++ votequorum_node_t node_list[] ++ ); ++ ++typedef struct { ++ votequorum_notification_fn_t votequorum_notify_fn; ++} votequorum_callbacks_t; ++ ++ ++/* ++ * Create a new quorum connection ++ */ ++cs_error_t votequorum_initialize ( ++ votequorum_handle_t *handle, ++ votequorum_callbacks_t *callbacks); ++ ++/* ++ * Close the quorum handle ++ */ ++cs_error_t votequorum_finalize ( ++ votequorum_handle_t handle); ++ ++ ++/* ++ * Dispatch messages and configuration changes ++ */ ++cs_error_t votequorum_dispatch ( ++ votequorum_handle_t handle, ++ cs_dispatch_flags_t dispatch_types); ++ ++/* ++ * Get a file descriptor on which to poll. votequorum_handle_t is NOT a ++ * file descriptor and may not be used directly. ++ */ ++cs_error_t votequorum_fd_get ( ++ votequorum_handle_t handle, ++ int *fd); ++ ++/* ++ * Get quorum information. ++ */ ++cs_error_t votequorum_getinfo ( ++ votequorum_handle_t handle, ++ unsigned int nodeid, ++ struct votequorum_info *info); ++ ++/* ++ * set expected_votes ++ */ ++cs_error_t votequorum_setexpected ( ++ votequorum_handle_t handle, ++ unsigned int expected_votes); ++ ++/* ++ * set votes for a node ++ */ ++cs_error_t votequorum_setvotes ( ++ votequorum_handle_t handle, ++ unsigned int nodeid, ++ unsigned int votes); ++ ++/* ++ * Register a quorum device ++ * it will be DEAD until polled ++ */ ++cs_error_t votequorum_qdisk_register ( ++ votequorum_handle_t handle, ++ char *name, ++ unsigned int votes); ++ ++/* ++ * Unregister a quorum device ++ */ ++cs_error_t votequorum_qdisk_unregister ( ++ votequorum_handle_t handle); ++ ++/* ++ * Poll a quorum device ++ */ ++cs_error_t votequorum_qdisk_poll ( ++ votequorum_handle_t handle, ++ unsigned int state); ++ ++/* ++ * Get quorum device information ++ */ ++cs_error_t votequorum_qdisk_getinfo ( ++ votequorum_handle_t handle, ++ struct votequorum_qdisk_info *info); ++ ++/* ++ * Set the "hasstate" bit for this node ++ */ ++cs_error_t votequorum_setstate ( ++ votequorum_handle_t handle); ++ ++/* Track node and quorum changes */ ++cs_error_t votequorum_trackstart ( ++ votequorum_handle_t handle, ++ uint64_t context, ++ unsigned int flags ); ++ ++cs_error_t votequorum_trackstop ( ++ votequorum_handle_t handle); ++ ++/* ++ * Set our LEAVING flag. we should exit soon after this ++ */ ++cs_error_t votequorum_leaving ( ++ votequorum_handle_t handle); ++ ++/* ++ * Save and retrieve private data/context ++ */ ++cs_error_t votequorum_context_get ( ++ votequorum_handle_t handle, ++ void **context); ++ ++cs_error_t votequorum_context_set ( ++ votequorum_handle_t handle, ++ void *context); ++ ++#endif /* COROSYNC_VOTEQUORUM_H_DEFINED */ +diff -Naurd corosync-0.92/lcr/Makefile corosync-trunk/lcr/Makefile +--- corosync-0.92/lcr/Makefile 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/lcr/Makefile 2008-11-11 18:26:58.000000000 +0100 +@@ -84,3 +84,6 @@ + rm -f test libtest.so* *.o uic liblcr.so* liblcr.a *.lcrso *.da *.ba *.bb *.bbg \ + test_static + ++lint: ++ -splint $(LINT_FLAGS) $(CFLAGS) lcr_ifact.c uic.c uis.c ++ +diff -Naurd corosync-0.92/lcr/uic.c corosync-trunk/lcr/uic.c +--- corosync-0.92/lcr/uic.c 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/lcr/uic.c 2008-11-11 19:13:47.000000000 +0100 +@@ -88,7 +88,7 @@ + return 0; + } + +-struct req_msg { ++struct uic_req_msg { + int len; + char msg[0]; + }; +@@ -97,12 +97,13 @@ + { + struct msghdr msg_send; + struct iovec iov_send[2]; +- struct req_msg req_msg; ++ struct uic_req_msg req_msg; ++ ssize_t send_res; + int res; + + req_msg.len = strlen (msg) + 1; + iov_send[0].iov_base = (void *)&req_msg; +- iov_send[0].iov_len = sizeof (struct req_msg); ++ iov_send[0].iov_len = sizeof (struct uic_req_msg); + iov_send[1].iov_base = (void *)msg; + iov_send[1].iov_len = req_msg.len; + +@@ -120,12 +121,14 @@ + #endif + + retry_send: +- res = sendmsg (fd, &msg_send, 0); +- if (res == -1 && errno == EINTR) { ++ send_res = sendmsg (fd, &msg_send, 0); ++ if (send_res == -1 && errno == EINTR) { + goto retry_send; + } +- if (res == -1) { ++ if (send_res == -1) { + res = -errno; ++ } else { ++ res = (int)send_res; + } + return (res); + +diff -Naurd corosync-0.92/lcr/uis.c corosync-trunk/lcr/uis.c +--- corosync-0.92/lcr/uis.c 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/lcr/uis.c 2008-11-11 18:26:58.000000000 +0100 +@@ -115,14 +115,14 @@ + } + }; + +-struct req_msg { ++struct uis_req_msg { + int len; + char msg[0]; + }; + + static void lcr_uis_dispatch (int fd) + { +- struct req_msg header; ++ struct uis_req_msg header; + char msg_contents[512]; + ssize_t readsize; + +diff -Naurd corosync-0.92/lib/cfg.c corosync-trunk/lib/cfg.c +--- corosync-0.92/lib/cfg.c 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/lib/cfg.c 2009-01-29 10:17:43.000000000 +0100 +@@ -1,13 +1,13 @@ + /* + * Copyright (c) 2002-2005 MontaVista Software, Inc. +- * Copyright (c) 2006-2007 Red Hat, Inc. ++ * Copyright (c) 2006-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: + * +@@ -40,19 +40,21 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + +-#include ++#include + #include ++#include + #include + #include + #include + #include + +-struct res_overlay { ++struct cfg_res_overlay { + mar_res_header_t header; + char data[4096]; + }; +@@ -63,15 +65,15 @@ + struct cfg_instance { + int response_fd; + int dispatch_fd; +- CorosyncCfgCallbacksT callbacks; +- SaNameT compName; +- int compRegistered; ++ corosync_cfg_callbacks_t callbacks; ++ cs_name_t comp_name; ++ int comp_registered; + int finalize; + pthread_mutex_t response_mutex; + pthread_mutex_t dispatch_mutex; + }; + +-static void cfg_handleInstanceDestructor (void *); ++static void cfg_handle_instance_destructor (void *); + + /* + * All instances in one database +@@ -80,13 +82,13 @@ + .handleCount = 0, + .handles = 0, + .mutex = PTHREAD_MUTEX_INITIALIZER, +- .handleInstanceDestructor = cfg_handleInstanceDestructor ++ .handleInstanceDestructor = cfg_handle_instance_destructor + }; + + /* + * Implementation + */ +-void cfg_handleInstanceDestructor (void *instance) ++void cfg_handle_instance_destructor (void *instance) + { + struct cfg_instance *cfg_instance = instance; + +@@ -94,84 +96,85 @@ + pthread_mutex_destroy (&cfg_instance->dispatch_mutex); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_initialize ( + corosync_cfg_handle_t *cfg_handle, +- const CorosyncCfgCallbacksT *cfgCallbacks) ++ const corosync_cfg_callbacks_t *cfg_callbacks) + { + struct cfg_instance *cfg_instance; +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + + error = saHandleCreate (&cfg_hdb, sizeof (struct cfg_instance), cfg_handle); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_no_destroy; + } + + error = saHandleInstanceGet (&cfg_hdb, *cfg_handle, (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_destroy; + } + + cfg_instance->response_fd = -1; + + cfg_instance->dispatch_fd = -1; +- ++ + error = saServiceConnect (&cfg_instance->response_fd, + &cfg_instance->dispatch_fd, CFG_SERVICE); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_put_destroy; + } + +- if (cfgCallbacks) { +- memcpy (&cfg_instance->callbacks, cfgCallbacks, sizeof (CorosyncCfgCallbacksT)); ++ if (cfg_callbacks) { ++ memcpy (&cfg_instance->callbacks, cfg_callbacks, sizeof (corosync_cfg_callbacks_t)); + } + + pthread_mutex_init (&cfg_instance->response_mutex, NULL); + + pthread_mutex_init (&cfg_instance->dispatch_mutex, NULL); + +- saHandleInstancePut (&cfg_hdb, *cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, *cfg_handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + + error_put_destroy: +- saHandleInstancePut (&cfg_hdb, *cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, *cfg_handle); + error_destroy: +- saHandleDestroy (&cfg_hdb, *cfg_handle); ++ (void)saHandleDestroy (&cfg_hdb, *cfg_handle); + error_no_destroy: + return (error); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_fd_get ( + corosync_cfg_handle_t cfg_handle, +- SaSelectionObjectT *selectionObject) ++ int32_t *selection_fd) + { + struct cfg_instance *cfg_instance; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +- *selectionObject = cfg_instance->dispatch_fd; ++ *selection_fd = cfg_instance->dispatch_fd; + +- saHandleInstancePut (&cfg_hdb, cfg_handle); +- return (SA_AIS_OK); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); ++ return (CS_OK); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_dispatch ( + corosync_cfg_handle_t cfg_handle, +- SaDispatchFlagsT dispatchFlags) ++ cs_dispatch_flags_t dispatch_flags) + { + struct pollfd ufds; + int timeout = -1; +- SaAisErrorT error; ++ cs_error_t error; + int cont = 1; /* always continue do loop except when set to 0 */ + int dispatch_avail; + struct cfg_instance *cfg_instance; ++ struct res_lib_cfg_testshutdown *res_lib_cfg_testshutdown; + #ifdef COMPILE_OUT + struct res_lib_corosync_healthcheckcallback *res_lib_corosync_healthcheckcallback; + struct res_lib_corosync_readinessstatesetcallback *res_lib_corosync_readinessstatesetcallback; +@@ -179,19 +182,19 @@ + struct res_lib_corosync_csiremovecallback *res_lib_corosync_csiremovecallback; + struct res_lib_cfg_statetrackcallback *res_lib_cfg_statetrackcallback; + #endif +- CorosyncCfgCallbacksT callbacks; +- struct res_overlay dispatch_data; ++ corosync_cfg_callbacks_t callbacks; ++ struct cfg_res_overlay dispatch_data; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, + (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + /* +- * Timeout instantly for SA_DISPATCH_ALL ++ * Timeout instantly for CS_DISPATCH_ALL + */ +- if (dispatchFlags == SA_DISPATCH_ALL) { ++ if (dispatch_flags == CS_DISPATCH_ALL) { + timeout = 0; + } + +@@ -204,14 +207,14 @@ + ufds.revents = 0; + + error = saPollRetry (&ufds, 1, timeout); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_nounlock; + } + + pthread_mutex_lock (&cfg_instance->dispatch_mutex); + + error = saPollRetry (&ufds, 1, 0); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_nounlock; + } + +@@ -219,13 +222,13 @@ + * Handle has been finalized in another thread + */ + if (cfg_instance->finalize == 1) { +- error = SA_AIS_OK; ++ error = CS_OK; + pthread_mutex_unlock (&cfg_instance->dispatch_mutex); + goto error_unlock; + } + + dispatch_avail = ufds.revents & POLLIN; +- if (dispatch_avail == 0 && dispatchFlags == SA_DISPATCH_ALL) { ++ if (dispatch_avail == 0 && dispatch_flags == CS_DISPATCH_ALL) { + pthread_mutex_unlock (&cfg_instance->dispatch_mutex); + break; /* exit do while cont is 1 loop */ + } else +@@ -240,13 +243,13 @@ + */ + error = saRecvRetry (cfg_instance->dispatch_fd, &dispatch_data.header, + sizeof (mar_res_header_t)); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_unlock; + } + if (dispatch_data.header.size > sizeof (mar_res_header_t)) { + error = saRecvRetry (cfg_instance->dispatch_fd, &dispatch_data.data, + dispatch_data.header.size - sizeof (mar_res_header_t)); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_unlock; + } + } +@@ -260,16 +263,21 @@ + * A risk of this dispatch method is that the callback routines may + * operate at the same time that cfgFinalize has been called in another thread. + */ +- memcpy (&callbacks, &cfg_instance->callbacks, sizeof (CorosyncCfgCallbacksT)); ++ memcpy (&callbacks, &cfg_instance->callbacks, sizeof (corosync_cfg_callbacks_t)); + pthread_mutex_unlock (&cfg_instance->dispatch_mutex); + + /* + * Dispatch incoming response + */ + switch (dispatch_data.header.id) { +- ++ case MESSAGE_RES_CFG_TESTSHUTDOWN: ++ if (callbacks.corosync_cfg_shutdown_callback) { ++ res_lib_cfg_testshutdown = (struct res_lib_cfg_testshutdown *)&dispatch_data; ++ callbacks.corosync_cfg_shutdown_callback(cfg_handle, res_lib_cfg_testshutdown->flags); ++ } ++ break; + default: +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + goto error_nounlock; + break; + } +@@ -277,32 +285,32 @@ + /* + * Determine if more messages should be processed + */ +- switch (dispatchFlags) { +- case SA_DISPATCH_ONE: ++ switch (dispatch_flags) { ++ case CS_DISPATCH_ONE: + cont = 0; + break; +- case SA_DISPATCH_ALL: ++ case CS_DISPATCH_ALL: + break; +- case SA_DISPATCH_BLOCKING: ++ case CS_DISPATCH_BLOCKING: + break; + } + } while (cont); + + error_unlock: +- saHandleInstancePut (&cfg_hdb, cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); + error_nounlock: + return (error); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_finalize ( + corosync_cfg_handle_t cfg_handle) + { + struct cfg_instance *cfg_instance; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -316,8 +324,8 @@ + if (cfg_instance->finalize) { + pthread_mutex_unlock (&cfg_instance->response_mutex); + pthread_mutex_unlock (&cfg_instance->dispatch_mutex); +- saHandleInstancePut (&cfg_hdb, cfg_handle); +- return (SA_AIS_ERR_BAD_HANDLE); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); ++ return (CS_ERR_BAD_HANDLE); + } + + cfg_instance->finalize = 1; +@@ -330,7 +338,7 @@ + + pthread_mutex_destroy (&cfg_instance->dispatch_mutex); + +- saHandleDestroy (&cfg_hdb, cfg_handle); ++ (void)saHandleDestroy (&cfg_hdb, cfg_handle); + + if (cfg_instance->response_fd != -1) { + shutdown (cfg_instance->response_fd, 0); +@@ -341,12 +349,12 @@ + close (cfg_instance->dispatch_fd); + } + +- saHandleInstancePut (&cfg_hdb, cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); + + return (error); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_ring_status_get ( + corosync_cfg_handle_t cfg_handle, + char ***interface_names, +@@ -357,10 +365,10 @@ + struct req_lib_cfg_ringstatusget req_lib_cfg_ringstatusget; + struct res_lib_cfg_ringstatusget res_lib_cfg_ringstatusget; + unsigned int i; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -380,13 +388,13 @@ + *interface_count = res_lib_cfg_ringstatusget.interface_count; + *interface_names = malloc (sizeof (char *) * *interface_count); + if (*interface_names == NULL) { +- return (SA_AIS_ERR_NO_MEMORY); ++ return (CS_ERR_NO_MEMORY); + } + memset (*interface_names, 0, sizeof (char *) * *interface_count); + + *status = malloc (sizeof (char *) * *interface_count); + if (*status == NULL) { +- error = SA_AIS_ERR_NO_MEMORY; ++ error = CS_ERR_NO_MEMORY; + goto error_free_interface_names; + } + memset (*status, 0, sizeof (char *) * *interface_count); +@@ -394,12 +402,12 @@ + for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) { + (*(interface_names))[i] = strdup (res_lib_cfg_ringstatusget.interface_name[i]); + if ((*(interface_names))[i] == NULL) { +- error = SA_AIS_ERR_NO_MEMORY; ++ error = CS_ERR_NO_MEMORY; + goto error_free_contents; + } + (*(status))[i] = strdup (res_lib_cfg_ringstatusget.interface_status[i]); + if ((*(status))[i] == NULL) { +- error = SA_AIS_ERR_NO_MEMORY; ++ error = CS_ERR_NO_MEMORY; + goto error_free_contents; + } + } +@@ -416,27 +424,27 @@ + } + + free (*status); +- ++ + error_free_interface_names: + free (*interface_names); +- ++ + no_error: +- saHandleInstancePut (&cfg_hdb, cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); + + return (error); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_ring_reenable ( + corosync_cfg_handle_t cfg_handle) + { + struct cfg_instance *cfg_instance; + struct req_lib_cfg_ringreenable req_lib_cfg_ringreenable; + struct res_lib_cfg_ringreenable res_lib_cfg_ringreenable; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -452,12 +460,12 @@ + sizeof (struct res_lib_cfg_ringreenable)); + + pthread_mutex_unlock (&cfg_instance->response_mutex); +- saHandleInstancePut (&cfg_hdb, cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); + + return (error); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_service_load ( + corosync_cfg_handle_t cfg_handle, + char *service_name, +@@ -466,10 +474,10 @@ + struct cfg_instance *cfg_instance; + struct req_lib_cfg_serviceload req_lib_cfg_serviceload; + struct res_lib_cfg_serviceload res_lib_cfg_serviceload; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -477,7 +485,7 @@ + req_lib_cfg_serviceload.header.id = MESSAGE_REQ_CFG_SERVICELOAD; + memset (&req_lib_cfg_serviceload.service_name, 0, + sizeof (req_lib_cfg_serviceload.service_name)); +- strncpy ((char *)req_lib_cfg_serviceload.service_name, service_name, ++ strncpy (req_lib_cfg_serviceload.service_name, service_name, + sizeof (req_lib_cfg_serviceload.service_name) - 1); + req_lib_cfg_serviceload.service_ver = service_ver; + +@@ -490,12 +498,12 @@ + sizeof (struct res_lib_cfg_serviceload)); + + pthread_mutex_unlock (&cfg_instance->response_mutex); +- saHandleInstancePut (&cfg_hdb, cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); + + return (error); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_service_unload ( + corosync_cfg_handle_t cfg_handle, + char *service_name, +@@ -504,10 +512,10 @@ + struct cfg_instance *cfg_instance; + struct req_lib_cfg_serviceunload req_lib_cfg_serviceunload; + struct res_lib_cfg_serviceunload res_lib_cfg_serviceunload; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -515,7 +523,7 @@ + req_lib_cfg_serviceunload.header.id = MESSAGE_REQ_CFG_SERVICEUNLOAD; + memset (&req_lib_cfg_serviceunload.service_name, 0, + sizeof (req_lib_cfg_serviceunload.service_name)); +- strncpy ((char *)req_lib_cfg_serviceunload.service_name, service_name, ++ strncpy (req_lib_cfg_serviceunload.service_name, service_name, + sizeof (req_lib_cfg_serviceunload.service_name) - 1); + req_lib_cfg_serviceunload.service_ver = service_ver; + +@@ -528,29 +536,29 @@ + sizeof (struct res_lib_cfg_serviceunload)); + + pthread_mutex_unlock (&cfg_instance->response_mutex); +- saHandleInstancePut (&cfg_hdb, cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); + + return (error); + } +-SaAisErrorT ++cs_error_t + corosync_cfg_state_track ( + corosync_cfg_handle_t cfg_handle, +- SaUint8T trackFlags, +- const CorosyncCfgStateNotificationT *notificationBuffer) ++ uint8_t track_flags, ++ const corosync_cfg_state_notification_t *notification_buffer) + { + struct cfg_instance *cfg_instance; + struct req_lib_cfg_statetrack req_lib_cfg_statetrack; + struct res_lib_cfg_statetrack res_lib_cfg_statetrack; +- SaAisErrorT error; ++ cs_error_t error; + + req_lib_cfg_statetrack.header.size = sizeof (struct req_lib_cfg_statetrack); + req_lib_cfg_statetrack.header.id = MESSAGE_REQ_CFG_STATETRACKSTART; +- req_lib_cfg_statetrack.trackFlags = trackFlags; +- req_lib_cfg_statetrack.notificationBufferAddress = (CorosyncCfgStateNotificationT *)notificationBuffer; ++ req_lib_cfg_statetrack.track_flags = track_flags; ++ req_lib_cfg_statetrack.notification_buffer_address = (corosync_cfg_state_notification_t *)notification_buffer; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, + (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -564,23 +572,23 @@ + + pthread_mutex_unlock (&cfg_instance->response_mutex); + +- saHandleInstancePut (&cfg_hdb, cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); + +- return (error == SA_AIS_OK ? res_lib_cfg_statetrack.header.error : error); ++ return (error == CS_OK ? res_lib_cfg_statetrack.header.error : error); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_state_track_stop ( + corosync_cfg_handle_t cfg_handle) + { + struct cfg_instance *cfg_instance; + struct req_lib_cfg_statetrackstop req_lib_cfg_statetrackstop; + struct res_lib_cfg_statetrackstop res_lib_cfg_statetrackstop; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, + (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -597,31 +605,33 @@ + + pthread_mutex_unlock (&cfg_instance->response_mutex); + +- saHandleInstancePut (&cfg_hdb, cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); + +- return (error == SA_AIS_OK ? res_lib_cfg_statetrackstop.header.error : error); ++ return (error == CS_OK ? res_lib_cfg_statetrackstop.header.error : error); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_admin_state_get ( + corosync_cfg_handle_t cfg_handle, +- CorosyncCfgAdministrativeTargetT administrativeTarget, +- CorosyncCfgAdministrativeStateT *administrativeState) ++ corosync_cfg_administrative_target_t administrative_target, ++ corosync_cfg_administrative_state_t *administrative_state) + { + struct cfg_instance *cfg_instance; + struct req_lib_cfg_administrativestateget req_lib_cfg_administrativestateget; + struct res_lib_cfg_administrativestateget res_lib_cfg_administrativestateget; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, + (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + req_lib_cfg_administrativestateget.header.id = MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET; + req_lib_cfg_administrativestateget.header.size = sizeof (struct req_lib_cfg_administrativestateget); +- req_lib_cfg_administrativestateget.administrativeTarget = administrativeTarget; ++ req_lib_cfg_administrativestateget.administrative_target = administrative_target; ++ ++ pthread_mutex_lock (&cfg_instance->response_mutex); + + error = saSendReceiveReply (cfg_instance->response_fd, + &req_lib_cfg_administrativestateget, +@@ -633,32 +643,34 @@ + + pthread_mutex_unlock (&cfg_instance->response_mutex); + +- saHandleInstancePut (&cfg_hdb, cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); + +- return (error == SA_AIS_OK ? res_lib_cfg_administrativestateget.header.error : error); ++ return (error == CS_OK ? res_lib_cfg_administrativestateget.header.error : error); + } + +-SaAisErrorT ++cs_error_t + corosync_cfg_admin_state_set ( + corosync_cfg_handle_t cfg_handle, +- CorosyncCfgAdministrativeTargetT administrativeTarget, +- CorosyncCfgAdministrativeStateT administrativeState) ++ corosync_cfg_administrative_target_t administrative_target, ++ corosync_cfg_administrative_state_t administrative_state) + { + struct cfg_instance *cfg_instance; + struct req_lib_cfg_administrativestateset req_lib_cfg_administrativestateset; + struct res_lib_cfg_administrativestateset res_lib_cfg_administrativestateset; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&cfg_hdb, cfg_handle, + (void *)&cfg_instance); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + req_lib_cfg_administrativestateset.header.id = MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET; + req_lib_cfg_administrativestateset.header.size = sizeof (struct req_lib_cfg_administrativestateset); +- req_lib_cfg_administrativestateset.administrativeTarget = administrativeTarget; +- req_lib_cfg_administrativestateset.administrativeState = administrativeState; ++ req_lib_cfg_administrativestateset.administrative_target = administrative_target; ++ req_lib_cfg_administrativestateset.administrative_state = administrative_state; ++ ++ pthread_mutex_lock (&cfg_instance->response_mutex); + + error = saSendReceiveReply (cfg_instance->response_fd, + &req_lib_cfg_administrativestateset, +@@ -670,7 +682,191 @@ + + pthread_mutex_unlock (&cfg_instance->response_mutex); + +- saHandleInstancePut (&cfg_hdb, cfg_handle); ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); + +- return (error == SA_AIS_OK ? res_lib_cfg_administrativestateset.header.error : error); ++ return (error == CS_OK ? res_lib_cfg_administrativestateset.header.error : error); ++} ++ ++cs_error_t ++corosync_cfg_kill_node ( ++ corosync_cfg_handle_t cfg_handle, ++ unsigned int nodeid, ++ char *reason) ++{ ++ struct cfg_instance *cfg_instance; ++ struct req_lib_cfg_killnode req_lib_cfg_killnode; ++ struct res_lib_cfg_killnode res_lib_cfg_killnode; ++ cs_error_t error; ++ ++ if (strlen(reason) >= CS_MAX_NAME_LENGTH) ++ return CS_ERR_NAME_TOO_LONG; ++ ++ error = saHandleInstanceGet (&cfg_hdb, cfg_handle, ++ (void *)&cfg_instance); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ req_lib_cfg_killnode.header.id = MESSAGE_REQ_CFG_KILLNODE; ++ req_lib_cfg_killnode.header.size = sizeof (struct req_lib_cfg_killnode); ++ req_lib_cfg_killnode.nodeid = nodeid; ++ strcpy((char *)req_lib_cfg_killnode.reason.value, reason); ++ req_lib_cfg_killnode.reason.length = strlen(reason)+1; ++ ++ pthread_mutex_lock (&cfg_instance->response_mutex); ++ ++ error = saSendReceiveReply (cfg_instance->response_fd, ++ &req_lib_cfg_killnode, ++ sizeof (struct req_lib_cfg_killnode), ++ &res_lib_cfg_killnode, ++ sizeof (struct res_lib_cfg_killnode)); ++ ++ error = res_lib_cfg_killnode.header.error; ++ ++ pthread_mutex_unlock (&cfg_instance->response_mutex); ++ ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); ++ ++ return (error == CS_OK ? res_lib_cfg_killnode.header.error : error); ++} ++ ++cs_error_t ++corosync_cfg_try_shutdown ( ++ corosync_cfg_handle_t cfg_handle, ++ corosync_cfg_shutdown_flags_t flags) ++{ ++ struct cfg_instance *cfg_instance; ++ struct req_lib_cfg_tryshutdown req_lib_cfg_tryshutdown; ++ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown; ++ cs_error_t error; ++ ++ error = saHandleInstanceGet (&cfg_hdb, cfg_handle, ++ (void *)&cfg_instance); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ req_lib_cfg_tryshutdown.header.id = MESSAGE_REQ_CFG_TRYSHUTDOWN; ++ req_lib_cfg_tryshutdown.header.size = sizeof (struct req_lib_cfg_tryshutdown); ++ req_lib_cfg_tryshutdown.flags = flags; ++ ++ pthread_mutex_lock (&cfg_instance->response_mutex); ++ ++ error = saSendReceiveReply (cfg_instance->response_fd, ++ &req_lib_cfg_tryshutdown, ++ sizeof (struct req_lib_cfg_tryshutdown), ++ &res_lib_cfg_tryshutdown, ++ sizeof (struct res_lib_cfg_tryshutdown)); ++ ++ pthread_mutex_unlock (&cfg_instance->response_mutex); ++ ++ (void)saHandleInstancePut (&cfg_hdb, cfg_handle); ++ ++ return (error == CS_OK ? res_lib_cfg_tryshutdown.header.error : error); ++} ++ ++cs_error_t ++corosync_cfg_replyto_shutdown ( ++ corosync_cfg_handle_t cfg_handle, ++ corosync_cfg_shutdown_reply_flags_t response) ++{ ++ struct cfg_instance *cfg_instance; ++ struct req_lib_cfg_replytoshutdown req_lib_cfg_replytoshutdown; ++ struct iovec iov; ++ cs_error_t error; ++ ++ error = saHandleInstanceGet (&cfg_hdb, cfg_handle, ++ (void *)&cfg_instance); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ req_lib_cfg_replytoshutdown.header.id = MESSAGE_REQ_CFG_REPLYTOSHUTDOWN; ++ req_lib_cfg_replytoshutdown.header.size = sizeof (struct req_lib_cfg_replytoshutdown); ++ req_lib_cfg_replytoshutdown.response = response; ++ ++ iov.iov_base = &req_lib_cfg_replytoshutdown; ++ iov.iov_len = sizeof (struct req_lib_cfg_replytoshutdown); ++ ++ pthread_mutex_lock (&cfg_instance->response_mutex); ++ error = saSendMsgRetry (cfg_instance->response_fd, ++ &iov, 1); ++ ++ pthread_mutex_unlock (&cfg_instance->response_mutex); ++ ++ return (error); ++} ++ ++cs_error_t corosync_cfg_get_node_addrs ( ++ corosync_cfg_handle_t cfg_handle, ++ int nodeid, ++ int max_addrs, ++ int *num_addrs, ++ corosync_cfg_node_address_t *addrs) ++{ ++ cs_error_t error; ++ char buf[PIPE_BUF]; ++ struct req_lib_cfg_get_node_addrs req_lib_cfg_get_node_addrs; ++ struct res_lib_cfg_get_node_addrs * res_lib_cfg_get_node_addrs = (struct res_lib_cfg_get_node_addrs *)buf; ++ struct cfg_instance *cfg_instance; ++ int addrlen; ++ int i; ++ struct iovec iov[2]; ++ ++ error = saHandleInstanceGet (&cfg_hdb, cfg_handle, ++ (void *)&cfg_instance); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&cfg_instance->response_mutex); ++ ++ req_lib_cfg_get_node_addrs.header.size = sizeof (req_lib_cfg_get_node_addrs); ++ req_lib_cfg_get_node_addrs.header.id = MESSAGE_REQ_CFG_GET_NODE_ADDRS; ++ req_lib_cfg_get_node_addrs.nodeid = nodeid; ++ ++ iov[0].iov_base = (char *)&req_lib_cfg_get_node_addrs; ++ iov[0].iov_len = sizeof (req_lib_cfg_get_node_addrs); ++ ++ error = saSendMsgReceiveReply (cfg_instance->response_fd, iov, 1, ++ res_lib_cfg_get_node_addrs, sizeof (mar_res_header_t)); ++ ++ if (error == CS_OK && res_lib_cfg_get_node_addrs->header.size > sizeof(mar_res_header_t)) { ++ error = saRecvRetry (cfg_instance->response_fd, (char *)res_lib_cfg_get_node_addrs + sizeof (mar_res_header_t), ++ res_lib_cfg_get_node_addrs->header.size - sizeof (mar_res_header_t)); ++ } ++ pthread_mutex_unlock (&cfg_instance->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ if (res_lib_cfg_get_node_addrs->family == AF_INET) ++ addrlen = sizeof(struct sockaddr_in); ++ if (res_lib_cfg_get_node_addrs->family == AF_INET6) ++ addrlen = sizeof(struct sockaddr_in6); ++ ++ for (i=0; inum_addrs; i++) { ++ addrs[i].address_length = addrlen; ++ struct sockaddr_in *in; ++ struct sockaddr_in6 *in6; ++ ++ if (res_lib_cfg_get_node_addrs->family == AF_INET) { ++ in = (struct sockaddr_in *)addrs[i].address; ++ in->sin_family = AF_INET; ++ memcpy(&in->sin_addr, &res_lib_cfg_get_node_addrs->addrs[i][0], sizeof(struct in_addr)); ++ } ++ if (res_lib_cfg_get_node_addrs->family == AF_INET6) { ++ in6 = (struct sockaddr_in6 *)addrs[i].address; ++ in6->sin6_family = AF_INET6; ++ memcpy(&in6->sin6_addr, &res_lib_cfg_get_node_addrs->addrs[i][0], sizeof(struct in6_addr)); ++ } ++ } ++ *num_addrs = res_lib_cfg_get_node_addrs->num_addrs; ++ errno = error = res_lib_cfg_get_node_addrs->header.error; ++ ++error_exit: ++ ++ pthread_mutex_unlock (&cfg_instance->response_mutex); ++ return (error); + } +diff -Naurd corosync-0.92/lib/confdb.c corosync-trunk/lib/confdb.c +--- corosync-0.92/lib/confdb.c 2008-09-03 09:58:08.000000000 +0200 ++++ corosync-trunk/lib/confdb.c 2009-01-23 16:41:06.000000000 +0100 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2008 Red Hat, Inc. ++ * Copyright (c) 2008-2009 Red Hat, Inc. + * + * All rights reserved. + * +@@ -42,7 +42,7 @@ + #include + #include + +-#include ++#include + #include + #include + #include +@@ -86,7 +86,7 @@ + }; + + +-static confdb_error_t do_find_destroy(struct confdb_inst *confdb_inst, unsigned int find_handle); ++static cs_error_t do_find_destroy(struct confdb_inst *confdb_inst, unsigned int find_handle); + + + /* Safely tidy one iterator context list */ +@@ -99,7 +99,7 @@ + iter != list; iter = tmp, tmp = iter->next) { + + context = list_entry (iter, struct iter_context, list); +- do_find_destroy(confdb_inst, context->find_handle); ++ (void)do_find_destroy(confdb_inst, context->find_handle); + free(context); + } + } +@@ -137,20 +137,20 @@ + * @{ + */ + +-confdb_error_t confdb_initialize ( ++cs_error_t confdb_initialize ( + confdb_handle_t *handle, + confdb_callbacks_t *callbacks) + { +- SaAisErrorT error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + + error = saHandleCreate (&confdb_handle_t_db, sizeof (struct confdb_inst), handle); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_no_destroy; + } + + error = saHandleInstanceGet (&confdb_handle_t_db, *handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_destroy; + } + +@@ -163,7 +163,7 @@ + &confdb_inst->response_fd, + CONFDB_SERVICE); + } +- if (error != SA_AIS_OK) ++ if (error != CS_OK) + goto error_put_destroy; + + memcpy (&confdb_inst->callbacks, callbacks, sizeof (confdb_callbacks_t)); +@@ -175,26 +175,26 @@ + list_init (&confdb_inst->object_iter_head); + list_init (&confdb_inst->key_iter_head); + +- saHandleInstancePut (&confdb_handle_t_db, *handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, *handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + + error_put_destroy: +- saHandleInstancePut (&confdb_handle_t_db, *handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, *handle); + error_destroy: +- saHandleDestroy (&confdb_handle_t_db, *handle); ++ (void)saHandleDestroy (&confdb_handle_t_db, *handle); + error_no_destroy: + return (error); + } + +-confdb_error_t confdb_finalize ( ++cs_error_t confdb_finalize ( + confdb_handle_t handle) + { + struct confdb_inst *confdb_inst; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -205,15 +205,15 @@ + */ + if (confdb_inst->finalize) { + pthread_mutex_unlock (&confdb_inst->response_mutex); +- saHandleInstancePut (&confdb_handle_t_db, handle); +- return (CONFDB_ERR_BAD_HANDLE); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); ++ return (CS_ERR_BAD_HANDLE); + } + + confdb_inst->finalize = 1; + + pthread_mutex_unlock (&confdb_inst->response_mutex); + +- saHandleDestroy (&confdb_handle_t_db, handle); ++ (void)saHandleDestroy (&confdb_handle_t_db, handle); + + /* Free saved context handles */ + free_context_list(confdb_inst, &confdb_inst->object_find_head); +@@ -233,80 +233,80 @@ + close(confdb_inst->dispatch_fd); + } + } +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + +- return (CONFDB_OK); ++ return (CS_OK); + } + +-confdb_error_t confdb_fd_get ( ++cs_error_t confdb_fd_get ( + confdb_handle_t handle, + int *fd) + { +- SaAisErrorT error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + *fd = confdb_inst->dispatch_fd; + +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + } + +-confdb_error_t confdb_context_get ( ++cs_error_t confdb_context_get ( + confdb_handle_t handle, + void **context) + { +- SaAisErrorT error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + *context = confdb_inst->context; + +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + } + +-confdb_error_t confdb_context_set ( ++cs_error_t confdb_context_set ( + confdb_handle_t handle, + void *context) + { +- SaAisErrorT error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + confdb_inst->context = context; + +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + } + +-struct res_overlay { ++struct confdb_res_overlay { + mar_res_header_t header __attribute__((aligned(8))); + char data[512000]; + }; + +-confdb_error_t confdb_dispatch ( ++cs_error_t confdb_dispatch ( + confdb_handle_t handle, +- confdb_dispatch_t dispatch_types) ++ cs_dispatch_flags_t dispatch_types) + { + struct pollfd ufds; + int timeout = -1; +- SaAisErrorT error; ++ cs_error_t error; + int cont = 1; /* always continue do loop except when set to 0 */ + int dispatch_avail; + struct confdb_inst *confdb_inst; +@@ -314,16 +314,15 @@ + struct res_lib_confdb_key_change_callback *res_key_changed_pt; + struct res_lib_confdb_object_create_callback *res_object_created_pt; + struct res_lib_confdb_object_destroy_callback *res_object_destroyed_pt; +- struct res_overlay dispatch_data; +- int ignore_dispatch = 0; ++ struct confdb_res_overlay dispatch_data; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = CONFDB_ERR_NOT_SUPPORTED; ++ error = CS_ERR_NOT_SUPPORTED; + goto error_unlock; + } + +@@ -341,7 +340,7 @@ + ufds.revents = 0; + + error = saPollRetry (&ufds, 1, timeout); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_nounlock; + } + +@@ -351,7 +350,7 @@ + * Regather poll data in case ufds has changed since taking lock + */ + error = saPollRetry (&ufds, 1, timeout); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_nounlock; + } + +@@ -359,7 +358,7 @@ + * Handle has been finalized in another thread + */ + if (confdb_inst->finalize == 1) { +- error = CONFDB_OK; ++ error = CS_OK; + pthread_mutex_unlock (&confdb_inst->dispatch_mutex); + goto error_unlock; + } +@@ -380,14 +379,14 @@ + */ + error = saRecvRetry (confdb_inst->dispatch_fd, &dispatch_data.header, + sizeof (mar_res_header_t)); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_unlock; + } + if (dispatch_data.header.size > sizeof (mar_res_header_t)) { + error = saRecvRetry (confdb_inst->dispatch_fd, &dispatch_data.data, + dispatch_data.header.size - sizeof (mar_res_header_t)); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_unlock; + } + } +@@ -443,7 +442,7 @@ + break; + + default: +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + goto error_nounlock; + break; + } +@@ -453,16 +452,9 @@ + * */ + switch (dispatch_types) { + case CONFDB_DISPATCH_ONE: +- if (ignore_dispatch) { +- ignore_dispatch = 0; +- } else { +- cont = 0; +- } ++ cont = 0; + break; + case CONFDB_DISPATCH_ALL: +- if (ignore_dispatch) { +- ignore_dispatch = 0; +- } + break; + case CONFDB_DISPATCH_BLOCKING: + break; +@@ -470,36 +462,36 @@ + } while (cont); + + error_unlock: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + error_nounlock: + return (error); + } + +-confdb_error_t confdb_object_create ( ++cs_error_t confdb_object_create ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *object_name, + int object_name_len, + unsigned int *object_handle) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct req_lib_confdb_object_create req_lib_confdb_object_create; + struct res_lib_confdb_object_create res_lib_confdb_object_create; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_object_create(parent_object_handle, + object_name, object_name_len, + object_handle)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -518,7 +510,7 @@ + &res_lib_confdb_object_create, sizeof (struct res_lib_confdb_object_create)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -526,31 +518,31 @@ + *object_handle = res_lib_confdb_object_create.object_handle; + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_object_destroy ( ++cs_error_t confdb_object_destroy ( + confdb_handle_t handle, + unsigned int object_handle) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct req_lib_confdb_object_destroy req_lib_confdb_object_destroy; + mar_res_header_t res; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_object_destroy(object_handle)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -567,39 +559,39 @@ + &res, sizeof ( mar_res_header_t)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res.error; + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_object_parent_get ( ++cs_error_t confdb_object_parent_get ( + confdb_handle_t handle, + unsigned int object_handle, + unsigned int *parent_object_handle) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct req_lib_confdb_object_parent_get req_lib_confdb_object_parent_get; + struct res_lib_confdb_object_parent_get res_lib_confdb_object_parent_get; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_object_parent_get(object_handle, parent_object_handle)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -616,7 +608,7 @@ + &res_lib_confdb_object_parent_get, sizeof (struct res_lib_confdb_object_parent_get)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -624,28 +616,28 @@ + *parent_object_handle = res_lib_confdb_object_parent_get.parent_object_handle; + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-static confdb_error_t do_find_destroy( ++static cs_error_t do_find_destroy( + struct confdb_inst *confdb_inst, + unsigned int find_handle) + { +- confdb_error_t error; ++ cs_error_t error; + struct iovec iov[2]; + struct req_lib_confdb_object_find_destroy req_lib_confdb_object_find_destroy; + mar_res_header_t res; + + if (!find_handle) +- return SA_AIS_OK; ++ return CS_OK; + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_find_destroy(find_handle)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -662,7 +654,7 @@ + &res, sizeof (mar_res_header_t)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -673,56 +665,56 @@ + return (error); + } + +-confdb_error_t confdb_object_find_destroy( ++cs_error_t confdb_object_find_destroy( + confdb_handle_t handle, + unsigned int parent_object_handle) + { + struct iter_context *context; +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle); + error = do_find_destroy(confdb_inst, context->find_handle); +- if (error == SA_AIS_OK) { ++ if (error == CS_OK) { + list_del(&context->list); + free(context); + } + +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + return error; + } + +-confdb_error_t confdb_object_iter_destroy( ++cs_error_t confdb_object_iter_destroy( + confdb_handle_t handle, + unsigned int parent_object_handle) + { + struct iter_context *context; +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + context = find_iter_context(&confdb_inst->object_iter_head, parent_object_handle); + error = do_find_destroy(confdb_inst, context->find_handle); +- if (error == SA_AIS_OK) { ++ if (error == CS_OK) { + list_del(&context->list); + free(context); + } + +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + return error; + } + + +-confdb_error_t confdb_key_create ( ++cs_error_t confdb_key_create ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +@@ -730,24 +722,24 @@ + void *value, + int value_len) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct req_lib_confdb_key_create req_lib_confdb_key_create; + mar_res_header_t res; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_key_create(parent_object_handle, + key_name, key_name_len, + value, value_len)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -768,19 +760,19 @@ + &res, sizeof (res)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res.error; + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_key_delete ( ++cs_error_t confdb_key_delete ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +@@ -788,24 +780,24 @@ + void *value, + int value_len) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct req_lib_confdb_key_delete req_lib_confdb_key_delete; + mar_res_header_t res; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_key_delete(parent_object_handle, + key_name, key_name_len, + value, value_len)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -826,19 +818,19 @@ + &res, sizeof (res)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res.error; + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_key_get ( ++cs_error_t confdb_key_get ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +@@ -846,24 +838,24 @@ + void *value, + int *value_len) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct req_lib_confdb_key_get req_lib_confdb_key_get; + struct res_lib_confdb_key_get res_lib_confdb_key_get; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_key_get(parent_object_handle, + key_name, key_name_len, + value, value_len)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -882,47 +874,47 @@ + &res_lib_confdb_key_get, sizeof (struct res_lib_confdb_key_get)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_confdb_key_get.header.error; +- if (error == SA_AIS_OK) { ++ if (error == CS_OK) { + *value_len = res_lib_confdb_key_get.value.length; + memcpy(value, res_lib_confdb_key_get.value.value, *value_len); + } + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_key_increment ( ++cs_error_t confdb_key_increment ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, + int key_name_len, + unsigned int *value) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct req_lib_confdb_key_get req_lib_confdb_key_get; + struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_key_increment(parent_object_handle, + key_name, key_name_len, + value)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -941,46 +933,46 @@ + &res_lib_confdb_key_incdec, sizeof (struct res_lib_confdb_key_incdec)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_confdb_key_incdec.header.error; +- if (error == SA_AIS_OK) { ++ if (error == CS_OK) { + *value = res_lib_confdb_key_incdec.value; + } + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_key_decrement ( ++cs_error_t confdb_key_decrement ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, + int key_name_len, + unsigned int *value) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct req_lib_confdb_key_get req_lib_confdb_key_get; + struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_key_decrement(parent_object_handle, + key_name, key_name_len, + value)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -999,22 +991,22 @@ + &res_lib_confdb_key_incdec, sizeof (struct res_lib_confdb_key_incdec)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_confdb_key_incdec.header.error; +- if (error == SA_AIS_OK) { ++ if (error == CS_OK) { + *value = res_lib_confdb_key_incdec.value; + } + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_key_replace ( ++cs_error_t confdb_key_replace ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +@@ -1024,25 +1016,25 @@ + void *new_value, + int new_value_len) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct req_lib_confdb_key_replace req_lib_confdb_key_replace; + mar_res_header_t res; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_key_replace(parent_object_handle, + key_name, key_name_len, + old_value, old_value_len, + new_value, new_value_len)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + req_lib_confdb_key_replace.header.size = sizeof (struct req_lib_confdb_key_replace); +@@ -1064,28 +1056,28 @@ + &res, sizeof (res)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res.error; + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_object_iter_start ( ++cs_error_t confdb_object_iter_start ( + confdb_handle_t handle, + unsigned int object_handle) + { + struct confdb_inst *confdb_inst; +- confdb_error_t error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + struct iter_context *context; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -1093,7 +1085,7 @@ + if (!context) { + context = malloc(sizeof(struct iter_context)); + if (!context) { +- error = CONFDB_ERR_NO_MEMORY; ++ error = CS_ERR_NO_MEMORY; + goto ret; + } + context->parent_object_handle = object_handle; +@@ -1103,26 +1095,26 @@ + + /* Start a new find context */ + if (context->find_handle) { +- do_find_destroy(confdb_inst, context->find_handle); ++ (void)do_find_destroy(confdb_inst, context->find_handle); + context->find_handle = 0; + } + +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + ret: + return error; + } + +-confdb_error_t confdb_key_iter_start ( ++cs_error_t confdb_key_iter_start ( + confdb_handle_t handle, + unsigned int object_handle) + { + struct confdb_inst *confdb_inst; +- confdb_error_t error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + struct iter_context *context; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -1130,7 +1122,7 @@ + if (!context) { + context = malloc(sizeof(struct iter_context)); + if (!context) { +- error = CONFDB_ERR_NO_MEMORY; ++ error = CS_ERR_NO_MEMORY; + goto ret; + } + context->parent_object_handle = object_handle; +@@ -1140,22 +1132,22 @@ + context->find_handle = 0; + context->next_entry = 0; + +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + ret: + return error; + } + +-confdb_error_t confdb_object_find_start ( ++cs_error_t confdb_object_find_start ( + confdb_handle_t handle, + unsigned int parent_object_handle) + { + struct confdb_inst *confdb_inst; +- confdb_error_t error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + struct iter_context *context; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -1163,7 +1155,7 @@ + if (!context) { + context = malloc(sizeof(struct iter_context)); + if (!context) { +- error = CONFDB_ERR_NO_MEMORY; ++ error = CS_ERR_NO_MEMORY; + goto ret; + } + context->find_handle = 0; +@@ -1172,24 +1164,24 @@ + } + /* Start a new find context */ + if (context->find_handle) { +- do_find_destroy(confdb_inst, context->find_handle); ++ (void)do_find_destroy(confdb_inst, context->find_handle); + context->find_handle = 0; + } + +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + ret: + return error; + } + +-confdb_error_t confdb_object_find ( ++cs_error_t confdb_object_find ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *object_name, + int object_name_len, + unsigned int *object_handle) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct iter_context *context; +@@ -1197,26 +1189,26 @@ + struct res_lib_confdb_object_find res_lib_confdb_object_find; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + /* You MUST call confdb_object_find_start first */ + context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle); + if (!context) { +- error = CONFDB_ERR_CONTEXT_NOT_FOUND; ++ error = CS_ERR_CONTEXT_NOT_FOUND; + goto error_exit; + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_object_find(parent_object_handle, + &context->find_handle, + object_handle, + object_name, &object_name_len, + 0)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -1236,7 +1228,7 @@ + &res_lib_confdb_object_find, sizeof (struct res_lib_confdb_object_find)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -1245,20 +1237,20 @@ + context->find_handle = res_lib_confdb_object_find.find_handle; + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + + +-confdb_error_t confdb_object_iter ( ++cs_error_t confdb_object_iter ( + confdb_handle_t handle, + unsigned int parent_object_handle, + unsigned int *object_handle, + void *object_name, + int *object_name_len) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct iter_context *context; +@@ -1266,19 +1258,19 @@ + struct res_lib_confdb_object_iter res_lib_confdb_object_iter; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + /* You MUST call confdb_object_iter_start first */ + context = find_iter_context(&confdb_inst->object_iter_head, parent_object_handle); + if (!context) { +- error = CONFDB_ERR_CONTEXT_NOT_FOUND; ++ error = CS_ERR_CONTEXT_NOT_FOUND; + goto error_exit; + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + *object_name_len = 0; + if (confdb_sa_object_find(parent_object_handle, +@@ -1286,7 +1278,7 @@ + object_handle, + object_name, object_name_len, + 1)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto sa_exit; + } + +@@ -1304,12 +1296,12 @@ + &res_lib_confdb_object_iter, sizeof (struct res_lib_confdb_object_iter)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_confdb_object_iter.header.error; +- if (error == SA_AIS_OK) { ++ if (error == CS_OK) { + *object_name_len = res_lib_confdb_object_iter.object_name.length; + memcpy(object_name, res_lib_confdb_object_iter.object_name.value, *object_name_len); + *object_handle = res_lib_confdb_object_iter.object_handle; +@@ -1318,12 +1310,12 @@ + sa_exit: + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_key_iter ( ++cs_error_t confdb_key_iter ( + confdb_handle_t handle, + unsigned int parent_object_handle, + void *key_name, +@@ -1331,7 +1323,7 @@ + void *value, + int *value_len) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct iter_context *context; +@@ -1339,25 +1331,25 @@ + struct res_lib_confdb_key_iter res_lib_confdb_key_iter; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + /* You MUST call confdb_key_iter_start first */ + context = find_iter_context(&confdb_inst->key_iter_head, parent_object_handle); + if (!context) { +- error = CONFDB_ERR_CONTEXT_NOT_FOUND; ++ error = CS_ERR_CONTEXT_NOT_FOUND; + goto error_exit; + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_key_iter(parent_object_handle, + context->next_entry, + key_name, key_name_len, + value, value_len)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto sa_exit; + } + +@@ -1375,12 +1367,12 @@ + &res_lib_confdb_key_iter, sizeof (struct res_lib_confdb_key_iter)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_confdb_key_iter.header.error; +- if (error == SA_AIS_OK) { ++ if (error == CS_OK) { + *key_name_len = res_lib_confdb_key_iter.key_name.length; + memcpy(key_name, res_lib_confdb_key_iter.key_name.value, *key_name_len); + *value_len = res_lib_confdb_key_iter.value.length; +@@ -1391,31 +1383,31 @@ + context->next_entry++; + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_write ( ++cs_error_t confdb_write ( + confdb_handle_t handle, + char *error_text) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + mar_req_header_t req; + struct res_lib_confdb_write res_lib_confdb_write; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_write(error_text)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -1431,7 +1423,7 @@ + &res_lib_confdb_write, sizeof ( struct res_lib_confdb_write)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -1440,32 +1432,32 @@ + memcpy(error_text, res_lib_confdb_write.error.value, res_lib_confdb_write.error.length); + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_reload ( ++cs_error_t confdb_reload ( + confdb_handle_t handle, + int flush, + char *error_text) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct res_lib_confdb_reload res_lib_confdb_reload; + struct req_lib_confdb_reload req_lib_confdb_reload; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = SA_AIS_OK; ++ error = CS_OK; + + if (confdb_sa_reload(flush, error_text)) +- error = SA_AIS_ERR_ACCESS; ++ error = CS_ERR_ACCESS; + goto error_exit; + } + +@@ -1483,7 +1475,7 @@ + + pthread_mutex_unlock (&confdb_inst->response_mutex); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -1492,29 +1484,29 @@ + memcpy(error_text, res_lib_confdb_reload.error.value, res_lib_confdb_reload.error.length); + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_track_changes ( ++cs_error_t confdb_track_changes ( + confdb_handle_t handle, + unsigned int object_handle, + unsigned int flags) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + struct req_lib_confdb_object_track_start req; + mar_res_header_t res; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = CONFDB_ERR_NOT_SUPPORTED; ++ error = CS_ERR_NOT_SUPPORTED; + goto error_exit; + } + +@@ -1532,33 +1524,33 @@ + &res, sizeof ( mar_res_header_t)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res.error; + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } + +-confdb_error_t confdb_stop_track_changes (confdb_handle_t handle) ++cs_error_t confdb_stop_track_changes (confdb_handle_t handle) + { +- confdb_error_t error; ++ cs_error_t error; + struct confdb_inst *confdb_inst; + struct iovec iov[2]; + mar_req_header_t req; + mar_res_header_t res; + + error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + if (confdb_inst->standalone) { +- error = CONFDB_ERR_NOT_SUPPORTED; ++ error = CS_ERR_NOT_SUPPORTED; + goto error_exit; + } + +@@ -1574,14 +1566,14 @@ + &res, sizeof ( mar_res_header_t)); + + pthread_mutex_unlock (&confdb_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res.error; + + error_exit: +- saHandleInstancePut (&confdb_handle_t_db, handle); ++ (void)saHandleInstancePut (&confdb_handle_t_db, handle); + + return (error); + } +diff -Naurd corosync-0.92/lib/cpg.c corosync-trunk/lib/cpg.c +--- corosync-0.92/lib/cpg.c 2008-09-17 21:15:00.000000000 +0200 ++++ corosync-trunk/lib/cpg.c 2009-01-08 07:29:16.000000000 +0100 +@@ -45,7 +45,7 @@ + #include + #include + +-#include ++#include + #include + #include + #include +@@ -90,27 +90,27 @@ + * @{ + */ + +-cpg_error_t cpg_initialize ( ++cs_error_t cpg_initialize ( + cpg_handle_t *handle, + cpg_callbacks_t *callbacks) + { +- SaAisErrorT error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + + error = saHandleCreate (&cpg_handle_t_db, sizeof (struct cpg_inst), handle); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_no_destroy; + } + + error = saHandleInstanceGet (&cpg_handle_t_db, *handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_destroy; + } + + error = saServiceConnect (&cpg_inst->dispatch_fd, + &cpg_inst->response_fd, + CPG_SERVICE); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_put_destroy; + } + +@@ -120,26 +120,26 @@ + + pthread_mutex_init (&cpg_inst->dispatch_mutex, NULL); + +- saHandleInstancePut (&cpg_handle_t_db, *handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, *handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + + error_put_destroy: +- saHandleInstancePut (&cpg_handle_t_db, *handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, *handle); + error_destroy: +- saHandleDestroy (&cpg_handle_t_db, *handle); ++ (void)saHandleDestroy (&cpg_handle_t_db, *handle); + error_no_destroy: + return (error); + } + +-cpg_error_t cpg_finalize ( ++cs_error_t cpg_finalize ( + cpg_handle_t handle) + { + struct cpg_inst *cpg_inst; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -150,15 +150,15 @@ + */ + if (cpg_inst->finalize) { + pthread_mutex_unlock (&cpg_inst->response_mutex); +- saHandleInstancePut (&cpg_handle_t_db, handle); +- return (CPG_ERR_BAD_HANDLE); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); ++ return (CS_ERR_BAD_HANDLE); + } + + cpg_inst->finalize = 1; + + pthread_mutex_unlock (&cpg_inst->response_mutex); + +- saHandleDestroy (&cpg_handle_t_db, handle); ++ (void)saHandleDestroy (&cpg_handle_t_db, handle); + + /* + * Disconnect from the server +@@ -171,80 +171,80 @@ + shutdown(cpg_inst->dispatch_fd, 0); + close(cpg_inst->dispatch_fd); + } +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + +- return (CPG_OK); ++ return (CS_OK); + } + +-cpg_error_t cpg_fd_get ( ++cs_error_t cpg_fd_get ( + cpg_handle_t handle, + int *fd) + { +- SaAisErrorT error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + *fd = cpg_inst->dispatch_fd; + +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + } + +-cpg_error_t cpg_context_get ( ++cs_error_t cpg_context_get ( + cpg_handle_t handle, + void **context) + { +- SaAisErrorT error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + *context = cpg_inst->context; + +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + } + +-cpg_error_t cpg_context_set ( ++cs_error_t cpg_context_set ( + cpg_handle_t handle, + void *context) + { +- SaAisErrorT error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + cpg_inst->context = context; + +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + } + +-struct res_overlay { ++struct cpg_res_overlay { + mar_res_header_t header __attribute__((aligned(8))); + char data[512000]; + }; + +-cpg_error_t cpg_dispatch ( ++cs_error_t cpg_dispatch ( + cpg_handle_t handle, +- cpg_dispatch_t dispatch_types) ++ cs_dispatch_flags_t dispatch_types) + { + struct pollfd ufds; + int timeout = -1; +- SaAisErrorT error; ++ cs_error_t error; + int cont = 1; /* always continue do loop except when set to 0 */ + int dispatch_avail; + struct cpg_inst *cpg_inst; +@@ -253,8 +253,7 @@ + struct res_lib_cpg_deliver_callback *res_cpg_deliver_callback; + struct res_lib_cpg_groups_get_callback *res_lib_cpg_groups_get_callback; + cpg_callbacks_t callbacks; +- struct res_overlay dispatch_data; +- int ignore_dispatch = 0; ++ struct cpg_res_overlay dispatch_data; + struct cpg_address member_list[CPG_MEMBERS_MAX]; + struct cpg_address left_list[CPG_MEMBERS_MAX]; + struct cpg_address joined_list[CPG_MEMBERS_MAX]; +@@ -264,7 +263,7 @@ + unsigned int i; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -272,7 +271,7 @@ + * Timeout instantly for SA_DISPATCH_ONE or SA_DISPATCH_ALL and + * wait indefinately for SA_DISPATCH_BLOCKING + */ +- if (dispatch_types == CPG_DISPATCH_ALL) { ++ if (dispatch_types == CS_DISPATCH_ALL) { + timeout = 0; + } + +@@ -282,7 +281,7 @@ + ufds.revents = 0; + + error = saPollRetry (&ufds, 1, timeout); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_nounlock; + } + +@@ -292,7 +291,7 @@ + * Regather poll data in case ufds has changed since taking lock + */ + error = saPollRetry (&ufds, 1, timeout); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_nounlock; + } + +@@ -300,13 +299,13 @@ + * Handle has been finalized in another thread + */ + if (cpg_inst->finalize == 1) { +- error = CPG_OK; ++ error = CS_OK; + pthread_mutex_unlock (&cpg_inst->dispatch_mutex); + goto error_unlock; + } + + dispatch_avail = ufds.revents & POLLIN; +- if (dispatch_avail == 0 && dispatch_types == CPG_DISPATCH_ALL) { ++ if (dispatch_avail == 0 && dispatch_types == CS_DISPATCH_ALL) { + pthread_mutex_unlock (&cpg_inst->dispatch_mutex); + break; /* exit do while cont is 1 loop */ + } else +@@ -321,14 +320,14 @@ + */ + error = saRecvRetry (cpg_inst->dispatch_fd, &dispatch_data.header, + sizeof (mar_res_header_t)); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_unlock; + } + if (dispatch_data.header.size > sizeof (mar_res_header_t)) { + error = saRecvRetry (cpg_inst->dispatch_fd, &dispatch_data.data, + dispatch_data.header.size - sizeof (mar_res_header_t)); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_unlock; + } + } +@@ -424,7 +423,7 @@ + break; + + default: +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + goto error_nounlock; + break; + } +@@ -433,34 +432,27 @@ + * Determine if more messages should be processed + * */ + switch (dispatch_types) { +- case CPG_DISPATCH_ONE: +- if (ignore_dispatch) { +- ignore_dispatch = 0; +- } else { +- cont = 0; +- } ++ case CS_DISPATCH_ONE: ++ cont = 0; + break; +- case CPG_DISPATCH_ALL: +- if (ignore_dispatch) { +- ignore_dispatch = 0; +- } ++ case CS_DISPATCH_ALL: + break; +- case CPG_DISPATCH_BLOCKING: ++ case CS_DISPATCH_BLOCKING: + break; + } + } while (cont); + + error_unlock: +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + error_nounlock: + return (error); + } + +-cpg_error_t cpg_join ( ++cs_error_t cpg_join ( + cpg_handle_t handle, + struct cpg_name *group) + { +- cpg_error_t error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + struct iovec iov[2]; + struct req_lib_cpg_join req_lib_cpg_join; +@@ -469,7 +461,7 @@ + struct res_lib_cpg_trackstart res_lib_cpg_trackstart; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -487,7 +479,7 @@ + error = saSendMsgReceiveReply (cpg_inst->dispatch_fd, iov, 1, + &res_lib_cpg_trackstart, sizeof (struct res_lib_cpg_trackstart)); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + pthread_mutex_unlock (&cpg_inst->response_mutex); + goto error_exit; + } +@@ -507,30 +499,30 @@ + + pthread_mutex_unlock (&cpg_inst->response_mutex); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_cpg_join.header.error; + + error_exit: +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + + return (error); + } + +-cpg_error_t cpg_leave ( ++cs_error_t cpg_leave ( + cpg_handle_t handle, + struct cpg_name *group) + { +- cpg_error_t error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + struct iovec iov[2]; + struct req_lib_cpg_leave req_lib_cpg_leave; + struct res_lib_cpg_leave res_lib_cpg_leave; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -549,26 +541,26 @@ + &res_lib_cpg_leave, sizeof (struct res_lib_cpg_leave)); + + pthread_mutex_unlock (&cpg_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_cpg_leave.header.error; + + error_exit: +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + + return (error); + } + +-cpg_error_t cpg_mcast_joined ( ++cs_error_t cpg_mcast_joined ( + cpg_handle_t handle, + cpg_guarantee_t guarantee, + struct iovec *iovec, + int iov_len) + { + int i; +- cpg_error_t error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + struct iovec iov[64]; + struct req_lib_cpg_mcast req_lib_cpg_mcast; +@@ -576,7 +568,7 @@ + int msg_len = 0; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -602,7 +594,7 @@ + + pthread_mutex_unlock (&cpg_inst->response_mutex); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -612,85 +604,108 @@ + * Also, don't set to ENABLED if the return value is TRY_AGAIN as this can lead + * to Flow Control State sync issues between AIS LIB and EXEC. + */ +- if (res_lib_cpg_mcast.header.error == CPG_OK) { ++ if (res_lib_cpg_mcast.header.error == CS_OK) { + cpg_inst->flow_control_state = res_lib_cpg_mcast.flow_control_state; + } + error = res_lib_cpg_mcast.header.error; + + error_exit: +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + + return (error); + } + +-cpg_error_t cpg_membership_get ( ++cs_error_t cpg_membership_get ( + cpg_handle_t handle, + struct cpg_name *group_name, + struct cpg_address *member_list, + int *member_list_entries) + { +- cpg_error_t error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + struct iovec iov; + struct req_lib_cpg_membership req_lib_cpg_membership_get; +- struct res_lib_cpg_confchg_callback res_lib_cpg_membership_get; +- unsigned int i; ++ struct res_lib_cpg_confchg_callback *res_lib_cpg_membership_get; ++ mar_res_header_t header; ++ unsigned int i, bytesleft; ++ char *buffer = NULL; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +- req_lib_cpg_membership_get.header.size = sizeof (mar_req_header_t); ++ req_lib_cpg_membership_get.header.size = sizeof (req_lib_cpg_membership_get); + req_lib_cpg_membership_get.header.id = MESSAGE_REQ_CPG_MEMBERSHIP; +- marshall_to_mar_cpg_name_t (&req_lib_cpg_membership_get.group_name, +- group_name); + + iov.iov_base = (char *)&req_lib_cpg_membership_get; +- iov.iov_len = sizeof (mar_req_header_t); ++ iov.iov_len = sizeof (req_lib_cpg_membership_get); + + pthread_mutex_lock (&cpg_inst->response_mutex); + + error = saSendMsgReceiveReply (cpg_inst->response_fd, &iov, 1, +- &res_lib_cpg_membership_get, sizeof (mar_res_header_t)); ++ &header, sizeof (header)); ++ if (error != CS_OK) { ++ goto error_exit; ++ } + +- pthread_mutex_unlock (&cpg_inst->response_mutex); ++ buffer = malloc(header.size); ++ if (buffer == NULL) { ++ error = CS_ERR_NO_MEMORY; ++ goto error_exit; ++ } + +- if (error != SA_AIS_OK) { ++ memcpy (buffer, &header, sizeof (header)); ++ bytesleft = header.size - sizeof (header); ++ ++ error = saRecvRetry (cpg_inst->response_fd, ++ buffer + sizeof (header), bytesleft); ++ if (error != CS_OK) { + goto error_exit; + } + +- error = res_lib_cpg_membership_get.header.error; ++ error = header.error; ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ res_lib_cpg_membership_get = (struct res_lib_cpg_confchg_callback *) buffer; + + /* + * Copy results to caller + */ +- *member_list_entries = res_lib_cpg_membership_get.member_list_entries; ++ *member_list_entries = res_lib_cpg_membership_get->member_list_entries; + if (member_list) { +- for (i = 0; i < res_lib_cpg_membership_get.member_list_entries; i++) { ++ for (i = 0; i < res_lib_cpg_membership_get->member_list_entries; i++) { + marshall_from_mar_cpg_address_t (&member_list[i], +- &res_lib_cpg_membership_get.member_list[i]); ++ &res_lib_cpg_membership_get->member_list[i]); + } + } + + error_exit: +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ ++ if (buffer != NULL) ++ free(buffer); ++ ++ pthread_mutex_unlock (&cpg_inst->response_mutex); ++ ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + + return (error); + } + +-cpg_error_t cpg_local_get ( ++cs_error_t cpg_local_get ( + cpg_handle_t handle, + unsigned int *local_nodeid) + { +- cpg_error_t error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + struct iovec iov; + struct req_lib_cpg_local_get req_lib_cpg_local_get; + struct res_lib_cpg_local_get res_lib_cpg_local_get; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -707,7 +722,7 @@ + + pthread_mutex_unlock (&cpg_inst->response_mutex); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -716,23 +731,23 @@ + *local_nodeid = res_lib_cpg_local_get.local_nodeid; + + error_exit: +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + + return (error); + } + +-cpg_error_t cpg_groups_get ( ++cs_error_t cpg_groups_get ( + cpg_handle_t handle, + unsigned int *num_groups) + { +- cpg_error_t error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + struct iovec iov; + struct req_lib_cpg_groups_get req_lib_cpg_groups_get; + struct res_lib_cpg_groups_get res_lib_cpg_groups_get; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -749,7 +764,7 @@ + + pthread_mutex_unlock (&cpg_inst->response_mutex); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -758,26 +773,26 @@ + + /* Real output is delivered via a callback */ + error_exit: +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + + return (error); + } + +-cpg_error_t cpg_flow_control_state_get ( ++cs_error_t cpg_flow_control_state_get ( + cpg_handle_t handle, + cpg_flow_control_state_t *flow_control_state) + { +- cpg_error_t error; ++ cs_error_t error; + struct cpg_inst *cpg_inst; + + error = saHandleInstanceGet (&cpg_handle_t_db, handle, (void *)&cpg_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + *flow_control_state = cpg_inst->flow_control_state; + +- saHandleInstancePut (&cpg_handle_t_db, handle); ++ (void)saHandleInstancePut (&cpg_handle_t_db, handle); + + return (error); + } +diff -Naurd corosync-0.92/lib/evs.c corosync-trunk/lib/evs.c +--- corosync-0.92/lib/evs.c 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/lib/evs.c 2008-12-28 10:25:17.000000000 +0100 +@@ -48,7 +48,7 @@ + + #include + #include +-#include ++#include + #include + #include + #include +@@ -62,7 +62,7 @@ + pthread_mutex_t dispatch_mutex; + }; + +-struct res_overlay { ++struct evs_res_overlay { + mar_res_header_t header __attribute__((aligned(8))); + char data[512000]; + }; +@@ -98,29 +98,29 @@ + * test + * @param handle The handle of evs initialize + * @param callbacks The callbacks for evs_initialize +- * @returns EVS_OK ++ * @returns CS_OK + */ +-evs_error_t evs_initialize ( ++cs_error_t evs_initialize ( + evs_handle_t *handle, + evs_callbacks_t *callbacks) + { +- SaAisErrorT error; ++ cs_error_t error; + struct evs_inst *evs_inst; + + error = saHandleCreate (&evs_handle_t_db, sizeof (struct evs_inst), handle); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_no_destroy; + } + + error = saHandleInstanceGet (&evs_handle_t_db, *handle, (void *)&evs_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_destroy; + } + + error = saServiceConnect (&evs_inst->response_fd, + &evs_inst->dispatch_fd, + EVS_SERVICE); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_put_destroy; + } + +@@ -130,26 +130,26 @@ + + pthread_mutex_init (&evs_inst->dispatch_mutex, NULL); + +- saHandleInstancePut (&evs_handle_t_db, *handle); ++ (void)saHandleInstancePut (&evs_handle_t_db, *handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + + error_put_destroy: +- saHandleInstancePut (&evs_handle_t_db, *handle); ++ (void)saHandleInstancePut (&evs_handle_t_db, *handle); + error_destroy: +- saHandleDestroy (&evs_handle_t_db, *handle); ++ (void)saHandleDestroy (&evs_handle_t_db, *handle); + error_no_destroy: + return (error); + } + +-evs_error_t evs_finalize ( ++cs_error_t evs_finalize ( + evs_handle_t handle) + { + struct evs_inst *evs_inst; +- SaAisErrorT error; ++ cs_error_t error; + + error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + // TODO is the locking right here +@@ -160,15 +160,15 @@ + */ + if (evs_inst->finalize) { + pthread_mutex_unlock (&evs_inst->response_mutex); +- saHandleInstancePut (&evs_handle_t_db, handle); +- return (EVS_ERR_BAD_HANDLE); ++ (void)saHandleInstancePut (&evs_handle_t_db, handle); ++ return (CS_ERR_BAD_HANDLE); + } + + evs_inst->finalize = 1; + + pthread_mutex_unlock (&evs_inst->response_mutex); + +- saHandleDestroy (&evs_handle_t_db, handle); ++ (void)saHandleDestroy (&evs_handle_t_db, handle); + /* + * Disconnect from the server + */ +@@ -180,49 +180,48 @@ + shutdown(evs_inst->dispatch_fd, 0); + close(evs_inst->dispatch_fd); + } +- saHandleInstancePut (&evs_handle_t_db, handle); ++ (void)saHandleInstancePut (&evs_handle_t_db, handle); + + +- return (EVS_OK); ++ return (CS_OK); + } + +-evs_error_t evs_fd_get ( ++cs_error_t evs_fd_get ( + evs_handle_t handle, + int *fd) + { +- SaAisErrorT error; ++ cs_error_t error; + struct evs_inst *evs_inst; + + error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + + *fd = evs_inst->dispatch_fd; + +- saHandleInstancePut (&evs_handle_t_db, handle); ++ (void)saHandleInstancePut (&evs_handle_t_db, handle); + +- return (SA_AIS_OK); ++ return (CS_OK); + } + +-evs_error_t evs_dispatch ( ++cs_error_t evs_dispatch ( + evs_handle_t handle, +- evs_dispatch_t dispatch_types) ++ cs_dispatch_flags_t dispatch_types) + { + struct pollfd ufds; + int timeout = -1; +- SaAisErrorT error; ++ cs_error_t error; + int cont = 1; /* always continue do loop except when set to 0 */ + int dispatch_avail; + struct evs_inst *evs_inst; + struct res_evs_confchg_callback *res_evs_confchg_callback; + struct res_evs_deliver_callback *res_evs_deliver_callback; + evs_callbacks_t callbacks; +- struct res_overlay dispatch_data; +- int ignore_dispatch = 0; ++ struct evs_res_overlay dispatch_data; + + error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -230,7 +229,7 @@ + * Timeout instantly for SA_DISPATCH_ONE or SA_DISPATCH_ALL and + * wait indefinately for SA_DISPATCH_BLOCKING + */ +- if (dispatch_types == EVS_DISPATCH_ALL) { ++ if (dispatch_types == CS_DISPATCH_ALL) { + timeout = 0; + } + +@@ -240,7 +239,7 @@ + ufds.revents = 0; + + error = saPollRetry (&ufds, 1, timeout); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_nounlock; + } + +@@ -250,7 +249,7 @@ + * Regather poll data in case ufds has changed since taking lock + */ + error = saPollRetry (&ufds, 1, 0); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_nounlock; + } + +@@ -258,13 +257,13 @@ + * Handle has been finalized in another thread + */ + if (evs_inst->finalize == 1) { +- error = EVS_OK; ++ error = CS_OK; + pthread_mutex_unlock (&evs_inst->dispatch_mutex); + goto error_unlock; + } + + dispatch_avail = ufds.revents & POLLIN; +- if (dispatch_avail == 0 && dispatch_types == EVS_DISPATCH_ALL) { ++ if (dispatch_avail == 0 && dispatch_types == CS_DISPATCH_ALL) { + pthread_mutex_unlock (&evs_inst->dispatch_mutex); + break; /* exit do while cont is 1 loop */ + } else +@@ -279,14 +278,14 @@ + */ + error = saRecvRetry (evs_inst->dispatch_fd, &dispatch_data.header, + sizeof (mar_res_header_t)); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_unlock; + } + if (dispatch_data.header.size > sizeof (mar_res_header_t)) { + error = saRecvRetry (evs_inst->dispatch_fd, &dispatch_data.data, + dispatch_data.header.size - sizeof (mar_res_header_t)); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_unlock; + } + } +@@ -327,7 +326,7 @@ + break; + + default: +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + goto error_nounlock; + break; + } +@@ -336,42 +335,35 @@ + * Determine if more messages should be processed + * */ + switch (dispatch_types) { +- case EVS_DISPATCH_ONE: +- if (ignore_dispatch) { +- ignore_dispatch = 0; +- } else { +- cont = 0; +- } ++ case CS_DISPATCH_ONE: ++ cont = 0; + break; +- case EVS_DISPATCH_ALL: +- if (ignore_dispatch) { +- ignore_dispatch = 0; +- } ++ case CS_DISPATCH_ALL: + break; +- case EVS_DISPATCH_BLOCKING: ++ case CS_DISPATCH_BLOCKING: + break; + } + } while (cont); + + error_unlock: +- saHandleInstancePut (&evs_handle_t_db, handle); ++ (void)saHandleInstancePut (&evs_handle_t_db, handle); + error_nounlock: + return (error); + } + +-evs_error_t evs_join ( ++cs_error_t evs_join ( + evs_handle_t handle, + struct evs_group *groups, + int group_entries) + { +- evs_error_t error; ++ cs_error_t error; + struct evs_inst *evs_inst; + struct iovec iov[2]; + struct req_lib_evs_join req_lib_evs_join; + struct res_lib_evs_join res_lib_evs_join; + + error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -392,31 +384,31 @@ + + pthread_mutex_unlock (&evs_inst->response_mutex); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_evs_join.header.error; + + error_exit: +- saHandleInstancePut (&evs_handle_t_db, handle); ++ (void)saHandleInstancePut (&evs_handle_t_db, handle); + + return (error); + } + +-evs_error_t evs_leave ( ++cs_error_t evs_leave ( + evs_handle_t handle, + struct evs_group *groups, + int group_entries) + { +- evs_error_t error; ++ cs_error_t error; + struct evs_inst *evs_inst; + struct iovec iov[2]; + struct req_lib_evs_leave req_lib_evs_leave; + struct res_lib_evs_leave res_lib_evs_leave; + + error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -437,26 +429,26 @@ + + pthread_mutex_unlock (&evs_inst->response_mutex); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_evs_leave.header.error; + + error_exit: +- saHandleInstancePut (&evs_handle_t_db, handle); ++ (void)saHandleInstancePut (&evs_handle_t_db, handle); + + return (error); + } + +-evs_error_t evs_mcast_joined ( ++cs_error_t evs_mcast_joined ( + evs_handle_t handle, + evs_guarantee_t guarantee, + struct iovec *iovec, + int iov_len) + { + int i; +- evs_error_t error; ++ cs_error_t error; + struct evs_inst *evs_inst; + struct iovec iov[64]; + struct req_lib_evs_mcast_joined req_lib_evs_mcast_joined; +@@ -464,7 +456,7 @@ + int msg_len = 0; + + error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -490,19 +482,19 @@ + + pthread_mutex_unlock (&evs_inst->response_mutex); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_evs_mcast_joined.header.error; + + error_exit: +- saHandleInstancePut (&evs_handle_t_db, handle); ++ (void)saHandleInstancePut (&evs_handle_t_db, handle); + + return (error); + } + +-evs_error_t evs_mcast_groups ( ++cs_error_t evs_mcast_groups ( + evs_handle_t handle, + evs_guarantee_t guarantee, + struct evs_group *groups, +@@ -511,7 +503,7 @@ + int iov_len) + { + int i; +- evs_error_t error; ++ cs_error_t error; + struct evs_inst *evs_inst; + struct iovec iov[64]; + struct req_lib_evs_mcast_groups req_lib_evs_mcast_groups; +@@ -519,7 +511,7 @@ + int msg_len = 0; + + error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + for (i = 0; i < iov_len; i++) { +@@ -544,32 +536,32 @@ + &res_lib_evs_mcast_groups, sizeof (struct res_lib_evs_mcast_groups)); + + pthread_mutex_unlock (&evs_inst->response_mutex); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_evs_mcast_groups.header.error; + + error_exit: +- saHandleInstancePut (&evs_handle_t_db, handle); ++ (void)saHandleInstancePut (&evs_handle_t_db, handle); + + return (error); + } + +-evs_error_t evs_membership_get ( ++cs_error_t evs_membership_get ( + evs_handle_t handle, + unsigned int *local_nodeid, + unsigned int *member_list, + unsigned int *member_list_entries) + { +- evs_error_t error; ++ cs_error_t error; + struct evs_inst *evs_inst; + struct iovec iov; + struct req_lib_evs_membership_get req_lib_evs_membership_get; + struct res_lib_evs_membership_get res_lib_evs_membership_get; + + error = saHandleInstanceGet (&evs_handle_t_db, handle, (void *)&evs_inst); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + return (error); + } + +@@ -586,7 +578,7 @@ + + pthread_mutex_unlock (&evs_inst->response_mutex); + +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -606,7 +598,7 @@ + } + + error_exit: +- saHandleInstancePut (&evs_handle_t_db, handle); ++ (void)saHandleInstancePut (&evs_handle_t_db, handle); + + return (error); + } +diff -Naurd corosync-0.92/lib/libpload.versions corosync-trunk/lib/libpload.versions +--- corosync-0.92/lib/libpload.versions 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/lib/libpload.versions 2008-10-30 23:41:34.000000000 +0100 +@@ -0,0 +1,21 @@ ++# Version and symbol export for libSaClm.so ++ ++COROSYNC_PLOAD_1.0 { ++ global: ++ pload_start; ++ ++ local: ++ saHandleCreate; ++ saHandleDestroy; ++ saHandleInstanceGet; ++ saHandleInstancePut; ++ saRecvRetry; ++ saSelectRetry; ++ saSendMsgReceiveReply; ++ saSendMsgRetry; ++ saSendReceiveReply; ++ saSendRetry; ++ saServiceConnect; ++ saVersionVerify; ++ clustTimeNow; ++}; +diff -Naurd corosync-0.92/lib/libquorum.versions corosync-trunk/lib/libquorum.versions +--- corosync-0.92/lib/libquorum.versions 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/lib/libquorum.versions 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,50 @@ ++# Version and symbol export for libquorum.so ++ ++OPENAIS_QUORUM_1.0 { ++ global: ++ quorum_initialize; ++ quorum_finalize; ++ quorum_getquorate; ++ quorum_initialize; ++ quorum_finalize; ++ quorum_dispatch; ++ ++ local: ++ saHandleCreate; ++ saHandleDestroy; ++ saHandleInstanceGet; ++ saHandleInstancePut; ++ saRecvRetry; ++ saSelectRetry; ++ saSendMsgReceiveReply; ++ saSendMsgRetry; ++ saSendReceiveReply; ++ saSendRetry; ++ saServiceConnect; ++ saVersionVerify; ++ clustTimeNow; ++}; ++# Version and symbol export for libquorum.so ++ ++COROSYNC_QUORUM_1.0 { ++ global: ++ quorum_initialize; ++ quorum_finalize; ++ quorum_getquorate; ++ quorum_dispatch; ++ ++ local: ++ saHandleCreate; ++ saHandleDestroy; ++ saHandleInstanceGet; ++ saHandleInstancePut; ++ saRecvRetry; ++ saSelectRetry; ++ saSendMsgReceiveReply; ++ saSendMsgRetry; ++ saSendReceiveReply; ++ saSendRetry; ++ saServiceConnect; ++ saVersionVerify; ++ clustTimeNow; ++}; +diff -Naurd corosync-0.92/lib/libvotequorum.versions corosync-trunk/lib/libvotequorum.versions +--- corosync-0.92/lib/libvotequorum.versions 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/lib/libvotequorum.versions 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,71 @@ ++# Version and symbol export for libvotequorum.so ++ ++OPENAIS_VOTEQUORUM_1.0 { ++ global: ++ votequorum_initialize; ++ votequorum_finalize; ++ votequorum_getinfo; ++ votequorum_setexpected; ++ votequorum_setvotes; ++ votequorum_qdisk_register; ++ votequorum_qdisk_unregister; ++ votequorum_qdisk_poll; ++ votequorum_qdisk_getinfo; ++ votequorum_setstate; ++ votequorum_leaving; ++ votequorum_trackstart; ++ votequorum_trackstop; ++ votequorum_context_get; ++ votequorum_context_set; ++ ++ local: ++ saHandleCreate; ++ saHandleDestroy; ++ saHandleInstanceGet; ++ saHandleInstancePut; ++ saRecvRetry; ++ saSelectRetry; ++ saSendMsgReceiveReply; ++ saSendMsgRetry; ++ saSendReceiveReply; ++ saSendRetry; ++ saServiceConnect; ++ saVersionVerify; ++ clustTimeNow; ++}; ++# Version and symbol export for libvotequorum.so ++ ++COROSYNC_VOTEQUORUM_1.0 { ++ global: ++ votequorum_initialize; ++ votequorum_finalize; ++ votequorum_getinfo; ++ votequorum_setexpected; ++ votequorum_setvotes; ++ votequorum_qdisk_register; ++ votequorum_qdisk_unregister; ++ votequorum_qdisk_poll; ++ votequorum_qdisk_getinfo; ++ votequorum_setdirty; ++ votequorum_killnode; ++ votequorum_leaving; ++ votequorum_trackstart; ++ votequorum_trackstop; ++ votequorum_context_get; ++ votequorum_context_set; ++ ++ local: ++ saHandleCreate; ++ saHandleDestroy; ++ saHandleInstanceGet; ++ saHandleInstancePut; ++ saRecvRetry; ++ saSelectRetry; ++ saSendMsgReceiveReply; ++ saSendMsgRetry; ++ saSendReceiveReply; ++ saSendRetry; ++ saServiceConnect; ++ saVersionVerify; ++ clustTimeNow; ++}; +diff -Naurd corosync-0.92/lib/Makefile corosync-trunk/lib/Makefile +--- corosync-0.92/lib/Makefile 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/lib/Makefile 2009-01-26 11:46:08.000000000 +0100 +@@ -41,7 +41,10 @@ + libconfdb.a libconfdb.so.2.0.0 \ + libevs.a libevs.so.2.0.0 \ + libcfg.a libcfg.so.2.0.0 \ +- libcoroutil.a libcoroutil.so.2.0.0 ++ libquorum.a libquorum.so.2.0.0 \ ++ libpload.a libpload.so.2.0.0 \ ++ libcoroutil.a libcoroutil.so.2.0.0 \ ++ libvotequorum.a libvotequorum.so.2.0.0 + + libcoroutil.a: util.o + $(AR) -rc libcoroutil.a util.o +@@ -58,14 +61,20 @@ + libcpg.so.2.0.0: util.o cpg.o + $(CC) $(DARWIN_OPTS) util.o cpg.o -o $@ + ++libquorum.so.2.0.0: util.o quorum.o ++ $(CC) $(DARWIN_OPTS) util.o quorum.o -o $@ ++ ++libvotequorum.so.2.0.0: util.o votequorum.o ++ $(CC) $(DARWIN_OPTS) util.o votequorum.o -o $@ ++ + libconfdb.so.2.0.0: util.o confdb.o sa-confdb.o + $(CC) $(LDFLAGS) $(DARWIN_OPTS) util.o confdb.o sa-confdb.o ../lcr/lcr_ifact.o -o $@ + + libcfg.so.2.0.0: util.o cfg.o + $(CC) $(DARWIN_OPTS) util.o cfg.o -o $@ + +-libcpg.so.2.0.0: util.o cpg.o +- $(CC) $(DARWIN_OPTS) util.o cpg.o -o $@ ++libpload.so.2.0.0: util.o pload.o ++ $(CC) $(DARWIN_OPTS) util.o pload.o -o $@ + + else + +@@ -78,12 +87,21 @@ + libcpg.so.2.0.0: util.o cpg.o + $(CC) -shared -Wl,-soname,libcpg.so.2,-version-script=$(srcdir)$(subdir)libcpg.versions util.o cpg.o -o $@ + ++libquorum.so.2.0.0: util.o quorum.o ++ $(CC) -shared -Wl,-soname,libquorum.so.2,-version-script=$(srcdir)$(subdir)libquorum.versions util.o quorum.o -o $@ ++ ++libvotequorum.so.2.0.0: util.o votequorum.o ++ $(CC) -shared -Wl,-soname,libvotequorum.so.2,-version-script=$(srcdir)$(subdir)libvotequorum.versions util.o votequorum.o -o $@ ++ + libconfdb.so.2.0.0: util.o confdb.o sa-confdb.o + $(CC) $(LDFLAGS) -shared -Wl,-soname,libconfdb.so.2,-version-script=$(srcdir)$(subdir)libconfdb.versions util.o confdb.o sa-confdb.o ../lcr/lcr_ifact.o -o $@ + + libcfg.so.2.0.0: util.o cfg.o + $(CC) -shared -Wl,-soname,libcfg.so.2,-version-script=$(srcdir)$(subdir)libcfg.versions util.o cfg.o -o $@ + ++libpload.so.2.0.0: util.o pload.o ++ $(CC) -shared -Wl,-soname,libpload.so.2,-version-script=$(srcdir)$(subdir)libpload.versions util.o cfg.o -o $@ ++ + endif + + libevs.a: util.o evs.o +@@ -92,17 +110,27 @@ + libcpg.a: util.o cpg.o + $(AR) -rc libcpg.a util.o cpg.o + ++libquorum.a: util.o quorum.o ++ $(AR) -rc libquorum.a util.o quorum.o ++ ++libvotequorum.a: util.o votequorum.o ++ $(AR) -rc libvotequorum.a util.o votequorum.o ++ + libconfdb.a: util.o confdb.o sa-confdb.o + $(AR) -rc libconfdb.a util.o confdb.o sa-confdb.o ../lcr/lcr_ifact.o + + libcfg.a: util.o cfg.o + $(AR) -rc libcfg.a util.o cfg.o + ++libpload.a: util.o pload.o ++ $(AR) -rc libpload.a util.o pload.o ++ + clean: +- rm -f *.o libcfg.so* libcoroutil.so* libcoroutil.a \ +- libevs.so* libevs.a libcpg.so* libcpg.a libcfg.a libconfdb.so* \ +- libconfdb.a libconfdb.a \ *.da *.bb *.bbg ++ rm -f *.o *.a *.so* *.da *.bb *.bbg + ++lint: ++ -splint $(LINT_FLAGS) $(CFLAGS) *.c ++ + # -fPIC rules required for all libraries + %.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c -o $@ $< +diff -Naurd corosync-0.92/lib/pload.c corosync-trunk/lib/pload.c +--- corosync-0.92/lib/pload.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/lib/pload.c 2008-11-11 18:25:22.000000000 +0100 +@@ -0,0 +1,238 @@ ++/* ++ * Copyright (c) 2008 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 ++ ++static void pload_instance_destructor (void *instance); ++ ++struct pload_inst { ++ int dispatch_fd; ++ int response_fd; ++ pthread_mutex_t response_mutex; ++ pthread_mutex_t dispatch_mutex; ++ unsigned int finalize; ++}; ++ ++static struct saHandleDatabase pload_handle_t_db = { ++ .handleCount = 0, ++ .handles = 0, ++ .mutex = PTHREAD_MUTEX_INITIALIZER, ++ .handleInstanceDestructor = pload_instance_destructor ++}; ++ ++/* ++ * Clean up function for an evt instance (saEvtInitialize) handle ++ */ ++static void pload_instance_destructor (void *instance) ++{ ++ struct pload_inst *pload_inst = instance; ++ ++ pthread_mutex_destroy (&pload_inst->response_mutex); ++ pthread_mutex_destroy (&pload_inst->dispatch_mutex); ++} ++ ++ ++/** ++ * @defgroup pload_corosync The extended virtual synchrony passthrough API ++ * @ingroup corosync ++ * ++ * @{ ++ */ ++/** ++ * test ++ * @param handle The handle of pload initialize ++ * @param callbacks The callbacks for pload_initialize ++ * @returns PLOAD_OK ++ */ ++unsigned int pload_initialize ( ++ pload_handle_t *handle, ++ pload_callbacks_t *callbacks) ++{ ++ cs_error_t error; ++ struct pload_inst *pload_inst; ++ ++ error = saHandleCreate (&pload_handle_t_db, sizeof (struct pload_inst), handle); ++ if (error != CS_OK) { ++ goto error_no_destroy; ++ } ++ ++ error = saHandleInstanceGet (&pload_handle_t_db, *handle, (void *)&pload_inst); ++ if (error != CS_OK) { ++ goto error_destroy; ++ } ++ ++ error = saServiceConnect (&pload_inst->response_fd, ++ &pload_inst->dispatch_fd, ++ PLOAD_SERVICE); ++ if (error != CS_OK) { ++ goto error_put_destroy; ++ } ++ ++ pthread_mutex_init (&pload_inst->response_mutex, NULL); ++ ++ pthread_mutex_init (&pload_inst->dispatch_mutex, NULL); ++ ++ (void)saHandleInstancePut (&pload_handle_t_db, *handle); ++ ++ return (CS_OK); ++ ++error_put_destroy: ++ (void)saHandleInstancePut (&pload_handle_t_db, *handle); ++error_destroy: ++ (void)saHandleDestroy (&pload_handle_t_db, *handle); ++error_no_destroy: ++ return (error); ++} ++ ++unsigned int pload_finalize ( ++ pload_handle_t handle) ++{ ++ struct pload_inst *pload_inst; ++ cs_error_t error; ++ ++ error = saHandleInstanceGet (&pload_handle_t_db, handle, (void *)&pload_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++// TODO is the locking right here ++ pthread_mutex_lock (&pload_inst->response_mutex); ++ ++ /* ++ * Another thread has already started finalizing ++ */ ++ if (pload_inst->finalize) { ++ pthread_mutex_unlock (&pload_inst->response_mutex); ++ (void)saHandleInstancePut (&pload_handle_t_db, handle); ++ return (PLOAD_ERR_BAD_HANDLE); ++ } ++ ++ pload_inst->finalize = 1; ++ ++ pthread_mutex_unlock (&pload_inst->response_mutex); ++ ++ (void)saHandleDestroy (&pload_handle_t_db, handle); ++ /* ++ * Disconnect from the server ++ */ ++ if (pload_inst->response_fd != -1) { ++ shutdown(pload_inst->response_fd, 0); ++ close(pload_inst->response_fd); ++ } ++ if (pload_inst->dispatch_fd != -1) { ++ shutdown(pload_inst->dispatch_fd, 0); ++ close(pload_inst->dispatch_fd); ++ } ++ (void)saHandleInstancePut (&pload_handle_t_db, handle); ++ ++ ++ return (PLOAD_OK); ++} ++ ++unsigned int pload_fd_get ( ++ pload_handle_t handle, ++ int *fd) ++{ ++ cs_error_t error; ++ struct pload_inst *pload_inst; ++ ++ error = saHandleInstanceGet (&pload_handle_t_db, handle, (void *)&pload_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ *fd = pload_inst->dispatch_fd; ++ ++ (void)saHandleInstancePut (&pload_handle_t_db, handle); ++ ++ return (CS_OK); ++} ++ ++unsigned int pload_start ( ++ pload_handle_t handle, ++ unsigned int code, ++ unsigned int msg_count, ++ unsigned int msg_size) ++{ ++ unsigned int error; ++ struct pload_inst *pload_inst; ++ struct iovec iov; ++ struct req_lib_pload_start req_lib_pload_start; ++ struct res_lib_pload_start res_lib_pload_start; ++ ++ error = saHandleInstanceGet (&pload_handle_t_db, handle, (void *)&pload_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ req_lib_pload_start.header.size = sizeof (struct req_lib_pload_start); ++ req_lib_pload_start.header.id = MESSAGE_REQ_PLOAD_START; ++ req_lib_pload_start.msg_code = code; ++ req_lib_pload_start.msg_count = msg_count; ++ req_lib_pload_start.msg_size = msg_size; ++ ++ iov.iov_base = (char *)&req_lib_pload_start; ++ iov.iov_len = sizeof (struct req_lib_pload_start); ++ ++ pthread_mutex_lock (&pload_inst->response_mutex); ++ ++ error = saSendMsgReceiveReply (pload_inst->response_fd, &iov, 1, ++ &res_lib_pload_start, sizeof (struct res_lib_pload_start)); ++ ++ pthread_mutex_unlock (&pload_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_pload_start.header.error; ++ ++error_exit: ++ (void)saHandleInstancePut (&pload_handle_t_db, handle); ++ ++ return (error); ++} ++ ++/** @} */ +diff -Naurd corosync-0.92/lib/quorum.c corosync-trunk/lib/quorum.c +--- corosync-0.92/lib/quorum.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/lib/quorum.c 2008-11-11 18:26:58.000000000 +0100 +@@ -0,0 +1,493 @@ ++/* ++ * Copyright (c) 2008 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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. ++ */ ++/* ++ * Provides a quorum API using the corosync executive ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include "corosync/quorum.h" ++#include "corosync/ipc_quorum.h" ++ ++struct quorum_inst { ++ int response_fd; ++ int dispatch_fd; ++ int finalize; ++ void *context; ++ quorum_callbacks_t callbacks; ++ pthread_mutex_t response_mutex; ++ pthread_mutex_t dispatch_mutex; ++}; ++ ++static void quorum_instance_destructor (void *instance); ++ ++static struct saHandleDatabase quorum_handle_t_db = { ++ .handleCount = 0, ++ .handles = 0, ++ .mutex = PTHREAD_MUTEX_INITIALIZER, ++ .handleInstanceDestructor = quorum_instance_destructor ++}; ++ ++/* ++ * Clean up function for a quorum instance (quorum_initialize) handle ++ */ ++static void quorum_instance_destructor (void *instance) ++{ ++ struct quorum_inst *quorum_inst = instance; ++ ++ pthread_mutex_destroy (&quorum_inst->response_mutex); ++} ++ ++cs_error_t quorum_initialize ( ++ quorum_handle_t *handle, ++ quorum_callbacks_t *callbacks) ++{ ++ cs_error_t error; ++ struct quorum_inst *quorum_inst; ++ ++ error = saHandleCreate (&quorum_handle_t_db, sizeof (struct quorum_inst), handle); ++ if (error != CS_OK) { ++ goto error_no_destroy; ++ } ++ ++ error = saHandleInstanceGet (&quorum_handle_t_db, *handle, (void *)&quorum_inst); ++ if (error != CS_OK) { ++ goto error_destroy; ++ } ++ ++ error = saServiceConnect (&quorum_inst->dispatch_fd, ++ &quorum_inst->response_fd, ++ QUORUM_SERVICE); ++ if (error != CS_OK) { ++ goto error_put_destroy; ++ } ++ ++ pthread_mutex_init (&quorum_inst->response_mutex, NULL); ++ pthread_mutex_init (&quorum_inst->dispatch_mutex, NULL); ++ if (callbacks) ++ memcpy(&quorum_inst->callbacks, callbacks, sizeof (callbacks)); ++ else ++ memset(&quorum_inst->callbacks, 0, sizeof (callbacks)); ++ ++ (void)saHandleInstancePut (&quorum_handle_t_db, *handle); ++ ++ return (CS_OK); ++ ++error_put_destroy: ++ (void)saHandleInstancePut (&quorum_handle_t_db, *handle); ++error_destroy: ++ (void)saHandleDestroy (&quorum_handle_t_db, *handle); ++error_no_destroy: ++ return (error); ++} ++ ++cs_error_t quorum_finalize ( ++ quorum_handle_t handle) ++{ ++ struct quorum_inst *quorum_inst; ++ cs_error_t error; ++ ++ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&quorum_inst->response_mutex); ++ ++ /* ++ * Another thread has already started finalizing ++ */ ++ if (quorum_inst->finalize) { ++ pthread_mutex_unlock (&quorum_inst->response_mutex); ++ (void)saHandleInstancePut (&quorum_handle_t_db, handle); ++ return (CS_ERR_BAD_HANDLE); ++ } ++ ++ quorum_inst->finalize = 1; ++ ++ pthread_mutex_unlock (&quorum_inst->response_mutex); ++ ++ (void)saHandleDestroy (&quorum_handle_t_db, handle); ++ ++ /* ++ * Disconnect from the server ++ */ ++ if (quorum_inst->response_fd != -1) { ++ shutdown(quorum_inst->response_fd, 0); ++ close(quorum_inst->response_fd); ++ } ++ (void)saHandleInstancePut (&quorum_handle_t_db, handle); ++ ++ return (CS_OK); ++} ++ ++cs_error_t quorum_getquorate ( ++ quorum_handle_t handle, ++ int *quorate) ++{ ++ cs_error_t error; ++ struct quorum_inst *quorum_inst; ++ struct iovec iov[2]; ++ mar_req_header_t req; ++ struct res_lib_quorum_getquorate res_lib_quorum_getquorate; ++ ++ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&quorum_inst->response_mutex); ++ ++ req.size = sizeof (req); ++ req.id = MESSAGE_REQ_QUORUM_GETQUORATE; ++ ++ iov[0].iov_base = (char *)&req; ++ iov[0].iov_len = sizeof (req); ++ ++ error = saSendMsgReceiveReply (quorum_inst->response_fd, iov, 1, ++ &res_lib_quorum_getquorate, sizeof (struct res_lib_quorum_getquorate)); ++ ++ pthread_mutex_unlock (&quorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_quorum_getquorate.header.error; ++ ++ *quorate = res_lib_quorum_getquorate.quorate; ++ ++error_exit: ++ (void)saHandleInstancePut (&quorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t quorum_fd_get ( ++ quorum_handle_t handle, ++ int *fd) ++{ ++ cs_error_t error; ++ struct quorum_inst *quorum_inst; ++ ++ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ *fd = quorum_inst->dispatch_fd; ++ ++ (void)saHandleInstancePut (&quorum_handle_t_db, handle); ++ ++ return (CS_OK); ++} ++ ++ ++cs_error_t quorum_context_get ( ++ quorum_handle_t handle, ++ void **context) ++{ ++ cs_error_t error; ++ struct quorum_inst *quorum_inst; ++ ++ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ *context = quorum_inst->context; ++ ++ (void)saHandleInstancePut (&quorum_handle_t_db, handle); ++ ++ return (CS_OK); ++} ++ ++cs_error_t quorum_context_set ( ++ quorum_handle_t handle, ++ void *context) ++{ ++ cs_error_t error; ++ struct quorum_inst *quorum_inst; ++ ++ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ quorum_inst->context = context; ++ ++ (void)saHandleInstancePut (&quorum_handle_t_db, handle); ++ ++ return (CS_OK); ++} ++ ++ ++cs_error_t quorum_trackstart ( ++ quorum_handle_t handle, ++ unsigned int flags ) ++{ ++ cs_error_t error; ++ struct quorum_inst *quorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_quorum_trackstart req_lib_quorum_trackstart; ++ mar_res_header_t res; ++ ++ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&quorum_inst->response_mutex); ++ ++ req_lib_quorum_trackstart.header.size = sizeof (struct req_lib_quorum_trackstart); ++ req_lib_quorum_trackstart.header.id = MESSAGE_REQ_QUORUM_TRACKSTART; ++ req_lib_quorum_trackstart.track_flags = flags; ++ ++ iov[0].iov_base = (char *)&req_lib_quorum_trackstart; ++ iov[0].iov_len = sizeof (struct req_lib_quorum_trackstart); ++ ++ error = saSendMsgReceiveReply (quorum_inst->response_fd, iov, 1, ++ &res, sizeof (res)); ++ ++ pthread_mutex_unlock (&quorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res.error; ++ ++error_exit: ++ (void)saHandleInstancePut (&quorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t quorum_trackstop ( ++ quorum_handle_t handle) ++{ ++ cs_error_t error; ++ struct quorum_inst *quorum_inst; ++ struct iovec iov[2]; ++ mar_req_header_t req; ++ mar_res_header_t res; ++ ++ error = saHandleInstanceGet (&quorum_handle_t_db, handle, (void *)&quorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&quorum_inst->response_mutex); ++ ++ req.size = sizeof (req); ++ req.id = MESSAGE_REQ_QUORUM_TRACKSTOP; ++ ++ iov[0].iov_base = (char *)&req; ++ iov[0].iov_len = sizeof (req); ++ ++ error = saSendMsgReceiveReply (quorum_inst->response_fd, iov, 1, ++ &res, sizeof (res)); ++ ++ pthread_mutex_unlock (&quorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res.error; ++ ++error_exit: ++ (void)saHandleInstancePut (&quorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++struct quorum_res_overlay { ++ mar_res_header_t header __attribute__((aligned(8))); ++ char data[512000]; ++}; ++ ++cs_error_t quorum_dispatch ( ++ quorum_handle_t handle, ++ cs_dispatch_flags_t dispatch_types) ++{ ++ struct pollfd ufds; ++ int timeout = -1; ++ cs_error_t error; ++ int cont = 1; /* always continue do loop except when set to 0 */ ++ int dispatch_avail; ++ struct quorum_inst *quorum_inst; ++ quorum_callbacks_t callbacks; ++ struct quorum_res_overlay dispatch_data; ++ struct res_lib_quorum_notification *res_lib_quorum_notification; ++ ++ if (dispatch_types != CS_DISPATCH_ONE && ++ dispatch_types != CS_DISPATCH_ALL && ++ dispatch_types != CS_DISPATCH_BLOCKING) { ++ ++ return (CS_ERR_INVALID_PARAM); ++ } ++ ++ error = saHandleInstanceGet (&quorum_handle_t_db, handle, ++ (void *)&quorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ /* ++ * Timeout instantly for CS_DISPATCH_ONE or SA_DISPATCH_ALL and ++ * wait indefinately for CS_DISPATCH_BLOCKING ++ */ ++ if (dispatch_types == CS_DISPATCH_ALL) { ++ timeout = 0; ++ } ++ ++ do { ++ ufds.fd = quorum_inst->dispatch_fd; ++ ufds.events = POLLIN; ++ ufds.revents = 0; ++ ++ pthread_mutex_lock (&quorum_inst->dispatch_mutex); ++ ++ error = saPollRetry (&ufds, 1, timeout); ++ if (error != CS_OK) { ++ goto error_unlock; ++ } ++ ++ /* ++ * Handle has been finalized in another thread ++ */ ++ if (quorum_inst->finalize == 1) { ++ error = CS_OK; ++ goto error_unlock; ++ } ++ ++ if ((ufds.revents & (POLLERR|POLLHUP|POLLNVAL)) != 0) { ++ error = CS_ERR_BAD_HANDLE; ++ goto error_unlock; ++ } ++ ++ dispatch_avail = ufds.revents & POLLIN; ++ if (dispatch_avail == 0 && dispatch_types == CS_DISPATCH_ALL) { ++ pthread_mutex_unlock (&quorum_inst->dispatch_mutex); ++ break; /* exit do while cont is 1 loop */ ++ } else ++ if (dispatch_avail == 0) { ++ pthread_mutex_unlock (&quorum_inst->dispatch_mutex); ++ continue; /* next poll */ ++ } ++ ++ if (ufds.revents & POLLIN) { ++ error = saRecvRetry (quorum_inst->dispatch_fd, &dispatch_data.header, ++ sizeof (mar_res_header_t)); ++ if (error != CS_OK) { ++ goto error_unlock; ++ } ++ if (dispatch_data.header.size > sizeof (mar_res_header_t)) { ++ error = saRecvRetry (quorum_inst->dispatch_fd, &dispatch_data.data, ++ dispatch_data.header.size - sizeof (mar_res_header_t)); ++ if (error != CS_OK) { ++ goto error_unlock; ++ } ++ } ++ } else { ++ pthread_mutex_unlock (&quorum_inst->dispatch_mutex); ++ continue; ++ } ++ ++ /* ++ * Make copy of callbacks, message data, unlock instance, and call callback ++ * A risk of this dispatch method is that the callback routines may ++ * operate at the same time that quorum_finalize has been called in another thread. ++ */ ++ memcpy (&callbacks, &quorum_inst->callbacks, sizeof (quorum_callbacks_t)); ++ pthread_mutex_unlock (&quorum_inst->dispatch_mutex); ++ ++ /* ++ * Dispatch incoming message ++ */ ++ switch (dispatch_data.header.id) { ++ ++ case MESSAGE_RES_QUORUM_NOTIFICATION: ++ if (callbacks.quorum_notify_fn == NULL) { ++ continue; ++ } ++ res_lib_quorum_notification = (struct res_lib_quorum_notification *)&dispatch_data; ++ ++ callbacks.quorum_notify_fn ( handle, ++ res_lib_quorum_notification->quorate, ++ res_lib_quorum_notification->ring_seq, ++ res_lib_quorum_notification->view_list_entries, ++ res_lib_quorum_notification->view_list); ++ break; ++ ++ default: ++ error = CS_ERR_LIBRARY; ++ goto error_put; ++ break; ++ } ++ ++ /* ++ * Determine if more messages should be processed ++ * */ ++ switch (dispatch_types) { ++ case CS_DISPATCH_ONE: ++ cont = 0; ++ break; ++ case CS_DISPATCH_ALL: ++ break; ++ case CS_DISPATCH_BLOCKING: ++ break; ++ } ++ } while (cont); ++ ++ goto error_put; ++ ++error_unlock: ++ pthread_mutex_unlock (&quorum_inst->dispatch_mutex); ++ ++error_put: ++ (void)saHandleInstancePut (&quorum_handle_t_db, handle); ++ return (error); ++} +diff -Naurd corosync-0.92/lib/sa-confdb.c corosync-trunk/lib/sa-confdb.c +--- corosync-0.92/lib/sa-confdb.c 2008-09-03 09:58:08.000000000 +0200 ++++ corosync-trunk/lib/sa-confdb.c 2008-11-12 18:39:37.000000000 +0100 +@@ -43,7 +43,7 @@ + #include + #include + +-#include ++#include + #include + #include + #include +@@ -80,7 +80,7 @@ + objdb = (struct objdb_iface_ver0 *)objdb_p; + + objdb->objdb_init (); +- return SA_AIS_OK; ++ return CS_OK; + } + + static int load_config() +@@ -130,7 +130,7 @@ + if (config_iface) + free(config_iface); + +- return SA_AIS_OK; ++ return CS_OK; + } + + /* Needed by objdb when it writes back the configuration */ +@@ -174,7 +174,7 @@ + int res; + + res = load_objdb(); +- if (res != SA_AIS_OK) ++ if (res != CS_OK) + return res; + + res = load_config(); +@@ -295,7 +295,6 @@ + } + + int confdb_sa_write ( +- unsigned int parent_object_handle, + char *error_text) + { + char *errtext; +@@ -309,7 +308,6 @@ + } + + int confdb_sa_reload ( +- unsigned int parent_object_handle, + int flush, + char *error_text) + { +diff -Naurd corosync-0.92/lib/sa-confdb.h corosync-trunk/lib/sa-confdb.h +--- corosync-0.92/lib/sa-confdb.h 2008-08-26 09:34:22.000000000 +0200 ++++ corosync-trunk/lib/sa-confdb.h 2008-10-06 09:46:04.000000000 +0200 +@@ -42,6 +42,8 @@ + extern int confdb_sa_key_replace(unsigned int parent_object_handle, void *key_name, int key_name_len, void *old_value, int old_value_len, void *new_value, int new_value_len); + extern int confdb_sa_object_find(unsigned int parent_object_handle, unsigned int *find_handle, unsigned int *object_handle, void *object_name, int *object_name_len, int copy_name); + extern int confdb_sa_key_iter(unsigned int parent_object_handle, unsigned int start_pos, void *key_name, int *key_name_len, void *value, int *value_len); ++extern int confdb_sa_key_increment(unsigned int parent_object_handle, void *key_name, int key_name_len, unsigned int *value); ++extern int confdb_sa_key_decrement(unsigned int parent_object_handle, void *key_name, int key_name_len, unsigned int *value); + extern int confdb_sa_find_destroy(unsigned int find_handle); + extern int confdb_sa_write(char *error_text); + extern int confdb_sa_reload(int flush, char *error_text); +diff -Naurd corosync-0.92/lib/util.c corosync-trunk/lib/util.c +--- corosync-0.92/lib/util.c 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/lib/util.c 2008-11-11 19:13:47.000000000 +0100 +@@ -53,7 +53,7 @@ + #include + #include + +-#include ++#include + #include + #include + +@@ -96,7 +96,7 @@ + } + #endif + +-SaAisErrorT ++cs_error_t + saServiceConnect ( + int *responseOut, + int *callbackOut, +@@ -110,7 +110,7 @@ + mar_res_lib_response_init_t res_lib_response_init; + mar_req_lib_dispatch_init_t req_lib_dispatch_init; + mar_res_lib_dispatch_init_t res_lib_dispatch_init; +- SaAisErrorT error; ++ cs_error_t error; + gid_t egid; + + /* +@@ -131,7 +131,7 @@ + #endif + responseFD = socket (PF_UNIX, SOCK_STREAM, 0); + if (responseFD == -1) { +- return (SA_AIS_ERR_NO_RESOURCES); ++ return (CS_ERR_NO_RESOURCES); + } + + socket_nosigpipe (responseFD); +@@ -139,7 +139,7 @@ + result = connect (responseFD, (struct sockaddr *)&address, AIS_SUN_LEN(&address)); + if (result == -1) { + close (responseFD); +- return (SA_AIS_ERR_TRY_AGAIN); ++ return (CS_ERR_TRY_AGAIN); + } + + req_lib_response_init.resdis_header.size = sizeof (req_lib_response_init); +@@ -148,19 +148,19 @@ + + error = saSendRetry (responseFD, &req_lib_response_init, + sizeof (mar_req_lib_response_init_t)); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + error = saRecvRetry (responseFD, &res_lib_response_init, + sizeof (mar_res_lib_response_init_t)); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + /* + * Check for security errors + */ +- if (res_lib_response_init.header.error != SA_AIS_OK) { ++ if (res_lib_response_init.header.error != CS_OK) { + error = res_lib_response_init.header.error; + goto error_exit; + } +@@ -171,7 +171,7 @@ + callbackFD = socket (PF_UNIX, SOCK_STREAM, 0); + if (callbackFD == -1) { + close (responseFD); +- return (SA_AIS_ERR_NO_RESOURCES); ++ return (CS_ERR_NO_RESOURCES); + } + + socket_nosigpipe (callbackFD); +@@ -180,7 +180,7 @@ + if (result == -1) { + close (callbackFD); + close (responseFD); +- return (SA_AIS_ERR_TRY_AGAIN); ++ return (CS_ERR_TRY_AGAIN); + } + + req_lib_dispatch_init.resdis_header.size = sizeof (req_lib_dispatch_init); +@@ -191,25 +191,25 @@ + + error = saSendRetry (callbackFD, &req_lib_dispatch_init, + sizeof (mar_req_lib_dispatch_init_t)); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit_two; + } + error = saRecvRetry (callbackFD, &res_lib_dispatch_init, + sizeof (mar_res_lib_dispatch_init_t)); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit_two; + } + + /* + * Check for security errors + */ +- if (res_lib_dispatch_init.header.error != SA_AIS_OK) { ++ if (res_lib_dispatch_init.header.error != CS_OK) { + error = res_lib_dispatch_init.header.error; + goto error_exit; + } + + *callbackOut = callbackFD; +- return (SA_AIS_OK); ++ return (CS_OK); + + error_exit_two: + close (callbackFD); +@@ -218,14 +218,14 @@ + return (error); + } + +-SaAisErrorT ++cs_error_t + saRecvRetry ( + int s, + void *msg, + size_t len) + { +- SaAisErrorT error = SA_AIS_OK; +- int result; ++ cs_error_t error = CS_OK; ++ ssize_t result; + struct msghdr msg_recv; + struct iovec iov_recv; + char *rbuf = (char *)msg; +@@ -260,12 +260,12 @@ + * EOF is detected when recvmsg return 0. + */ + if (result == 0) { +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + goto error_exit; + } + #endif + if (result == -1 || result == 0) { +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + goto error_exit; + } + processed += result; +@@ -277,14 +277,14 @@ + return (error); + } + +-SaAisErrorT ++cs_error_t + saSendRetry ( + int s, + const void *msg, + size_t len) + { +- SaAisErrorT error = SA_AIS_OK; +- int result; ++ cs_error_t error = CS_OK; ++ ssize_t result; + struct msghdr msg_send; + struct iovec iov_send; + char *rbuf = (char *)msg; +@@ -315,15 +315,15 @@ + */ + if (result == -1 && processed == 0) { + if (errno == EINTR) { +- error = SA_AIS_ERR_TRY_AGAIN; ++ error = CS_ERR_TRY_AGAIN; + goto error_exit; + } + if (errno == EAGAIN) { +- error = SA_AIS_ERR_TRY_AGAIN; ++ error = CS_ERR_TRY_AGAIN; + goto error_exit; + } + if (errno == EFAULT) { +- error = SA_AIS_ERR_INVALID_PARAM; ++ error = CS_ERR_INVALID_PARAM; + goto error_exit; + } + } +@@ -340,7 +340,7 @@ + goto retry_send; + } + if (errno == EFAULT) { +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + goto error_exit; + } + } +@@ -349,7 +349,7 @@ + * return ERR_LIBRARY on any other syscall error + */ + if (result == -1) { +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + goto error_exit; + } + +@@ -362,13 +362,13 @@ + return (error); + } + +-SaAisErrorT saSendMsgRetry ( ++cs_error_t saSendMsgRetry ( + int s, + struct iovec *iov, + int iov_len) + { +- SaAisErrorT error = SA_AIS_OK; +- int result; ++ cs_error_t error = CS_OK; ++ ssize_t result; + int total_size = 0; + int i; + int csize; +@@ -404,15 +404,15 @@ + */ + if (result == -1 && iovec_saved_position == -1) { + if (errno == EINTR) { +- error = SA_AIS_ERR_TRY_AGAIN; ++ error = CS_ERR_TRY_AGAIN; + goto error_exit; + } + if (errno == EAGAIN) { +- error = SA_AIS_ERR_TRY_AGAIN; ++ error = CS_ERR_TRY_AGAIN; + goto error_exit; + } + if (errno == EFAULT) { +- error = SA_AIS_ERR_INVALID_PARAM; ++ error = CS_ERR_INVALID_PARAM; + goto error_exit; + } + } +@@ -428,7 +428,7 @@ + goto retry_sendmsg; + } + if (errno == EFAULT) { +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + goto error_exit; + } + } +@@ -437,7 +437,7 @@ + * ERR_LIBRARY for any other syscall error + */ + if (result == -1) { +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + goto error_exit; + } + +@@ -470,22 +470,22 @@ + return (error); + } + +-SaAisErrorT saSendMsgReceiveReply ( ++cs_error_t saSendMsgReceiveReply ( + int s, + struct iovec *iov, + int iov_len, + void *responseMessage, + int responseLen) + { +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + + error = saSendMsgRetry (s, iov, iov_len); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = saRecvRetry (s, responseMessage, responseLen); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -493,22 +493,22 @@ + return (error); + } + +-SaAisErrorT saSendReceiveReply ( ++cs_error_t saSendReceiveReply ( + int s, + void *requestMessage, + int requestLen, + void *responseMessage, + int responseLen) + { +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + + error = saSendRetry (s, requestMessage, requestLen); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + + error = saRecvRetry (s, responseMessage, responseLen); +- if (error != SA_AIS_OK) { ++ if (error != CS_OK) { + goto error_exit; + } + +@@ -516,13 +516,13 @@ + return (error); + } + +-SaAisErrorT ++cs_error_t + saPollRetry ( + struct pollfd *ufds, + unsigned int nfds, + int timeout) + { +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + int result; + + retry_poll: +@@ -531,18 +531,18 @@ + goto retry_poll; + } + if (result == -1) { +- error = SA_AIS_ERR_LIBRARY; ++ error = CS_ERR_LIBRARY; + } + + return (error); + } + + +-SaAisErrorT ++cs_error_t + saHandleCreate ( + struct saHandleDatabase *handleDatabase, + int instanceSize, +- SaUint64T *handleOut) ++ uint64_t *handleOut) + { + uint32_t handle; + uint32_t check; +@@ -566,7 +566,7 @@ + sizeof (struct saHandle) * handleDatabase->handleCount); + if (newHandles == NULL) { + pthread_mutex_unlock (&handleDatabase->mutex); +- return (SA_AIS_ERR_NO_MEMORY); ++ return (CS_ERR_NO_MEMORY); + } + handleDatabase->handles = newHandles; + } +@@ -575,7 +575,7 @@ + if (instance == 0) { + free (newHandles); + pthread_mutex_unlock (&handleDatabase->mutex); +- return (SA_AIS_ERR_NO_MEMORY); ++ return (CS_ERR_NO_MEMORY); + } + + +@@ -601,20 +601,20 @@ + + handleDatabase->handles[handle].check = check; + +- *handleOut = (SaUint64T)((uint64_t)check << 32 | handle); ++ *handleOut = (uint64_t)((uint64_t)check << 32 | handle); + + pthread_mutex_unlock (&handleDatabase->mutex); + +- return (SA_AIS_OK); ++ return (CS_OK); + } + + +-SaAisErrorT ++cs_error_t + saHandleDestroy ( + struct saHandleDatabase *handleDatabase, +- SaUint64T inHandle) ++ uint64_t inHandle) + { +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + uint32_t check = inHandle >> 32; + uint32_t handle = inHandle & 0xffffffff; + +@@ -622,7 +622,7 @@ + + if (check != handleDatabase->handles[handle].check) { + pthread_mutex_unlock (&handleDatabase->mutex); +- error = SA_AIS_ERR_BAD_HANDLE; ++ error = CS_ERR_BAD_HANDLE; + return (error); + } + +@@ -630,34 +630,34 @@ + + pthread_mutex_unlock (&handleDatabase->mutex); + +- saHandleInstancePut (handleDatabase, inHandle); ++ (void)saHandleInstancePut (handleDatabase, inHandle); + + return (error); + } + + +-SaAisErrorT ++cs_error_t + saHandleInstanceGet ( + struct saHandleDatabase *handleDatabase, +- SaUint64T inHandle, ++ uint64_t inHandle, + void **instance) + { + uint32_t check = inHandle >> 32; + uint32_t handle = inHandle & 0xffffffff; + +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + pthread_mutex_lock (&handleDatabase->mutex); + +- if (handle >= (SaUint64T)handleDatabase->handleCount) { +- error = SA_AIS_ERR_BAD_HANDLE; ++ if (handle >= (uint64_t)handleDatabase->handleCount) { ++ error = CS_ERR_BAD_HANDLE; + goto error_exit; + } + if (handleDatabase->handles[handle].state != SA_HANDLE_STATE_ACTIVE) { +- error = SA_AIS_ERR_BAD_HANDLE; ++ error = CS_ERR_BAD_HANDLE; + goto error_exit; + } + if (check != handleDatabase->handles[handle].check) { +- error = SA_AIS_ERR_BAD_HANDLE; ++ error = CS_ERR_BAD_HANDLE; + goto error_exit; + } + +@@ -673,20 +673,20 @@ + } + + +-SaAisErrorT ++cs_error_t + saHandleInstancePut ( + struct saHandleDatabase *handleDatabase, +- SaUint64T inHandle) ++ uint64_t inHandle) + { + void *instance; +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + uint32_t check = inHandle >> 32; + uint32_t handle = inHandle & 0xffffffff; + + pthread_mutex_lock (&handleDatabase->mutex); + + if (check != handleDatabase->handles[handle].check) { +- error = SA_AIS_ERR_BAD_HANDLE; ++ error = CS_ERR_BAD_HANDLE; + goto error_exit; + } + +@@ -707,16 +707,16 @@ + } + + +-SaAisErrorT ++cs_error_t + saVersionVerify ( + struct saVersionDatabase *versionDatabase, +- SaVersionT *version) ++ cs_version_t *version) + { + int i; +- SaAisErrorT error = SA_AIS_ERR_VERSION; ++ cs_error_t error = CS_ERR_VERSION; + + if (version == 0) { +- return (SA_AIS_ERR_INVALID_PARAM); ++ return (CS_ERR_INVALID_PARAM); + } + + /* +@@ -742,7 +742,7 @@ + * Check if we can support the major version requested. + */ + if (versionDatabase->versionsSupported[i].majorVersion >= version->majorVersion) { +- error = SA_AIS_OK; ++ error = CS_OK; + break; + } + +@@ -771,17 +771,17 @@ + /* + * Get the time of day and convert to nanoseconds + */ +-SaTimeT clustTimeNow(void) ++cs_time_t clustTimeNow(void) + { + struct timeval tv; +- SaTimeT time_now; ++ cs_time_t time_now; + + if (gettimeofday(&tv, 0)) { + return 0ULL; + } + +- time_now = (SaTimeT)(tv.tv_sec) * 1000000000ULL; +- time_now += (SaTimeT)(tv.tv_usec) * 1000ULL; ++ time_now = (cs_time_t)(tv.tv_sec) * 1000000000ULL; ++ time_now += (cs_time_t)(tv.tv_usec) * 1000ULL; + + return time_now; + } +diff -Naurd corosync-0.92/lib/util.h corosync-trunk/lib/util.h +--- corosync-0.92/lib/util.h 2008-05-12 15:48:06.000000000 +0200 ++++ corosync-trunk/lib/util.h 2008-11-06 22:49:07.000000000 +0100 +@@ -72,72 +72,72 @@ + SaVersionT *versionsSupported; + }; + +-SaAisErrorT ++cs_error_t + saServiceConnect ( + int *responseOut, + int *callbackOut, + enum service_types service); + +-SaAisErrorT ++cs_error_t + saRecvRetry ( + int s, + void *msg, + size_t len); + +-SaAisErrorT ++cs_error_t + saSendRetry ( + int s, + const void *msg, + size_t len); + +-SaAisErrorT saSendMsgRetry ( ++cs_error_t saSendMsgRetry ( + int s, + struct iovec *iov, + int iov_len); + +-SaAisErrorT saSendMsgReceiveReply ( ++cs_error_t saSendMsgReceiveReply ( + int s, + struct iovec *iov, + int iov_len, + void *responseMessage, + int responseLen); + +-SaAisErrorT saSendReceiveReply ( ++cs_error_t saSendReceiveReply ( + int s, + void *requestMessage, + int requestLen, + void *responseMessage, + int responseLen); + +-SaAisErrorT ++cs_error_t + saPollRetry ( + struct pollfd *ufds, + unsigned int nfds, + int timeout); + +-SaAisErrorT ++cs_error_t + saHandleCreate ( + struct saHandleDatabase *handleDatabase, + int instanceSize, + SaUint64T *handleOut); + +-SaAisErrorT ++cs_error_t + saHandleDestroy ( + struct saHandleDatabase *handleDatabase, + SaUint64T handle); + +-SaAisErrorT ++cs_error_t + saHandleInstanceGet ( + struct saHandleDatabase *handleDatabase, + SaUint64T handle, + void **instance); + +-SaAisErrorT ++cs_error_t + saHandleInstancePut ( + struct saHandleDatabase *handleDatabase, + SaUint64T handle); + +-SaAisErrorT ++cs_error_t + saVersionVerify ( + struct saVersionDatabase *versionDatabase, + SaVersionT *version); +diff -Naurd corosync-0.92/lib/votequorum.c corosync-trunk/lib/votequorum.c +--- corosync-0.92/lib/votequorum.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/lib/votequorum.c 2009-01-30 14:31:40.000000000 +0100 +@@ -0,0 +1,841 @@ ++/* ++ * Copyright (c) 2009 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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. ++ */ ++ ++/* ++ * Provides a quorum API using the corosync executive ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include "corosync/votequorum.h" ++#include "corosync/ipc_votequorum.h" ++ ++struct votequorum_inst { ++ int response_fd; ++ int dispatch_fd; ++ int finalize; ++ void *context; ++ votequorum_callbacks_t callbacks; ++ pthread_mutex_t response_mutex; ++ pthread_mutex_t dispatch_mutex; ++}; ++ ++static void votequorum_instance_destructor (void *instance); ++ ++static struct saHandleDatabase votequorum_handle_t_db = { ++ .handleCount = 0, ++ .handles = 0, ++ .mutex = PTHREAD_MUTEX_INITIALIZER, ++ .handleInstanceDestructor = votequorum_instance_destructor ++}; ++ ++/* ++ * Clean up function for a quorum instance (votequorum_initialize) handle ++ */ ++static void votequorum_instance_destructor (void *instance) ++{ ++ struct votequorum_inst *votequorum_inst = instance; ++ ++ pthread_mutex_destroy (&votequorum_inst->response_mutex); ++} ++ ++cs_error_t votequorum_initialize ( ++ votequorum_handle_t *handle, ++ votequorum_callbacks_t *callbacks) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ ++ error = saHandleCreate (&votequorum_handle_t_db, sizeof (struct votequorum_inst), handle); ++ if (error != CS_OK) { ++ goto error_no_destroy; ++ } ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, *handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ goto error_destroy; ++ } ++ ++ error = saServiceConnect (&votequorum_inst->dispatch_fd, ++ &votequorum_inst->response_fd, ++ VOTEQUORUM_SERVICE); ++ if (error != CS_OK) { ++ goto error_put_destroy; ++ } ++ ++ pthread_mutex_init (&votequorum_inst->response_mutex, NULL); ++ pthread_mutex_init (&votequorum_inst->dispatch_mutex, NULL); ++ if (callbacks) ++ memcpy(&votequorum_inst->callbacks, callbacks, sizeof (callbacks)); ++ else ++ memset(&votequorum_inst->callbacks, 0, sizeof (callbacks)); ++ ++ saHandleInstancePut (&votequorum_handle_t_db, *handle); ++ ++ return (CS_OK); ++ ++error_put_destroy: ++ saHandleInstancePut (&votequorum_handle_t_db, *handle); ++error_destroy: ++ saHandleDestroy (&votequorum_handle_t_db, *handle); ++error_no_destroy: ++ return (error); ++} ++ ++cs_error_t votequorum_finalize ( ++ votequorum_handle_t handle) ++{ ++ struct votequorum_inst *votequorum_inst; ++ cs_error_t error; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ /* ++ * Another thread has already started finalizing ++ */ ++ if (votequorum_inst->finalize) { ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ return (CS_ERR_BAD_HANDLE); ++ } ++ ++ votequorum_inst->finalize = 1; ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ saHandleDestroy (&votequorum_handle_t_db, handle); ++ ++ /* ++ * Disconnect from the server ++ */ ++ if (votequorum_inst->response_fd != -1) { ++ shutdown(votequorum_inst->response_fd, 0); ++ close(votequorum_inst->response_fd); ++ } ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (CS_OK); ++} ++ ++ ++cs_error_t votequorum_getinfo ( ++ votequorum_handle_t handle, ++ unsigned int nodeid, ++ struct votequorum_info *info) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_getinfo req_lib_votequorum_getinfo; ++ struct res_lib_votequorum_getinfo res_lib_votequorum_getinfo; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_getinfo.header.size = sizeof (struct req_lib_votequorum_getinfo); ++ req_lib_votequorum_getinfo.header.id = MESSAGE_REQ_VOTEQUORUM_GETINFO; ++ req_lib_votequorum_getinfo.nodeid = nodeid; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_getinfo; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_getinfo); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_getinfo, sizeof (struct res_lib_votequorum_getinfo)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_getinfo.header.error; ++ ++ info->node_id = res_lib_votequorum_getinfo.nodeid; ++ info->node_votes = res_lib_votequorum_getinfo.votes; ++ info->node_expected_votes = res_lib_votequorum_getinfo.expected_votes; ++ info->highest_expected = res_lib_votequorum_getinfo.highest_expected; ++ info->total_votes = res_lib_votequorum_getinfo.total_votes; ++ info->quorum = res_lib_votequorum_getinfo.quorum; ++ info->flags = res_lib_votequorum_getinfo.flags; ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t votequorum_setexpected ( ++ votequorum_handle_t handle, ++ unsigned int expected_votes) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_setexpected req_lib_votequorum_setexpected; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_setexpected.header.size = sizeof (struct req_lib_votequorum_setexpected); ++ req_lib_votequorum_setexpected.header.id = MESSAGE_REQ_VOTEQUORUM_SETEXPECTED; ++ req_lib_votequorum_setexpected.expected_votes = expected_votes; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_setexpected; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_setexpected); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_status.header.error; ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t votequorum_setvotes ( ++ votequorum_handle_t handle, ++ unsigned int nodeid, ++ unsigned int votes) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_setvotes req_lib_votequorum_setvotes; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_setvotes.header.size = sizeof (struct req_lib_votequorum_setvotes); ++ req_lib_votequorum_setvotes.header.id = MESSAGE_REQ_VOTEQUORUM_SETVOTES; ++ req_lib_votequorum_setvotes.nodeid = nodeid; ++ req_lib_votequorum_setvotes.votes = votes; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_setvotes; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_setvotes); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_status.header.error; ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t votequorum_qdisk_register ( ++ votequorum_handle_t handle, ++ char *name, ++ unsigned int votes) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_qdisk_register req_lib_votequorum_qdisk_register; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ ++ if (strlen(name) > VOTEQUORUM_MAX_QDISK_NAME_LEN) ++ return CS_ERR_INVALID_PARAM; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_qdisk_register.header.size = sizeof (struct req_lib_votequorum_qdisk_register); ++ req_lib_votequorum_qdisk_register.header.id = MESSAGE_REQ_VOTEQUORUM_QDISK_REGISTER; ++ strcpy(req_lib_votequorum_qdisk_register.name, name); ++ req_lib_votequorum_qdisk_register.votes = votes; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_qdisk_register; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_qdisk_register); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_status.header.error; ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t votequorum_qdisk_poll ( ++ votequorum_handle_t handle, ++ unsigned int state) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_qdisk_poll req_lib_votequorum_qdisk_poll; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_qdisk_poll.header.size = sizeof (struct req_lib_votequorum_qdisk_poll); ++ req_lib_votequorum_qdisk_poll.header.id = MESSAGE_REQ_VOTEQUORUM_QDISK_POLL; ++ req_lib_votequorum_qdisk_poll.state = state; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_qdisk_poll; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_qdisk_poll); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_status.header.error; ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t votequorum_qdisk_unregister ( ++ votequorum_handle_t handle) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_general req_lib_votequorum_general; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general); ++ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_QDISK_UNREGISTER; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_general; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_general); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_status.header.error; ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++ ++ ++cs_error_t votequorum_qdisk_getinfo ( ++ votequorum_handle_t handle, ++ struct votequorum_qdisk_info *qinfo) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_general req_lib_votequorum_general; ++ struct res_lib_votequorum_qdisk_getinfo res_lib_votequorum_qdisk_getinfo; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general); ++ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_QDISK_GETINFO; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_general; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_general); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_qdisk_getinfo, sizeof (struct res_lib_votequorum_qdisk_getinfo)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_qdisk_getinfo.header.error; ++ ++ qinfo->votes = res_lib_votequorum_qdisk_getinfo.votes; ++ qinfo->state = res_lib_votequorum_qdisk_getinfo.state; ++ strcpy(qinfo->name, res_lib_votequorum_qdisk_getinfo.name); ++ ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t votequorum_setstate ( ++ votequorum_handle_t handle) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_general req_lib_votequorum_general; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general); ++ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_SETSTATE; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_general; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_general); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_status.header.error; ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t votequorum_leaving ( ++ votequorum_handle_t handle) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_general req_lib_votequorum_general; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general); ++ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_LEAVING; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_general; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_general); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_status.header.error; ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t votequorum_trackstart ( ++ votequorum_handle_t handle, ++ uint64_t context, ++ unsigned int flags ) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_trackstart req_lib_votequorum_trackstart; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_trackstart.header.size = sizeof (struct req_lib_votequorum_trackstart); ++ req_lib_votequorum_trackstart.header.id = MESSAGE_REQ_VOTEQUORUM_TRACKSTART; ++ req_lib_votequorum_trackstart.track_flags = flags; ++ req_lib_votequorum_trackstart.context = context; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_trackstart; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_trackstart); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_status.header.error; ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++cs_error_t votequorum_trackstop ( ++ votequorum_handle_t handle) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ struct iovec iov[2]; ++ struct req_lib_votequorum_general req_lib_votequorum_general; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ pthread_mutex_lock (&votequorum_inst->response_mutex); ++ ++ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general); ++ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_TRACKSTOP; ++ ++ iov[0].iov_base = (char *)&req_lib_votequorum_general; ++ iov[0].iov_len = sizeof (struct req_lib_votequorum_general); ++ ++ error = saSendMsgReceiveReply (votequorum_inst->response_fd, iov, 1, ++ &res_lib_votequorum_status, sizeof (struct res_lib_votequorum_status)); ++ ++ pthread_mutex_unlock (&votequorum_inst->response_mutex); ++ ++ if (error != CS_OK) { ++ goto error_exit; ++ } ++ ++ error = res_lib_votequorum_status.header.error; ++ ++error_exit: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (error); ++} ++ ++ ++cs_error_t votequorum_context_get ( ++ votequorum_handle_t handle, ++ void **context) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ *context = votequorum_inst->context; ++ ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (CS_OK); ++} ++ ++cs_error_t votequorum_context_set ( ++ votequorum_handle_t handle, ++ void *context) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ votequorum_inst->context = context; ++ ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (CS_OK); ++} ++ ++ ++cs_error_t votequorum_fd_get ( ++ votequorum_handle_t handle, ++ int *fd) ++{ ++ cs_error_t error; ++ struct votequorum_inst *votequorum_inst; ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ *fd = votequorum_inst->dispatch_fd; ++ ++ (void)saHandleInstancePut (&votequorum_handle_t_db, handle); ++ ++ return (CS_OK); ++} ++ ++ ++struct res_overlay { ++ mar_res_header_t header __attribute__((aligned(8))); ++ char data[512000]; ++}; ++ ++cs_error_t votequorum_dispatch ( ++ votequorum_handle_t handle, ++ cs_dispatch_flags_t dispatch_types) ++{ ++ struct pollfd ufds; ++ int timeout = -1; ++ cs_error_t error; ++ int cont = 1; /* always continue do loop except when set to 0 */ ++ int dispatch_avail; ++ struct votequorum_inst *votequorum_inst; ++ votequorum_callbacks_t callbacks; ++ struct res_overlay dispatch_data; ++ struct res_lib_votequorum_notification *res_lib_votequorum_notification; ++ ++ if (dispatch_types != CS_DISPATCH_ONE && ++ dispatch_types != CS_DISPATCH_ALL && ++ dispatch_types != CS_DISPATCH_BLOCKING) { ++ ++ return (CS_ERR_INVALID_PARAM); ++ } ++ ++ error = saHandleInstanceGet (&votequorum_handle_t_db, handle, ++ (void *)&votequorum_inst); ++ if (error != CS_OK) { ++ return (error); ++ } ++ ++ /* ++ * Timeout instantly for CS_DISPATCH_ONE or CS_DISPATCH_ALL and ++ * wait indefinately for CS_DISPATCH_BLOCKING ++ */ ++ if (dispatch_types == CS_DISPATCH_ALL) { ++ timeout = 0; ++ } ++ ++ do { ++ ufds.fd = votequorum_inst->dispatch_fd; ++ ufds.events = POLLIN; ++ ufds.revents = 0; ++ ++ pthread_mutex_lock (&votequorum_inst->dispatch_mutex); ++ ++ error = saPollRetry (&ufds, 1, timeout); ++ if (error != CS_OK) { ++ goto error_unlock; ++ } ++ ++ /* ++ * Handle has been finalized in another thread ++ */ ++ if (votequorum_inst->finalize == 1) { ++ error = CS_OK; ++ goto error_unlock; ++ } ++ ++ if ((ufds.revents & (POLLERR|POLLHUP|POLLNVAL)) != 0) { ++ error = CS_ERR_BAD_HANDLE; ++ goto error_unlock; ++ } ++ ++ dispatch_avail = ufds.revents & POLLIN; ++ if (dispatch_avail == 0 && dispatch_types == CS_DISPATCH_ALL) { ++ pthread_mutex_unlock (&votequorum_inst->dispatch_mutex); ++ break; /* exit do while cont is 1 loop */ ++ } else ++ if (dispatch_avail == 0) { ++ pthread_mutex_unlock (&votequorum_inst->dispatch_mutex); ++ continue; /* next poll */ ++ } ++ ++ if (ufds.revents & POLLIN) { ++ error = saRecvRetry (votequorum_inst->dispatch_fd, &dispatch_data.header, ++ sizeof (mar_res_header_t)); ++ if (error != CS_OK) { ++ goto error_unlock; ++ } ++ if (dispatch_data.header.size > sizeof (mar_res_header_t)) { ++ error = saRecvRetry (votequorum_inst->dispatch_fd, &dispatch_data.data, ++ dispatch_data.header.size - sizeof (mar_res_header_t)); ++ if (error != CS_OK) { ++ goto error_unlock; ++ } ++ } ++ } else { ++ pthread_mutex_unlock (&votequorum_inst->dispatch_mutex); ++ continue; ++ } ++ ++ /* ++ * Make copy of callbacks, message data, unlock instance, and call callback ++ * A risk of this dispatch method is that the callback routines may ++ * operate at the same time that votequorum_finalize has been called in another thread. ++ */ ++ memcpy (&callbacks, &votequorum_inst->callbacks, sizeof (votequorum_callbacks_t)); ++ pthread_mutex_unlock (&votequorum_inst->dispatch_mutex); ++ ++ /* ++ * Dispatch incoming message ++ */ ++ switch (dispatch_data.header.id) { ++ ++ case MESSAGE_RES_VOTEQUORUM_NOTIFICATION: ++ if (callbacks.votequorum_notify_fn == NULL) { ++ continue; ++ } ++ res_lib_votequorum_notification = (struct res_lib_votequorum_notification *)&dispatch_data; ++ ++ callbacks.votequorum_notify_fn ( handle, ++ res_lib_votequorum_notification->context, ++ res_lib_votequorum_notification->quorate, ++ res_lib_votequorum_notification->node_list_entries, ++ (votequorum_node_t *)res_lib_votequorum_notification->node_list ); ++ ; ++ break; ++ ++ default: ++ error = CS_ERR_LIBRARY; ++ goto error_put; ++ break; ++ } ++ ++ /* ++ * Determine if more messages should be processed ++ * */ ++ switch (dispatch_types) { ++ case CS_DISPATCH_ONE: ++ cont = 0; ++ break; ++ case CS_DISPATCH_ALL: ++ break; ++ case CS_DISPATCH_BLOCKING: ++ break; ++ } ++ } while (cont); ++ ++ goto error_put; ++ ++error_unlock: ++ pthread_mutex_unlock (&votequorum_inst->dispatch_mutex); ++ ++error_put: ++ saHandleInstancePut (&votequorum_handle_t_db, handle); ++ return (error); ++} +diff -Naurd corosync-0.92/Makefile corosync-trunk/Makefile +--- corosync-0.92/Makefile 2008-09-03 09:58:08.000000000 +0200 ++++ corosync-trunk/Makefile 2009-01-30 19:44:13.000000000 +0100 +@@ -46,24 +46,8 @@ + INCLUDEDIR_ENGINE=$(PREFIX)/include/corosync/engine + MANDIR=$(PREFIX)/share/man + ETCDIR=/etc +-ARCH=$(shell uname -p) + +-ifeq (,$(findstring 64,$(ARCH))) +-LIBDIR=$(PREFIX)/lib/corosync +-else +-LIBDIR=$(PREFIX)/lib64/corosync +-endif +-ifeq (s390,$(ARCH)) +-LIBDIR=$(PREFIX)/lib/corosync +-endif +-ifeq (s390x,$(ARCH)) +-LIBDIR=$(PREFIX)/lib64/corosync +-endif +-ifeq (ia64,$(ARCH)) +-LIBDIR=$(PREFIX)/lib/corosync +-endif +- +-SUBDIRS:=$(builddir)lcr $(builddir)lib $(builddir)tools $(builddir)exec $(builddir)test $(builddir)services ++SUBDIRS:=$(builddir)lcr $(builddir)lib $(builddir)tools $(builddir)exec $(builddir)test $(builddir)services $(builddir)pkgconfig + sub_make = srcdir=$(srcdir) builddir=$(builddir) subdir=$(1)/ $(MAKE) -I$(srcdir)$(1) -f $(srcdir)$(1)/Makefile $(2) + + all: $(SUBDIRS) +@@ -73,6 +57,7 @@ + @(cd $(builddir)tools; echo ==== `pwd` ===; $(call sub_make,tools,all)); + @(cd $(builddir)services; echo ==== `pwd` ===; $(call sub_make,services,all)); + @(cd $(builddir)test; echo ==== `pwd` ===; $(call sub_make,test,all)); ++ @(cd $(builddir)pkgconfig; echo ==== `pwd` ===; $(call sub_make,pkgconfig,all)); + + # subdirs are not phony + .PHONY: all clean install doxygen +@@ -113,12 +98,21 @@ + (cd $(builddir)exec; echo ==== `pwd` ===; $(call sub_make,exec,clean)); + (cd $(builddir)services; echo ==== `pwd` ===; $(call sub_make,services,clean)); + (cd $(builddir)test; echo ==== `pwd` ===; $(call sub_make,test,clean)); ++ (cd $(builddir)pkgconfig; echo ==== `pwd` ===; $(call sub_make,pkgconfig,clean)); ++ + rm -rf $(builddir)doc/api + +-COROSYNC_LIBS = evs cpg cfg coroutil confdb ++lint: ++ (cd $(builddir)exec; echo ==== `pwd` ===; $(call sub_make,exec,lint)); ++ (cd $(builddir)services; echo ==== `pwd` ===; $(call sub_make,services,lint)); ++ (cd $(builddir)lcr; echo ==== `pwd` ===; $(call sub_make,lcr,lint)); ++ (cd $(builddir)lib; echo ==== `pwd` ===; $(call sub_make,lib,lint)); ++ (cd $(builddir)tools; echo ==== `pwd` ===; $(call sub_make,tools,lint)); ++ ++COROSYNC_LIBS = evs cpg cfg coroutil confdb quorum votequorum + + COROSYNC_HEADERS = cpg.h cfg.h evs.h ipc_gen.h mar_gen.h swab.h \ +- ais_util.h confdb.h list.h saAis.h ++ ais_util.h confdb.h quorum.h list.h corotypes.h votequorum.h + + EXEC_LIBS = totem_pg logsys + +@@ -134,6 +128,7 @@ + mkdir -p $(DESTDIR)$(MANDIR)/man5 + mkdir -p $(DESTDIR)$(MANDIR)/man8 + mkdir -p $(DESTDIR)$(ETCDIR)/ld.so.conf.d ++ mkdir -p $(DESTDIR)$(PKGCONFIGDIR) + + + for eLib in $(EXEC_LIBS); do \ +@@ -145,7 +140,7 @@ + install -m 755 exec/lib$$eLib.so.2.* $(DESTDIR)$(LIBDIR); \ + if [ "xYES" = "x$(STATICLIBS)" ]; then \ + install -m 755 exec/lib$$eLib.a $(DESTDIR)$(LIBDIR); \ +- if [ ${OPENCOROSYNC_COMPAT} = "DARWIN" ]; then \ ++ if [ ${COROSYNC_COMPAT} = "DARWIN" ]; then \ + ranlib $(DESTDIR)$(LIBDIR)/lib$$eLib.a; \ + fi \ + fi \ +@@ -161,7 +156,7 @@ + install -m 755 lib/lib$$aLib.so.2.* $(DESTDIR)$(LIBDIR); \ + if [ "xYES" = "x$(STATICLIBS)" ]; then \ + install -m 755 lib/lib$$aLib.a $(DESTDIR)$(LIBDIR); \ +- if [ ${OPENCOROSYNC_COMPAT} = "DARWIN" ]; then \ ++ if [ ${COROSYNC_COMPAT} = "DARWIN" ]; then \ + ranlib $(DESTDIR)$(LIBDIR)/lib$$aLib.a; \ + fi \ + fi \ +@@ -177,7 +172,7 @@ + install -m 755 $(builddir)tools/corosync-cfgtool $(DESTDIR)$(SBINDIR) + install -m 755 $(builddir)tools/corosync-keygen $(DESTDIR)$(SBINDIR) + +- if [ ! -f $(DESTDIR)$(ETCDIR)/penais.conf ] ; then \ ++ if [ ! -f $(DESTDIR)$(ETCDIR)/corosync.conf ] ; then \ + install -m 644 $(srcdir)conf/corosync.conf $(DESTDIR)$(ETCDIR) ; \ + fi + +@@ -196,10 +191,13 @@ + install -m 644 $(srcdir)include/corosync/engine/coroapi.h $(DESTDIR)$(INCLUDEDIR_ENGINE) + install -m 644 $(srcdir)include/corosync/engine/objdb.h $(DESTDIR)$(INCLUDEDIR_ENGINE) + install -m 644 $(srcdir)include/corosync/engine/logsys.h $(DESTDIR)$(INCLUDEDIR_ENGINE) ++ install -m 644 $(srcdir)include/corosync/engine/quorum.h $(DESTDIR)$(INCLUDEDIR_ENGINE) + install -m 644 $(srcdir)include/corosync/engine/config.h $(DESTDIR)$(INCLUDEDIR_ENGINE) + install -m 644 $(srcdir)man/*.3 $(DESTDIR)$(MANDIR)/man3 + install -m 644 $(srcdir)man/*.5 $(DESTDIR)$(MANDIR)/man5 + install -m 644 $(srcdir)man/*.8 $(DESTDIR)$(MANDIR)/man8 + ++ install -m 644 $(builddir)/pkgconfig/*.pc $(DESTDIR)$(PKGCONFIGDIR) ++ + doxygen: + mkdir -p doc/api && doxygen +diff -Naurd corosync-0.92/Makefile.inc corosync-trunk/Makefile.inc +--- corosync-0.92/Makefile.inc 2008-09-03 09:58:08.000000000 +0200 ++++ corosync-trunk/Makefile.inc 2009-01-30 19:25:04.000000000 +0100 +@@ -3,6 +3,25 @@ + DESTDIR= + LCRSODIR=$(PREFIX)/libexec/lcrso + ++ARCH=$(shell uname -p) ++ifeq (,$(findstring 64,$(ARCH))) ++PRELIBDIR=$(PREFIX)/lib ++else ++PRELIBDIR=$(PREFIX)/lib64 ++endif ++ifeq (s390,$(ARCH)) ++PRELIBDIR=$(PREFIX)/lib ++endif ++ifeq (s390x,$(ARCH)) ++PRELIBDIR=$(PREFIX)/lib64 ++endif ++ifeq (ia64,$(ARCH)) ++PRELIBDIR=$(PREFIX)/lib ++endif ++ ++LIBDIR=$(PRELIBDIR)/corosync ++PKGCONFIGDIR=$(PRELIBDIR)/pkgconfig ++ + # Do not modify below this line + + # Basic OS detection +@@ -38,16 +57,15 @@ + # COROSYNC_BUILD can be defined as RELEASE or DEBUG + # + ifndef COROSYNC_BUILD +- COROSYNC_BUILD=DEBUG ++ COROSYNC_BUILD=RELEASE + endif + +-# COROSYNC_PROFILE +- + # default CFLAGS, LDFLAGS + # + CFLAGS = + LDFLAGS = + DYFLAGS = ++LINT_FLAGS = -weak -unrecog +posixlib +ignoresigns -fcnuse -badflag -D__gnuc_va_list=va_list -D__attribute\(x\)= + + override CFLAGS += -DLCRSODIR='"$(LCRSODIR)"' + +@@ -58,35 +76,26 @@ + # build CFLAGS, LDFLAGS + # + ifeq (${COROSYNC_BUILD}, RELEASE) +- CFLAGS += -O3 -Wall +-# -Wstrict-aliasing=2 TODO sameday fix all of these +-ifndef COROSYNC_PROFILE +- CFLAGS += -fomit-frame-pointer +-endif +- LDFLAGS += ++ override CFLAGS += -O3 -Wall ++ override LDFLAGS += + endif + ifeq (${COROSYNC_BUILD}, DEBUG) +- CFLAGS += -O0 -g -Wall -DDEBUG --time +- LDFLAGS += -g ++ override CFLAGS += -O0 -g -Wall ++ override LDFLAGS += -g + ifeq (${COROSYNC_COMPAT}, SOLARIS) + CFLAGS += -Werror -DTS_CLASS + endif + endif + ifeq (${COROSYNC_BUILD}, COVERAGE) +- CFLAGS += -O0 -g -ftest-coverage -fprofile-arcs +- LDFLAGS += -g -ftest-coverage -fprofile-arcs ++ override CFLAGS += -O0 -g -ftest-coverage -fprofile-arcs ++ override LDFLAGS += -g -ftest-coverage -fprofile-arcs + BUILD_DYNAMIC=0 + endif + +-ifdef COROSYNC_PROFILE +- CFLAGS += -pg +- LDFLAGS += -pg +-endif +- + # platform specific CFLAGS, LDFLAGS + # + ifeq (${COROSYNC_COMPAT}, LINUX) +- override CFLAGS += -DCOROSYNC_LINUX ++ override CFLAGS += -DCOROSYNC_LINUX -D_XOPEN_SOURCE=600 -D_GNU_SOURCE + override LDFLAGS += -ldl -lpthread + override DYFLAGS += -rdynamic + endif +diff -Naurd corosync-0.92/man/confdb_overview.8 corosync-trunk/man/confdb_overview.8 +--- corosync-0.92/man/confdb_overview.8 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/man/confdb_overview.8 2009-01-26 11:46:08.000000000 +0100 +@@ -34,16 +34,24 @@ + .TH CONFDB_OVERVIEW 8 2006-03-06 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" + .SH OVERVIEW + The CONFDB library is delivered with the corosync project. This library is used +-to examine manipulate the configuratin databser used by corosync. ++to examine manipulate the configuration database used by corosync. + .PP + The library provides a mechanism to: ++.PP + * Create new objects ++.PP + * Create new key/value pairs within those objects ++.PP + * Remove existing keys ++.PP + * Remove an existing object and all it sub-objects and keys ++.PP + * Read keys and values ++.PP + * Iterate keys within an object ++.PP + * Iterate subobjects within a parent object ++.PP + * Find a named object + .PP + .SH BUGS +diff -Naurd corosync-0.92/man/corosync.conf.5 corosync-trunk/man/corosync.conf.5 +--- corosync-0.92/man/corosync.conf.5 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/man/corosync.conf.5 2008-10-21 00:05:51.000000000 +0200 +@@ -435,20 +435,6 @@ + No default. + + .TP +-debug +-This specifies whether debug output is logged for all services. This is +-generally a bad idea, unless there is some specific bug or problem that must be +-found in the executive. Set the value to +-.B on +-to debug, +-.B off +-to turn off debugging. If enabled, individual loggers can be disabled using a +-.B logger_subsys +-directive. +- +-The default is off. +- +-.TP + timestamp + This specifies that a timestamp is placed on all log messages. + +diff -Naurd corosync-0.92/man/index.html corosync-trunk/man/index.html +--- corosync-0.92/man/index.html 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/man/index.html 2009-01-26 11:46:08.000000000 +0100 +@@ -85,5 +85,30 @@ +
+ confdb_object_parent_get(3): Description of the confdb_object_parent_get interface. + ++
++votequorum_overview(8): An overview of the vote-based quorum service ++
++votequorum_initialize(3): Description of the votequorum interface. ++
++votequorum_finalize(3): Description of the votequorum interface. ++
++votequorum_fd_get(3): Description of the votequorum interface. ++
++votequorum_getinfo(3): Description of the votequorum interface. ++
++votequorum_leaving(3): Description of the votequorum interface. ++
++votequorum_setexpected(3): Description of the votequorum interface. ++
++votequorum_setvotes(3): Description of the votequorum interface. ++
++votequorum_qdisk_register(3): Description of the votequorum interface. ++
++votequorum_qdisk_unregister(3): Description of the votequorum interface. ++
++votequorum_qdisk_poll(3): Description of the votequorum interface. ++
++votequorum_qdisk_getinfo(3): Description of the votequorum interface. ++
+ + +diff -Naurd corosync-0.92/man/Makefile corosync-trunk/man/Makefile +--- corosync-0.92/man/Makefile 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/man/Makefile 2009-01-26 11:46:08.000000000 +0100 +@@ -74,6 +74,19 @@ + groff -mandoc -Thtml confdb_object_parent_get.3 > html/confdb_object_parent_get.html + groff -mandoc -Thtml confdb_overview.8 > html/confdb_overview.html + ++ groff -mandoc -Thtml votequorum_overview.8 > html/votequorum_overview.html ++ groff -mandoc -Thtml votequorum_initialize.3 > html/votequorum_initialize.html ++ groff -mandoc -Thtml votequorum_finalize.3 > html/votequorum_finalize.html ++ groff -mandoc -Thtml votequorum_fd_get.3 > html/votequorum_fd_get.html ++ groff -mandoc -Thtml votequorum_dispatch.3 > html/votequorum_dispatch.html ++ groff -mandoc -Thtml votequorum_getinfo.3 > html/votequorum_getinfo.html ++ groff -mandoc -Thtml votequorum_leaving.3 > html/votequorum_leaving.html ++ groff -mandoc -Thtml votequorum_setexpected.3 > html/votequorum_setexpected.html ++ groff -mandoc -Thtml votequorum_setvotes.3 > html/votequorum_setvotes.html ++ groff -mandoc -Thtml votequorum_qdisk_register.3 > html/votequorum_qdisk_register.html ++ groff -mandoc -Thtml votequorum_qdisk_unregister.3 > html/votequorum_qdisk_unregister.html ++ groff -mandoc -Thtml votequorum_qdisk_poll.3 > html/votequorum_poll.html ++ groff -mandoc -Thtml votequorum_qdisk_getinfo.3 > html/votequorum_qdisk_getinfo.html + cp index.html html + + clean: +diff -Naurd corosync-0.92/man/votequorum_dispatch.3 corosync-trunk/man/votequorum_dispatch.3 +--- corosync-0.92/man/votequorum_dispatch.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_dispatch.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,96 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_DISPATCH 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_dispatch \- Dispatches callbacks from the votequorum service ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_dispatch(votequorum_handle_t " handle ", votequorum_dispatch_t *" dispatch_types ");" ++.SH DESCRIPTION ++The ++.B votequorum_dispatch ++function is used to dispatch configuration changes. ++.PP ++Each application may have several connections to the votequorum API. Each application ++uses the ++.I handle ++argument to uniquely identify the connection. ++.PP ++The ++.I dispatch_types ++argument is used to identify the type of dispatch to execute. The possible types are ++defined by the structure: ++ ++.IP ++.RS ++.ne 18 ++.nf ++.ta 4n 30n 33n ++typedef enum { ++ CS_DISPATCH_ONE, ++ CS_DISPATCH_ALL, ++ CS_DISPATCH_BLOCKING ++} votequorum_dispatch_t; ++.ta ++.fi ++.RE ++.IP ++.PP ++.PP ++The dispatch values have the following meanings: ++.TP ++.B CS_DISPATCH_ONE ++Dispatch at least one callback, blocking until the callback is dispatched. ++.TP ++.B CS_DISPATCH_ALL ++Dispatch all waiting callbacks without blocking to wait for any callbacks. ++.TP ++.B CS_DISPATCH_BLOCKING ++Dispatch all callbacks blocking indefinitely. This is used in a threaded ++program where a thread is created, and then votequorum_dispatch() is called immediately ++from the created thread to execute callbacks. ++ ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_fd_get (3), ++ ++.PP +diff -Naurd corosync-0.92/man/votequorum_fd_get.3 corosync-trunk/man/votequorum_fd_get.3 +--- corosync-0.92/man/votequorum_fd_get.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_fd_get.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,64 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_FD_GET 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_fd_get \- Dispatches callbacks from the votequorum service ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_fd_get(votequorum_handle_t " handle ", int *" fd ");" ++.SH DESCRIPTION ++The ++.B votequorum_fd_get ++function is used to retrieve the file descriptor that may be used with the poll ++system call to determine when ++.B votequorum_dispatch(3) ++won't block. The ++.I handle ++argument may not be used directly with ++.B poll ++because it is not the file descriptor, but instead an internal identifier used ++by the votequorum library. ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_dispatch (3), ++.BR votequorum_fd_get (3), ++.PP +diff -Naurd corosync-0.92/man/votequorum_finalize.3 corosync-trunk/man/votequorum_finalize.3 +--- corosync-0.92/man/votequorum_finalize.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_finalize.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,61 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_FINALIZE 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_finalize \- Terminate a connection to the votequorum service ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_finalize(votequorum_handle_t " handle ");" ++.SH DESCRIPTION ++The ++.B votequorum_finalize ++function is used to close a connection to the configuration dabatase API. ++Once the connection is finalized, the handle may not be used again by applications. ++No more callbacks will be dispatched from the ++.B votequorum_dispatch function. ++.PP ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_dispatch (3), ++.BR votequorum_fd_get (3), ++ ++.PP +diff -Naurd corosync-0.92/man/votequorum_getinfo.3 corosync-trunk/man/votequorum_getinfo.3 +--- corosync-0.92/man/votequorum_getinfo.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_getinfo.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,91 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_GETINFO 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_getinfo \- Get information about the VoteQuorum service ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_getinfo(votequorum_handle_t *" handle ", unsigned int " nodeid ", struct votequorum_info *" info "); ++.SH DESCRIPTION ++The ++.B votequorum_getinfo ++function is used to get information about the voteing system and its nodes. ++ ++The votequorum_info structure is defined as follows: ++.PP ++.PP ++.IP ++.RS ++.ne 18 ++.nf ++.ta 4n 20n 32n ++ ++struct votequorum_info { ++ unsigned int node_id; ++ unsigned int node_votes; ++ unsigned int node_expected_votes; ++ unsigned int highest_expected; ++ unsigned int total_votes; ++ unsigned int quorum; ++ unsigned int flags; ++}; ++ ++#define VOTEQUORUM_INFO_FLAG_DIRTY 1 ++#define VOTEQUORUM_INFO_FLAG_DISALLOWED 2 ++#define VOTEQUORUM_INFO_FLAG_TWONODE 4 ++#define VOTEQUORUM_INFO_FLAG_QUORATE 8 ++ ++.ta ++.fi ++.RE ++.IP ++.PP ++.PP ++The members starting node_ hold information specific to the requested nodeid, the other are ++general to the voting system. ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH BUGS ++Callbacks are not support at the moment. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_finalize (3), ++.BR votequorum_fd_get (3), ++.BR votequorum_dispatch (3), ++.PP +diff -Naurd corosync-0.92/man/votequorum_initialize.3 corosync-trunk/man/votequorum_initialize.3 +--- corosync-0.92/man/votequorum_initialize.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_initialize.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,106 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_INITIALIZE 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_initialize \- Create a new connection to the VoteQuorum service ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_initialize(votequorum_handle_t *" handle ", votequorum_callbacks_t *" callbacks "); ++.SH DESCRIPTION ++The ++.B votequorum_initialize ++function is used to initialize a connection to the vote-based quorum database API. ++.PP ++Each application may have several connections to the votequorum API. Each application ++uses the ++.I handle ++argument to uniquely identify the connection. The ++.I handle ++argument is then used in other function calls to identify the connection to be used ++for communication with the votequorum service. ++.PP ++Every time the voting configuraton changes (eg a node joins or leave the cluster), the callback is called. ++The callback function is described by the following type definitions: ++ ++typedef void (*votequorum_notification_fn_t) ( ++ votequorum_handle_t handle, ++ uint64_t context, ++ uint32_t quorate, ++ uint32_t node_list_entries, ++ votequorum_node_t node_list[] ++ ); ++ ++.ta ++.fi ++.RE ++.IP ++.PP ++.PP ++The ++.I callbacks ++argument is of the type: ++.IP ++.RS ++.ne 18 ++.nf ++.PP ++typedef struct { ++ votequorum_notification_fn_t votequorum_notify_fn; ++} votequorum_callbacks_t; ++ ++.ta ++.fi ++.RE ++.IP ++.PP ++When a configuration change occurs, the callback ++is called from the ++.B votequorum_dispatch() ++function. ++.PP ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH BUGS ++Callbacks are not support at the moment. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_finalize (3), ++.BR votequorum_fd_get (3), ++.BR votequorum_dispatch (3), ++.PP +diff -Naurd corosync-0.92/man/votequorum_leaving.3 corosync-trunk/man/votequorum_leaving.3 +--- corosync-0.92/man/votequorum_leaving.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_leaving.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,67 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_LEAVING 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_leaving \- Tell other nodes that we are leaving the cluster ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_leaving(votequorum_handle_t " handle ");" ++.SH DESCRIPTION ++The ++.B votequorum_leaving ++function is used to tell the other nodes in the cluster that this node is leaving. They ++will (when the node actually leaves) reduce quorum to keep the cluster running without ++this node. ++.PP ++This function should only be called if it is known that the node is being shut down for ++a known reason and could be out of the cluster for an extended period of time. ++.PP ++Normal behaviour is for the cluster to reduce the total number of votes, but NOT expected_votes ++when a node leave the cluster, so the cluster could become inquorate. This is correct behaviour ++and is ther eto prevent split-brain. ++.PP ++Do NOT call this function unless you know what you are doing. ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_dispatch (3), ++.BR votequorum_fd_get (3), ++.PP +diff -Naurd corosync-0.92/man/votequorum_overview.8 corosync-trunk/man/votequorum_overview.8 +--- corosync-0.92/man/votequorum_overview.8 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_overview.8 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,82 @@ ++.\"/* ++.\" * Copyright (c) 2008 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_OVERVIEW 8 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH OVERVIEW ++The votequuorum library is delivered with the corosync project. It is the external interface to ++the vote-based quorum service. This service is optionally loaded into all ndes in a corosync cluster ++to avoid split-brain situations. It does this by having a number of votes assigned to each system ++in the cluster and ensuring that only when a majority of the votes are present, cluster operations are ++allowed to proceed. ++.PP ++The library provides a mechanism to: ++* Query the quorum status ++.PP ++* Get a list of nodes known to the quorum service ++.PP ++* Receive notifications of quorum state changes ++.PP ++* Change the number of votes assigned to a node ++.PP ++* Change the number of expected votes for a cluster to be quorate ++.PP ++* Connect an additional quorum device to allow small clusters to remain quorate during node outages. ++.PP ++.B votequorum ++reads its configuration from the objdb. The following keys are read when it starts up: ++.PP ++* quorum.expected_votes ++.br ++* quorum.votes ++.br ++* quorum.quorumdev_poll ++.br ++* quorum.disallowed ++.br ++* quorum.two_node ++.PP ++Most of those values can be changed while corosync is running with the following exceptions: ++.B quorum.disallowed ++cannot be changed, and ++.B two_node ++cannot be set on-the-fly, though it can be cleared. ie you can start with two nodes in the cluster ++and add a third without rebooting all the nodes. ++.PP ++.SH BUGS ++This software is not yet production, so there may still be some bugs. ++.SH "SEE ALSO" ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_fd_get (3), ++.BR votequorum_dispatch (3), ++.PP +diff -Naurd corosync-0.92/man/votequorum_qdisk_getinfo.3 corosync-trunk/man/votequorum_qdisk_getinfo.3 +--- corosync-0.92/man/votequorum_qdisk_getinfo.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_qdisk_getinfo.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,80 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_QDISK_GETINFO 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_qdisk_getinfo \- Get details of the quorum device ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_qdisk_getinfo(votequorum_handle_t " handle ", struct votequorum_qdisk_info " *info ");" ++.SH DESCRIPTION ++The ++.B votequorum_qdisk_getinfo ++Returns information about the quorum device in the following structure: ++.PP ++.PP ++.IP ++.RS ++.ne 18 ++.nf ++.ta 4n 20n 32n ++ ++struct votequorum_qdisk_info { ++ unsigned int votes; ++ unsigned int state; ++ char name[VOTEQUORUM_MAX_QDISK_NAME_LEN]; ++}; ++ ++.ta ++.fi ++.RE ++.IP ++.PP ++.PP ++ ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_dispatch (3), ++.BR votequorum_fd_get (3), ++.BR votequorum_qdisk_poll (3), ++.BR votequorum_qdisk_unregister (3), ++.BR votequorum_qdisk_getinfo (3), ++.PP +diff -Naurd corosync-0.92/man/votequorum_qdisk_poll.3 corosync-trunk/man/votequorum_qdisk_poll.3 +--- corosync-0.92/man/votequorum_qdisk_poll.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_qdisk_poll.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,69 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_QDISK_POLL 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_qdisk_poll \- Tells votequorum the result of the quorum device poll ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_qdisk_poll(votequorum_handle_t " handle ", unsigned int " state ");" ++.SH DESCRIPTION ++The ++.B votequorum_qdisk_poll ++is called by the quorum device subsyetem (not provided as part of votequorum) to tell ++the voting system if the qurum device is present/active or not. If ++.B state ++is 1 then the votes for the device are included in the quorum calculation, otherwise not. ++This routine should be called at regular intervals to ensure that the device status ++is always known to votequorum. If ++.B votequorum_qdisk_poll ++is not called after (default) 10 seconds then the device will be deeded to be dead and ++its votes removed from the cluster. This does not unregister the device. ++The default poll time can be changed by setting the object database variable ++quorum.quorumdev_poll. ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_dispatch (3), ++.BR votequorum_fd_get (3), ++.BR votequorum_qdisk_poll (3), ++.BR votequorum_qdisk_unregister (3), ++.BR votequorum_qdisk_getinfo (3), ++.PP +diff -Naurd corosync-0.92/man/votequorum_qdisk_register.3 corosync-trunk/man/votequorum_qdisk_register.3 +--- corosync-0.92/man/votequorum_qdisk_register.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_qdisk_register.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,68 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_QDISK_REGISTER 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_qdisk_register \- Registers a new quorum device ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_qdisk_register(votequorum_handle_t " handle ", char * " name ", unsigned int " votes ");" ++.SH DESCRIPTION ++The ++.B votequorum_qdisk_register ++is used to register a new quorum device. A quorum device is an external way of adding votes to a small ++cluster. The quorum device is, in effect, a pseudo node in the cluster that provide votes based on some ++external device, usually a shared disk partition or perhaps a network router. ++.br ++This call creates the device but does not mark it active. ++.B votequorum_qdisk_poll ++must be called for the votes to be included in the quorum calculation. ++.br ++Note that it is the responsibility of the quorum device subsystem (not provided as part of votequorum) ++to keep all nodes informed of the quorum device status. ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_dispatch (3), ++.BR votequorum_fd_get (3), ++.BR votequorum_qdisk_poll (3), ++.BR votequorum_qdisk_unregister (3), ++.BR votequorum_qdisk_getinfo (3), ++.PP +diff -Naurd corosync-0.92/man/votequorum_qdisk_unregister.3 corosync-trunk/man/votequorum_qdisk_unregister.3 +--- corosync-0.92/man/votequorum_qdisk_unregister.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_qdisk_unregister.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,60 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_QDISK_UNREGISTER 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_qdisk_unregister \- Unregisters a new quorum device ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_qdisk_unregister(votequorum_handle_t " handle ");" ++.SH DESCRIPTION ++The ++.B votequorum_qdisk_unregister ++unregisters a quorum device. Any votes it had will be removed from the cluster. Not that this could ++make the cluster inquorate. ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_dispatch (3), ++.BR votequorum_fd_get (3), ++.BR votequorum_qdisk_poll (3), ++.BR votequorum_qdisk_unregister (3), ++.BR votequorum_qdisk_getinfo (3), ++.PP +diff -Naurd corosync-0.92/man/votequorum_setexpected.3 corosync-trunk/man/votequorum_setexpected.3 +--- corosync-0.92/man/votequorum_setexpected.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_setexpected.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,60 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_SETEXPECTED 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_setexpected \- Sets the expected votes for the cluster ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_setexpected(votequorum_handle_t " handle ", int " expected_votes ");" ++.SH DESCRIPTION ++The ++.B votequorum_setexpected ++function is used to change the expected votes in the cluster. Expected votes is used to calculate ++quorum and should normally be the total number of votes that will exist when all the expected nodes ++are joined. Quorum will usually be half of this (rounded up). ++.br ++It is not possible to set expected votes up so that it makes the cluster inquorate using this command. ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_dispatch (3), ++.BR votequorum_fd_get (3), ++.PP +diff -Naurd corosync-0.92/man/votequorum_setvotes.3 corosync-trunk/man/votequorum_setvotes.3 +--- corosync-0.92/man/votequorum_setvotes.3 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/man/votequorum_setvotes.3 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,57 @@ ++.\"/* ++.\" * Copyright (c) 2009 Red Hat, Inc. ++.\" * ++.\" * All rights reserved. ++.\" * ++.\" * Author: Christine Caulfield ++.\" * ++.\" * 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. ++.\" */ ++.TH VOTEQUORUM_VOTES 3 2009-01-26 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" ++.SH NAME ++votequorum_setvotes \- Sets the number of votes for a node ++.SH SYNOPSIS ++.B #include ++.sp ++.BI "int votequorum_setexpected(votequorum_handle_t " handle ", unsigned int " nodeid ", int " votes ");" ++.SH DESCRIPTION ++The ++.B votequorum_setvotes ++is used to change the number of votes that a node has. Note that it is not possible, using this function, ++to change the number of node votes such that the cluster goes inquorate. ++.SH RETURN VALUE ++This call returns the CS_OK value if successful, otherwise an error is returned. ++.PP ++.SH ERRORS ++The errors are undocumented. ++.SH "SEE ALSO" ++.BR votequorum_overview (8), ++.BR votequorum_initialize (3), ++.BR votequorum_finalize (3), ++.BR votequorum_dispatch (3), ++.BR votequorum_fd_get (3), ++.PP +diff -Naurd corosync-0.92/pkgconfig/libtemplate.pc.in corosync-trunk/pkgconfig/libtemplate.pc.in +--- corosync-0.92/pkgconfig/libtemplate.pc.in 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/pkgconfig/libtemplate.pc.in 2009-01-30 19:25:04.000000000 +0100 +@@ -0,0 +1,11 @@ ++prefix=@PREFIX@ ++exec_prefix=${prefix} ++libdir=@LIBDIR@ ++includedir=${prefix}/include ++ ++Name: @LIB@ ++Version: trunk ++Description: @LIB@ ++Requires: ++Libs: -L${libdir} -l@LIB@ ++Cflags: -I${includedir} +diff -Naurd corosync-0.92/pkgconfig/Makefile corosync-trunk/pkgconfig/Makefile +--- corosync-0.92/pkgconfig/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/pkgconfig/Makefile 2009-01-30 19:25:04.000000000 +0100 +@@ -0,0 +1,50 @@ ++# Copyright (c) 2009 Red Hat, Inc. ++# ++# All rights reserved. ++# ++# 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 ENGINES; 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 configuration ++# ++srcdir ?= $(CURDIR)/../ ++subdir ?= pkgconfig ++ ++include $(srcdir)/Makefile.inc ++ ++LIBS = evs cpg cfg coroutil confdb quorum votequorum totem_pg logsys ++ ++all: ++ for i in $(LIBS); do \ ++ cat ${srcdir}/pkgconfig/libtemplate.pc.in | sed \ ++ -e 's#@PREFIX@#$(PREFIX)#g' \ ++ -e 's#@LIBDIR@#$(LIBDIR)#g' \ ++ -e 's#@LIB@#'$${i}'#g' \ ++ > lib$${i}.pc; \ ++ done; ++ ++clean: ++ rm -f *.pc +diff -Naurd corosync-0.92/services/cfg.c corosync-trunk/services/cfg.c +--- corosync-0.92/services/cfg.c 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/services/cfg.c 2009-01-30 12:56:34.000000000 +0100 +@@ -1,13 +1,13 @@ + /* + * Copyright (c) 2005-2006 MontaVista Software, Inc. +- * Copyright (c) 2006-2008 Red Hat, Inc. ++ * Copyright (c) 2006-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: + * +@@ -42,16 +42,18 @@ + #include + #include + #include ++#include + #include + #include + #include + +-#include ++#include + #include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -60,7 +62,31 @@ + LOGSYS_DECLARE_SUBSYS ("CFG", LOG_INFO); + + enum cfg_message_req_types { +- MESSAGE_REQ_EXEC_CFG_RINGREENABLE = 0 ++ MESSAGE_REQ_EXEC_CFG_RINGREENABLE = 0, ++ MESSAGE_REQ_EXEC_CFG_KILLNODE = 1, ++ MESSAGE_REQ_EXEC_CFG_SHUTDOWN = 2 ++}; ++ ++#define DEFAULT_SHUTDOWN_TIMEOUT 5 ++ ++static struct list_head trackers_list; ++ ++/* ++ * Variables controlling a requested shutdown ++ */ ++static corosync_timer_handle_t shutdown_timer; ++static struct cfg_info *shutdown_con; ++static uint32_t shutdown_flags; ++static int shutdown_yes; ++static int shutdown_no; ++static int shutdown_expected; ++ ++struct cfg_info ++{ ++ struct list_head list; ++ void *conn; ++ void *tracker_conn; ++ enum {SHUTDOWN_REPLY_UNKNOWN, SHUTDOWN_REPLY_YES, SHUTDOWN_REPLY_NO} shutdown_reply; + }; + + static void cfg_confchg_fn ( +@@ -82,6 +108,16 @@ + void *message, + unsigned int nodeid); + ++static void message_handler_req_exec_cfg_killnode ( ++ void *message, ++ unsigned int nodeid); ++ ++static void message_handler_req_exec_cfg_shutdown ( ++ void *message, ++ unsigned int nodeid); ++ ++static void exec_cfg_killnode_endian_convert (void *msg); ++ + static void message_handler_req_lib_cfg_ringstatusget ( + void *conn, + void *msg); +@@ -114,6 +150,22 @@ + void *conn, + void *msg); + ++static void message_handler_req_lib_cfg_killnode ( ++ void *conn, ++ void *msg); ++ ++static void message_handler_req_lib_cfg_tryshutdown ( ++ void *conn, ++ void *msg); ++ ++static void message_handler_req_lib_cfg_replytoshutdown ( ++ void *conn, ++ void *msg); ++ ++static void message_handler_req_lib_cfg_get_node_addrs ( ++ void *conn, ++ void *msg); ++ + /* + * Service Handler Definition + */ +@@ -123,56 +175,87 @@ + .lib_handler_fn = message_handler_req_lib_cfg_ringstatusget, + .response_size = sizeof (struct res_lib_cfg_ringstatusget), + .response_id = MESSAGE_RES_CFG_RINGSTATUSGET, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED + }, + { /* 1 */ + .lib_handler_fn = message_handler_req_lib_cfg_ringreenable, + .response_size = sizeof (struct res_lib_cfg_ringreenable), + .response_id = MESSAGE_RES_CFG_RINGREENABLE, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED + }, + { /* 2 */ + .lib_handler_fn = message_handler_req_lib_cfg_statetrack, + .response_size = sizeof (struct res_lib_cfg_statetrack), + .response_id = MESSAGE_RES_CFG_STATETRACKSTART, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED + }, + { /* 3 */ + .lib_handler_fn = message_handler_req_lib_cfg_statetrackstop, + .response_size = sizeof (struct res_lib_cfg_statetrackstop), + .response_id = MESSAGE_RES_CFG_STATETRACKSTOP, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED + }, + { /* 4 */ + .lib_handler_fn = message_handler_req_lib_cfg_administrativestateset, + .response_size = sizeof (struct res_lib_cfg_administrativestateset), + .response_id = MESSAGE_RES_CFG_ADMINISTRATIVESTATESET, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 5 */ + .lib_handler_fn = message_handler_req_lib_cfg_administrativestateget, + .response_size = sizeof (struct res_lib_cfg_administrativestateget), + .response_id = MESSAGE_RES_CFG_ADMINISTRATIVESTATEGET, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 6 */ + .lib_handler_fn = message_handler_req_lib_cfg_serviceload, + .response_size = sizeof (struct res_lib_cfg_serviceload), + .response_id = MESSAGE_RES_CFG_SERVICELOAD, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 7 */ + .lib_handler_fn = message_handler_req_lib_cfg_serviceunload, + .response_size = sizeof (struct res_lib_cfg_serviceunload), + .response_id = MESSAGE_RES_CFG_SERVICEUNLOAD, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 8 */ ++ .lib_handler_fn = message_handler_req_lib_cfg_killnode, ++ .response_size = sizeof (struct res_lib_cfg_killnode), ++ .response_id = MESSAGE_RES_CFG_KILLNODE, ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 9 */ ++ .lib_handler_fn = message_handler_req_lib_cfg_tryshutdown, ++ .response_size = sizeof (struct res_lib_cfg_tryshutdown), ++ .response_id = MESSAGE_RES_CFG_TRYSHUTDOWN, ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 10 */ ++ .lib_handler_fn = message_handler_req_lib_cfg_replytoshutdown, ++ .response_size = 0, ++ .response_id = 0, ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 11 */ ++ .lib_handler_fn = message_handler_req_lib_cfg_get_node_addrs, ++ .response_size = sizeof (struct res_lib_cfg_get_node_addrs), ++ .response_id = MESSAGE_RES_CFG_GET_NODE_ADDRS, ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + } + }; + + static struct corosync_exec_handler cfg_exec_engine[] = + { +- { +- message_handler_req_exec_cfg_ringreenable ++ { /* 0 */ ++ .exec_handler_fn = message_handler_req_exec_cfg_ringreenable, ++ }, ++ { /* 1 */ ++ .exec_handler_fn = message_handler_req_exec_cfg_killnode, ++ .exec_endian_convert_fn = exec_cfg_killnode_endian_convert ++ }, ++ { /* 2 */ ++ .exec_handler_fn = message_handler_req_exec_cfg_shutdown, + } + }; + +@@ -182,8 +265,9 @@ + struct corosync_service_engine cfg_service_engine = { + .name = "corosync configuration service", + .id = CFG_SERVICE, +- .private_data_size = 0, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED, ++ .private_data_size = sizeof(struct cfg_info), ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED, ++ .allow_inquorate = CS_LIB_ALLOW_INQUORATE, + .lib_init_fn = cfg_lib_init_fn, + .lib_exit_fn = cfg_lib_exit_fn, + .lib_engine = cfg_lib_engine, +@@ -238,12 +322,24 @@ + mar_message_source_t source __attribute__((aligned(8))); + }; + ++struct req_exec_cfg_killnode { ++ mar_req_header_t header __attribute__((aligned(8))); ++ mar_uint32_t nodeid __attribute__((aligned(8))); ++ mar_name_t reason __attribute__((aligned(8))); ++}; ++ ++struct req_exec_cfg_shutdown { ++ mar_req_header_t header __attribute__((aligned(8))); ++}; ++ + /* IMPL */ + + static int cfg_exec_init_fn ( + struct corosync_api_v1 *corosync_api_v1) + { + api = corosync_api_v1; ++ ++ list_init(&trackers_list); + return (0); + } + +@@ -256,16 +352,193 @@ + { + } + ++/* ++ * Tell other nodes we are shutting down ++ */ ++static int send_shutdown() ++{ ++ struct req_exec_cfg_shutdown req_exec_cfg_shutdown; ++ struct iovec iovec; ++ ++ ENTER(); ++ req_exec_cfg_shutdown.header.size = ++ sizeof (struct req_exec_cfg_shutdown); ++ req_exec_cfg_shutdown.header.id = SERVICE_ID_MAKE (CFG_SERVICE, ++ MESSAGE_REQ_EXEC_CFG_SHUTDOWN); ++ ++ iovec.iov_base = (char *)&req_exec_cfg_shutdown; ++ iovec.iov_len = sizeof (struct req_exec_cfg_shutdown); ++ ++ assert (api->totem_mcast (&iovec, 1, TOTEM_SAFE) == 0); ++ ++ LEAVE(); ++ return 0; ++} ++ ++static void send_test_shutdown(void * conn, int status) ++{ ++ struct res_lib_cfg_testshutdown res_lib_cfg_testshutdown; ++ struct list_head *iter; ++ ++ ENTER(); ++ res_lib_cfg_testshutdown.header.size = sizeof(struct res_lib_cfg_testshutdown); ++ res_lib_cfg_testshutdown.header.id = MESSAGE_RES_CFG_TESTSHUTDOWN; ++ res_lib_cfg_testshutdown.header.error = status; ++ res_lib_cfg_testshutdown.flags = shutdown_flags; ++ ++ if (conn) { ++ TRACE1("sending testshutdown to %p", conn); ++ api->ipc_conn_send_response(conn, &res_lib_cfg_testshutdown, ++ sizeof(res_lib_cfg_testshutdown)); ++ } else { ++ for (iter = trackers_list.next; iter != &trackers_list; iter = iter->next) { ++ struct cfg_info *ci = list_entry(iter, struct cfg_info, list); ++ ++ TRACE1("sending testshutdown to %p", ci->tracker_conn); ++ api->ipc_conn_send_response(ci->tracker_conn, &res_lib_cfg_testshutdown, ++ sizeof(res_lib_cfg_testshutdown)); ++ } ++ } ++ LEAVE(); ++} ++ ++static void check_shutdown_status() ++{ ++ ENTER(); ++ ++ /* ++ * Shutdown client might have gone away ++ */ ++ if (!shutdown_con) { ++ LEAVE(); ++ return; ++ } ++ ++ /* ++ * All replies safely gathered in ? ++ */ ++ if (shutdown_yes + shutdown_no >= shutdown_expected) { ++ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown; ++ ++ api->timer_delete(shutdown_timer); ++ ++ if (shutdown_yes >= shutdown_expected || ++ shutdown_flags == CFG_SHUTDOWN_FLAG_REGARDLESS) { ++ TRACE1("shutdown confirmed"); ++ ++ /* ++ * Tell other nodes we are going down ++ */ ++ send_shutdown(); ++ ++ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown); ++ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN; ++ res_lib_cfg_tryshutdown.header.error = CS_OK; ++ ++ /* ++ * Tell originator that shutdown was confirmed ++ */ ++ api->ipc_conn_send_response(shutdown_con->conn, &res_lib_cfg_tryshutdown, ++ sizeof(res_lib_cfg_tryshutdown)); ++ shutdown_con = NULL; ++ } ++ else { ++ ++ TRACE1("shutdown cancelled"); ++ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown); ++ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN; ++ res_lib_cfg_tryshutdown.header.error = CS_ERR_BUSY; ++ ++ /* ++ * Tell originator that shutdown was cancelled ++ */ ++ api->ipc_conn_send_response(shutdown_con->conn, &res_lib_cfg_tryshutdown, ++ sizeof(res_lib_cfg_tryshutdown)); ++ shutdown_con = NULL; ++ } ++ ++ log_printf(LOG_DEBUG, "shutdown decision is: (yes count: %d, no count: %d) flags=%x\n", shutdown_yes, shutdown_no, shutdown_flags); ++ } ++ LEAVE(); ++} ++ ++ ++/* ++ * Not all nodes responded to the shutdown (in time) ++ */ ++static void shutdown_timer_fn(void *arg) ++{ ++ ENTER(); ++ ++ /* ++ * Mark undecideds as "NO" ++ */ ++ shutdown_no = shutdown_expected; ++ check_shutdown_status(); ++ ++ send_test_shutdown(NULL, CS_ERR_TIMEOUT); ++ LEAVE(); ++} ++ ++static void remove_ci_from_shutdown(struct cfg_info *ci) ++{ ++ ENTER(); ++ ++ /* ++ * If the controlling shutdown process has quit, then cancel the ++ * shutdown session ++ */ ++ if (ci == shutdown_con) { ++ shutdown_con = NULL; ++ api->timer_delete(shutdown_timer); ++ } ++ ++ if (!list_empty(&ci->list)) { ++ list_del(&ci->list); ++ list_init(&ci->list); ++ ++ /* ++ * Remove our option ++ */ ++ if (shutdown_con) { ++ if (ci->shutdown_reply == SHUTDOWN_REPLY_YES) ++ shutdown_yes--; ++ if (ci->shutdown_reply == SHUTDOWN_REPLY_NO) ++ shutdown_no--; ++ } ++ ++ /* ++ * If we are leaving, then that's an implicit YES to shutdown ++ */ ++ ci->shutdown_reply = SHUTDOWN_REPLY_YES; ++ shutdown_yes++; ++ ++ check_shutdown_status(); ++ } ++ LEAVE(); ++} ++ ++ + int cfg_lib_exit_fn (void *conn) + { ++ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); ++ ++ ENTER(); ++ if (!list_empty(&ci->list)) { ++ list_del(&ci->list); ++ remove_ci_from_shutdown(ci); ++ } ++ LEAVE(); + return (0); + } + + static int cfg_lib_init_fn (void *conn) + { +- +- ENTER(""); +- LEAVE(""); ++ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); ++ ++ ENTER(); ++ list_init(&ci->list); ++ LEAVE(); + + return (0); + } +@@ -281,18 +554,64 @@ + (struct req_exec_cfg_ringreenable *)message; + struct res_lib_cfg_ringreenable res_lib_cfg_ringreenable; + +- ENTER(""); ++ ENTER(); + api->totem_ring_reenable (); + if (api->ipc_source_is_local(&req_exec_cfg_ringreenable->source)) { + res_lib_cfg_ringreenable.header.id = MESSAGE_RES_CFG_RINGREENABLE; + res_lib_cfg_ringreenable.header.size = sizeof (struct res_lib_cfg_ringreenable); +- res_lib_cfg_ringreenable.header.error = SA_AIS_OK; ++ res_lib_cfg_ringreenable.header.error = CS_OK; + api->ipc_conn_send_response ( + req_exec_cfg_ringreenable->source.conn, + &res_lib_cfg_ringreenable, + sizeof (struct res_lib_cfg_ringreenable)); + } +- LEAVE(""); ++ LEAVE(); ++} ++ ++static void exec_cfg_killnode_endian_convert (void *msg) ++{ ++ struct req_exec_cfg_killnode *req_exec_cfg_killnode = ++ (struct req_exec_cfg_killnode *)msg; ++ ENTER(); ++ ++ swab_mar_name_t(&req_exec_cfg_killnode->reason); ++ LEAVE(); ++} ++ ++ ++static void message_handler_req_exec_cfg_killnode ( ++ void *message, ++ unsigned int nodeid) ++{ ++ struct req_exec_cfg_killnode *req_exec_cfg_killnode = ++ (struct req_exec_cfg_killnode *)message; ++ cs_name_t reason; ++ ++ ENTER(); ++ log_printf(LOG_DEBUG, "request to kill node %d(us=%d): %s\n", req_exec_cfg_killnode->nodeid, api->totem_nodeid_get(), reason.value); ++ if (req_exec_cfg_killnode->nodeid == api->totem_nodeid_get()) { ++ marshall_from_mar_name_t(&reason, &req_exec_cfg_killnode->reason); ++ log_printf(LOG_NOTICE, "Killed by node %d: %s\n", ++ nodeid, reason.value); ++ corosync_fatal_error(COROSYNC_FATAL_ERROR_EXIT); ++ } ++ LEAVE(); ++} ++ ++/* ++ * Self shutdown ++ */ ++static void message_handler_req_exec_cfg_shutdown ( ++ void *message, ++ unsigned int nodeid) ++{ ++ ENTER(); ++ ++ log_printf(LOG_NOTICE, "Node %d was shut down by sysadmin\n", nodeid); ++ if (nodeid == api->totem_nodeid_get()) { ++ corosync_fatal_error(COROSYNC_FATAL_ERROR_EXIT); ++ } ++ LEAVE(); + } + + +@@ -310,11 +629,11 @@ + char *totem_ip_string; + unsigned int i; + +- ENTER(""); ++ ENTER(); + + res_lib_cfg_ringstatusget.header.id = MESSAGE_RES_CFG_RINGSTATUSGET; + res_lib_cfg_ringstatusget.header.size = sizeof (struct res_lib_cfg_ringstatusget); +- res_lib_cfg_ringstatusget.header.error = SA_AIS_OK; ++ res_lib_cfg_ringstatusget.header.error = CS_OK; + + api->totem_ifaces_get ( + api->totem_nodeid_get(), +@@ -336,7 +655,7 @@ + &res_lib_cfg_ringstatusget, + sizeof (struct res_lib_cfg_ringstatusget)); + +- LEAVE(""); ++ LEAVE(); + } + + static void message_handler_req_lib_cfg_ringreenable ( +@@ -346,7 +665,7 @@ + struct req_exec_cfg_ringreenable req_exec_cfg_ringreenable; + struct iovec iovec; + +- ENTER(""); ++ ENTER(); + req_exec_cfg_ringreenable.header.size = + sizeof (struct req_exec_cfg_ringreenable); + req_exec_cfg_ringreenable.header.id = SERVICE_ID_MAKE (CFG_SERVICE, +@@ -358,27 +677,56 @@ + + assert (api->totem_mcast (&iovec, 1, TOTEM_SAFE) == 0); + +- LEAVE(""); ++ LEAVE(); + } + + static void message_handler_req_lib_cfg_statetrack ( + void *conn, + void *msg) + { ++ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); + // struct req_lib_cfg_statetrack *req_lib_cfg_statetrack = (struct req_lib_cfg_statetrack *)message; ++ struct res_lib_cfg_statetrack res_lib_cfg_statetrack; + +- ENTER(""); +- LEAVE(""); ++ ENTER(); ++ ++ /* ++ * We only do shutdown tracking at the moment ++ */ ++ if (list_empty(&ci->list)) { ++ list_add(&ci->list, &trackers_list); ++ ci->tracker_conn = api->ipc_conn_partner_get (conn); ++ ++ if (shutdown_con) { ++ /* ++ * Shutdown already in progress, ask the newcomer's opinion ++ */ ++ ci->shutdown_reply = SHUTDOWN_REPLY_UNKNOWN; ++ shutdown_expected++; ++ send_test_shutdown(ci->tracker_conn, CS_OK); ++ } ++ } ++ ++ res_lib_cfg_statetrack.header.size = sizeof(struct res_lib_cfg_statetrack); ++ res_lib_cfg_statetrack.header.id = MESSAGE_RES_CFG_STATETRACKSTART; ++ res_lib_cfg_statetrack.header.error = CS_OK; ++ ++ api->ipc_conn_send_response(conn, &res_lib_cfg_statetrack, ++ sizeof(res_lib_cfg_statetrack)); ++ ++ LEAVE(); + } + + static void message_handler_req_lib_cfg_statetrackstop ( + void *conn, + void *msg) + { ++ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); + // struct req_lib_cfg_statetrackstop *req_lib_cfg_statetrackstop = (struct req_lib_cfg_statetrackstop *)message; + +- ENTER(""); +- LEAVE(""); ++ ENTER(); ++ remove_ci_from_shutdown(ci); ++ LEAVE(); + } + + static void message_handler_req_lib_cfg_administrativestateset ( +@@ -386,16 +734,17 @@ + void *msg) + { + // struct req_lib_cfg_administrativestateset *req_lib_cfg_administrativestateset = (struct req_lib_cfg_administrativestateset *)message; +- ENTER(""); +- LEAVE(""); ++ ++ ENTER(); ++ LEAVE(); + } + static void message_handler_req_lib_cfg_administrativestateget ( + void *conn, + void *msg) + { + // struct req_lib_cfg_administrativestateget *req_lib_cfg_administrativestateget = (struct req_lib_cfg_administrativestateget *)message; +- ENTER(""); +- LEAVE(""); ++ ENTER(); ++ LEAVE(); + } + + static void message_handler_req_lib_cfg_serviceload ( +@@ -406,7 +755,7 @@ + (struct req_lib_cfg_serviceload *)msg; + struct res_lib_cfg_serviceload res_lib_cfg_serviceload; + +- ENTER(""); ++ ENTER(); + api->service_link_and_init ( + api, + (char *)req_lib_cfg_serviceload->service_name, +@@ -414,12 +763,12 @@ + + res_lib_cfg_serviceload.header.id = MESSAGE_RES_CFG_SERVICEUNLOAD; + res_lib_cfg_serviceload.header.size = sizeof (struct res_lib_cfg_serviceload); +- res_lib_cfg_serviceload.header.error = SA_AIS_OK; ++ res_lib_cfg_serviceload.header.error = CS_OK; + api->ipc_conn_send_response ( + conn, + &res_lib_cfg_serviceload, + sizeof (struct res_lib_cfg_serviceload)); +- LEAVE(""); ++ LEAVE(); + } + + static void message_handler_req_lib_cfg_serviceunload ( +@@ -430,17 +779,225 @@ + (struct req_lib_cfg_serviceunload *)msg; + struct res_lib_cfg_serviceunload res_lib_cfg_serviceunload; + +- ENTER(""); ++ ENTER(); + api->service_unlink_and_exit ( + api, + (char *)req_lib_cfg_serviceunload->service_name, + req_lib_cfg_serviceunload->service_ver); + res_lib_cfg_serviceunload.header.id = MESSAGE_RES_CFG_SERVICEUNLOAD; + res_lib_cfg_serviceunload.header.size = sizeof (struct res_lib_cfg_serviceunload); +- res_lib_cfg_serviceunload.header.error = SA_AIS_OK; ++ res_lib_cfg_serviceunload.header.error = CS_OK; + api->ipc_conn_send_response ( + conn, + &res_lib_cfg_serviceunload, + sizeof (struct res_lib_cfg_serviceunload)); +- LEAVE(""); ++ LEAVE(); ++} ++ ++ ++static void message_handler_req_lib_cfg_killnode ( ++ void *conn, ++ void *msg) ++{ ++ struct req_lib_cfg_killnode *req_lib_cfg_killnode = (struct req_lib_cfg_killnode *)msg; ++ struct res_lib_cfg_killnode res_lib_cfg_killnode; ++ struct req_exec_cfg_killnode req_exec_cfg_killnode; ++ struct iovec iovec; ++ int res; ++ ++ ENTER(); ++ req_exec_cfg_killnode.header.size = ++ sizeof (struct req_exec_cfg_killnode); ++ req_exec_cfg_killnode.header.id = SERVICE_ID_MAKE (CFG_SERVICE, ++ MESSAGE_REQ_EXEC_CFG_KILLNODE); ++ req_exec_cfg_killnode.nodeid = req_lib_cfg_killnode->nodeid; ++ marshall_to_mar_name_t(&req_exec_cfg_killnode.reason, &req_lib_cfg_killnode->reason); ++ ++ iovec.iov_base = (char *)&req_exec_cfg_killnode; ++ iovec.iov_len = sizeof (struct req_exec_cfg_killnode); ++ ++ res = api->totem_mcast (&iovec, 1, TOTEM_SAFE); ++ ++ res_lib_cfg_killnode.header.size = sizeof(struct res_lib_cfg_killnode); ++ res_lib_cfg_killnode.header.id = MESSAGE_RES_CFG_KILLNODE; ++ res_lib_cfg_killnode.header.error = CS_OK; ++ ++ api->ipc_conn_send_response(conn, &res_lib_cfg_killnode, ++ sizeof(res_lib_cfg_killnode)); ++ ++ LEAVE(); ++} ++ ++ ++static void message_handler_req_lib_cfg_tryshutdown ( ++ void *conn, ++ void *msg) ++{ ++ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); ++ struct req_lib_cfg_tryshutdown *req_lib_cfg_tryshutdown = (struct req_lib_cfg_tryshutdown *)msg; ++ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown; ++ struct list_head *iter; ++ ++ ENTER(); ++ ++ if (req_lib_cfg_tryshutdown->flags == CFG_SHUTDOWN_FLAG_IMMEDIATE) { ++ ++ /* ++ * Tell other nodes ++ */ ++ send_shutdown(); ++ ++ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown); ++ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN; ++ res_lib_cfg_tryshutdown.header.error = CS_OK; ++ api->ipc_conn_send_response(conn, &res_lib_cfg_tryshutdown, ++ sizeof(res_lib_cfg_tryshutdown)); ++ ++ LEAVE(); ++ return; ++ } ++ ++ /* ++ * Shutdown in progress, return an error ++ */ ++ if (shutdown_con) { ++ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown; ++ ++ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown); ++ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN; ++ res_lib_cfg_tryshutdown.header.error = CS_ERR_EXIST; ++ ++ api->ipc_conn_send_response(conn, &res_lib_cfg_tryshutdown, ++ sizeof(res_lib_cfg_tryshutdown)); ++ ++ ++ LEAVE(); ++ ++ return; ++ } ++ ++ ci->conn = conn; ++ shutdown_con = (struct cfg_info *)api->ipc_private_data_get (conn); ++ shutdown_flags = req_lib_cfg_tryshutdown->flags; ++ shutdown_yes = 0; ++ shutdown_no = 0; ++ ++ /* ++ * Count the number of listeners ++ */ ++ shutdown_expected = 0; ++ ++ for (iter = trackers_list.next; iter != &trackers_list; iter = iter->next) { ++ struct cfg_info *ci = list_entry(iter, struct cfg_info, list); ++ ci->shutdown_reply = SHUTDOWN_REPLY_UNKNOWN; ++ shutdown_expected++; ++ } ++ ++ /* ++ * If no-one is listening for events then we can just go down now ++ */ ++ if (shutdown_expected == 0) { ++ send_shutdown(); ++ LEAVE(); ++ return; ++ } ++ else { ++ unsigned int cfg_handle; ++ unsigned int find_handle; ++ char *timeout_str; ++ unsigned int shutdown_timeout = DEFAULT_SHUTDOWN_TIMEOUT; ++ ++ /* ++ * Look for a shutdown timeout in objdb ++ */ ++ api->object_find_create(OBJECT_PARENT_HANDLE, "cfg", strlen("cfg"), &find_handle); ++ api->object_find_next(find_handle, &cfg_handle); ++ api->object_find_destroy(find_handle); ++ ++ if (cfg_handle) { ++ if ( !api->object_key_get(cfg_handle, ++ "shutdown_timeout", ++ strlen("shutdown_timeout"), ++ (void *)&timeout_str, ++ NULL)) { ++ shutdown_timeout = atoi(timeout_str); ++ } ++ } ++ ++ /* ++ * Start the timer. If we don't get a full set of replies before this goes ++ * off we'll cancel the shutdown ++ */ ++ api->timer_add_duration((unsigned long long)shutdown_timeout*1000000000, NULL, ++ shutdown_timer_fn, &shutdown_timer); ++ ++ /* ++ * Tell the users we would like to shut down ++ */ ++ send_test_shutdown(NULL, CS_OK); ++ } ++ ++ /* ++ * We don't sent a reply to the caller here. ++ * We send it when we know if we can shut down or not ++ */ ++ ++ LEAVE(); ++} ++ ++static void message_handler_req_lib_cfg_replytoshutdown ( ++ void *conn, ++ void *msg) ++{ ++ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn); ++ struct req_lib_cfg_replytoshutdown *req_lib_cfg_replytoshutdown = (struct req_lib_cfg_replytoshutdown *)msg; ++ ++ ENTER(); ++ if (!shutdown_con) { ++ LEAVE(); ++ return; ++ } ++ ++ if (req_lib_cfg_replytoshutdown->response) { ++ shutdown_yes++; ++ ci->shutdown_reply = SHUTDOWN_REPLY_YES; ++ } ++ else { ++ shutdown_no++; ++ ci->shutdown_reply = SHUTDOWN_REPLY_NO; ++ } ++ check_shutdown_status(); ++ LEAVE(); ++} ++ ++static void message_handler_req_lib_cfg_get_node_addrs (void *conn, void *msg) ++{ ++ struct totem_ip_address node_ifs[INTERFACE_MAX]; ++ char buf[PIPE_BUF]; ++ char **status; ++ unsigned int num_interfaces = 0; ++ int ret = CS_OK; ++ int i; ++ struct req_lib_cfg_get_node_addrs *req_lib_cfg_get_node_addrs = (struct req_lib_cfg_get_node_addrs *)msg; ++ struct res_lib_cfg_get_node_addrs *res_lib_cfg_get_node_addrs = (struct res_lib_cfg_get_node_addrs *)buf; ++ ++ if (req_lib_cfg_get_node_addrs->nodeid == 0) ++ req_lib_cfg_get_node_addrs->nodeid = api->totem_nodeid_get(); ++ ++ api->totem_ifaces_get(req_lib_cfg_get_node_addrs->nodeid, node_ifs, &status, &num_interfaces); ++ ++ res_lib_cfg_get_node_addrs->header.size = sizeof(struct res_lib_cfg_get_node_addrs) + (num_interfaces * TOTEMIP_ADDRLEN); ++ res_lib_cfg_get_node_addrs->header.id = MESSAGE_RES_CFG_GET_NODE_ADDRS; ++ res_lib_cfg_get_node_addrs->header.error = ret; ++ res_lib_cfg_get_node_addrs->num_addrs = num_interfaces; ++ if (num_interfaces) { ++ res_lib_cfg_get_node_addrs->family = node_ifs[0].family; ++ for (i = 0; iaddrs[i][0], node_ifs[i].addr, TOTEMIP_ADDRLEN); ++ } ++ } ++ else { ++ res_lib_cfg_get_node_addrs->header.error = CS_ERR_NOT_EXIST; ++ } ++ api->ipc_conn_send_response(conn, res_lib_cfg_get_node_addrs, res_lib_cfg_get_node_addrs->header.size); + } +diff -Naurd corosync-0.92/services/confdb.c corosync-trunk/services/confdb.c +--- corosync-0.92/services/confdb.c 2008-09-03 09:58:08.000000000 +0200 ++++ corosync-trunk/services/confdb.c 2009-01-23 16:41:06.000000000 +0100 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2008 Red Hat, Inc. ++ * Copyright (c) 2008-2009 Red Hat, Inc. + * + * All rights reserved. + * +@@ -38,7 +38,7 @@ + #include + #include + +-#include ++#include + #include + #include + #include +@@ -106,103 +106,103 @@ + .lib_handler_fn = message_handler_req_lib_confdb_object_create, + .response_size = sizeof (mar_res_header_t), + .response_id = MESSAGE_RES_CONFDB_OBJECT_CREATE, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 1 */ + .lib_handler_fn = message_handler_req_lib_confdb_object_destroy, + .response_size = sizeof (mar_res_header_t), + .response_id = MESSAGE_RES_CONFDB_OBJECT_DESTROY, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 2 */ + .lib_handler_fn = message_handler_req_lib_confdb_object_find, + .response_size = sizeof (struct res_lib_confdb_object_find), + .response_id = MESSAGE_RES_CONFDB_OBJECT_FIND, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 3 */ + .lib_handler_fn = message_handler_req_lib_confdb_key_create, + .response_size = sizeof (mar_res_header_t), + .response_id = MESSAGE_RES_CONFDB_KEY_CREATE, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 4 */ + .lib_handler_fn = message_handler_req_lib_confdb_key_get, + .response_size = sizeof (struct res_lib_confdb_key_get), + .response_id = MESSAGE_RES_CONFDB_KEY_GET, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 5 */ + .lib_handler_fn = message_handler_req_lib_confdb_key_replace, + .response_size = sizeof (mar_res_header_t), + .response_id = MESSAGE_RES_CONFDB_KEY_REPLACE, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 6 */ + .lib_handler_fn = message_handler_req_lib_confdb_key_delete, + .response_size = sizeof (mar_res_header_t), + .response_id = MESSAGE_RES_CONFDB_KEY_DELETE, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 7 */ + .lib_handler_fn = message_handler_req_lib_confdb_object_iter, + .response_size = sizeof (struct res_lib_confdb_object_iter), + .response_id = MESSAGE_RES_CONFDB_OBJECT_ITER, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 8 */ + .lib_handler_fn = message_handler_req_lib_confdb_object_parent_get, + .response_size = sizeof (struct res_lib_confdb_object_parent_get), + .response_id = MESSAGE_RES_CONFDB_OBJECT_PARENT_GET, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 9 */ + .lib_handler_fn = message_handler_req_lib_confdb_key_iter, + .response_size = sizeof (struct res_lib_confdb_key_iter), + .response_id = MESSAGE_RES_CONFDB_KEY_ITER, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 10 */ + .lib_handler_fn = message_handler_req_lib_confdb_track_start, + .response_size = sizeof (mar_res_header_t), + .response_id = MESSAGE_RES_CONFDB_TRACK_START, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 11 */ + .lib_handler_fn = message_handler_req_lib_confdb_track_stop, + .response_size = sizeof (mar_res_header_t), + .response_id = MESSAGE_RES_CONFDB_TRACK_STOP, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 12 */ + .lib_handler_fn = message_handler_req_lib_confdb_write, + .response_size = sizeof (struct res_lib_confdb_write), + .response_id = MESSAGE_RES_CONFDB_WRITE, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 13 */ + .lib_handler_fn = message_handler_req_lib_confdb_reload, + .response_size = sizeof (struct res_lib_confdb_reload), + .response_id = MESSAGE_RES_CONFDB_RELOAD, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 14 */ + .lib_handler_fn = message_handler_req_lib_confdb_object_find_destroy, + .response_size = sizeof (mar_res_header_t), + .response_id = MESSAGE_RES_CONFDB_OBJECT_FIND_DESTROY, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 15 */ + .lib_handler_fn = message_handler_req_lib_confdb_key_increment, + .response_size = sizeof (struct res_lib_confdb_key_incdec), + .response_id = MESSAGE_RES_CONFDB_KEY_INCREMENT, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 16 */ + .lib_handler_fn = message_handler_req_lib_confdb_key_decrement, + .response_size = sizeof (struct res_lib_confdb_key_incdec), + .response_id = MESSAGE_RES_CONFDB_KEY_DECREMENT, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + }; + +@@ -211,7 +211,8 @@ + .name = "corosync cluster config database access v1.01", + .id = CONFDB_SERVICE, + .private_data_size = 0, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED, ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED, ++ .allow_inquorate = CS_LIB_ALLOW_INQUORATE, + .lib_init_fn = confdb_lib_init_fn, + .lib_exit_fn = confdb_lib_exit_fn, + .lib_engine = confdb_lib_engine, +@@ -279,6 +280,7 @@ + api->object_track_stop(confdb_notify_lib_of_key_change, + confdb_notify_lib_of_new_object, + confdb_notify_lib_of_destroyed_object, ++ NULL, + api->ipc_conn_partner_get (conn)); + return (0); + } +@@ -288,13 +290,13 @@ + struct req_lib_confdb_object_create *req_lib_confdb_object_create = (struct req_lib_confdb_object_create *)message; + struct res_lib_confdb_object_create res_lib_confdb_object_create; + unsigned int object_handle; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (api->object_create(req_lib_confdb_object_create->parent_object_handle, + &object_handle, + req_lib_confdb_object_create->object_name.value, + req_lib_confdb_object_create->object_name.length)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res_lib_confdb_object_create.object_handle = object_handle; + res_lib_confdb_object_create.header.size = sizeof(res_lib_confdb_object_create); +@@ -307,10 +309,10 @@ + { + struct req_lib_confdb_object_destroy *req_lib_confdb_object_destroy = (struct req_lib_confdb_object_destroy *)message; + mar_res_header_t res; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (api->object_destroy(req_lib_confdb_object_destroy->object_handle)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res.size = sizeof(res); + res.id = MESSAGE_RES_CONFDB_OBJECT_DESTROY; +@@ -322,12 +324,10 @@ + { + struct req_lib_confdb_object_find_destroy *req_lib_confdb_object_find_destroy = (struct req_lib_confdb_object_find_destroy *)message; + mar_res_header_t res; +- int ret = SA_AIS_OK; +- +- log_printf(LOG_LEVEL_DEBUG, "object_find_destroy for conn=%p, %d\n", conn, req_lib_confdb_object_find_destroy->find_handle); ++ int ret = CS_OK; + + if (api->object_find_destroy(req_lib_confdb_object_find_destroy->find_handle)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res.size = sizeof(res); + res.id = MESSAGE_RES_CONFDB_OBJECT_FIND_DESTROY; +@@ -340,14 +340,14 @@ + { + struct req_lib_confdb_key_create *req_lib_confdb_key_create = (struct req_lib_confdb_key_create *)message; + mar_res_header_t res; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (api->object_key_create(req_lib_confdb_key_create->object_handle, + req_lib_confdb_key_create->key_name.value, + req_lib_confdb_key_create->key_name.length, + req_lib_confdb_key_create->value.value, + req_lib_confdb_key_create->value.length)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res.size = sizeof(res); + res.id = MESSAGE_RES_CONFDB_KEY_CREATE; +@@ -361,14 +361,14 @@ + struct res_lib_confdb_key_get res_lib_confdb_key_get; + int value_len; + void *value; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (api->object_key_get(req_lib_confdb_key_get->parent_object_handle, + req_lib_confdb_key_get->key_name.value, + req_lib_confdb_key_get->key_name.length, + &value, + &value_len)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + else { + memcpy(res_lib_confdb_key_get.value.value, value, value_len); + res_lib_confdb_key_get.value.length = value_len; +@@ -384,15 +384,13 @@ + { + struct req_lib_confdb_key_get *req_lib_confdb_key_get = (struct req_lib_confdb_key_get *)message; + struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec; +- int value_len; +- void *value; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (api->object_key_increment(req_lib_confdb_key_get->parent_object_handle, + req_lib_confdb_key_get->key_name.value, + req_lib_confdb_key_get->key_name.length, + &res_lib_confdb_key_incdec.value)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res_lib_confdb_key_incdec.header.size = sizeof(res_lib_confdb_key_incdec); + res_lib_confdb_key_incdec.header.id = MESSAGE_RES_CONFDB_KEY_INCREMENT; +@@ -404,15 +402,13 @@ + { + struct req_lib_confdb_key_get *req_lib_confdb_key_get = (struct req_lib_confdb_key_get *)message; + struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec; +- int value_len; +- void *value; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (api->object_key_decrement(req_lib_confdb_key_get->parent_object_handle, + req_lib_confdb_key_get->key_name.value, + req_lib_confdb_key_get->key_name.length, + &res_lib_confdb_key_incdec.value)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res_lib_confdb_key_incdec.header.size = sizeof(res_lib_confdb_key_incdec); + res_lib_confdb_key_incdec.header.id = MESSAGE_RES_CONFDB_KEY_DECREMENT; +@@ -424,7 +420,7 @@ + { + struct req_lib_confdb_key_replace *req_lib_confdb_key_replace = (struct req_lib_confdb_key_replace *)message; + mar_res_header_t res; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (api->object_key_replace(req_lib_confdb_key_replace->object_handle, + req_lib_confdb_key_replace->key_name.value, +@@ -433,7 +429,7 @@ + req_lib_confdb_key_replace->old_value.length, + req_lib_confdb_key_replace->new_value.value, + req_lib_confdb_key_replace->new_value.length)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res.size = sizeof(res); + res.id = MESSAGE_RES_CONFDB_KEY_REPLACE; +@@ -445,14 +441,14 @@ + { + struct req_lib_confdb_key_delete *req_lib_confdb_key_delete = (struct req_lib_confdb_key_delete *)message; + mar_res_header_t res; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (api->object_key_delete(req_lib_confdb_key_delete->object_handle, + req_lib_confdb_key_delete->key_name.value, + req_lib_confdb_key_delete->key_name.length, + req_lib_confdb_key_delete->value.value, + req_lib_confdb_key_delete->value.length)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res.size = sizeof(res); + res.id = MESSAGE_RES_CONFDB_KEY_DELETE; +@@ -465,11 +461,11 @@ + struct req_lib_confdb_object_parent_get *req_lib_confdb_object_parent_get = (struct req_lib_confdb_object_parent_get *)message; + struct res_lib_confdb_object_parent_get res_lib_confdb_object_parent_get; + unsigned int object_handle; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (api->object_parent_get(req_lib_confdb_object_parent_get->object_handle, + &object_handle)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res_lib_confdb_object_parent_get.parent_object_handle = object_handle; + res_lib_confdb_object_parent_get.header.size = sizeof(res_lib_confdb_object_parent_get); +@@ -487,7 +483,7 @@ + int key_name_len; + void *value; + int value_len; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (api->object_key_iter_from(req_lib_confdb_key_iter->parent_object_handle, + req_lib_confdb_key_iter->next_entry, +@@ -495,7 +491,7 @@ + &key_name_len, + &value, + &value_len)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + else { + memcpy(res_lib_confdb_key_iter.key_name.value, key_name, key_name_len); + memcpy(res_lib_confdb_key_iter.value.value, value, value_len); +@@ -514,7 +510,7 @@ + struct req_lib_confdb_object_iter *req_lib_confdb_object_iter = (struct req_lib_confdb_object_iter *)message; + struct res_lib_confdb_object_iter res_lib_confdb_object_iter; + int object_name_len; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (!req_lib_confdb_object_iter->find_handle) { + api->object_find_create(req_lib_confdb_object_iter->parent_object_handle, +@@ -525,8 +521,10 @@ + res_lib_confdb_object_iter.find_handle = req_lib_confdb_object_iter->find_handle; + + if (api->object_find_next(res_lib_confdb_object_iter.find_handle, +- &res_lib_confdb_object_iter.object_handle)) +- ret = SA_AIS_ERR_ACCESS; ++ &res_lib_confdb_object_iter.object_handle)) { ++ ret = CS_ERR_ACCESS; ++ api->object_find_destroy(res_lib_confdb_object_iter.find_handle); ++ } + else { + api->object_name_get(res_lib_confdb_object_iter.object_handle, + (char *)res_lib_confdb_object_iter.object_name.value, +@@ -545,7 +543,7 @@ + { + struct req_lib_confdb_object_find *req_lib_confdb_object_find = (struct req_lib_confdb_object_find *)message; + struct res_lib_confdb_object_find res_lib_confdb_object_find; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + + if (!req_lib_confdb_object_find->find_handle) { + api->object_find_create(req_lib_confdb_object_find->parent_object_handle, +@@ -557,8 +555,10 @@ + res_lib_confdb_object_find.find_handle = req_lib_confdb_object_find->find_handle; + + if (api->object_find_next(res_lib_confdb_object_find.find_handle, +- &res_lib_confdb_object_find.object_handle)) +- ret = SA_AIS_ERR_ACCESS; ++ &res_lib_confdb_object_find.object_handle)) { ++ ret = CS_ERR_ACCESS; ++ api->object_find_destroy(res_lib_confdb_object_find.find_handle); ++ } + + res_lib_confdb_object_find.header.size = sizeof(res_lib_confdb_object_find); + res_lib_confdb_object_find.header.id = MESSAGE_RES_CONFDB_OBJECT_FIND; +@@ -571,11 +571,11 @@ + static void message_handler_req_lib_confdb_write (void *conn, void *message) + { + struct res_lib_confdb_write res_lib_confdb_write; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + char *error_string = NULL; + + if (api->object_write_config(&error_string)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res_lib_confdb_write.header.size = sizeof(res_lib_confdb_write); + res_lib_confdb_write.header.id = MESSAGE_RES_CONFDB_WRITE; +@@ -593,11 +593,11 @@ + { + struct req_lib_confdb_reload *req_lib_confdb_reload = (struct req_lib_confdb_reload *)message; + struct res_lib_confdb_reload res_lib_confdb_reload; +- int ret = SA_AIS_OK; ++ int ret = CS_OK; + char *error_string = NULL; + + if (api->object_reload_config(req_lib_confdb_reload->flush, &error_string)) +- ret = SA_AIS_ERR_ACCESS; ++ ret = CS_ERR_ACCESS; + + res_lib_confdb_reload.header.size = sizeof(res_lib_confdb_reload); + res_lib_confdb_reload.header.id = MESSAGE_RES_CONFDB_RELOAD; +@@ -624,7 +624,7 @@ + + res.header.size = sizeof(res); + res.header.id = MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK; +- res.header.error = SA_AIS_OK; ++ res.header.error = CS_OK; + // handle & type + res.change_type = change_type; + res.parent_object_handle = parent_object_handle; +@@ -651,7 +651,7 @@ + + res.header.size = sizeof(res); + res.header.id = MESSAGE_RES_CONFDB_OBJECT_CREATE_CALLBACK; +- res.header.error = SA_AIS_OK; ++ res.header.error = CS_OK; + res.parent_object_handle = parent_object_handle; + res.object_handle = object_handle; + memcpy(res.name.value, name_pt, name_len); +@@ -668,7 +668,7 @@ + + res.header.size = sizeof(res); + res.header.id = MESSAGE_RES_CONFDB_OBJECT_DESTROY_CALLBACK; +- res.header.error = SA_AIS_OK; ++ res.header.error = CS_OK; + res.parent_object_handle = parent_object_handle; + memcpy(res.name.value, name_pt, name_len); + res.name.length = name_len; +@@ -686,10 +686,11 @@ + confdb_notify_lib_of_key_change, + confdb_notify_lib_of_new_object, + confdb_notify_lib_of_destroyed_object, ++ NULL, + api->ipc_conn_partner_get (conn)); + res.size = sizeof(res); + res.id = MESSAGE_RES_CONFDB_TRACK_START; +- res.error = SA_AIS_OK; ++ res.error = CS_OK; + api->ipc_conn_send_response(conn, &res, sizeof(res)); + } + +@@ -700,11 +701,12 @@ + api->object_track_stop(confdb_notify_lib_of_key_change, + confdb_notify_lib_of_new_object, + confdb_notify_lib_of_destroyed_object, ++ NULL, + api->ipc_conn_partner_get (conn)); + + res.size = sizeof(res); + res.id = MESSAGE_RES_CONFDB_TRACK_STOP; +- res.error = SA_AIS_OK; ++ res.error = CS_OK; + api->ipc_conn_send_response(conn, &res, sizeof(res)); + } + +diff -Naurd corosync-0.92/services/cpg.c corosync-trunk/services/cpg.c +--- corosync-0.92/services/cpg.c 2008-09-17 21:15:00.000000000 +0200 ++++ corosync-trunk/services/cpg.c 2009-01-08 07:29:16.000000000 +0100 +@@ -51,7 +51,7 @@ + #include + #include + +-#include ++#include + #include + #include + #include +@@ -99,7 +99,7 @@ + void *conn; + void *trackerconn; + struct group_info *group; +- enum corosync_flow_control_state flow_control_state; ++ enum cs_flow_control_state flow_control_state; + struct list_head list; /* on the group_info members list */ + }; + +@@ -189,49 +189,49 @@ + .lib_handler_fn = message_handler_req_lib_cpg_join, + .response_size = sizeof (struct res_lib_cpg_join), + .response_id = MESSAGE_RES_CPG_JOIN, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED + }, + { /* 1 */ + .lib_handler_fn = message_handler_req_lib_cpg_leave, + .response_size = sizeof (struct res_lib_cpg_leave), + .response_id = MESSAGE_RES_CPG_LEAVE, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED + }, + { /* 2 */ + .lib_handler_fn = message_handler_req_lib_cpg_mcast, + .response_size = sizeof (struct res_lib_cpg_mcast), + .response_id = MESSAGE_RES_CPG_MCAST, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED + }, + { /* 3 */ + .lib_handler_fn = message_handler_req_lib_cpg_membership, + .response_size = sizeof (mar_res_header_t), + .response_id = MESSAGE_RES_CPG_MEMBERSHIP, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 4 */ + .lib_handler_fn = message_handler_req_lib_cpg_trackstart, + .response_size = sizeof (struct res_lib_cpg_trackstart), + .response_id = MESSAGE_RES_CPG_TRACKSTART, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 5 */ + .lib_handler_fn = message_handler_req_lib_cpg_trackstop, + .response_size = sizeof (struct res_lib_cpg_trackstart), + .response_id = MESSAGE_RES_CPG_TRACKSTOP, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 6 */ + .lib_handler_fn = message_handler_req_lib_cpg_local_get, + .response_size = sizeof (struct res_lib_cpg_local_get), + .response_id = MESSAGE_RES_CPG_LOCAL_GET, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 7 */ + .lib_handler_fn = message_handler_req_lib_cpg_groups_get, + .response_size = sizeof (struct res_lib_cpg_groups_get), + .response_id = MESSAGE_RES_CPG_GROUPS_GET, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + } + }; + +@@ -263,7 +263,7 @@ + .name = "corosync cluster closed process group service v1.01", + .id = CPG_SERVICE, + .private_data_size = sizeof (struct process_info), +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED, ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED, + .lib_init_fn = cpg_lib_init_fn, + .lib_exit_fn = cpg_lib_exit_fn, + .lib_engine = cpg_lib_engine, +@@ -395,7 +395,7 @@ + sizeof(mar_cpg_address_t) * (count + left_list_entries + joined_list_entries); + buf = alloca(size); + if (!buf) +- return SA_AIS_ERR_NO_SPACE; ++ return CS_ERR_NO_SPACE; + + res = (struct res_lib_cpg_confchg_callback *)buf; + res->joined_list_entries = joined_list_entries; +@@ -404,6 +404,7 @@ + + res->header.size = size; + res->header.id = id; ++ res->header.error = CS_OK; + memcpy(&res->group_name, &gi->group_name, sizeof(mar_cpg_name_t)); + + /* Build up the message */ +@@ -453,7 +454,7 @@ + } + } + +- return SA_AIS_OK; ++ return CS_OK; + } + + static void remove_group(struct group_info *gi) +@@ -571,6 +572,8 @@ + return; + } + } ++ if (!buf) ++ continue; + + res = (struct res_lib_cpg_groups_get_callback *)buf; + retgi = res->member_list; +@@ -694,7 +697,7 @@ + struct memb_ring_id *ring_id) + { + int i; +- uint32_t lowest_nodeid = 0xffffff; ++ uint32_t lowest_nodeid = 0xffffffff; + struct iovec req_exec_cpg_iovec; + + /* We don't send the library joinlist in here because it can end up +@@ -736,7 +739,7 @@ + + static void cpg_flow_control_state_set_fn ( + void *context, +- enum corosync_flow_control_state flow_control_state) ++ enum cs_flow_control_state flow_control_state) + { + struct res_lib_cpg_flowcontrol_callback res_lib_cpg_flowcontrol_callback; + struct process_info *process_info = (struct process_info *)context; +@@ -1105,19 +1108,19 @@ + struct process_info *pi = (struct process_info *)api->ipc_private_data_get (conn); + struct res_lib_cpg_join res_lib_cpg_join; + struct group_info *gi; +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + + log_printf(LOG_LEVEL_DEBUG, "got join request on %p, pi=%p, pi->pid=%d\n", conn, pi, pi->pid); + + /* Already joined on this conn */ + if (pi->pid) { +- error = SA_AIS_ERR_INVALID_PARAM; ++ error = CS_ERR_INVALID_PARAM; + goto join_err; + } + + gi = get_group(&req_lib_cpg_join->group_name); + if (!gi) { +- error = SA_AIS_ERR_NO_SPACE; ++ error = CS_ERR_NO_SPACE; + goto join_err; + } + +@@ -1151,12 +1154,12 @@ + struct process_info *pi = (struct process_info *)api->ipc_private_data_get (conn); + struct res_lib_cpg_leave res_lib_cpg_leave; + struct group_info *gi; +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + + log_printf(LOG_LEVEL_DEBUG, "got leave request on %p\n", conn); + + if (!pi || !pi->pid || !pi->group) { +- error = SA_AIS_ERR_INVALID_PARAM; ++ error = CS_ERR_INVALID_PARAM; + goto leave_ret; + } + gi = pi->group; +@@ -1198,7 +1201,7 @@ + if (!gi) { + res_lib_cpg_mcast.header.size = sizeof(res_lib_cpg_mcast); + res_lib_cpg_mcast.header.id = MESSAGE_RES_CPG_MCAST; +- res_lib_cpg_mcast.header.error = SA_AIS_ERR_ACCESS; /* TODO Better error code ?? */ ++ res_lib_cpg_mcast.header.error = CS_ERR_ACCESS; /* TODO Better error code ?? */ + res_lib_cpg_mcast.flow_control_state = CPG_FLOW_CONTROL_DISABLED; + api->ipc_conn_send_response(conn, &res_lib_cpg_mcast, + sizeof(res_lib_cpg_mcast)); +@@ -1225,7 +1228,7 @@ + + res_lib_cpg_mcast.header.size = sizeof(res_lib_cpg_mcast); + res_lib_cpg_mcast.header.id = MESSAGE_RES_CPG_MCAST; +- res_lib_cpg_mcast.header.error = SA_AIS_OK; ++ res_lib_cpg_mcast.header.error = CS_OK; + res_lib_cpg_mcast.flow_control_state = pi->flow_control_state; + api->ipc_conn_send_response(conn, &res_lib_cpg_mcast, + sizeof(res_lib_cpg_mcast)); +@@ -1240,7 +1243,7 @@ + mar_res_header_t res; + res.size = sizeof(res); + res.id = MESSAGE_RES_CPG_MEMBERSHIP; +- res.error = SA_AIS_ERR_ACCESS; /* TODO Better error code */ ++ res.error = CS_ERR_ACCESS; /* TODO Better error code */ + api->ipc_conn_send_response(conn, &res, sizeof(res)); + return; + } +@@ -1256,13 +1259,13 @@ + struct group_info *gi; + struct process_info *otherpi; + void *otherconn; +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + + log_printf(LOG_LEVEL_DEBUG, "got trackstart request on %p\n", conn); + + gi = get_group(&req_lib_cpg_trackstart->group_name); + if (!gi) { +- error = SA_AIS_ERR_NO_SPACE; ++ error = CS_ERR_NO_SPACE; + goto tstart_ret; + } + +@@ -1274,7 +1277,7 @@ + tstart_ret: + res_lib_cpg_trackstart.header.size = sizeof(res_lib_cpg_trackstart); + res_lib_cpg_trackstart.header.id = MESSAGE_RES_CPG_TRACKSTART; +- res_lib_cpg_trackstart.header.error = SA_AIS_OK; ++ res_lib_cpg_trackstart.header.error = CS_OK; + api->ipc_conn_send_response(conn, &res_lib_cpg_trackstart, sizeof(res_lib_cpg_trackstart)); + } + +@@ -1285,13 +1288,13 @@ + struct process_info *otherpi; + void *otherconn; + struct group_info *gi; +- SaAisErrorT error = SA_AIS_OK; ++ cs_error_t error = CS_OK; + + log_printf(LOG_LEVEL_DEBUG, "got trackstop request on %p\n", conn); + + gi = get_group(&req_lib_cpg_trackstop->group_name); + if (!gi) { +- error = SA_AIS_ERR_NO_SPACE; ++ error = CS_ERR_NO_SPACE; + goto tstop_ret; + } + +@@ -1303,7 +1306,7 @@ + tstop_ret: + res_lib_cpg_trackstop.header.size = sizeof(res_lib_cpg_trackstop); + res_lib_cpg_trackstop.header.id = MESSAGE_RES_CPG_TRACKSTOP; +- res_lib_cpg_trackstop.header.error = SA_AIS_OK; ++ res_lib_cpg_trackstop.header.error = CS_OK; + api->ipc_conn_send_response(conn, &res_lib_cpg_trackstop.header, sizeof(res_lib_cpg_trackstop)); + } + +@@ -1313,7 +1316,7 @@ + + res_lib_cpg_local_get.header.size = sizeof(res_lib_cpg_local_get); + res_lib_cpg_local_get.header.id = MESSAGE_RES_CPG_LOCAL_GET; +- res_lib_cpg_local_get.header.error = SA_AIS_OK; ++ res_lib_cpg_local_get.header.error = CS_OK; + res_lib_cpg_local_get.local_nodeid = api->totem_nodeid_get (); + + api->ipc_conn_send_response(conn, &res_lib_cpg_local_get, +@@ -1326,7 +1329,7 @@ + + res_lib_cpg_groups_get.header.size = sizeof(res_lib_cpg_groups_get); + res_lib_cpg_groups_get.header.id = MESSAGE_RES_CPG_GROUPS_GET; +- res_lib_cpg_groups_get.header.error = SA_AIS_OK; ++ res_lib_cpg_groups_get.header.error = CS_OK; + res_lib_cpg_groups_get.num_groups = count_groups(); + + api->ipc_conn_send_response(conn, &res_lib_cpg_groups_get, +diff -Naurd corosync-0.92/services/evs.c corosync-trunk/services/evs.c +--- corosync-0.92/services/evs.c 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/services/evs.c 2008-11-06 22:49:07.000000000 +0100 +@@ -49,7 +49,7 @@ + #include + + #include +-#include ++#include + #include + #include + #include +@@ -104,31 +104,31 @@ + .lib_handler_fn = message_handler_req_evs_join, + .response_size = sizeof (struct res_lib_evs_join), + .response_id = MESSAGE_RES_EVS_JOIN, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 1 */ + .lib_handler_fn = message_handler_req_evs_leave, + .response_size = sizeof (struct res_lib_evs_leave), + .response_id = MESSAGE_RES_EVS_LEAVE, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 2 */ + .lib_handler_fn = message_handler_req_evs_mcast_joined, + .response_size = sizeof (struct res_lib_evs_mcast_joined), + .response_id = MESSAGE_RES_EVS_MCAST_JOINED, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED + }, + { /* 3 */ + .lib_handler_fn = message_handler_req_evs_mcast_groups, + .response_size = sizeof (struct res_lib_evs_mcast_groups), + .response_id = MESSAGE_RES_EVS_MCAST_GROUPS, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED + }, + { /* 4 */ + .lib_handler_fn = message_handler_req_evs_membership_get, + .response_size = sizeof (struct res_lib_evs_membership_get), + .response_id = MESSAGE_RES_EVS_MEMBERSHIP_GET, +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + } + }; + +@@ -144,7 +144,7 @@ + .name = "corosync extended virtual synchrony service", + .id = EVS_SERVICE, + .private_data_size = sizeof (struct evs_pd), +- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED, ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED, + .lib_init_fn = evs_lib_init_fn, + .lib_exit_fn = evs_lib_exit_fn, + .lib_engine = evs_lib_engine, +@@ -223,7 +223,7 @@ + */ + res_evs_confchg_callback.header.size = sizeof (struct res_evs_confchg_callback); + res_evs_confchg_callback.header.id = MESSAGE_RES_EVS_CONFCHG_CALLBACK; +- res_evs_confchg_callback.header.error = SA_AIS_OK; ++ res_evs_confchg_callback.header.error = CS_OK; + + memcpy (res_evs_confchg_callback.member_list, + member_list, member_list_entries * sizeof(*member_list)); +@@ -276,21 +276,21 @@ + + static void message_handler_req_evs_join (void *conn, void *msg) + { +- evs_error_t error = EVS_OK; ++ cs_error_t error = CS_OK; + struct req_lib_evs_join *req_lib_evs_join = (struct req_lib_evs_join *)msg; + struct res_lib_evs_join res_lib_evs_join; + void *addr; + struct evs_pd *evs_pd = (struct evs_pd *)api->ipc_private_data_get (conn); + + if (req_lib_evs_join->group_entries > 50) { +- error = EVS_ERR_TOO_MANY_GROUPS; ++ error = CS_ERR_TOO_MANY_GROUPS; + goto exit_error; + } + + addr = realloc (evs_pd->groups, sizeof (struct evs_group) * + (evs_pd->group_entries + req_lib_evs_join->group_entries)); + if (addr == NULL) { +- error = SA_AIS_ERR_NO_MEMORY; ++ error = CS_ERR_NO_MEMORY; + goto exit_error; + } + evs_pd->groups = addr; +@@ -314,7 +314,7 @@ + { + struct req_lib_evs_leave *req_lib_evs_leave = (struct req_lib_evs_leave *)msg; + struct res_lib_evs_leave res_lib_evs_leave; +- evs_error_t error = EVS_OK; ++ cs_error_t error = CS_OK; + int error_index; + int i, j; + int found; +@@ -342,7 +342,7 @@ + } + } + if (found == 0) { +- error = EVS_ERR_NOT_EXIST; ++ error = CS_ERR_NOT_EXIST; + error_index = i; + break; + } +@@ -358,7 +358,7 @@ + + static void message_handler_req_evs_mcast_joined (void *conn, void *msg) + { +- evs_error_t error = EVS_ERR_TRY_AGAIN; ++ cs_error_t error = CS_ERR_TRY_AGAIN; + struct req_lib_evs_mcast_joined *req_lib_evs_mcast_joined = (struct req_lib_evs_mcast_joined *)msg; + struct res_lib_evs_mcast_joined res_lib_evs_mcast_joined; + struct iovec req_exec_evs_mcast_iovec[3]; +@@ -388,7 +388,7 @@ + res = api->totem_mcast (req_exec_evs_mcast_iovec, 3, TOTEM_AGREED); + // TODO + if (res == 0) { +- error = EVS_OK; ++ error = CS_OK; + } + + res_lib_evs_mcast_joined.header.size = sizeof (struct res_lib_evs_mcast_joined); +@@ -401,7 +401,7 @@ + + static void message_handler_req_evs_mcast_groups (void *conn, void *msg) + { +- evs_error_t error = EVS_ERR_TRY_AGAIN; ++ cs_error_t error = CS_ERR_TRY_AGAIN; + struct req_lib_evs_mcast_groups *req_lib_evs_mcast_groups = (struct req_lib_evs_mcast_groups *)msg; + struct res_lib_evs_mcast_groups res_lib_evs_mcast_groups; + struct iovec req_exec_evs_mcast_iovec[3]; +@@ -434,7 +434,7 @@ + send_ok = api->totem_send_ok (req_exec_evs_mcast_iovec, 3); + res = api->totem_mcast (req_exec_evs_mcast_iovec, 3, TOTEM_AGREED); + if (res == 0) { +- error = EVS_OK; ++ error = CS_OK; + } + + res_lib_evs_mcast_groups.header.size = sizeof (struct res_lib_evs_mcast_groups); +@@ -451,7 +451,7 @@ + + res_lib_evs_membership_get.header.size = sizeof (struct res_lib_evs_membership_get); + res_lib_evs_membership_get.header.id = MESSAGE_RES_EVS_MEMBERSHIP_GET; +- res_lib_evs_membership_get.header.error = EVS_OK; ++ res_lib_evs_membership_get.header.error = CS_OK; + res_lib_evs_membership_get.local_nodeid = api->totem_nodeid_get (); + memcpy (&res_lib_evs_membership_get.member_list, + &res_evs_confchg_callback.member_list, +@@ -488,7 +488,7 @@ + res_evs_deliver_callback.header.size = sizeof (struct res_evs_deliver_callback) + + req_exec_evs_mcast->msg_len; + res_evs_deliver_callback.header.id = MESSAGE_RES_EVS_DELIVER_CALLBACK; +- res_evs_deliver_callback.header.error = SA_AIS_OK; ++ res_evs_deliver_callback.header.error = CS_OK; + res_evs_deliver_callback.msglen = req_exec_evs_mcast->msg_len; + + msg_addr = (char *)req_exec_evs_mcast + sizeof (struct req_exec_evs_mcast) + +diff -Naurd corosync-0.92/services/Makefile corosync-trunk/services/Makefile +--- corosync-0.92/services/Makefile 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/services/Makefile 2009-01-26 11:46:08.000000000 +0100 +@@ -50,12 +50,12 @@ + endif + + # LCR objects +-LCR_SRC = evs.c cfg.c cpg.c confdb.c +-LCR_OBJS = evs.o cfg.o cpg.o confdb.o $(AMF_OBJS) ++LCR_SRC = evs.c cfg.c cpg.c confdb.c pload.c ++LCR_OBJS = evs.o cfg.o cpg.o confdb.o $(AMF_OBJS) pload.o + + override CFLAGS += -fPIC + +-all: service_evs.lcrso service_cfg.lcrso service_cpg.lcrso service_confdb.lcrso ++all: service_evs.lcrso service_cfg.lcrso service_cpg.lcrso service_confdb.lcrso service_pload.lcrso testquorum.lcrso service_votequorum.lcrso + + ifeq (${COROSYNC_COMPAT}, DARWIN) + +@@ -71,6 +71,15 @@ + service_cpg.lcrso: cpg.o + $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ../exec/corosync -bind_at_load cpg.o -o $@ + ++service_pload.lcrso: pload.o ++ $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ../exec/corosync -bind_at_load pload.o -o $@ ++ ++service_votequorum.lcrso: votequorum.o ++ $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ../exec/corosync -bind_at_load votequorum.o -o $@ ++ ++testquorum.lcrso: testquorum.o ++ $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ../exec/corosync -bind_at_load testquorum.o -o $@ ++ + else + + service_evs.lcrso: evs.o +@@ -85,11 +94,23 @@ + service_cpg.lcrso: cpg.o + $(CC) -shared -Wl,-soname,service_cpg.lcrso cpg.o -o $@ + ++service_pload.lcrso: pload.o ++ $(CC) -shared -Wl,-soname,service_pload.lcrso pload.o -o $@ ++ ++service_votequorum.lcrso: votequorum.o ++ $(CC) -shared -Wl,-soname,service_votequorum.lcrso votequorum.o -o $@ ++ ++testquorum.lcrso: testquorum.o ++ $(CC) -shared -Wl,-soname,testquorum.lcrso testquorum.o -o $@ ++ + endif + + clean: + rm -f *.o *.lcrso + ++lint: ++ -splint $(LINT_FLAGS) $(CFLAGS) *.c ++ + depend: + makedepend -Y -- $(CFLAGS) $(CPPFLAGS) $(EXEC_SRC) $(TOTEM_SRC) $(LOGSYS_SRC) $(LCR_SRC) > /dev/null 2>&1 + +@@ -104,3 +125,6 @@ + + cpg.o: cpg.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< ++ ++testquorum.o: testquorum.c ++ $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< +diff -Naurd corosync-0.92/services/pload.c corosync-trunk/services/pload.c +--- corosync-0.92/services/pload.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/services/pload.c 2008-11-06 22:49:07.000000000 +0100 +@@ -0,0 +1,356 @@ ++/* ++ * Copyright (c) 2008 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 ++#include ++ ++LOGSYS_DECLARE_SUBSYS ("PLOAD", LOG_INFO); ++ ++enum pload_exec_message_req_types { ++ MESSAGE_REQ_EXEC_PLOAD_START = 0, ++ MESSAGE_REQ_EXEC_PLOAD_MCAST = 1 ++}; ++ ++/* ++ * Service Interfaces required by service_message_handler struct ++ */ ++static int pload_exec_init_fn ( ++ struct corosync_api_v1 *corosync_api); ++ ++static void pload_confchg_fn ( ++ enum totem_configuration_type configuration_type, ++ unsigned int *member_list, int member_list_entries, ++ unsigned int *left_list, int left_list_entries, ++ unsigned int *joined_list, int joined_list_entries, ++ struct memb_ring_id *ring_id); ++ ++static void message_handler_req_exec_pload_start (void *msg, unsigned int nodeid); ++ ++static void message_handler_req_exec_pload_mcast (void *msg, unsigned int nodeid); ++ ++static void req_exec_pload_start_endian_convert (void *msg); ++ ++static void req_exec_pload_mcast_endian_convert (void *msg); ++ ++static void message_handler_req_pload_start (void *conn, void *msg); ++ ++static int pload_lib_init_fn (void *conn); ++ ++static int pload_lib_exit_fn (void *conn); ++ ++static char buffer[1000000]; ++ ++static unsigned int msgs_delivered = 0; ++ ++static unsigned int msgs_wanted = 0; ++ ++static unsigned int msg_size = 0; ++ ++static unsigned int msg_code = 1; ++ ++static unsigned int msgs_sent = 0; ++ ++ ++static struct corosync_api_v1 *api; ++ ++struct req_exec_pload_start { ++ mar_req_header_t header; ++ unsigned int msg_code; ++ unsigned int msg_count; ++ unsigned int msg_size; ++ unsigned int time_interval; ++}; ++ ++struct req_exec_pload_mcast { ++ mar_req_header_t header; ++ unsigned int msg_code; ++}; ++ ++static struct corosync_lib_handler pload_lib_engine[] = ++{ ++ { /* 0 */ ++ .lib_handler_fn = message_handler_req_pload_start, ++ .response_size = sizeof (struct res_lib_pload_start), ++ .response_id = MESSAGE_RES_PLOAD_START, ++ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED ++ } ++}; ++ ++static struct corosync_exec_handler pload_exec_engine[] = ++{ ++ { ++ .exec_handler_fn = message_handler_req_exec_pload_start, ++ .exec_endian_convert_fn = req_exec_pload_start_endian_convert ++ }, ++ { ++ .exec_handler_fn = message_handler_req_exec_pload_mcast, ++ .exec_endian_convert_fn = req_exec_pload_mcast_endian_convert ++ } ++}; ++ ++struct corosync_service_engine pload_service_engine = { ++ .name = "corosync profile loading service", ++ .id = PLOAD_SERVICE, ++ .private_data_size = 0, ++ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED, ++ .lib_init_fn = pload_lib_init_fn, ++ .lib_exit_fn = pload_lib_exit_fn, ++ .lib_engine = pload_lib_engine, ++ .lib_engine_count = sizeof (pload_lib_engine) / sizeof (struct corosync_lib_handler), ++ .exec_engine = pload_exec_engine, ++ .exec_engine_count = sizeof (pload_exec_engine) / sizeof (struct corosync_exec_handler), ++ .confchg_fn = pload_confchg_fn, ++ .exec_init_fn = pload_exec_init_fn, ++ .exec_dump_fn = NULL ++}; ++ ++static DECLARE_LIST_INIT (confchg_notify); ++ ++/* ++ * Dynamic loading descriptor ++ */ ++ ++static struct corosync_service_engine *pload_get_service_engine_ver0 (void); ++ ++static struct corosync_service_engine_iface_ver0 pload_service_engine_iface = { ++ .corosync_get_service_engine_ver0 = pload_get_service_engine_ver0 ++}; ++ ++static struct lcr_iface corosync_pload_ver0[1] = { ++ { ++ .name = "corosync_pload", ++ .version = 0, ++ .versions_replace = 0, ++ .versions_replace_count = 0, ++ .dependencies = 0, ++ .dependency_count = 0, ++ .constructor = NULL, ++ .destructor = NULL, ++ .interfaces = NULL, ++ } ++}; ++ ++static struct lcr_comp pload_comp_ver0 = { ++ .iface_count = 1, ++ .ifaces = corosync_pload_ver0 ++}; ++ ++static struct corosync_service_engine *pload_get_service_engine_ver0 (void) ++{ ++ return (&pload_service_engine); ++} ++ ++__attribute__ ((constructor)) static void pload_comp_register (void) { ++ lcr_interfaces_set (&corosync_pload_ver0[0], &pload_service_engine_iface); ++ ++ lcr_component_register (&pload_comp_ver0); ++} ++ ++static int pload_exec_init_fn ( ++ struct corosync_api_v1 *corosync_api) ++{ ++ api = corosync_api; ++ ++ return 0; ++} ++ ++static void pload_confchg_fn ( ++ enum totem_configuration_type configuration_type, ++ unsigned int *member_list, int member_list_entries, ++ unsigned int *left_list, int left_list_entries, ++ unsigned int *joined_list, int joined_list_entries, ++ struct memb_ring_id *ring_id) ++{ ++} ++ ++static int pload_lib_init_fn (void *conn) ++{ ++ return (0); ++} ++ ++static int pload_lib_exit_fn (void *conn) ++{ ++ return (0); ++} ++ ++static void message_handler_req_pload_start (void *conn, void *msg) ++{ ++ struct req_lib_pload_start *req_lib_pload_start = (struct req_lib_pload_start *)msg; ++ struct req_exec_pload_start req_exec_pload_start; ++ struct iovec iov; ++ ++ req_exec_pload_start.header.id = ++ SERVICE_ID_MAKE (PLOAD_SERVICE, MESSAGE_REQ_EXEC_PLOAD_START); ++ req_exec_pload_start.msg_code = req_lib_pload_start->msg_code; ++ req_exec_pload_start.msg_size = req_lib_pload_start->msg_size; ++ req_exec_pload_start.msg_count = req_lib_pload_start->msg_count; ++ req_exec_pload_start.time_interval = req_lib_pload_start->time_interval; ++ iov.iov_base = &req_exec_pload_start; ++ iov.iov_len = sizeof (struct req_exec_pload_start); ++ ++ api->totem_mcast (&iov, 1, TOTEM_AGREED); ++} ++ ++static void req_exec_pload_start_endian_convert (void *msg) ++{ ++} ++ ++static void req_exec_pload_mcast_endian_convert (void *msg) ++{ ++} ++ ++static int msg_no = 0; ++ ++int send_message (enum totem_callback_token_type type, void *arg) ++{ ++ struct req_exec_pload_mcast req_exec_pload_mcast; ++ struct iovec iov[2]; ++ unsigned int res; ++ int iov_len = 2; ++ ++ req_exec_pload_mcast.header.id = ++ SERVICE_ID_MAKE (PLOAD_SERVICE, MESSAGE_REQ_EXEC_PLOAD_MCAST); ++ req_exec_pload_mcast.header.size = sizeof (struct req_exec_pload_mcast) + msg_size; ++ ++ iov[0].iov_base = &req_exec_pload_mcast; ++ iov[0].iov_len = sizeof (struct req_exec_pload_mcast); ++ iov[1].iov_base = buffer; ++ iov[1].iov_len = msg_size - sizeof (struct req_exec_pload_mcast); ++ if (iov[1].iov_len < 0) { ++ iov_len = 1; ++ } ++ ++ do { ++ res = api->totem_mcast (iov, iov_len, TOTEM_AGREED); ++ if (res == -1) { ++ break; ++ } else { ++ msgs_sent++; ++ msg_code++; ++ } ++ } while (msgs_sent <= msgs_wanted); ++ if (msgs_sent == msgs_wanted) { ++ return (0); ++ } else { ++ return (-1); ++ } ++} ++ ++void *token_callback; ++void start_mcasting (void) ++{ ++ api->totem_callback_token_create ( ++ &token_callback, ++ TOTEM_CALLBACK_TOKEN_RECEIVED, ++ 1, ++ send_message, ++ &token_callback); ++} ++ ++static void message_handler_req_exec_pload_start ( ++ void *msg, ++ unsigned int nodeid) ++{ ++ struct req_exec_pload_start *req_exec_pload_start = (struct req_exec_pload_start *)msg; ++ ++ msgs_wanted = req_exec_pload_start->msg_count; ++ msg_size = req_exec_pload_start->msg_size; ++ msg_code = req_exec_pload_start->msg_code; ++ ++ start_mcasting (); ++} ++ ++# define timersub(a, b, result) \ ++ do { \ ++ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ ++ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ ++ if ((result)->tv_usec < 0) { \ ++ --(result)->tv_sec; \ ++ (result)->tv_usec += 1000000; \ ++ } \ ++ } while (0) ++ ++struct timeval tv1; ++struct timeval tv2; ++struct timeval tv_elapsed; ++int last_msg_no = 0; ++ ++static void message_handler_req_exec_pload_mcast ( ++ void *msg, ++ unsigned int nodeid) ++{ ++ struct req_exec_pload_mcast *pload_mcast = (struct req_exec_pload_mcast *)msg; ++ ++ assert (pload_mcast->msg_code - 1 == last_msg_no); ++ last_msg_no = pload_mcast->msg_code; ++ if (msgs_delivered == 0) { ++ gettimeofday (&tv1, NULL); ++ } ++ msgs_delivered += 1; ++ if (msgs_delivered == msgs_wanted) { ++ gettimeofday (&tv2, NULL); ++ timersub (&tv2, &tv1, &tv_elapsed); ++ printf ("%5d Writes ", msgs_delivered); ++ printf ("%5d bytes per write ", msg_size); ++ printf ("%7.3f Seconds runtime ", ++ (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0))); ++ printf ("%9.3f TP/s ", ++ ((float)msgs_delivered) / (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0))); ++ printf ("%7.3f MB/s.\n", ++ ((float)msgs_delivered) * ((float)msg_size) / ((tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)) * 1000000.0)); ++ } ++} +diff -Naurd corosync-0.92/services/testquorum.c corosync-trunk/services/testquorum.c +--- corosync-0.92/services/testquorum.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/services/testquorum.c 2008-12-09 14:48:47.000000000 +0100 +@@ -0,0 +1,153 @@ ++/* ++ * Copyright (c) 2008 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 Red Hat, 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 ++#include ++ ++#include ++ ++LOGSYS_DECLARE_SUBSYS ("TEST", LOG_INFO); ++ ++static void test_init(struct corosync_api_v1 *api, quorum_set_quorate_fn_t report); ++ ++/* ++ * lcrso object definition ++ */ ++static struct quorum_services_api_ver1 test_quorum_iface_ver0 = { ++ .init = test_init ++}; ++ ++static struct lcr_iface corosync_test_quorum_ver0[1] = { ++ { ++ .name = "testquorum", ++ .version = 0, ++ .versions_replace = 0, ++ .versions_replace_count = 0, ++ .dependencies = 0, ++ .dependency_count = 0, ++ .constructor = NULL, ++ .destructor = NULL, ++ .interfaces = (void **)(void *)&test_quorum_iface_ver0, ++ }, ++}; ++ ++static struct lcr_comp test_quorum_comp_ver0 = { ++ .iface_count = 1, ++ .ifaces = corosync_test_quorum_ver0 ++}; ++ ++__attribute__ ((constructor)) static void test_quorum_comp_register (void) { ++ lcr_interfaces_set (&corosync_test_quorum_ver0[0], &test_quorum_iface_ver0); ++ lcr_component_register (&test_quorum_comp_ver0); ++} ++ ++/* -------------------------------------------------- */ ++ ++static quorum_set_quorate_fn_t set_quorum; ++ ++static void key_change_notify(object_change_type_t change_type, ++ unsigned int parent_object_handle, ++ unsigned int object_handle, ++ void *object_name_pt, int object_name_len, ++ void *key_name_pt, int key_len, ++ void *key_value_pt, int key_value_len, ++ void *priv_data_pt) ++{ ++ unsigned int members[1]; ++ struct memb_ring_id ring_id; ++ ++ memset(&ring_id, 0, sizeof(ring_id)); ++ ++ /* If the 'quorum.quorate' key changes, then that changes quorum */ ++ if (strncmp(key_name_pt, "quorate", key_len) == 0) { ++ set_quorum(members, 0, atoi(key_value_pt), &ring_id); ++ } ++} ++ ++static void quorum_callback(int quorate, void *context) ++{ ++ log_printf(LOG_LEVEL_DEBUG, "quorum callback: quorate = %d\n", quorate); ++} ++ ++static void test_init(struct corosync_api_v1 *api, ++ quorum_set_quorate_fn_t report) ++{ ++ ++ unsigned int find_handle; ++ unsigned int quorum_handle = 0; ++ ++ set_quorum = report; ++ ++ /* ++ * Register for objdb changes on quorum { } ++ */ ++ api->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle); ++ api->object_find_next(find_handle, &quorum_handle); ++ api->object_find_destroy(find_handle); ++ ++ api->object_track_start(quorum_handle, ++ 1, ++ key_change_notify, ++ NULL, // object_create_notify ++ NULL, // object_destroy_notify ++ NULL, // object_reload_notify ++ NULL); // priv_data ++ ++ /* Register for quorum changes too! */ ++ api->quorum_register_callback(quorum_callback, NULL); ++} +diff -Naurd corosync-0.92/services/votequorum.c corosync-trunk/services/votequorum.c +--- corosync-0.92/services/votequorum.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/services/votequorum.c 2009-01-29 15:21:05.000000000 +0100 +@@ -0,0 +1,1619 @@ ++/* ++ * Copyright (c) 2009 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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 ++#ifndef COROSYNC_BSD ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define VOTEQUORUM_MAJOR_VERSION 6 ++#define VOTEQUORUM_MINOR_VERSION 3 ++#define VOTEQUORUM_PATCH_VERSION 0 ++ ++ /* Silly default to prevent accidents! */ ++#define DEFAULT_EXPECTED 1024 ++#define DEFAULT_QDEV_POLL 10000 ++ ++LOGSYS_DECLARE_SUBSYS ("VOTEQ", LOG_INFO); ++ ++enum quorum_message_req_types { ++ MESSAGE_REQ_EXEC_VOTEQUORUM_NODEINFO = 0, ++ MESSAGE_REQ_EXEC_VOTEQUORUM_RECONFIGURE = 1, ++ MESSAGE_REQ_EXEC_VOTEQUORUM_KILLNODE = 2, ++}; ++ ++#define NODE_FLAGS_BEENDOWN 1 ++#define NODE_FLAGS_SEESDISALLOWED 8 ++#define NODE_FLAGS_HASSTATE 16 ++#define NODE_FLAGS_QDISK 32 ++#define NODE_FLAGS_REMOVED 64 ++#define NODE_FLAGS_US 128 ++ ++ ++typedef enum { NODESTATE_JOINING=1, NODESTATE_MEMBER, ++ NODESTATE_DEAD, NODESTATE_LEAVING, NODESTATE_DISALLOWED } nodestate_t; ++ ++ ++/* This structure is tacked onto the start of a cluster message packet for our ++ * own nefarious purposes. */ ++struct q_protheader { ++ unsigned char tgtport; /* Target port number */ ++ unsigned char srcport; /* Source (originating) port number */ ++ unsigned short pad; ++ unsigned int flags; ++ int srcid; /* Node ID of the sender */ ++ int tgtid; /* Node ID of the target */ ++} __attribute__((packed)); ++ ++struct cluster_node { ++ int flags; ++ int node_id; ++ unsigned int expected_votes; ++ unsigned int votes; ++ time_t join_time; ++ ++ nodestate_t state; ++ ++ struct timeval last_hello; /* Only used for quorum devices */ ++ ++ struct list_head list; ++}; ++ ++static int quorum_flags; ++#define VOTEQUORUM_FLAG_FEATURE_DISALLOWED 1 ++#define VOTEQUORUM_FLAG_FEATURE_TWONODE 1 ++ ++static int quorum; ++static int cluster_is_quorate; ++static int first_trans = 1; ++static unsigned int quorumdev_poll = DEFAULT_QDEV_POLL; ++ ++static struct cluster_node *us; ++static struct cluster_node *quorum_device = NULL; ++static char quorum_device_name[VOTEQUORUM_MAX_QDISK_NAME_LEN]; ++static corosync_timer_handle_t quorum_device_timer; ++static struct list_head cluster_members_list; ++static struct corosync_api_v1 *corosync_api; ++static struct list_head trackers_list; ++static unsigned int quorum_members[PROCESSOR_COUNT_MAX+1]; ++static int quorum_members_entries = 0; ++static struct memb_ring_id quorum_ringid; ++static cs_tpg_handle group_handle; ++ ++#define max(a,b) (((a) > (b)) ? (a) : (b)) ++static struct cluster_node *find_node_by_nodeid(int nodeid); ++static struct cluster_node *allocate_node(int nodeid); ++static char *kill_reason(int reason); ++ ++static struct corosync_tpg_group quorum_group[1] = { ++ { .group = "VOTEQ", .group_len = 5}, ++}; ++ ++#define list_iterate(v, head) \ ++ for (v = (head)->next; v != head; v = v->next) ++ ++struct quorum_pd { ++ unsigned char track_flags; ++ int tracking_enabled; ++ uint64_t tracking_context; ++ struct list_head list; ++ void *conn; ++}; ++ ++/* ++ * Service Interfaces required by service_message_handler struct ++ */ ++ ++static void votequorum_init(struct corosync_api_v1 *api, ++ quorum_set_quorate_fn_t report); ++ ++static void quorum_confchg_fn ( ++ enum totem_configuration_type configuration_type, ++ unsigned int *member_list, int member_list_entries, ++ unsigned int *left_list, int left_list_entries, ++ unsigned int *joined_list, int joined_list_entries, ++ struct memb_ring_id *ring_id); ++ ++static void quorum_deliver_fn(unsigned int nodeid, struct iovec *iovec, int iov_len, ++ int endian_conversion_required); ++ ++static int votequorum_exec_init_fn (struct corosync_api_v1 *corosync_api); ++ ++static int quorum_lib_init_fn (void *conn); ++ ++static int quorum_lib_exit_fn (void *conn); ++ ++static void message_handler_req_exec_quorum_nodeinfo ( ++ void *message, ++ unsigned int nodeid); ++ ++static void message_handler_req_exec_quorum_reconfigure ( ++ void *message, ++ unsigned int nodeid); ++ ++static void message_handler_req_exec_quorum_killnode ( ++ void *message, ++ unsigned int nodeid); ++ ++ ++static void message_handler_req_lib_votequorum_getinfo (void *conn, void *message); ++ ++static void message_handler_req_lib_votequorum_setexpected (void *conn, void *message); ++ ++static void message_handler_req_lib_votequorum_setvotes (void *conn, void *message); ++ ++static void message_handler_req_lib_votequorum_qdisk_register (void *conn, void *message); ++ ++static void message_handler_req_lib_votequorum_qdisk_unregister (void *conn, void *message); ++ ++static void message_handler_req_lib_votequorum_qdisk_poll (void *conn, void *message); ++ ++static void message_handler_req_lib_votequorum_qdisk_getinfo (void *conn, void *message); ++ ++static void message_handler_req_lib_votequorum_setstate (void *conn, void *message); ++ ++static void message_handler_req_lib_votequorum_leaving (void *conn, void *message); ++static void message_handler_req_lib_votequorum_trackstart (void *conn, void *msg); ++static void message_handler_req_lib_votequorum_trackstop (void *conn, void *msg); ++ ++static int quorum_exec_send_nodeinfo(void); ++static int quorum_exec_send_reconfigure(int param, int nodeid, int value); ++static int quorum_exec_send_killnode(int nodeid, unsigned int reason); ++ ++static void add_votequorum_config_notification(unsigned int quorum_object_handle); ++ ++ ++/* ++ * Library Handler Definition ++ */ ++static struct corosync_lib_handler quorum_lib_service[] = ++{ ++ { /* 0 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_getinfo, ++ .response_size = sizeof (struct res_lib_votequorum_getinfo), ++ .response_id = MESSAGE_RES_VOTEQUORUM_GETINFO, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 1 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_setexpected, ++ .response_size = sizeof (struct res_lib_votequorum_status), ++ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 2 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_setvotes, ++ .response_size = sizeof (struct res_lib_votequorum_status), ++ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 3 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_qdisk_register, ++ .response_size = sizeof (struct res_lib_votequorum_status), ++ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 4 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_qdisk_unregister, ++ .response_size = sizeof (struct res_lib_votequorum_status), ++ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 5 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_qdisk_poll, ++ .response_size = sizeof (struct res_lib_votequorum_status), ++ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 6 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_qdisk_getinfo, ++ .response_size = sizeof (struct res_lib_votequorum_qdisk_getinfo), ++ .response_id = MESSAGE_RES_VOTEQUORUM_QDISK_GETINFO, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 7 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_setstate, ++ .response_size = sizeof (struct res_lib_votequorum_status), ++ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 8 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_leaving, ++ .response_size = sizeof (struct res_lib_votequorum_status), ++ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 9 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_trackstart, ++ .response_size = sizeof (struct res_lib_votequorum_status), ++ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ }, ++ { /* 10 */ ++ .lib_handler_fn = message_handler_req_lib_votequorum_trackstop, ++ .response_size = sizeof (struct res_lib_votequorum_status), ++ .response_id = MESSAGE_RES_VOTEQUORUM_STATUS, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED ++ } ++}; ++ ++static quorum_set_quorate_fn_t set_quorum; ++/* ++ * lcrso object definition ++ */ ++static struct quorum_services_api_ver1 votequorum_iface_ver0 = { ++ .init = votequorum_init ++}; ++ ++static struct corosync_service_engine quorum_service_handler = { ++ .name = "corosync votes quorum service v0.90", ++ .id = VOTEQUORUM_SERVICE, ++ .private_data_size = sizeof (struct quorum_pd), ++ .allow_inquorate = CS_LIB_ALLOW_INQUORATE, ++ .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED, ++ .lib_init_fn = quorum_lib_init_fn, ++ .lib_exit_fn = quorum_lib_exit_fn, ++ .lib_engine = quorum_lib_service, ++ .lib_engine_count = sizeof (quorum_lib_service) / sizeof (struct corosync_lib_handler), ++ .exec_init_fn = votequorum_exec_init_fn, ++ .exec_engine = NULL, ++ .exec_engine_count = 0, ++ .confchg_fn = NULL, ++}; ++ ++/* ++ * Dynamic loader definition ++ */ ++static struct corosync_service_engine *quorum_get_service_handler_ver0 (void); ++ ++static struct corosync_service_engine_iface_ver0 quorum_service_handler_iface = { ++ .corosync_get_service_engine_ver0 = quorum_get_service_handler_ver0 ++}; ++ ++static struct lcr_iface corosync_quorum_ver0[2] = { ++ { ++ .name = "corosync_votequorum", ++ .version = 0, ++ .versions_replace = 0, ++ .versions_replace_count = 0, ++ .dependencies = 0, ++ .dependency_count = 0, ++ .constructor = NULL, ++ .destructor = NULL, ++ .interfaces = (void **)(void *)&votequorum_iface_ver0 ++ }, ++ { ++ .name = "corosync_votequorum_iface", ++ .version = 0, ++ .versions_replace = 0, ++ .versions_replace_count = 0, ++ .dependencies = 0, ++ .dependency_count = 0, ++ .constructor = NULL, ++ .destructor = NULL, ++ .interfaces = NULL ++ } ++}; ++ ++static struct lcr_comp quorum_comp_ver0 = { ++ .iface_count = 2, ++ .ifaces = corosync_quorum_ver0 ++}; ++ ++ ++static struct corosync_service_engine *quorum_get_service_handler_ver0 (void) ++{ ++ return (&quorum_service_handler); ++} ++ ++__attribute__ ((constructor)) static void quorum_comp_register (void) { ++ lcr_interfaces_set (&corosync_quorum_ver0[0], &votequorum_iface_ver0); ++ lcr_interfaces_set (&corosync_quorum_ver0[1], &quorum_service_handler_iface); ++ lcr_component_register (&quorum_comp_ver0); ++} ++ ++static void votequorum_init(struct corosync_api_v1 *api, ++ quorum_set_quorate_fn_t report) ++{ ++ ENTER(); ++ set_quorum = report; ++ ++ /* Load the library-servicing part of this module */ ++ api->service_link_and_init(api, "corosync_votequorum_iface", 0); ++ ++ LEAVE(); ++} ++ ++/* Message types */ ++#define VOTEQUORUM_MSG_NODEINFO 5 ++#define VOTEQUORUM_MSG_KILLNODE 6 ++#define VOTEQUORUM_MSG_RECONFIGURE 8 ++ ++struct req_exec_quorum_nodeinfo { ++ unsigned char cmd; ++ unsigned char first_trans; ++ unsigned int votes; ++ unsigned int expected_votes; ++ ++ unsigned int major_version; /* Not backwards compatible */ ++ unsigned int minor_version; /* Backwards compatible */ ++ unsigned int patch_version; /* Backwards/forwards compatible */ ++ unsigned int config_version; ++ unsigned int flags; ++ ++} __attribute__((packed)); ++ ++/* Parameters for RECONFIG command */ ++#define RECONFIG_PARAM_EXPECTED_VOTES 1 ++#define RECONFIG_PARAM_NODE_VOTES 2 ++#define RECONFIG_PARAM_LEAVING 3 ++ ++struct req_exec_quorum_reconfigure { ++ unsigned char cmd; ++ unsigned char param; ++ unsigned short pad; ++ int nodeid; ++ unsigned int value; ++}; ++ ++struct req_exec_quorum_killnode { ++ unsigned char cmd; ++ unsigned char pad1; ++ uint16_t reason; ++ int nodeid; ++}; ++ ++/* These just make the access a little neater */ ++static inline int objdb_get_string(struct corosync_api_v1 *corosync, unsigned int object_service_handle, ++ char *key, char **value) ++{ ++ int res; ++ ++ *value = NULL; ++ if ( !(res = corosync_api->object_key_get(object_service_handle, ++ key, ++ strlen(key), ++ (void *)value, ++ NULL))) { ++ if (*value) ++ return 0; ++ } ++ return -1; ++} ++ ++static inline void objdb_get_int(struct corosync_api_v1 *corosync, unsigned int object_service_handle, ++ char *key, unsigned int *intvalue, unsigned int default_value) ++{ ++ char *value = NULL; ++ ++ *intvalue = default_value; ++ ++ if (!corosync_api->object_key_get(object_service_handle, key, strlen(key), ++ (void *)&value, NULL)) { ++ if (value) { ++ *intvalue = atoi(value); ++ } ++ } ++} ++ ++static int votequorum_send_message(void *message, int len) ++{ ++ struct iovec iov[2]; ++ struct q_protheader header; ++ ++ header.tgtport = 0; ++ header.srcport = 0; ++ header.flags = 0; ++ header.srcid = us->node_id; ++ header.tgtid = 0; ++ ++ iov[0].iov_base = &header; ++ iov[0].iov_len = sizeof(header); ++ iov[1].iov_base = message; ++ iov[1].iov_len = len; ++ ++ return corosync_api->tpg_joined_mcast(group_handle, iov, 2, TOTEM_AGREED); ++} ++ ++static void read_quorum_config(unsigned int quorum_handle) ++{ ++ unsigned int value = 0; ++ int cluster_members = 0; ++ struct list_head *tmp; ++ struct cluster_node *node; ++ ++ log_printf(LOG_INFO, "Reading configuration\n"); ++ ++ objdb_get_int(corosync_api, quorum_handle, "expected_votes", &us->expected_votes, DEFAULT_EXPECTED); ++ objdb_get_int(corosync_api, quorum_handle, "votes", &us->votes, 1); ++ objdb_get_int(corosync_api, quorum_handle, "quorumdev_poll", &quorumdev_poll, DEFAULT_QDEV_POLL); ++ objdb_get_int(corosync_api, quorum_handle, "disallowed", &value, 0); ++ if (value) ++ quorum_flags |= VOTEQUORUM_FLAG_FEATURE_DISALLOWED; ++ else ++ quorum_flags &= ~VOTEQUORUM_FLAG_FEATURE_DISALLOWED; ++ ++ objdb_get_int(corosync_api, quorum_handle, "two_node", &value, 0); ++ if (value) ++ quorum_flags |= VOTEQUORUM_FLAG_FEATURE_TWONODE; ++ else ++ quorum_flags &= ~VOTEQUORUM_FLAG_FEATURE_TWONODE; ++ ++ /* ++ * two_node mode is invalid if there are more than 2 nodes in the cluster! ++ */ ++ list_iterate(tmp, &cluster_members_list) { ++ node = list_entry(tmp, struct cluster_node, list); ++ cluster_members++; ++ } ++ ++ if (quorum_flags & VOTEQUORUM_FLAG_FEATURE_TWONODE && cluster_members > 2) { ++ log_printf(LOG_WARNING, "quorum.two_node was set but there are more than 2 nodes in the cluster. It will be ignored."); ++ quorum_flags &= ~VOTEQUORUM_FLAG_FEATURE_TWONODE; ++ } ++} ++ ++static int votequorum_exec_init_fn (struct corosync_api_v1 *api) ++{ ++ unsigned int object_handle; ++ unsigned int find_handle; ++ ++ ENTER(); ++ ++ corosync_api = api; ++ ++ list_init(&cluster_members_list); ++ list_init(&trackers_list); ++ ++ /* Allocate a cluster_node for us */ ++ us = allocate_node(corosync_api->totem_nodeid_get()); ++ if (!us) ++ return (1); ++ ++ us->flags |= NODE_FLAGS_US; ++ us->state = NODESTATE_MEMBER; ++ us->expected_votes = DEFAULT_EXPECTED; ++ us->votes = 1; ++ time(&us->join_time); ++ ++ /* Get configuration variables */ ++ corosync_api->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle); ++ ++ if (corosync_api->object_find_next(find_handle, &object_handle) == 0) { ++ read_quorum_config(object_handle); ++ } ++ /* Listen for changes */ ++ add_votequorum_config_notification(object_handle); ++ corosync_api->object_find_destroy(find_handle); ++ ++ api->tpg_init(&group_handle, quorum_deliver_fn, quorum_confchg_fn); ++ api->tpg_join(group_handle, quorum_group, 1); ++ ++ LEAVE(); ++ return (0); ++} ++ ++static int quorum_lib_exit_fn (void *conn) ++{ ++ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); ++ ++ ENTER(); ++ if (quorum_pd->tracking_enabled) { ++ list_del (&quorum_pd->list); ++ list_init (&quorum_pd->list); ++ } ++ LEAVE(); ++ return (0); ++} ++ ++ ++static int send_quorum_notification(void *conn, uint64_t context) ++{ ++ struct res_lib_votequorum_notification *res_lib_votequorum_notification; ++ struct list_head *tmp; ++ struct cluster_node *node; ++ int cluster_members = 0; ++ int i = 0; ++ int size; ++ char *buf; ++ ++ ENTER(); ++ list_iterate(tmp, &cluster_members_list) { ++ node = list_entry(tmp, struct cluster_node, list); ++ cluster_members++; ++ } ++ if (quorum_device) ++ cluster_members++; ++ ++ size = sizeof(struct res_lib_votequorum_notification) + sizeof(struct votequorum_node) * cluster_members; ++ buf = alloca(size); ++ if (!buf) { ++ LEAVE(); ++ return -1; ++ } ++ ++ res_lib_votequorum_notification = (struct res_lib_votequorum_notification *)buf; ++ res_lib_votequorum_notification->quorate = cluster_is_quorate; ++ res_lib_votequorum_notification->node_list_entries = cluster_members; ++ res_lib_votequorum_notification->context = context; ++ list_iterate(tmp, &cluster_members_list) { ++ node = list_entry(tmp, struct cluster_node, list); ++ res_lib_votequorum_notification->node_list[i].nodeid = node->node_id; ++ res_lib_votequorum_notification->node_list[i++].state = node->state; ++ } ++ if (quorum_device) { ++ res_lib_votequorum_notification->node_list[i].nodeid = 0; ++ res_lib_votequorum_notification->node_list[i++].state = quorum_device->state | 0x80; ++ } ++ res_lib_votequorum_notification->header.id = MESSAGE_RES_VOTEQUORUM_NOTIFICATION; ++ res_lib_votequorum_notification->header.size = size; ++ res_lib_votequorum_notification->header.error = CS_OK; ++ ++ /* Send it to all interested parties */ ++ if (conn) { ++ int ret = corosync_api->ipc_conn_send_response(conn, buf, size); ++ LEAVE(); ++ return ret; ++ } ++ else { ++ struct quorum_pd *qpd; ++ ++ list_iterate(tmp, &trackers_list) { ++ qpd = list_entry(tmp, struct quorum_pd, list); ++ res_lib_votequorum_notification->context = qpd->tracking_context; ++ corosync_api->ipc_conn_send_response(corosync_api->ipc_conn_partner_get(qpd->conn), buf, size); ++ } ++ } ++ LEAVE(); ++ return 0; ++} ++ ++static void set_quorate(int total_votes) ++{ ++ int quorate; ++ ++ ENTER(); ++ if (quorum > total_votes) { ++ quorate = 0; ++ } ++ else { ++ quorate = 1; ++ } ++ ++ if (cluster_is_quorate && !quorate) ++ log_printf(LOG_INFO, "quorum lost, blocking activity\n"); ++ if (!cluster_is_quorate && quorate) ++ log_printf(LOG_INFO, "quorum regained, resuming activity\n"); ++ ++ /* If we are newly quorate, then kill any DISALLOWED nodes */ ++ if (!cluster_is_quorate && quorate) { ++ struct cluster_node *node = NULL; ++ struct list_head *tmp; ++ ++ list_iterate(tmp, &cluster_members_list) { ++ node = list_entry(tmp, struct cluster_node, list); ++ if (node->state == NODESTATE_DISALLOWED) ++ quorum_exec_send_killnode(node->node_id, VOTEQUORUM_REASON_KILL_REJOIN); ++ } ++ } ++ ++ cluster_is_quorate = quorate; ++ set_quorum(quorum_members, quorum_members_entries, quorate, &quorum_ringid); ++ ENTER(); ++} ++ ++static int calculate_quorum(int allow_decrease, int max_expected, unsigned int *ret_total_votes) ++{ ++ struct list_head *nodelist; ++ struct cluster_node *node; ++ unsigned int total_votes = 0; ++ unsigned int highest_expected = 0; ++ unsigned int newquorum, q1, q2; ++ unsigned int total_nodes = 0; ++ unsigned int leaving = 0; ++ ++ ENTER(); ++ list_iterate(nodelist, &cluster_members_list) { ++ node = list_entry(nodelist, struct cluster_node, list); ++ ++ log_printf(LOG_DEBUG, "node %x state=%d, votes=%d, expected=%d\n", ++ node->node_id, node->state, node->votes, node->expected_votes); ++ ++ if (node->state == NODESTATE_MEMBER) { ++ if (max_expected) ++ node->expected_votes = max_expected; ++ else ++ highest_expected = max(highest_expected, node->expected_votes); ++ total_votes += node->votes; ++ total_nodes++; ++ } ++ if (node->state == NODESTATE_LEAVING) { ++ leaving = 1; ++ } ++ } ++ ++ if (quorum_device && quorum_device->state == NODESTATE_MEMBER) ++ total_votes += quorum_device->votes; ++ ++ if (max_expected > 0) ++ highest_expected = max_expected; ++ ++ /* This quorum calculation is taken from the OpenVMS Cluster Systems ++ * manual, but, then, you guessed that didn't you */ ++ q1 = (highest_expected + 2) / 2; ++ q2 = (total_votes + 2) / 2; ++ newquorum = max(q1, q2); ++ ++ /* Normally quorum never decreases but the system administrator can ++ * force it down by setting expected votes to a maximum value */ ++ if (!allow_decrease) ++ newquorum = max(quorum, newquorum); ++ ++ /* The special two_node mode allows each of the two nodes to retain ++ * quorum if the other fails. Only one of the two should live past ++ * fencing (as both nodes try to fence each other in split-brain.) ++ * Also: if there are more than two nodes, force us inquorate to avoid ++ * any damage or confusion. ++ */ ++ if ((quorum_flags & VOTEQUORUM_FLAG_FEATURE_TWONODE) && total_nodes <= 2) ++ newquorum = 1; ++ ++ if (ret_total_votes) ++ *ret_total_votes = total_votes; ++ ++ LEAVE(); ++ return newquorum; ++} ++ ++/* Recalculate cluster quorum, set quorate and notify changes */ ++static void recalculate_quorum(int allow_decrease) ++{ ++ unsigned int total_votes; ++ ++ ENTER(); ++ quorum = calculate_quorum(allow_decrease, 0, &total_votes); ++ set_quorate(total_votes); ++ send_quorum_notification(NULL, 0L); ++ LEAVE(); ++} ++ ++static int have_disallowed(void) ++{ ++ struct cluster_node *node; ++ struct list_head *tmp; ++ ++ list_iterate(tmp, &cluster_members_list) { ++ node = list_entry(tmp, struct cluster_node, list); ++ if (node->state == NODESTATE_DISALLOWED) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static void node_add_ordered(struct cluster_node *newnode) ++{ ++ struct cluster_node *node = NULL; ++ struct list_head *tmp; ++ struct list_head *newlist = &newnode->list; ++ ++ list_iterate(tmp, &cluster_members_list) { ++ node = list_entry(tmp, struct cluster_node, list); ++ ++ if (newnode->node_id < node->node_id) ++ break; ++ } ++ ++ if (!node) ++ list_add(&newnode->list, &cluster_members_list); ++ else { ++ newlist->prev = tmp->prev; ++ newlist->next = tmp; ++ tmp->prev->next = newlist; ++ tmp->prev = newlist; ++ } ++} ++ ++static struct cluster_node *allocate_node(int nodeid) ++{ ++ struct cluster_node *cl; ++ ++ cl = malloc(sizeof(struct cluster_node)); ++ if (cl) { ++ memset(cl, 0, sizeof(struct cluster_node)); ++ cl->node_id = nodeid; ++ if (nodeid) ++ node_add_ordered(cl); ++ } ++ return cl; ++} ++ ++static struct cluster_node *find_node_by_nodeid(int nodeid) ++{ ++ struct cluster_node *node; ++ struct list_head *tmp; ++ ++ list_iterate(tmp, &cluster_members_list) { ++ node = list_entry(tmp, struct cluster_node, list); ++ if (node->node_id == nodeid) ++ return node; ++ } ++ return NULL; ++} ++ ++ ++static int quorum_exec_send_nodeinfo() ++{ ++ struct req_exec_quorum_nodeinfo req_exec_quorum_nodeinfo; ++ int ret; ++ ++ ENTER(); ++ ++ req_exec_quorum_nodeinfo.cmd = VOTEQUORUM_MSG_NODEINFO; ++ req_exec_quorum_nodeinfo.expected_votes = us->expected_votes; ++ req_exec_quorum_nodeinfo.votes = us->votes; ++ req_exec_quorum_nodeinfo.major_version = VOTEQUORUM_MAJOR_VERSION; ++ req_exec_quorum_nodeinfo.minor_version = VOTEQUORUM_MINOR_VERSION; ++ req_exec_quorum_nodeinfo.patch_version = VOTEQUORUM_PATCH_VERSION; ++ req_exec_quorum_nodeinfo.flags = us->flags; ++ req_exec_quorum_nodeinfo.first_trans = first_trans; ++ if (have_disallowed()) ++ req_exec_quorum_nodeinfo.flags |= NODE_FLAGS_SEESDISALLOWED; ++ ++ ret = votequorum_send_message(&req_exec_quorum_nodeinfo, sizeof(req_exec_quorum_nodeinfo)); ++ LEAVE(); ++ return ret; ++} ++ ++ ++static int quorum_exec_send_reconfigure(int param, int nodeid, int value) ++{ ++ struct req_exec_quorum_reconfigure req_exec_quorum_reconfigure; ++ int ret; ++ ++ ENTER(); ++ ++ req_exec_quorum_reconfigure.cmd = VOTEQUORUM_MSG_RECONFIGURE; ++ req_exec_quorum_reconfigure.param = param; ++ req_exec_quorum_reconfigure.nodeid = nodeid; ++ req_exec_quorum_reconfigure.value = value; ++ ++ ret = votequorum_send_message(&req_exec_quorum_reconfigure, sizeof(req_exec_quorum_reconfigure)); ++ LEAVE(); ++ return ret; ++} ++ ++static int quorum_exec_send_killnode(int nodeid, unsigned int reason) ++{ ++ struct req_exec_quorum_killnode req_exec_quorum_killnode; ++ int ret; ++ ++ ENTER(); ++ ++ req_exec_quorum_killnode.cmd = VOTEQUORUM_MSG_KILLNODE; ++ req_exec_quorum_killnode.nodeid = nodeid; ++ req_exec_quorum_killnode.reason = reason; ++ ++ ret = votequorum_send_message(&req_exec_quorum_killnode, sizeof(req_exec_quorum_killnode)); ++ LEAVE(); ++ return ret; ++} ++ ++static void quorum_confchg_fn ( ++ enum totem_configuration_type configuration_type, ++ unsigned int *member_list, int member_list_entries, ++ unsigned int *left_list, int left_list_entries, ++ unsigned int *joined_list, int joined_list_entries, ++ struct memb_ring_id *ring_id) ++{ ++ int i; ++ int leaving = 0; ++ struct cluster_node *node; ++ ++ ENTER(); ++ if (member_list_entries > 1) ++ first_trans = 0; ++ ++ if (left_list_entries) { ++ for (i = 0; i< left_list_entries; i++) { ++ node = find_node_by_nodeid(left_list[i]); ++ if (node) { ++ if (node->state == NODESTATE_LEAVING) ++ leaving = 1; ++ node->state = NODESTATE_DEAD; ++ node->flags |= NODE_FLAGS_BEENDOWN; ++ } ++ } ++ recalculate_quorum(leaving); ++ } ++ ++ if (member_list_entries) { ++ memcpy(quorum_members, member_list, sizeof(unsigned int) * member_list_entries); ++ quorum_members_entries = member_list_entries; ++ if (quorum_device) { ++ quorum_members[quorum_members_entries++] = 0; ++ } ++ quorum_exec_send_nodeinfo(); ++ } ++ ++ memcpy(&quorum_ringid, ring_id, sizeof(*ring_id)); ++ LEAVE(); ++} ++ ++static void exec_quorum_nodeinfo_endian_convert (void *msg) ++{ ++ struct req_exec_quorum_nodeinfo *nodeinfo = (struct req_exec_quorum_nodeinfo *)msg; ++ ++ nodeinfo->votes = swab32(nodeinfo->votes); ++ nodeinfo->expected_votes = swab32(nodeinfo->expected_votes); ++ nodeinfo->major_version = swab32(nodeinfo->major_version); ++ nodeinfo->minor_version = swab32(nodeinfo->minor_version); ++ nodeinfo->patch_version = swab32(nodeinfo->patch_version); ++ nodeinfo->config_version = swab32(nodeinfo->config_version); ++ nodeinfo->flags = swab32(nodeinfo->flags); ++} ++ ++static void exec_quorum_reconfigure_endian_convert (void *msg) ++{ ++ struct req_exec_quorum_reconfigure *reconfigure = (struct req_exec_quorum_reconfigure *)msg; ++ reconfigure->nodeid = swab32(reconfigure->nodeid); ++ reconfigure->value = swab32(reconfigure->value); ++} ++ ++static void exec_quorum_killnode_endian_convert (void *msg) ++{ ++ struct req_exec_quorum_killnode *killnode = (struct req_exec_quorum_killnode *)msg; ++ killnode->reason = swab16(killnode->reason); ++ killnode->nodeid = swab32(killnode->nodeid); ++} ++ ++static void quorum_deliver_fn(unsigned int nodeid, struct iovec *iovec, int iov_len, ++ int endian_conversion_required) ++{ ++ struct q_protheader *header = iovec->iov_base; ++ char *buf; ++ ++ ENTER(); ++ ++ if (endian_conversion_required) { ++ header->srcid = swab32(header->srcid); ++ header->tgtid = swab32(header->tgtid); ++ header->flags = swab32(header->flags); ++ } ++ ++ /* Only pass on messages for us or everyone */ ++ if (header->tgtport == 0 && ++ (header->tgtid == us->node_id || ++ header->tgtid == 0)) { ++ buf = iovec->iov_base + sizeof(struct q_protheader); ++ switch (*buf) { ++ ++ case VOTEQUORUM_MSG_NODEINFO: ++ if (endian_conversion_required) ++ exec_quorum_nodeinfo_endian_convert(buf); ++ message_handler_req_exec_quorum_nodeinfo (buf, header->srcid); ++ break; ++ case VOTEQUORUM_MSG_RECONFIGURE: ++ if (endian_conversion_required) ++ exec_quorum_reconfigure_endian_convert(buf); ++ message_handler_req_exec_quorum_reconfigure (buf, header->srcid); ++ break; ++ case VOTEQUORUM_MSG_KILLNODE: ++ if (endian_conversion_required) ++ exec_quorum_killnode_endian_convert(buf); ++ message_handler_req_exec_quorum_killnode (buf, header->srcid); ++ break; ++ ++ /* Just ignore other messages */ ++ } ++ } ++ LEAVE(); ++} ++ ++static void message_handler_req_exec_quorum_nodeinfo ( ++ void *message, ++ unsigned int nodeid) ++{ ++ struct req_exec_quorum_nodeinfo *req_exec_quorum_nodeinfo = (struct req_exec_quorum_nodeinfo *)message; ++ struct cluster_node *node; ++ int old_votes; ++ int old_expected; ++ nodestate_t old_state; ++ int new_node = 0; ++ ++ ENTER(); ++ log_printf(LOG_LEVEL_DEBUG, "got nodeinfo message from cluster node %d\n", nodeid); ++ ++ node = find_node_by_nodeid(nodeid); ++ if (!node) { ++ node = allocate_node(nodeid); ++ new_node = 1; ++ } ++ if (!node) { ++ corosync_api->error_memory_failure(); ++ return; ++ } ++ ++ /* ++ * If the node sending the message sees disallowed nodes and we don't, then ++ * we have to leave ++ */ ++ if (req_exec_quorum_nodeinfo->flags & NODE_FLAGS_SEESDISALLOWED && !have_disallowed()) { ++ /* Must use syslog directly here or the message will never arrive */ ++ syslog(LOG_CRIT, "[VOTEQ]: Joined a cluster with disallowed nodes. must die"); ++ corosync_api->fatal_error(2, __FILE__, __LINE__); ++ exit(2); ++ } ++ old_votes = node->votes; ++ old_expected = node->expected_votes; ++ old_state = node->state; ++ ++ /* Update node state */ ++ if (req_exec_quorum_nodeinfo->minor_version >= 2) ++ node->votes = req_exec_quorum_nodeinfo->votes; ++ node->expected_votes = req_exec_quorum_nodeinfo->expected_votes; ++ node->state = NODESTATE_MEMBER; ++ ++ /* Check flags for disallowed (if enabled) */ ++ if (quorum_flags & VOTEQUORUM_FLAG_FEATURE_DISALLOWED) { ++ if ((req_exec_quorum_nodeinfo->flags & NODE_FLAGS_HASSTATE && node->flags & NODE_FLAGS_BEENDOWN) || ++ (req_exec_quorum_nodeinfo->flags & NODE_FLAGS_HASSTATE && req_exec_quorum_nodeinfo->first_trans && !(node->flags & NODE_FLAGS_US))) { ++ if (node->state != NODESTATE_DISALLOWED) { ++ if (cluster_is_quorate) { ++ log_printf(LOG_CRIT, "Killing node %d because it has rejoined the cluster with existing state", node->node_id); ++ node->state = NODESTATE_DISALLOWED; ++ quorum_exec_send_killnode(nodeid, VOTEQUORUM_REASON_KILL_REJOIN); ++ } ++ else { ++ log_printf(LOG_CRIT, "Node %d not joined to quorum because it has existing state", node->node_id); ++ node->state = NODESTATE_DISALLOWED; ++ } ++ } ++ } ++ } ++ node->flags &= ~NODE_FLAGS_BEENDOWN; ++ ++ if (new_node || old_votes != node->votes || old_expected != node->expected_votes || old_state != node->state) ++ recalculate_quorum(0); ++ LEAVE(); ++} ++ ++static void message_handler_req_exec_quorum_killnode ( ++ void *message, ++ unsigned int nodeid) ++{ ++ struct req_exec_quorum_killnode *req_exec_quorum_killnode = (struct req_exec_quorum_killnode *)message; ++ ++ if (req_exec_quorum_killnode->nodeid == corosync_api->totem_nodeid_get()) { ++ log_printf(LOG_CRIT, "Killed by node %d: %s\n", nodeid, kill_reason(req_exec_quorum_killnode->reason)); ++ ++ corosync_api->fatal_error(1, __FILE__, __LINE__); ++ exit(1); ++ } ++} ++ ++static void message_handler_req_exec_quorum_reconfigure ( ++ void *message, ++ unsigned int nodeid) ++{ ++ struct req_exec_quorum_reconfigure *req_exec_quorum_reconfigure = (struct req_exec_quorum_reconfigure *)message; ++ struct cluster_node *node; ++ struct list_head *nodelist; ++ ++ log_printf(LOG_LEVEL_DEBUG, "got reconfigure message from cluster node %d\n", nodeid); ++ ++ node = find_node_by_nodeid(req_exec_quorum_reconfigure->nodeid); ++ if (!node) ++ return; ++ ++ switch(req_exec_quorum_reconfigure->param) ++ { ++ case RECONFIG_PARAM_EXPECTED_VOTES: ++ node->expected_votes = req_exec_quorum_reconfigure->value; ++ ++ list_iterate(nodelist, &cluster_members_list) { ++ node = list_entry(nodelist, struct cluster_node, list); ++ if (node->state == NODESTATE_MEMBER && ++ node->expected_votes > req_exec_quorum_reconfigure->value) { ++ node->expected_votes = req_exec_quorum_reconfigure->value; ++ } ++ } ++ recalculate_quorum(1); /* Allow decrease */ ++ break; ++ ++ case RECONFIG_PARAM_NODE_VOTES: ++ node->votes = req_exec_quorum_reconfigure->value; ++ recalculate_quorum(1); /* Allow decrease */ ++ break; ++ ++ case RECONFIG_PARAM_LEAVING: ++ node->state = NODESTATE_LEAVING; ++ break; ++ } ++} ++ ++static int quorum_lib_init_fn (void *conn) ++{ ++ struct quorum_pd *pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); ++ ++ ENTER(); ++ ++ list_init (&pd->list); ++ pd->conn = conn; ++ ++ LEAVE(); ++ return (0); ++} ++ ++/* Message from the library */ ++static void message_handler_req_lib_votequorum_getinfo (void *conn, void *message) ++{ ++ struct req_lib_votequorum_getinfo *req_lib_votequorum_getinfo = (struct req_lib_votequorum_getinfo *)message; ++ struct res_lib_votequorum_getinfo res_lib_votequorum_getinfo; ++ struct cluster_node *node; ++ unsigned int highest_expected = 0; ++ unsigned int total_votes = 0; ++ cs_error_t error = CS_OK; ++ ++ log_printf(LOG_LEVEL_DEBUG, "got getinfo request on %p for node %d\n", conn, req_lib_votequorum_getinfo->nodeid); ++ ++ if (req_lib_votequorum_getinfo->nodeid) { ++ node = find_node_by_nodeid(req_lib_votequorum_getinfo->nodeid); ++ } ++ else { ++ node = us; ++ } ++ ++ if (node) { ++ struct cluster_node *iternode; ++ struct list_head *nodelist; ++ ++ list_iterate(nodelist, &cluster_members_list) { ++ iternode = list_entry(nodelist, struct cluster_node, list); ++ ++ if (iternode->state == NODESTATE_MEMBER) { ++ highest_expected = ++ max(highest_expected, iternode->expected_votes); ++ total_votes += iternode->votes; ++ } ++ } ++ ++ if (quorum_device && quorum_device->state == NODESTATE_MEMBER) { ++ total_votes += quorum_device->votes; ++ } ++ ++ res_lib_votequorum_getinfo.votes = us->votes; ++ res_lib_votequorum_getinfo.expected_votes = us->expected_votes; ++ res_lib_votequorum_getinfo.highest_expected = highest_expected; ++ ++ res_lib_votequorum_getinfo.quorum = quorum; ++ res_lib_votequorum_getinfo.total_votes = total_votes; ++ res_lib_votequorum_getinfo.flags = 0; ++ res_lib_votequorum_getinfo.nodeid = node->node_id; ++ ++ if (us->flags & NODE_FLAGS_HASSTATE) ++ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_FLAG_HASSTATE; ++ if (quorum_flags & VOTEQUORUM_FLAG_FEATURE_TWONODE) ++ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_FLAG_TWONODE; ++ if (cluster_is_quorate) ++ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_FLAG_QUORATE; ++ if (us->flags & NODE_FLAGS_SEESDISALLOWED) ++ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_FLAG_DISALLOWED; ++ } ++ else { ++ error = CS_ERR_NOT_EXIST; ++ } ++ ++ res_lib_votequorum_getinfo.header.size = sizeof(res_lib_votequorum_getinfo); ++ res_lib_votequorum_getinfo.header.id = MESSAGE_RES_VOTEQUORUM_GETINFO; ++ res_lib_votequorum_getinfo.header.error = error; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_getinfo, sizeof(res_lib_votequorum_getinfo)); ++ log_printf(LOG_LEVEL_DEBUG, "getinfo response error: %d\n", error); ++} ++ ++/* Message from the library */ ++static void message_handler_req_lib_votequorum_setexpected (void *conn, void *message) ++{ ++ struct req_lib_votequorum_setexpected *req_lib_votequorum_setexpected = (struct req_lib_votequorum_setexpected *)message; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ cs_error_t error = CS_OK; ++ unsigned int newquorum; ++ unsigned int total_votes; ++ ++ ENTER(); ++ ++ /* ++ * If there are disallowed nodes, then we can't allow the user ++ * to bypass them by fiddling with expected votes. ++ */ ++ if (quorum_flags & VOTEQUORUM_FLAG_FEATURE_DISALLOWED && have_disallowed()) { ++ error = CS_ERR_EXIST; ++ goto error_exit; ++ } ++ ++ /* Validate new expected votes */ ++ newquorum = calculate_quorum(1, req_lib_votequorum_setexpected->expected_votes, &total_votes); ++ if (newquorum < total_votes / 2 ++ || newquorum > total_votes) { ++ error = CS_ERR_INVALID_PARAM; ++ goto error_exit; ++ } ++ ++ quorum_exec_send_reconfigure(RECONFIG_PARAM_EXPECTED_VOTES, us->node_id, req_lib_votequorum_setexpected->expected_votes); ++ ++ /* send status */ ++error_exit: ++ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); ++ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; ++ res_lib_votequorum_status.header.error = error; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); ++ LEAVE(); ++} ++ ++/* Message from the library */ ++static void message_handler_req_lib_votequorum_setvotes (void *conn, void *message) ++{ ++ struct req_lib_votequorum_setvotes *req_lib_votequorum_setvotes = (struct req_lib_votequorum_setvotes *)message; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ struct cluster_node *node; ++ unsigned int newquorum; ++ unsigned int total_votes; ++ unsigned int saved_votes; ++ cs_error_t error = CS_OK; ++ ++ ENTER(); ++ ++ node = find_node_by_nodeid(req_lib_votequorum_setvotes->nodeid); ++ if (!node) { ++ error = CS_ERR_NAME_NOT_FOUND; ++ goto error_exit; ++ } ++ ++ /* Check votes is valid */ ++ saved_votes = node->votes; ++ node->votes = req_lib_votequorum_setvotes->votes; ++ ++ newquorum = calculate_quorum(1, 0, &total_votes); ++ ++ if (newquorum < total_votes / 2 || newquorum > total_votes) { ++ node->votes = saved_votes; ++ error = CS_ERR_INVALID_PARAM; ++ goto error_exit; ++ } ++ ++ if (!req_lib_votequorum_setvotes->nodeid) ++ req_lib_votequorum_setvotes->nodeid = corosync_api->totem_nodeid_get(); ++ ++ quorum_exec_send_reconfigure(RECONFIG_PARAM_NODE_VOTES, req_lib_votequorum_setvotes->nodeid, req_lib_votequorum_setvotes->votes); ++ ++error_exit: ++ /* send status */ ++ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); ++ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; ++ res_lib_votequorum_status.header.error = error; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); ++ LEAVE(); ++} ++ ++static void message_handler_req_lib_votequorum_leaving (void *conn, void *message) ++{ ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ cs_error_t error = CS_OK; ++ ++ ENTER(); ++ ++ quorum_exec_send_reconfigure(RECONFIG_PARAM_LEAVING, us->node_id, 0); ++ ++ /* send status */ ++ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); ++ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; ++ res_lib_votequorum_status.header.error = error; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); ++ LEAVE(); ++} ++ ++static void quorum_device_timer_fn(void *arg) ++{ ++ struct timeval now; ++ ++ ENTER(); ++ if (!quorum_device || quorum_device->state == NODESTATE_DEAD) ++ return; ++ gettimeofday(&now, NULL); ++ if (quorum_device->last_hello.tv_sec + quorumdev_poll/1000 < now.tv_sec) { ++ quorum_device->state = NODESTATE_DEAD; ++ log_printf(LOG_INFO, "lost contact with quorum device\n"); ++ recalculate_quorum(0); ++ } ++ else { ++ corosync_api->timer_add_duration((unsigned long long)quorumdev_poll*1000000, quorum_device, ++ quorum_device_timer_fn, &quorum_device_timer); ++ } ++ LEAVE(); ++} ++ ++ ++static void message_handler_req_lib_votequorum_qdisk_register (void *conn, void *message) ++{ ++ struct req_lib_votequorum_qdisk_register *req_lib_votequorum_qdisk_register = (struct req_lib_votequorum_qdisk_register *)message; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ cs_error_t error = CS_OK; ++ ++ ENTER(); ++ ++ if (quorum_device) { ++ error = CS_ERR_EXIST; ++ } ++ else { ++ quorum_device = allocate_node(0); ++ quorum_device->state = NODESTATE_DEAD; ++ quorum_device->votes = req_lib_votequorum_qdisk_register->votes; ++ strcpy(quorum_device_name, req_lib_votequorum_qdisk_register->name); ++ list_add(&quorum_device->list, &cluster_members_list); ++ } ++ ++ /* send status */ ++ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); ++ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; ++ res_lib_votequorum_status.header.error = error; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); ++ LEAVE(); ++} ++ ++static void message_handler_req_lib_votequorum_qdisk_unregister (void *conn, void *message) ++{ ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ cs_error_t error = CS_OK; ++ ++ ENTER(); ++ ++ if (quorum_device) { ++ struct cluster_node *node = quorum_device; ++ ++ quorum_device = NULL; ++ list_del(&node->list); ++ free(node); ++ recalculate_quorum(0); ++ } ++ else { ++ error = CS_ERR_NOT_EXIST; ++ } ++ ++ /* send status */ ++ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); ++ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; ++ res_lib_votequorum_status.header.error = error; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); ++ LEAVE(); ++} ++ ++static void message_handler_req_lib_votequorum_qdisk_poll (void *conn, void *message) ++{ ++ struct req_lib_votequorum_qdisk_poll *req_lib_votequorum_qdisk_poll = (struct req_lib_votequorum_qdisk_poll *)message; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ cs_error_t error = CS_OK; ++ ++ ENTER(); ++ ++ if (quorum_device) { ++ if (req_lib_votequorum_qdisk_poll->state) { ++ gettimeofday(&quorum_device->last_hello, NULL); ++ if (quorum_device->state == NODESTATE_DEAD) { ++ quorum_device->state = NODESTATE_MEMBER; ++ recalculate_quorum(0); ++ ++ corosync_api->timer_add_duration((unsigned long long)quorumdev_poll*1000000, quorum_device, ++ quorum_device_timer_fn, &quorum_device_timer); ++ } ++ } ++ else { ++ if (quorum_device->state == NODESTATE_MEMBER) { ++ quorum_device->state = NODESTATE_DEAD; ++ recalculate_quorum(0); ++ corosync_api->timer_delete(quorum_device_timer); ++ } ++ } ++ } ++ else { ++ error = CS_ERR_NOT_EXIST; ++ } ++ ++ /* send status */ ++ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); ++ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; ++ res_lib_votequorum_status.header.error = error; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); ++ ++ LEAVE(); ++} ++ ++static void message_handler_req_lib_votequorum_qdisk_getinfo (void *conn, void *message) ++{ ++ struct res_lib_votequorum_qdisk_getinfo res_lib_votequorum_qdisk_getinfo; ++ cs_error_t error = CS_OK; ++ ++ ENTER(); ++ ++ if (quorum_device) { ++ log_printf(LOG_LEVEL_DEBUG, "got qdisk_getinfo state %d\n", quorum_device->state); ++ res_lib_votequorum_qdisk_getinfo.votes = quorum_device->votes; ++ if (quorum_device->state == NODESTATE_MEMBER) ++ res_lib_votequorum_qdisk_getinfo.state = 1; ++ else ++ res_lib_votequorum_qdisk_getinfo.state = 0; ++ strcpy(res_lib_votequorum_qdisk_getinfo.name, quorum_device_name); ++ } ++ else { ++ error = CS_ERR_NOT_EXIST; ++ } ++ ++ /* send status */ ++ res_lib_votequorum_qdisk_getinfo.header.size = sizeof(res_lib_votequorum_qdisk_getinfo); ++ res_lib_votequorum_qdisk_getinfo.header.id = MESSAGE_RES_VOTEQUORUM_GETINFO; ++ res_lib_votequorum_qdisk_getinfo.header.error = error; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_qdisk_getinfo, sizeof(res_lib_votequorum_qdisk_getinfo)); ++ ++ LEAVE(); ++} ++ ++static void message_handler_req_lib_votequorum_setstate (void *conn, void *message) ++{ ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ cs_error_t error = CS_OK; ++ ++ ENTER(); ++ ++ us->flags |= NODE_FLAGS_HASSTATE; ++ ++ /* send status */ ++ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); ++ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; ++ res_lib_votequorum_status.header.error = error; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); ++ ++ LEAVE(); ++} ++ ++static void message_handler_req_lib_votequorum_trackstart (void *conn, void *msg) ++{ ++ struct req_lib_votequorum_trackstart *req_lib_votequorum_trackstart = (struct req_lib_votequorum_trackstart *)msg; ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); ++ ++ ENTER(); ++ /* ++ * If an immediate listing of the current cluster membership ++ * is requested, generate membership list ++ */ ++ if (req_lib_votequorum_trackstart->track_flags & CS_TRACK_CURRENT || ++ req_lib_votequorum_trackstart->track_flags & CS_TRACK_CHANGES) { ++ log_printf(LOG_LEVEL_DEBUG, "sending initial status to %p\n", conn); ++ send_quorum_notification(corosync_api->ipc_conn_partner_get (conn), req_lib_votequorum_trackstart->context); ++ } ++ ++ /* ++ * Record requests for tracking ++ */ ++ if (req_lib_votequorum_trackstart->track_flags & CS_TRACK_CHANGES || ++ req_lib_votequorum_trackstart->track_flags & CS_TRACK_CHANGES_ONLY) { ++ ++ quorum_pd->track_flags = req_lib_votequorum_trackstart->track_flags; ++ quorum_pd->tracking_enabled = 1; ++ quorum_pd->tracking_context = req_lib_votequorum_trackstart->context; ++ ++ list_add (&quorum_pd->list, &trackers_list); ++ } ++ ++ /* Send status */ ++ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); ++ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; ++ res_lib_votequorum_status.header.error = CS_OK; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); ++ ++ LEAVE(); ++} ++ ++static void message_handler_req_lib_votequorum_trackstop (void *conn, void *msg) ++{ ++ struct res_lib_votequorum_status res_lib_votequorum_status; ++ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); ++ int error = CS_OK; ++ ++ ENTER(); ++ ++ if (quorum_pd->tracking_enabled) { ++ error = CS_OK; ++ quorum_pd->tracking_enabled = 0; ++ list_del (&quorum_pd->list); ++ list_init (&quorum_pd->list); ++ } else { ++ error = CS_ERR_NOT_EXIST; ++ } ++ ++ /* send status */ ++ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status); ++ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS; ++ res_lib_votequorum_status.header.error = error; ++ corosync_api->ipc_conn_send_response(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status)); ++ ++ LEAVE(); ++} ++ ++ ++static char *kill_reason(int reason) ++{ ++ static char msg[1024]; ++ ++ switch (reason) ++ { ++ case VOTEQUORUM_REASON_KILL_REJECTED: ++ return "our membership application was rejected"; ++ ++ case VOTEQUORUM_REASON_KILL_APPLICATION: ++ return "we were killed by an application request"; ++ ++ case VOTEQUORUM_REASON_KILL_REJOIN: ++ return "we rejoined the cluster without a full restart"; ++ ++ default: ++ sprintf(msg, "we got kill message number %d", reason); ++ return msg; ++ } ++} ++ ++static void reread_config(unsigned int object_handle) ++{ ++ unsigned int old_votes; ++ unsigned int old_expected; ++ ++ old_votes = us->votes; ++ old_expected = us->expected_votes; ++ ++ /* ++ * Reload the configuration ++ */ ++ read_quorum_config(object_handle); ++ ++ /* ++ * Check for fundamental changes that we need to propogate ++ */ ++ if (old_votes != us->votes) { ++ quorum_exec_send_reconfigure(RECONFIG_PARAM_NODE_VOTES, us->node_id, us->votes); ++ } ++ if (old_expected != us->expected_votes) { ++ quorum_exec_send_reconfigure(RECONFIG_PARAM_EXPECTED_VOTES, us->node_id, us->expected_votes); ++ } ++} ++ ++static void quorum_key_change_notify(object_change_type_t change_type, ++ unsigned int parent_object_handle, ++ unsigned int object_handle, ++ void *object_name_pt, int object_name_len, ++ void *key_name_pt, int key_len, ++ void *key_value_pt, int key_value_len, ++ void *priv_data_pt) ++{ ++ if (memcmp(object_name_pt, "quorum", object_name_len) == 0) ++ reread_config(object_handle); ++} ++ ++ ++/* Called when the objdb is reloaded */ ++static void votequorum_objdb_reload_notify( ++ objdb_reload_notify_type_t type, int flush, ++ void *priv_data_pt) ++{ ++ /* ++ * A new quorum {} key might exist, cancel the ++ * existing notification at the start of reload, ++ * and start a new one on the new object when ++ * it's all settled. ++ */ ++ ++ if (type == OBJDB_RELOAD_NOTIFY_START) { ++ corosync_api->object_track_stop( ++ quorum_key_change_notify, ++ NULL, ++ NULL, ++ NULL, ++ NULL); ++ } ++ ++ if (type == OBJDB_RELOAD_NOTIFY_END || ++ type == OBJDB_RELOAD_NOTIFY_FAILED) { ++ unsigned int find_handle; ++ unsigned int object_handle; ++ ++ corosync_api->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle); ++ if (corosync_api->object_find_next(find_handle, &object_handle) == 0) { ++ add_votequorum_config_notification(object_handle); ++ ++ reread_config(object_handle); ++ } ++ else { ++ log_printf(LOG_LEVEL_ERROR, "votequorum objdb tracking stopped, cannot find quorum{} handle in objdb\n"); ++ } ++ } ++} ++ ++ ++static void add_votequorum_config_notification( ++ unsigned int quorum_object_handle) ++{ ++ ++ corosync_api->object_track_start(quorum_object_handle, ++ 1, ++ quorum_key_change_notify, ++ NULL, ++ NULL, ++ NULL, ++ NULL); ++ ++ /* ++ * Reload notify must be on the parent object ++ */ ++ corosync_api->object_track_start(OBJECT_PARENT_HANDLE, ++ 1, ++ NULL, ++ NULL, ++ NULL, ++ votequorum_objdb_reload_notify, ++ NULL); ++} +diff -Naurd corosync-0.92/test/cpgbench.c corosync-trunk/test/cpgbench.c +--- corosync-0.92/test/cpgbench.c 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/test/cpgbench.c 2008-11-06 22:49:07.000000000 +0100 +@@ -50,7 +50,7 @@ + #include + #include + +-#include ++#include + #include + + #ifdef COROSYNC_SOLARIS +@@ -121,12 +121,12 @@ + if (flow_control_state == CPG_FLOW_CONTROL_DISABLED) { + retry: + res = cpg_mcast_joined (handle, CPG_TYPE_AGREED, &iov, 1); +- if (res == CPG_ERR_TRY_AGAIN) { ++ if (res == CS_ERR_TRY_AGAIN) { + goto retry; + } + } +- res = cpg_dispatch (handle, CPG_DISPATCH_ALL); +- if (res != CPG_OK) { ++ res = cpg_dispatch (handle, CS_DISPATCH_ALL); ++ if (res != CS_OK) { + printf ("cpg dispatch returned error %d\n", res); + exit (1); + } +@@ -162,13 +162,13 @@ + + signal (SIGALRM, sigalrm_handler); + res = cpg_initialize (&handle, &callbacks); +- if (res != CPG_OK) { ++ if (res != CS_OK) { + printf ("cpg_initialize failed with result %d\n", res); + exit (1); + } + + res = cpg_join (handle, &group_name); +- if (res != CPG_OK) { ++ if (res != CS_OK) { + printf ("cpg_join failed with result %d\n", res); + exit (1); + } +@@ -179,7 +179,7 @@ + } + + res = cpg_finalize (handle); +- if (res != CPG_OK) { ++ if (res != CS_OK) { + printf ("cpg_join failed with result %d\n", res); + exit (1); + } +diff -Naurd corosync-0.92/test/evsbench.c corosync-trunk/test/evsbench.c +--- corosync-0.92/test/evsbench.c 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/test/evsbench.c 2008-11-06 22:49:07.000000000 +0100 +@@ -49,7 +49,7 @@ + #include + #include + +-#include ++#include + #include + + #ifdef COROSYNC_SOLARIS +@@ -124,7 +124,7 @@ + int write_size) + { + struct timeval tv1, tv2, tv_elapsed; +- evs_error_t result; ++ cs_error_t result; + int write_count = 0; + + /* +@@ -139,12 +139,12 @@ + if (outstanding < 10) { + result = evs_mcast_joined (handle, EVS_TYPE_AGREED, &iov, 1); + +- if (result != EVS_ERR_TRY_AGAIN) { ++ if (result != CS_ERR_TRY_AGAIN) { + write_count += 1; + outstanding++; + } + } +- result = evs_dispatch (handle, EVS_DISPATCH_ALL); ++ result = evs_dispatch (handle, CS_DISPATCH_ALL); + } while (alarm_notice == 0); + gettimeofday (&tv2, NULL); + timersub (&tv2, &tv1, &tv_elapsed); +@@ -174,7 +174,7 @@ + int main (void) { + int size; + int i; +- evs_error_t result; ++ cs_error_t result; + evs_handle_t handle; + + signal (SIGALRM, sigalrm_handler); +diff -Naurd corosync-0.92/test/evsverify.c corosync-trunk/test/evsverify.c +--- corosync-0.92/test/evsverify.c 2008-09-25 07:31:42.000000000 +0200 ++++ corosync-trunk/test/evsverify.c 2008-11-06 22:49:07.000000000 +0100 +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #include + #include "../exec/crypto.h" + +@@ -112,22 +113,22 @@ + + struct msg msg; + +-char buffer[200000]; ++unsigned char buffer[200000]; + int main (void) + { + evs_handle_t handle; +- evs_error_t result; ++ cs_error_t result; + unsigned int i = 0, j; + int fd; + unsigned int member_list[32]; + unsigned int local_nodeid; +- int member_list_entries = 32; ++ unsigned int member_list_entries = 32; + struct msg msg; + hash_state sha1_hash; + struct iovec iov[2]; + + result = evs_initialize (&handle, &callbacks); +- if (result != EVS_OK) { ++ if (result != CS_OK) { + printf ("Couldn't initialize EVS service %d\n", result); + exit (0); + } +@@ -169,10 +170,10 @@ + try_again_one: + result = evs_mcast_joined (handle, EVS_TYPE_AGREED, + iov, 2); +- if (result == EVS_ERR_TRY_AGAIN) { ++ if (result == CS_ERR_TRY_AGAIN) { + goto try_again_one; + } +- result = evs_dispatch (handle, EVS_DISPATCH_ALL); ++ result = evs_dispatch (handle, CS_DISPATCH_ALL); + } + + evs_fd_get (handle, &fd); +diff -Naurd corosync-0.92/test/logsysbench.c corosync-trunk/test/logsysbench.c +--- corosync-0.92/test/logsysbench.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/test/logsysbench.c 2008-10-30 23:25:56.000000000 +0100 +@@ -0,0 +1,171 @@ ++/* ++ * Copyright (c) 2008 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 ++ ++LOGSYS_DECLARE_SYSTEM ("logtest_rec", ++ LOG_MODE_OUTPUT_STDERR | LOG_MODE_THREADED, ++ NULL, ++ LOG_DAEMON, ++ "[%6s] %b", ++ 100000); ++ ++LOGSYS_DECLARE_NOSUBSYS(LOG_LEVEL_INFO); ++ ++#define LOGREC_ID_CHECKPOINT_CREATE 2 ++#define LOGREC_ARGS_CHECKPOINT_CREATE 2 ++#define ITERATIONS 1000000 ++ ++struct timeval tv1, tv2, tv_elapsed; ++ ++#define timersub(a, b, result) \ ++do { \ ++ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ ++ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ ++ if ((result)->tv_usec < 0) { \ ++ --(result)->tv_sec; \ ++ (result)->tv_usec += 1000000; \ ++ } \ ++} while (0) ++ ++void bm_start (void) ++{ ++ gettimeofday (&tv1, NULL); ++} ++void bm_finish (char *operation) ++{ ++ gettimeofday (&tv2, NULL); ++ timersub (&tv2, &tv1, &tv_elapsed); ++ ++ if (strlen (operation) > 22) { ++ printf ("%s\t\t", operation); ++ } else { ++ printf ("%s\t\t\t", operation); ++ } ++ printf ("%9.3f operations/sec\n", ++ ((float)ITERATIONS) / (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0))); ++} ++ ++char buffer[256]; ++int main (void) ++{ ++ int i; ++ char buf[1024]; ++ ++ ++ printf ("heating up cache with logrec functionality\n"); ++ for (i = 0; i < ITERATIONS; i++) { ++ log_rec (LOGREC_ID_CHECKPOINT_CREATE, ++ "recordA", 8, "recordB", 8, LOG_REC_END); ++ } ++ bm_start(); ++ for (i = 0; i < ITERATIONS; i++) { ++ log_rec (LOGREC_ID_CHECKPOINT_CREATE, ++ buffer, 7, LOG_REC_END); ++ } ++ bm_finish ("log_rec 1 arguments:"); ++ bm_start(); ++ for (i = 0; i < ITERATIONS; i++) { ++ log_rec (LOGREC_ID_CHECKPOINT_CREATE, ++ "recordA", 8, LOG_REC_END); ++ } ++ bm_finish ("log_rec 2 arguments:"); ++ bm_start(); ++ for (i = 0; i < 10; i++) { ++ log_rec (LOGREC_ID_CHECKPOINT_CREATE, ++ "recordA", 8, "recordB", 8, LOG_REC_END); ++ } ++ bm_start(); ++ for (i = 0; i < ITERATIONS; i++) { ++ log_rec (LOGREC_ID_CHECKPOINT_CREATE, ++ "recordA", 8, "recordB", 8, "recordC", 8, LOG_REC_END); ++ } ++ bm_finish ("log_rec 3 arguments:"); ++ bm_start(); ++ for (i = 0; i < ITERATIONS; i++) { ++ log_rec (LOGREC_ID_CHECKPOINT_CREATE, ++ "recordA", 8, "recordB", 8, "recordC", 8, "recordD", 8, LOG_REC_END); ++ } ++ bm_finish ("log_rec 4 arguments:"); ++ ++ /* ++ * sprintf testing ++ */ ++ printf ("heating up cache with sprintf functionality\n"); ++ for (i = 0; i < ITERATIONS; i++) { ++ sprintf (buf, "Some logging information %s", "recordA"); ++ } ++ bm_start(); ++ for (i = 0; i < ITERATIONS; i++) { ++ sprintf (buf, "Some logging information %s", "recordA"); ++ } ++ bm_finish ("sprintf 1 argument:"); ++ bm_start(); ++ for (i = 0; i < ITERATIONS; i++) { ++ sprintf (buf, "Some logging information %s %s", "recordA", "recordB"); ++ } ++ bm_finish ("sprintf 2 arguments:"); ++ bm_start(); ++ for (i = 0; i < ITERATIONS; i++) { ++ sprintf (buf, "Some logging information %s %s %s", "recordA", "recordB", "recordC"); ++ } ++ bm_finish ("sprintf 3 arguments:"); ++ bm_start(); ++ for (i = 0; i < ITERATIONS; i++) { ++ sprintf (buf, "Some logging information %s %s %s %s", "recordA", "recordB", "recordC", "recordD"); ++ } ++ bm_finish ("sprintf 4 arguments:"); ++ bm_start(); ++ for (i = 0; i < ITERATIONS; i++) { ++ sprintf (buf, "Some logging information %s %s %s %d", "recordA", "recordB", "recordC", i); ++ } ++ bm_finish ("sprintf 4 arguments (1 int):"); ++ ++ logsys_log_rec_store ("fdata"); ++/* TODO ++ currently fails under some circumstances ++ ++ bm_start(); ++ for (i = 0; i < ITERATIONS; i++) { ++ log_printf (LOG_LEVEL_NOTICE, "test %d", i); ++ } ++ bm_finish("log_printf"); ++*/ ++ ++ return (0); ++} +diff -Naurd corosync-0.92/test/logsysrec.c corosync-trunk/test/logsysrec.c +--- corosync-0.92/test/logsysrec.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/test/logsysrec.c 2008-10-30 23:25:56.000000000 +0100 +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (c) 2008 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 ++ ++LOGSYS_DECLARE_SYSTEM ("logtest_rec", ++ LOG_MODE_OUTPUT_STDERR | LOG_MODE_THREADED, ++ NULL, ++ LOG_DAEMON, ++ "[%6s] %b", ++ 100000); ++ ++LOGSYS_DECLARE_NOSUBSYS(LOG_LEVEL_INFO); ++ ++#define LOGREC_ID_CHECKPOINT_CREATE 2 ++#define LOGREC_ARGS_CHECKPOINT_CREATE 2 ++ ++int main(int argc, char **argv) ++{ ++ int i; ++ ++ for (i = 0; i < 10; i++) { ++ log_printf (LOG_LEVEL_NOTICE, "This is a test of %s\n", "stringparse"); ++ ++ log_rec (LOGREC_ID_CHECKPOINT_CREATE, "record1", 8, "record22", 9, "record333", 10, "record444", 11, LOG_REC_END); ++ } ++ logsys_log_rec_store ("fdata"); ++ ++ return 0; ++} +diff -Naurd corosync-0.92/test/logsys_s.c corosync-trunk/test/logsys_s.c +--- corosync-0.92/test/logsys_s.c 2008-05-12 15:48:06.000000000 +0200 ++++ corosync-trunk/test/logsys_s.c 2008-10-30 23:25:56.000000000 +0100 +@@ -38,7 +38,9 @@ + LOGSYS_DECLARE_SYSTEM ("logsystestsubsystems", + LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED, + NULL, +- LOG_DAEMON); ++ LOG_DAEMON, ++ "[%8s] %b", ++ 100000); + + extern void logsys_s1_print (void); + extern void logsys_s2_print (void); +diff -Naurd corosync-0.92/test/logsys_t1.c corosync-trunk/test/logsys_t1.c +--- corosync-0.92/test/logsys_t1.c 2008-06-20 08:04:03.000000000 +0200 ++++ corosync-trunk/test/logsys_t1.c 2008-10-30 23:25:56.000000000 +0100 +@@ -38,7 +38,9 @@ + LOGSYS_DECLARE_SYSTEM ("logsystestNOsubsystems", + LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED, + NULL, +- LOG_DAEMON); ++ LOG_DAEMON, ++ "%6s %b", ++ 100000); + + LOGSYS_DECLARE_NOSUBSYS(LOG_LEVEL_DEBUG); + +diff -Naurd corosync-0.92/test/logsys_t2.c corosync-trunk/test/logsys_t2.c +--- corosync-0.92/test/logsys_t2.c 2008-06-20 08:04:03.000000000 +0200 ++++ corosync-trunk/test/logsys_t2.c 2008-10-30 23:25:56.000000000 +0100 +@@ -36,9 +36,11 @@ + #include "../exec/logsys.h" + + LOGSYS_DECLARE_SYSTEM ("logtest_t2", +- LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED | LOG_MODE_BUFFER_BEFORE_CONFIG, ++ LOG_MODE_OUTPUT_STDERR | LOG_MODE_THREADED, + NULL, +- LOG_DAEMON); ++ LOG_DAEMON, ++ "[%6s] %b" ++ 100000); + + LOGSYS_DECLARE_NOSUBSYS(LOG_LEVEL_INFO); + +@@ -48,7 +50,7 @@ + /* + * fork could occur here and the file to output to could be set + */ +- logsys_config_mode_set (LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED | LOG_MODE_FLUSH_AFTER_CONFIG); ++ logsys_config_mode_set (LOG_MODE_OUTPUT_STDERR | LOG_MODE_THREADED); + + log_printf(LOG_NOTICE, "Hello, world!\n"); + log_printf(LOG_DEBUG, "If you see this, the logger's busted\n"); +diff -Naurd corosync-0.92/test/Makefile corosync-trunk/test/Makefile +--- corosync-0.92/test/Makefile 2008-09-25 07:31:42.000000000 +0200 ++++ corosync-trunk/test/Makefile 2009-01-26 11:46:08.000000000 +0100 +@@ -42,9 +42,10 @@ + override LDFLAGS += -lnsl -lsocket -lrt + endif + +-LIBRARIES= ../lib/libevs.a ../lib/libcpg.a ../lib/libcfg.a ../lib/libconfdb.a ++LIBRARIES= ../lib/libevs.a ../lib/libcpg.a ../lib/libcfg.a ../lib/libconfdb.a ../lib/libquorum.a ../lib/libvotequorum.a + LIBS = $(LIBRARIES) +-BINARIES= testevs evsbench evsverify testcpg testcpg2 cpgbench testconfdb ++BINARIES= testevs evsbench evsverify testcpg testcpg2 cpgbench testconfdb logsysbench logsysrec testquorum \ ++ testvotequorum1 testvotequorum2 + + override CFLAGS += -I../include + override LDFLAGS += -L../lib +@@ -75,12 +76,33 @@ + testcpg2: testcpg2.o $(LIBRARIES) + $(CC) $(LDFLAGS) -o testcpg2 testcpg2.o $(LIBS) + ++testquorum: testquorum.o $(LIBRARIES) ++ $(CC) $(LDFLAGS) -o testquorum testquorum.o $(LIBS) ++ + cpgbench: cpgbench.o $(LIBRARIES) + $(CC) $(LDFLAGS) -o cpgbench cpgbench.o $(LIBS) + + testconfdb: testconfdb.o $(LIBRARIES) + $(CC) $(LDFLAGS) -o testconfdb testconfdb.o $(LIBS) -rdynamic + ++logsysbench: logsysbench.o ../exec/liblogsys.a ++ $(CC) -o logsysbench logsysbench.o ../exec/liblogsys.a $(LDFLAGS) ++ ++logsysrec: logsysrec.o ../exec/liblogsys.a ++ $(CC) -o logsysrec logsysrec.o ../exec/liblogsys.a $(LDFLAGS) ++ ++testquorum1: testquorum1.o $(LIBRARIES) ++ $(CC) $(LDFLAGS) -o testquorum1 testquorum1.o $(LIBS) ++ ++testquorum2: testquorum2.o $(LIBRARIES) ++ $(CC) $(LDFLAGS) -o testquorum2 testquorum2.o $(LIBS) ++ ++testvotequorum1: testvotequorum1.o $(LIBRARIES) ++ $(CC) $(LDFLAGS) -o testvotequorum1 testvotequorum1.o $(LIBS) ++ ++testvotequorum2: testvotequorum2.o $(LIBRARIES) ++ $(CC) $(LDFLAGS) -o testvotequorum2 testvotequorum2.o $(LIBS) ++ + logsys_s: logsys_s.o logsys_s1.o logsys_s2.o ../exec/liblogsys.a + $(CC) -o logsys_s logsys_s.o logsys_s1.o logsys_s2.o ../exec/liblogsys.a $(LDFLAGS) + +diff -Naurd corosync-0.92/test/sa_error.c corosync-trunk/test/sa_error.c +--- corosync-0.92/test/sa_error.c 2006-01-24 08:19:11.000000000 +0100 ++++ corosync-trunk/test/sa_error.c 2008-11-06 22:49:07.000000000 +0100 +@@ -6,39 +6,39 @@ + + const char *sa_error_list[] = { + "OUT_OF_RANGE", +- "SA_AIS_OK", +- "SA_AIS_ERR_LIBRARY", +- "SA_AIS_ERR_VERSION", +- "SA_AIS_ERR_INIT", +- "SA_AIS_ERR_TIMEOUT", +- "SA_AIS_ERR_TRY_AGAIN", +- "SA_AIS_ERR_INVALID_PARAM", +- "SA_AIS_ERR_NO_MEMORY", +- "SA_AIS_ERR_BAD_HANDLE", +- "SA_AIS_ERR_BUSY", +- "SA_AIS_ERR_ACCESS", +- "SA_AIS_ERR_NOT_EXIST", +- "SA_AIS_ERR_NAME_TOO_LONG", +- "SA_AIS_ERR_EXIST", +- "SA_AIS_ERR_NO_SPACE", +- "SA_AIS_ERR_INTERRUPT", +- "SA_AIS_ERR_NAME_NOT_FOUND", +- "SA_AIS_ERR_NO_RESOURCES", +- "SA_AIS_ERR_NOT_SUPPORTED", +- "SA_AIS_ERR_BAD_OPERATION", +- "SA_AIS_ERR_FAILED_OPERATION", +- "SA_AIS_ERR_MESSAGE_ERROR", +- "SA_AIS_ERR_QUEUE_FULL", +- "SA_AIS_ERR_QUEUE_NOT_AVAILABLE", +- "SA_AIS_ERR_BAD_CHECKPOINT", +- "SA_AIS_ERR_BAD_FLAGS", +- "SA_AIS_ERR_NO_SECTIONS", ++ "CS_OK", ++ "CS_ERR_LIBRARY", ++ "CS_ERR_VERSION", ++ "CS_ERR_INIT", ++ "CS_ERR_TIMEOUT", ++ "CS_ERR_TRY_AGAIN", ++ "CS_ERR_INVALID_PARAM", ++ "CS_ERR_NO_MEMORY", ++ "CS_ERR_BAD_HANDLE", ++ "CS_ERR_BUSY", ++ "CS_ERR_ACCESS", ++ "CS_ERR_NOT_EXIST", ++ "CS_ERR_NAME_TOO_LONG", ++ "CS_ERR_EXIST", ++ "CS_ERR_NO_SPACE", ++ "CS_ERR_INTERRUPT", ++ "CS_ERR_NAME_NOT_FOUND", ++ "CS_ERR_NO_RESOURCES", ++ "CS_ERR_NOT_SUPPORTED", ++ "CS_ERR_BAD_OPERATION", ++ "CS_ERR_FAILED_OPERATION", ++ "CS_ERR_MESSAGE_ERROR", ++ "CS_ERR_QUEUE_FULL", ++ "CS_ERR_QUEUE_NOT_AVAILABLE", ++ "CS_ERR_BAD_CHECKPOINT", ++ "CS_ERR_BAD_FLAGS", ++ "CS_ERR_NO_SECTIONS", + }; + +-int get_sa_error(SaAisErrorT error, char *str, int len) ++int get_sa_error(cs_error_t error, char *str, int len) + { +- if (error < SA_AIS_OK || +- error > SA_AIS_ERR_NO_SECTIONS || ++ if (error < CS_OK || ++ error > CS_ERR_NO_SECTIONS || + len < strlen(sa_error_list[error])) { + errno = EINVAL; + return -1; +@@ -47,11 +47,11 @@ + return 0; + } + +-char *get_sa_error_b (SaAisErrorT error) { ++char *get_sa_error_b (cs_error_t error) { + return ((char *)sa_error_list[error]); + } + +-char *get_test_output (SaAisErrorT result, SaAisErrorT expected) { ++char *get_test_output (cs_error_t result, cs_error_t expected) { + static char test_result[256]; + + if (result == expected) { +diff -Naurd corosync-0.92/test/sa_error.h corosync-trunk/test/sa_error.h +--- corosync-0.92/test/sa_error.h 2006-01-24 08:19:11.000000000 +0100 ++++ corosync-trunk/test/sa_error.h 2008-11-06 22:49:07.000000000 +0100 +@@ -1,5 +1,5 @@ +-extern int get_sa_error(SaAisErrorT error, char *str, int len); ++extern int get_sa_error(cs_error_t error, char *str, int len); + +-extern char *get_sa_error_b (SaAisErrorT error); ++extern char *get_sa_error_b (cs_error_t error); + +-extern char *get_test_output (SaAisErrorT result, SaAisErrorT expected); ++extern char *get_test_output (cs_error_t result, cs_error_t expected); +diff -Naurd corosync-0.92/test/testconfdb.c corosync-trunk/test/testconfdb.c +--- corosync-0.92/test/testconfdb.c 2008-09-03 09:58:08.000000000 +0200 ++++ corosync-trunk/test/testconfdb.c 2008-11-06 22:49:07.000000000 +0100 +@@ -41,7 +41,7 @@ + #include + #include + +-#include ++#include + #include + + #define INCDEC_VALUE 45 +@@ -68,13 +68,13 @@ + + /* Show the keys */ + res = confdb_key_iter_start(handle, parent_object_handle); +- if (res != SA_AIS_OK) { ++ if (res != CS_OK) { + printf( "error resetting key iterator for object %d: %d\n", parent_object_handle, res); + return; + } + + while ( (res = confdb_key_iter(handle, parent_object_handle, key_name, &key_name_len, +- key_value, &key_value_len)) == SA_AIS_OK) { ++ key_value, &key_value_len)) == CS_OK) { + key_name[key_name_len] = '\0'; + key_value[key_value_len] = '\0'; + for (i=0; i + #include + ++#include + #include + + void deliver( +@@ -70,17 +71,17 @@ + int fd; + + printf ("All of the nodeids should match on a single node configuration\n for the test to pass."); +- assert(CPG_OK==cpg_initialize(&handle, &cb)); +- assert(CPG_OK==cpg_local_get(handle,&nodeid)); ++ assert(CS_OK==cpg_initialize(&handle, &cb)); ++ assert(CS_OK==cpg_local_get(handle,&nodeid)); + printf("local_get: %x\n", nodeid); +- assert(CPG_OK==cpg_join(handle, &group)); ++ assert(CS_OK==cpg_join(handle, &group)); + struct iovec msg={"hello", 5}; +- assert(CPG_OK==cpg_mcast_joined(handle,CPG_TYPE_AGREED,&msg,1)); ++ assert(CS_OK==cpg_mcast_joined(handle,CPG_TYPE_AGREED,&msg,1)); + cpg_fd_get (handle, &fd); + pfd.fd = fd; + pfd.events = POLLIN; + + poll (&pfd, 1, 1000); +- cpg_dispatch(handle, CPG_DISPATCH_ALL); ++ cpg_dispatch(handle, CS_DISPATCH_ALL); + return (0); + } +diff -Naurd corosync-0.92/test/testcpg.c corosync-trunk/test/testcpg.c +--- corosync-0.92/test/testcpg.c 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/test/testcpg.c 2008-11-06 22:49:07.000000000 +0100 +@@ -45,7 +45,7 @@ + #include + #include + +-#include ++#include + #include + + static int quit = 0; +@@ -206,25 +206,25 @@ + } + + result = cpg_initialize (&handle, &callbacks); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not initialize Cluster Process Group API instance error %d\n", result); + exit (1); + } + result = cpg_local_get (handle, &nodeid); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not get local node id\n"); + exit (1); + } + + printf ("Local node id is %x\n", nodeid); + result = cpg_join(handle, &group_name); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not join process group, error %d\n", result); + exit (1); + } + + cpg_groups_get(handle, &num_groups); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not get list of groups, error %d\n", result); + exit (1); + } +@@ -255,7 +255,7 @@ + } + } + if (FD_ISSET (select_fd, &read_fds)) { +- if (cpg_dispatch (handle, CPG_DISPATCH_ALL) != SA_AIS_OK) ++ if (cpg_dispatch (handle, CS_DISPATCH_ALL) != CS_OK) + exit(1); + } + } while (result && !quit); +diff -Naurd corosync-0.92/test/testevs.c corosync-trunk/test/testevs.c +--- corosync-0.92/test/testevs.c 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/test/testevs.c 2008-11-06 22:49:07.000000000 +0100 +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #include + + char *delivery_string; +@@ -99,7 +100,7 @@ + int main (void) + { + evs_handle_t handle; +- evs_error_t result; ++ cs_error_t result; + int i = 0; + int fd; + unsigned int member_list[32]; +@@ -107,7 +108,7 @@ + unsigned int member_list_entries = 32; + + result = evs_initialize (&handle, &callbacks); +- if (result != EVS_OK) { ++ if (result != CS_OK) { + printf ("Couldn't initialize EVS service %d\n", result); + exit (0); + } +@@ -142,15 +143,15 @@ + try_again_one: + result = evs_mcast_joined (handle, EVS_TYPE_AGREED, + &iov, 1); +- if (result == EVS_ERR_TRY_AGAIN) { ++ if (result == CS_ERR_TRY_AGAIN) { + //printf ("try again\n"); + goto try_again_one; + } +- result = evs_dispatch (handle, EVS_DISPATCH_ALL); ++ result = evs_dispatch (handle, CS_DISPATCH_ALL); + } + + do { +- result = evs_dispatch (handle, EVS_DISPATCH_ALL); ++ result = evs_dispatch (handle, CS_DISPATCH_ALL); + } while (deliveries < 20); + /* + * Demonstrate evs_mcast_joined +@@ -161,17 +162,17 @@ + try_again_two: + result = evs_mcast_groups (handle, EVS_TYPE_AGREED, + &groups[1], 1, &iov, 1); +- if (result == EVS_ERR_TRY_AGAIN) { ++ if (result == CS_ERR_TRY_AGAIN) { + goto try_again_two; + } + +- result = evs_dispatch (handle, EVS_DISPATCH_ALL); ++ result = evs_dispatch (handle, CS_DISPATCH_ALL); + } + /* + * Flush any pending callbacks + */ + do { +- result = evs_dispatch (handle, EVS_DISPATCH_ALL); ++ result = evs_dispatch (handle, CS_DISPATCH_ALL); + } while (deliveries < 500); + + evs_fd_get (handle, &fd); +diff -Naurd corosync-0.92/test/testquorum.c corosync-trunk/test/testquorum.c +--- corosync-0.92/test/testquorum.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/test/testquorum.c 2008-11-06 22:49:07.000000000 +0100 +@@ -0,0 +1,58 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static quorum_handle_t handle; ++ ++static void quorum_notification_fn( ++ quorum_handle_t handle, ++ uint32_t quorate, ++ uint64_t ring_id, ++ uint32_t view_list_entries, ++ uint32_t *view_list) ++{ ++ int i; ++ ++ printf("quorum notification called \n"); ++ printf(" quorate = %d\n", quorate); ++ printf(" ring id = %lld\n", ring_id); ++ printf(" num nodes = %d ", view_list_entries); ++ ++ for (i=0; i ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static votequorum_handle_t handle; ++ ++static char *node_state(int state) ++{ ++ switch (state) { ++ case NODESTATE_JOINING: ++ return "Joining"; ++ break; ++ case NODESTATE_MEMBER: ++ return "Member"; ++ break; ++ case NODESTATE_DEAD: ++ return "Dead"; ++ break; ++ case NODESTATE_LEAVING: ++ return "Leaving"; ++ break; ++ case NODESTATE_DISALLOWED: ++ return "Disallowed"; ++ break; ++ default: ++ return "UNKNOWN"; ++ break; ++ } ++} ++ ++static void votequorum_notification_fn( ++ votequorum_handle_t handle, ++ uint64_t context, ++ uint32_t quorate, ++ uint32_t node_list_entries, ++ votequorum_node_t node_list[] ++ ) ++{ ++ int i; ++ ++ printf("votequorum notification called \n"); ++ printf(" quorate = %d\n", quorate); ++ printf(" number of nodes = %d\n", node_list_entries); ++ ++ for (i = 0; i< node_list_entries; i++) { ++ printf(" %d: %s\n", node_list[i].nodeid, node_state(node_list[i].state)); ++ } ++ printf("\n"); ++} ++ ++ ++int main(int argc, char *argv[]) ++{ ++ struct votequorum_info info; ++ votequorum_callbacks_t callbacks; ++ int err; ++ ++ if (argc > 1 && strcmp(argv[1], "-h")==0) { ++ fprintf(stderr, "usage: %s [new-expected] [new-votes]\n", argv[0]); ++ return 0; ++ } ++ ++ callbacks.votequorum_notify_fn = votequorum_notification_fn; ++ if ( (err=votequorum_initialize(&handle, &callbacks)) != CS_OK) ++ fprintf(stderr, "votequorum_initialize FAILED: %d\n", err); ++ ++ if ( (err = votequorum_trackstart(handle, handle, CS_TRACK_CHANGES)) != CS_OK) ++ fprintf(stderr, "votequorum_trackstart FAILED: %d\n", err); ++ ++ if ( (err=votequorum_getinfo(handle, 0, &info)) != CS_OK) ++ fprintf(stderr, "votequorum_getinfo FAILED: %d\n", err); ++ else { ++ printf("node votes %d\n", info.node_votes); ++ printf("expected votes %d\n", info.node_expected_votes); ++ printf("highest expected %d\n", info.highest_expected); ++ printf("total votes %d\n", info.total_votes); ++ printf("quorum %d\n", info.quorum); ++ printf("flags "); ++ if (info.flags & VOTEQUORUM_INFO_FLAG_HASSTATE) printf("HasState "); ++ if (info.flags & VOTEQUORUM_INFO_FLAG_DISALLOWED) printf("Disallowed "); ++ if (info.flags & VOTEQUORUM_INFO_FLAG_TWONODE) printf("2Node "); ++ if (info.flags & VOTEQUORUM_INFO_FLAG_QUORATE) printf("Quorate "); ++ printf("\n"); ++ } ++ ++ if (argc >= 2 && atoi(argv[1])) { ++ if ( (err=votequorum_setexpected(handle, atoi(argv[1]))) != CS_OK) ++ fprintf(stderr, "set expected votes FAILED: %d\n", err); ++ } ++ if (argc >= 3 && atoi(argv[2])) { ++ if ( (err=votequorum_setvotes(handle, 0, atoi(argv[2]))) != CS_OK) ++ fprintf(stderr, "set votes FAILED: %d\n", err); ++ } ++ ++ if (argc >= 2) { ++ if ( (err=votequorum_getinfo(handle, 0, &info)) != CS_OK) ++ fprintf(stderr, "votequorum_getinfo2 FAILED: %d\n", err); ++ else { ++ printf("-------------------\n"); ++ printf("node votes %d\n", info.node_votes); ++ printf("expected votes %d\n", info.node_expected_votes); ++ printf("highest expected %d\n", info.highest_expected); ++ printf("total votes %d\n", info.total_votes); ++ printf("votequorum %d\n", info.quorum); ++ printf("flags "); ++ if (info.flags & VOTEQUORUM_INFO_FLAG_HASSTATE) printf("HasState "); ++ if (info.flags & VOTEQUORUM_INFO_FLAG_DISALLOWED) printf("Disallowed "); ++ if (info.flags & VOTEQUORUM_INFO_FLAG_TWONODE) printf("2Node "); ++ if (info.flags & VOTEQUORUM_INFO_FLAG_QUORATE) printf("Quorate "); ++ printf("\n"); ++ } ++ } ++ ++ printf("Waiting for votequorum events, press ^C to finish\n"); ++ printf("-------------------\n"); ++ ++ while (1) ++ votequorum_dispatch(handle, CS_DISPATCH_ALL); ++ ++ return 0; ++} +diff -Naurd corosync-0.92/test/testvotequorum2.c corosync-trunk/test/testvotequorum2.c +--- corosync-0.92/test/testvotequorum2.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/test/testvotequorum2.c 2009-01-26 11:46:08.000000000 +0100 +@@ -0,0 +1,96 @@ ++/* ++ * Copyright (c) 2009 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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 ++ ++static votequorum_handle_t handle; ++ ++ ++static void print_info(int ok_to_fail) ++{ ++ struct votequorum_qdisk_info qinfo; ++ int err; ++ ++ if ( (err=votequorum_qdisk_getinfo(handle, &qinfo)) != CS_OK) ++ fprintf(stderr, "votequorum_qdisk_getinfo error %d: %s\n", err, ok_to_fail?"OK":"FAILED"); ++ else { ++ printf("qdisk votes %d\n", qinfo.votes); ++ printf("state %d\n", qinfo.state); ++ printf("name %s\n", qinfo.name); ++ printf("\n"); ++ } ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int pollcount=0, polltime=1; ++ int err; ++ ++ if ( (err=votequorum_initialize(&handle, NULL)) != CS_OK) { ++ fprintf(stderr, "votequorum_initialize FAILED: %d\n", err); ++ return -1; ++ } ++ ++ print_info(1); ++ ++ if (argc >= 2 && atoi(argv[1])) { ++ pollcount = atoi(argv[1]); ++ } ++ if (argc >= 3 && atoi(argv[2])) { ++ polltime = atoi(argv[2]); ++ } ++ ++ if (argc >= 2) { ++ if ( (err=votequorum_qdisk_register(handle, "QDISK", 4)) != CS_OK) ++ fprintf(stderr, "qdisk_register FAILED: %d\n", err); ++ ++ while (pollcount--) { ++ print_info(0); ++ if ((err=votequorum_qdisk_poll(handle, 1)) != CS_OK) ++ fprintf(stderr, "qdisk poll FAILED: %d\n", err); ++ print_info(0); ++ sleep(polltime); ++ } ++ if ((err= votequorum_qdisk_unregister(handle)) != CS_OK) ++ fprintf(stderr, "qdisk unregister FAILED: %d\n", err); ++ } ++ print_info(1); ++ ++ return 0; ++} +diff -Naurd corosync-0.92/tools/corosync-cfgtool.c corosync-trunk/tools/corosync-cfgtool.c +--- corosync-0.92/tools/corosync-cfgtool.c 2008-08-14 18:54:46.000000000 +0200 ++++ corosync-trunk/tools/corosync-cfgtool.c 2009-01-19 09:31:21.000000000 +0100 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2006-2007 Red Hat, Inc. ++ * Copyright (c) 2006-2009 Red Hat, Inc. + * + * All rights reserved. + * +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -45,12 +46,13 @@ + #include + #include + +-#include ++#include ++#include + #include + + static void ringstatusget_do (void) + { +- SaAisErrorT result; ++ cs_error_t result; + corosync_cfg_handle_t handle; + unsigned int interface_count; + char **interface_names; +@@ -59,84 +61,199 @@ + + printf ("Printing ring status.\n"); + result = corosync_cfg_initialize (&handle, NULL); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not initialize corosync configuration API error %d\n", result); + exit (1); + } + +- corosync_cfg_ring_status_get (handle, +- &interface_names, +- &interface_status, +- &interface_count); +- +- for (i = 0; i < interface_count; i++) { +- printf ("RING ID %d\n", i); +- printf ("\tid\t= %s\n", interface_names[i]); +- printf ("\tstatus\t= %s\n", interface_status[i]); ++ result = corosync_cfg_ring_status_get (handle, ++ &interface_names, ++ &interface_status, ++ &interface_count); ++ if (result != CS_OK) { ++ printf ("Could not get the ring status, the error is: %d\n", result); ++ } else { ++ for (i = 0; i < interface_count; i++) { ++ printf ("RING ID %d\n", i); ++ printf ("\tid\t= %s\n", interface_names[i]); ++ printf ("\tstatus\t= %s\n", interface_status[i]); ++ } + } +- +- corosync_cfg_finalize (handle); ++ (void)corosync_cfg_finalize (handle); + } + + static void ringreenable_do (void) + { +- SaAisErrorT result; ++ cs_error_t result; + corosync_cfg_handle_t handle; + + printf ("Re-enabling all failed rings.\n"); + result = corosync_cfg_initialize (&handle, NULL); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not initialize corosync configuration API error %d\n", result); + exit (1); + } + + result = corosync_cfg_ring_reenable (handle); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not reenable ring error %d\n", result); + } + +- corosync_cfg_finalize (handle); ++ (void)corosync_cfg_finalize (handle); + } + + void service_load_do (char *service, unsigned int version) + { +- SaAisErrorT result; ++ cs_error_t result; + corosync_cfg_handle_t handle; + + printf ("Loading service '%s' version '%d'\n", service, version); + result = corosync_cfg_initialize (&handle, NULL); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not initialize corosync configuration API error %d\n", result); + exit (1); + } + result = corosync_cfg_service_load (handle, service, version); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not load service (error = %d)\n", result); + } +- corosync_cfg_finalize (handle); ++ (void)corosync_cfg_finalize (handle); + } + + void service_unload_do (char *service, unsigned int version) + { +- SaAisErrorT result; ++ cs_error_t result; + corosync_cfg_handle_t handle; + + printf ("Unloading service '%s' version '%d'\n", service, version); + result = corosync_cfg_initialize (&handle, NULL); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not initialize corosync configuration API error %d\n", result); + exit (1); + } + result = corosync_cfg_service_unload (handle, service, version); +- if (result != SA_AIS_OK) { ++ if (result != CS_OK) { + printf ("Could not unload service (error = %d)\n", result); + } +- corosync_cfg_finalize (handle); ++ (void)corosync_cfg_finalize (handle); ++} ++ ++void shutdown_callback (corosync_cfg_handle_t cfg_handle, corosync_cfg_shutdown_flags_t flags) ++{ ++ printf("shutdown callback called, flags = %d\n",flags); ++ ++ (void)corosync_cfg_replyto_shutdown (cfg_handle, COROSYNC_CFG_SHUTDOWN_FLAG_YES); ++} ++ ++void *shutdown_dispatch_thread(void *arg) ++{ ++ int res = CS_OK; ++ corosync_cfg_handle_t *handle = arg; ++ ++ while (res == CS_OK) { ++ res = corosync_cfg_dispatch(*handle, CS_DISPATCH_ALL); ++ if (res != CS_OK) ++ printf ("Could not dispatch cfg messages: %d\n", res); ++ } ++ return NULL; ++} ++ ++void shutdown_do() ++{ ++ cs_error_t result; ++ corosync_cfg_handle_t handle; ++ corosync_cfg_callbacks_t callbacks; ++ corosync_cfg_state_notification_t notification_buffer; ++ pthread_t dispatch_thread; ++ ++ printf ("Shutting down corosync\n"); ++ callbacks.corosync_cfg_shutdown_callback = shutdown_callback; ++ ++ result = corosync_cfg_initialize (&handle, &callbacks); ++ if (result != CS_OK) { ++ printf ("Could not initialize corosync configuration API error %d\n", result); ++ exit (1); ++ } ++ ++ pthread_create(&dispatch_thread, NULL, shutdown_dispatch_thread, &handle); ++ ++ result = corosync_cfg_state_track (handle, ++ 0, ++ ¬ification_buffer); ++ if (result != CS_OK) { ++ printf ("Could not start corosync cfg tracking error %d\n", result); ++ exit (1); ++ } ++ ++ result = corosync_cfg_try_shutdown (handle, COROSYNC_CFG_SHUTDOWN_FLAG_REQUEST); ++ if (result != CS_OK) { ++ printf ("Could not shutdown (error = %d)\n", result); ++ } ++ ++ (void)corosync_cfg_finalize (handle); + } + ++void showaddrs_do(int nodeid) ++{ ++ cs_error_t result; ++ corosync_cfg_handle_t handle; ++ corosync_cfg_callbacks_t callbacks; ++ int numaddrs; ++ int i; ++ corosync_cfg_node_address_t addrs[INTERFACE_MAX]; ++ ++ ++ result = corosync_cfg_initialize (&handle, &callbacks); ++ if (result != CS_OK) { ++ printf ("Could not initialize corosync configuration API error %d\n", result); ++ exit (1); ++ } ++ ++ if (!corosync_cfg_get_node_addrs(handle, nodeid, INTERFACE_MAX, &numaddrs, addrs) == CS_OK) { ++ for (i=0; iss_family == AF_INET6) ++ saddr = &sin6->sin6_addr; ++ else ++ saddr = &sin->sin_addr; ++ ++ inet_ntop(ss->ss_family, saddr, buf, sizeof(buf)); ++ printf("%s", buf); ++ } ++ printf("\n"); ++ } ++ ++ ++ (void)corosync_cfg_finalize (handle); ++} ++ ++void killnode_do(unsigned int nodeid) ++{ ++ cs_error_t result; ++ corosync_cfg_handle_t handle; ++ ++ printf ("Killing node %d\n", nodeid); ++ result = corosync_cfg_initialize (&handle, NULL); ++ if (result != CS_OK) { ++ printf ("Could not initialize corosync configuration API error %d\n", result); ++ exit (1); ++ } ++ result = corosync_cfg_kill_node (handle, nodeid, "Killed by corosync-cfgtool"); ++ if (result != CS_OK) { ++ printf ("Could not kill node (error = %d)\n", result); ++ } ++ (void)corosync_cfg_finalize (handle); ++} ++ ++ + void usage_do (void) + { +- printf ("corosync-cfgtool [-s] [-r] [-l] [-u] [service_name] [-v] [version]\n\n"); ++ printf ("corosync-cfgtool [-s] [-r] [-l] [-u] [service_name] [-v] [version] [-k] [nodeid] [-a] [nodeid]\n\n"); + printf ("A tool for displaying and configuring active parameters within corosync.\n"); + printf ("options:\n"); + printf ("\t-s\tDisplays the status of the current rings on this node.\n"); +@@ -144,15 +261,19 @@ + printf ("\t\tre-enable redundant ring operation.\n"); + printf ("\t-l\tLoad a service identified by name.\n"); + printf ("\t-u\tUnload a service identified by name.\n"); ++ printf ("\t-a\tDisplay the IP address(es) of a node\n"); ++ printf ("\t-k\tKill a node identified by node id.\n"); ++ printf ("\t-h\tShutdown corosync cleanly on this node.\n"); + } + + int main (int argc, char *argv[]) { +- const char *options = "srl:u:v:"; ++ const char *options = "srl:u:v:k:a:h"; + int opt; + int service_load = 0; ++ unsigned int nodeid; + int service_unload = 0; +- char *service; +- unsigned int version; ++ char *service = NULL; ++ unsigned int version = 0; + + if (argc == 1) { + usage_do (); +@@ -173,17 +294,28 @@ + service_unload = 1; + service = strdup (optarg); + break; ++ case 'k': ++ nodeid = atoi (optarg); ++ killnode_do(nodeid); ++ break; ++ case 'h': ++ shutdown_do(); ++ break; ++ case 'a': ++ showaddrs_do( atoi(optarg) ); ++ break; + case 'v': + version = atoi (optarg); ++ break; + } + } + + if (service_load) { + service_load_do (service, version); +- } else ++ } else + if (service_unload) { + service_unload_do (service, version); + } +- ++ + return (0); + } +diff -Naurd corosync-0.92/tools/corosync-fplay.c corosync-trunk/tools/corosync-fplay.c +--- corosync-0.92/tools/corosync-fplay.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/tools/corosync-fplay.c 2008-11-11 18:25:22.000000000 +0100 +@@ -0,0 +1,485 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++unsigned int flt_data_size = 1000000; ++ ++unsigned int *flt_data; ++#define FDHEAD_INDEX (flt_data_size) ++#define FDTAIL_INDEX (flt_data_size + 1) ++ ++#define TOTEMIP_ADDRLEN (sizeof(struct in6_addr)) ++ ++struct totem_ip_address { ++ unsigned int nodeid; ++ unsigned short family; ++ unsigned char addr[TOTEMIP_ADDRLEN]; ++} __attribute__((packed)); ++ ++struct memb_ring_id { ++ struct totem_ip_address rep; ++ unsigned long long seq; ++} __attribute__((packed)); ++ ++const char *totemip_print(struct totem_ip_address *addr) ++{ ++ static char buf[INET6_ADDRSTRLEN]; ++ ++ return inet_ntop(addr->family, addr->addr, buf, sizeof(buf)); ++} ++ ++char *print_string_len (unsigned char *str, unsigned int len) ++{ ++ unsigned int i; ++ static char buf[1024]; ++ memset (buf, 0, sizeof (buf)); ++ for (i = 0; i < len; i++) { ++ buf[i] = str[i]; ++ } ++ return (buf); ++} ++ ++void sync_printer_confchg_set_sync (void **record) ++{ ++ unsigned int *my_should_sync = record[0]; ++ printf ("Setting my_should_sync to %d\n", *my_should_sync); ++} ++ ++void sync_printer_set_sync_state (void **record) ++{ ++ unsigned int *my_sync_state = record[0]; ++ printf ("Setting my_sync_state to %d\n", *my_sync_state); ++} ++ ++void sync_printer_process_currentstate (void **record) ++{ ++ unsigned int *my_sync_state = record[0]; ++ printf ("Retrieving my_sync_state %d\n", *my_sync_state); ++} ++ ++void sync_printer_process_get_shouldsync (void **record) ++{ ++ unsigned int *my_should_sync = record[0]; ++ printf ("Getting my_should_sync %d\n", *my_should_sync); ++} ++ ++void sync_printer_checkpoint_release (void **record) ++{ ++ unsigned char *name = record[0]; ++ uint16_t *name_len = record[1]; ++ unsigned int *ckpt_id = record[2]; ++ unsigned int *from = record[3]; ++ ++ printf ("Checkpoint release name=[%s] id=[%d] from=[%d] len=[%d]\n", ++ print_string_len (name, *name_len), ++ *ckpt_id, ++ *from, ++ *name_len); ++} ++ ++void sync_printer_checkpoint_transmit (void **record) ++{ ++ unsigned char *name = record[0]; ++ uint16_t *name_len = record[1]; ++ unsigned int *ckpt_id = record[2]; ++ unsigned int *xmit_id = record[3]; ++ ++ printf ("xmit_id=[%d] Checkpoint transmit name=[%s] id=[%d]\n", ++ *xmit_id, print_string_len (name, *name_len), ++ *ckpt_id); ++} ++ ++void sync_printer_section_transmit (void **record) ++{ ++ unsigned char *ckpt_name = record[0]; ++ uint16_t *name_len = record[1]; ++ unsigned int *ckpt_id = record[2]; ++ unsigned int *xmit_id = record[3]; ++ unsigned char *section_name = record[4]; ++ uint16_t *section_name_len = record[5]; ++ ++ printf ("xmit_id=[%d] Section transmit checkpoint name=[%s] id=[%d] ", ++ *xmit_id, print_string_len (ckpt_name, *name_len), ++ *ckpt_id); ++ printf ("section=[%s]\n", ++ print_string_len (section_name, *section_name_len)); ++} ++void sync_printer_checkpoint_receive (void **record) ++{ ++ unsigned char *ckpt_name = record[0]; ++ uint16_t *name_len = record[1]; ++ unsigned int *ckpt_id = record[2]; ++ unsigned int *xmit_id = record[3]; ++ ++ printf ("xmit_id=[%d] Checkpoint receive checkpoint name=[%s] id=[%d]\n", ++ *xmit_id, print_string_len (ckpt_name, *name_len), *ckpt_id); ++} ++ ++void sync_printer_section_receive (void **record) ++{ ++ unsigned char *ckpt_name = record[0]; ++ uint16_t *name_len = record[1]; ++ unsigned int *ckpt_id = record[2]; ++ unsigned int *xmit_id = record[3]; ++ unsigned char *section_name = record[4]; ++ unsigned int *section_name_len = record[5]; ++ ++ printf ("xmit_id=[%d] Section receive checkpoint name=[%s] id=[%d] ", ++ *xmit_id, print_string_len (ckpt_name, *name_len), ++ *ckpt_id); ++ ++ printf ("section=[%s]\n", ++ print_string_len (section_name, *section_name_len)); ++} ++ ++void sync_printer_nada (void **record) ++{ ++printf ("nada\n"); ++} ++void sync_printer_confchg_fn (void **record) ++{ ++ unsigned int i; ++ ++ unsigned int *members = record[0]; ++ unsigned int *member_count = record[1]; ++ struct memb_ring_id *ring_id = record[2]; ++ struct in_addr addr; ++ ++ printf ("sync confchg fn ringid [ip=%s seq=%lld]\n", ++ totemip_print (&ring_id->rep), ++ ring_id->seq); ++ printf ("members [%d]:\n", *member_count); ++ for (i = 0; i < *member_count; i++) { ++ addr.s_addr = members[i]; ++ printf ("\tmember [%s]\n", inet_ntoa (addr)); ++ } ++} ++ ++void printer_totemsrp_mcast (void **record) ++{ ++ unsigned int *msgid = record[0]; ++ ++ printf ("totemsrp_mcast %d\n", *msgid); ++} ++ ++void printer_totemsrp_delv (void **record) ++{ ++ unsigned int *msgid = record[0]; ++ ++ printf ("totemsrp_delv %d\n", *msgid); ++} ++ ++void printer_totempg_mcast_fits (void **record) ++{ ++ unsigned int *index = record[0]; ++ unsigned int *iov_len = record[1]; ++ unsigned int *copy_len = record[2]; ++ unsigned int *fragment_size = record[3]; ++ unsigned int *max_packet_size = record[4]; ++ unsigned int *copy_base = record[5]; ++ unsigned char *next_fragment = record[6]; ++ ++ printf ("totempg_mcast index=[%d] iov_len=[%d] copy_len=[%d] fragment_size=[%d] max_packet_size=[%d] copy_base=[%d] next_fragment[%d]\n", ++ *index, *iov_len, *copy_len, *fragment_size, *max_packet_size, *copy_base, *next_fragment); ++} ++ ++void sync_printer_service_process (void **record) ++{ ++ struct memb_ring_id *ring_id = record[0]; ++ struct memb_ring_id *sync_ring_id = record[1]; ++ ++ printf ("sync service process callback ringid [ip=%s seq=%lld] ", ++ totemip_print (&ring_id->rep), ++ ring_id->seq); ++ printf ("sync ringid [ip=%s seq=%lld]\n", ++ totemip_print (&sync_ring_id->rep), ++ sync_ring_id->seq); ++} ++ ++struct printer_subsys_record_print { ++ int ident; ++ void (*print_fn)(void **record); ++ int record_length; ++}; ++ ++struct printer_subsys { ++ char *subsys; ++ struct printer_subsys_record_print *record_printers; ++ int record_printers_count; ++}; ++ ++#define LOGREC_ID_SYNC_CONFCHG_FN 0 ++#define LOGREC_ID_SYNC_SERVICE_PROCESS 1 ++ ++/* ++ * CKPT subsystem ++ */ ++#define LOGREC_ID_CONFCHG_SETSYNC 0 ++#define LOGREC_ID_SETSYNCSTATE 1 ++#define LOGREC_ID_SYNC_PROCESS_CURRENTSTATE 2 ++#define LOGREC_ID_SYNC_PROCESS_GETSHOULDSYNC 3 ++#define LOGREC_ID_SYNC_CHECKPOINT_TRANSMIT 4 ++#define LOGREC_ID_SYNC_SECTION_TRANSMIT 5 ++#define LOGREC_ID_SYNC_CHECKPOINT_RECEIVE 6 ++#define LOGREC_ID_SYNC_SECTION_RECEIVE 7 ++#define LOGREC_ID_SYNC_CHECKPOINT_RELEASE 8 ++ ++#define LOGREC_ID_TOTEMSRP_MCAST 0 ++#define LOGREC_ID_TOTEMSRP_DELV 1 ++#define LOGREC_ID_TOTEMPG_MCAST_FITS 2 ++ ++ ++struct printer_subsys_record_print record_print_sync[] = { ++ { ++ .ident = LOGREC_ID_SYNC_CONFCHG_FN, ++ .print_fn = sync_printer_confchg_fn, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_SYNC_SERVICE_PROCESS, ++ .print_fn = sync_printer_service_process, ++ .record_length = 28 ++ } ++}; ++ ++struct printer_subsys_record_print record_print_ckpt[] = { ++ { ++ .ident = LOGREC_ID_CONFCHG_SETSYNC, ++ .print_fn = sync_printer_confchg_set_sync, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_SETSYNCSTATE, ++ .print_fn = sync_printer_set_sync_state, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_SYNC_PROCESS_CURRENTSTATE, ++ .print_fn = sync_printer_process_currentstate, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_SYNC_PROCESS_GETSHOULDSYNC, ++ .print_fn = sync_printer_process_get_shouldsync, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_SYNC_CHECKPOINT_TRANSMIT, ++ .print_fn = sync_printer_checkpoint_transmit, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_SYNC_SECTION_TRANSMIT, ++ .print_fn = sync_printer_section_transmit, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_SYNC_CHECKPOINT_RECEIVE, ++ .print_fn = sync_printer_checkpoint_receive, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_SYNC_SECTION_RECEIVE, ++ .print_fn = sync_printer_section_receive, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_SYNC_CHECKPOINT_RELEASE, ++ .print_fn = sync_printer_checkpoint_release, ++ .record_length = 28 ++ } ++ ++}; ++struct printer_subsys_record_print record_print_totem[] = { ++ { ++ .ident = LOGREC_ID_TOTEMSRP_MCAST, ++ .print_fn = printer_totemsrp_mcast, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_TOTEMSRP_DELV, ++ .print_fn = printer_totemsrp_delv, ++ .record_length = 28 ++ }, ++ { ++ .ident = LOGREC_ID_TOTEMPG_MCAST_FITS, ++ .print_fn = printer_totempg_mcast_fits, ++ .record_length = 28 ++ } ++}; ++ ++struct printer_subsys printer_subsystems[] = { ++ { ++ .subsys = "SYNC", ++ .record_printers = record_print_sync, ++ .record_printers_count = sizeof (record_print_sync) / sizeof (struct printer_subsys_record_print) ++ }, ++ { ++ .subsys = "CKPT", ++ .record_printers = record_print_ckpt, ++ .record_printers_count = sizeof (record_print_ckpt) / sizeof (struct printer_subsys_record_print) ++ }, ++ { ++ .subsys = "TOTEM", ++ .record_printers = record_print_totem, ++ .record_printers_count = sizeof (record_print_totem) / sizeof (struct printer_subsys_record_print) ++ } ++}; ++ ++unsigned int printer_subsys_count = sizeof (printer_subsystems) / sizeof (struct printer_subsys); ++ ++unsigned int records_printed = 1; ++ ++unsigned int record[10000]; ++ ++/* ++ * Copy record, dealing with wrapping ++ */ ++int logsys_rec_get (int rec_idx) { ++ unsigned int rec_size; ++ int firstcopy, secondcopy; ++ ++ rec_size = flt_data[rec_idx]; ++ ++ firstcopy = rec_size; ++ secondcopy = 0; ++ if (firstcopy + rec_idx > flt_data_size) { ++ firstcopy = flt_data_size - rec_idx; ++ secondcopy -= firstcopy - rec_size; ++ } ++ memcpy (&record[0], &flt_data[rec_idx], firstcopy<<2); ++ if (secondcopy) { ++ memcpy (&record[firstcopy], &flt_data[0], secondcopy<<2); ++ } ++ return ((rec_idx + rec_size) % flt_data_size); ++} ++ ++void logsys_rec_print (void *record) ++{ ++ unsigned int *buf_uint32t = (unsigned int *)record; ++ unsigned int rec_size; ++ unsigned int rec_ident; ++ unsigned int line; ++ unsigned int arg_size_idx; ++ unsigned int i; ++ unsigned int j; ++ unsigned int rec_idx = 0; ++ unsigned int record_number; ++ unsigned int words_processed; ++ unsigned int found; ++ void *arguments[64]; ++ int arg_count = 0; ++ ++ rec_size = buf_uint32t[rec_idx]; ++ rec_ident = buf_uint32t[rec_idx+1]; ++ line = buf_uint32t[rec_idx+2]; ++ record_number = buf_uint32t[rec_idx+3]; ++ ++printf ("rec=[%d] ", record_number); ++ arg_size_idx = rec_idx + 4; ++ words_processed = 4; ++ for (i = 0; words_processed < rec_size; i++) { ++ arguments[arg_count++] = &buf_uint32t[arg_size_idx + 1]; ++ words_processed += buf_uint32t[arg_size_idx] + 1; ++ arg_size_idx += buf_uint32t[arg_size_idx] + 1; ++ ++ } ++ ++ found = 0; ++ for (i = 0; i < printer_subsys_count; i++) { ++ if (strcmp ((char *)arguments[0], printer_subsystems[i].subsys) == 0) { ++ for (j = 0; j < printer_subsystems[i].record_printers_count; j++) { ++ if (rec_ident == printer_subsystems[i].record_printers[j].ident) { ++ printer_subsystems[i].record_printers[j].print_fn (&arguments[3]); ++ found = 1; ++ } ++ } ++ } ++ } ++ if (rec_ident & LOGSYS_TAG_LOG) { ++ printf ("Log Message=%s\n", (char *)arguments[3]); ++ found = 1; ++ } ++ if (rec_ident & LOGSYS_TAG_ENTER) { ++ printf ("ENTERING function [%s] line [%d]\n", (char *)arguments[2], line); ++ found = 1; ++ } ++ if (rec_ident & LOGSYS_TAG_LEAVE) { ++ printf ("LEAVING function [%s] line [%d]\n", (char *)arguments[2], line); ++ found = 1; ++ } ++ if (found == 0) { ++ printf ("Unknown record type found subsys=[%s] ident=[%d]\n", ++ (char *)arguments[0], rec_ident); ++ } ++ ++ ++ if (rec_ident == 999) { ++ printf ("ENTERING function [%s] line [%d]\n", (char *)arguments[2], line); ++ found = 1; ++ } ++ if (rec_ident == 1000) { ++ printf ("LEAVING function [%s] line [%d]\n", (char *)arguments[2], line); ++ found = 1; ++ } ++ if (found == 0) { ++ printf ("Unknown record type found subsys=[%s] ident=[%d]\n", ++ (char *)arguments[0], rec_ident); ++ } ++ ++ ++#ifdef COMPILE_OUT ++printf ("\n"); ++#endif ++} ++ ++int main (void) ++{ ++ unsigned int fd; ++ int rec_idx; ++ int end_rec; ++ int record_count = 1; ++ int size_read; ++ ++ flt_data = malloc ((flt_data_size + 2) * sizeof (unsigned int)); ++ fd = open ("/var/lib/corosync/fdata", O_RDONLY); ++ size_read = (int)read (fd, flt_data, (flt_data_size + 2) * sizeof (unsigned int)); ++ ++ if (size_read != (flt_data_size + 2) * sizeof (unsigned int)) { ++ printf ("Warning: read %d bytes, but expected %d\n", ++ size_read, (flt_data_size + 2) * sizeof (unsigned int)); ++ } ++ ++ rec_idx = flt_data[FDTAIL_INDEX]; ++ end_rec = flt_data[FDHEAD_INDEX]; ++ ++ printf ("Starting replay: head [%d] tail [%d]\n", ++ flt_data[FDHEAD_INDEX], ++ flt_data[FDTAIL_INDEX]); ++ ++ for (;;) { ++ rec_idx = logsys_rec_get (rec_idx); ++ logsys_rec_print (record); ++ if (rec_idx == end_rec) { ++ break; ++ } ++ record_count += 1; ++ } ++ ++ printf ("Finishing replay: records found [%d]\n", record_count); ++ return (0); ++} +diff -Naurd corosync-0.92/tools/corosync-keygen.c corosync-trunk/tools/corosync-keygen.c +--- corosync-0.92/tools/corosync-keygen.c 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/tools/corosync-keygen.c 2008-11-11 19:13:47.000000000 +0100 +@@ -44,7 +44,7 @@ + int authkey_fd; + int random_fd; + unsigned char key[128]; +- int res; ++ ssize_t res; + + printf ("Corosync Cluster Engine Authentication key generator.\n"); + if (geteuid() != 0) { +@@ -80,7 +80,7 @@ + /* + * Set security of authorization key to uid = 0 uid = 0 mode = 0400 + */ +- res = fchown (authkey_fd, 0, 0); ++ fchown (authkey_fd, 0, 0); + fchmod (authkey_fd, 0400); + + printf ("Writing corosync key to /etc/ais/authkey.\n"); +diff -Naurd corosync-0.92/tools/corosync-objctl.c corosync-trunk/tools/corosync-objctl.c +--- corosync-0.92/tools/corosync-objctl.c 2008-08-14 18:44:26.000000000 +0200 ++++ corosync-trunk/tools/corosync-objctl.c 2008-12-08 17:11:07.000000000 +0100 +@@ -32,6 +32,7 @@ + * THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#include + #include + #include + #include +@@ -41,7 +42,7 @@ + #include + #include + +-#include ++#include + #include + + #define SEPERATOR '.' +@@ -104,12 +105,12 @@ + int key_name_len; + char key_value[OBJ_NAME_SIZE]; + int key_value_len; +- confdb_error_t res; ++ cs_error_t res; + int children_printed; + + /* Show the keys */ + res = confdb_key_iter_start(handle, parent_object_handle); +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + fprintf(stderr, "error resetting key iterator for object %d: %d\n", parent_object_handle, res); + exit(EXIT_FAILURE); + } +@@ -120,7 +121,7 @@ + key_name, + &key_name_len, + key_value, +- &key_value_len)) == CONFDB_OK) { ++ &key_value_len)) == CS_OK) { + key_name[key_name_len] = '\0'; + key_value[key_value_len] = '\0'; + if (parent_name != NULL) +@@ -133,7 +134,7 @@ + + /* Show sub-objects */ + res = confdb_object_iter_start(handle, parent_object_handle); +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + fprintf(stderr, "error resetting object iterator for object %d: %d\n", parent_object_handle, res); + exit(EXIT_FAILURE); + } +@@ -142,7 +143,7 @@ + parent_object_handle, + &object_handle, + object_name, +- &object_name_len)) == CONFDB_OK) { ++ &object_name_len)) == CS_OK) { + + object_name[object_name_len] = '\0'; + if (parent_name != NULL) { +@@ -165,7 +166,7 @@ + int result; + + result = confdb_initialize (&handle, &callbacks); +- if (result != CONFDB_OK) { ++ if (result != CS_OK) { + fprintf (stderr, "Could not initialize objdb library. Error %d\n", result); + return 1; + } +@@ -181,22 +182,23 @@ + static int print_help(void) + { + printf("\n"); +- printf ("usage: corosync-objctl object%ckey ...\n", SEPERATOR); +- printf (" corosync-objctl -c object%cchild_obj ...\n", SEPERATOR); +- printf (" corosync-objctl -d object%cchild_obj ...\n", SEPERATOR); +- printf (" corosync-objctl -w object%cchild_obj.key=value ...\n", SEPERATOR); +- printf (" corosync-objctl -a (print all objects)\n"); ++ printf ("usage: corosync-objctl object%ckey ... Print an object\n", SEPERATOR); ++ printf (" corosync-objctl -c object%cchild_obj ... Create Object\n", SEPERATOR); ++ printf (" corosync-objctl -d object%cchild_obj ... Delete object\n", SEPERATOR); ++ printf (" corosync-objctl -w object%cchild_obj.key=value ... Create a key\n", SEPERATOR); ++ printf (" corosync-objctl -t object%cchild_obj ... Track changes\n", SEPERATOR); ++ printf (" corosync-objctl -a Print all objects\n"); + printf("\n"); + return 0; + } + +-static confdb_error_t validate_name(char * obj_name_pt) ++static cs_error_t validate_name(char * obj_name_pt) + { + if ((strchr (obj_name_pt, SEPERATOR) == NULL) && + (strchr (obj_name_pt, '=') == NULL)) +- return CONFDB_OK; ++ return CS_OK; + else +- return CONFDB_ERR_INVALID_PARAM; ++ return CS_ERR_INVALID_PARAM; + } + + void get_child_name(char * name_pt, char * child_name) +@@ -251,7 +253,7 @@ + strcpy(key_name, tmp+1); + } + +-static confdb_error_t find_object (confdb_handle_t handle, ++static cs_error_t find_object (confdb_handle_t handle, + char * name_pt, + find_object_of_type_t type, + uint32_t * out_handle) +@@ -261,21 +263,21 @@ + uint32_t obj_handle; + confdb_handle_t parent_object_handle = OBJECT_PARENT_HANDLE; + char tmp_name[OBJ_NAME_SIZE]; +- confdb_error_t res; ++ cs_error_t res; + + strncpy (tmp_name, name_pt, OBJ_NAME_SIZE); + obj_name_pt = strtok_r(tmp_name, SEPERATOR_STR, &save_pt); + + while (obj_name_pt != NULL) { + res = confdb_object_find_start(handle, parent_object_handle); +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + fprintf (stderr, "Could not start object_find %d\n", res); + exit (EXIT_FAILURE); + } + + res = confdb_object_find(handle, parent_object_handle, + obj_name_pt, strlen (obj_name_pt), &obj_handle); +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + return res; + } + +@@ -291,11 +293,11 @@ + { + char parent_name[OBJ_NAME_SIZE]; + uint32_t obj_handle; +- confdb_error_t res; ++ cs_error_t res; + + get_parent_name(name_pt, parent_name); + res = find_object (handle, name_pt, FIND_OBJECT_OR_KEY, &obj_handle); +- if (res == CONFDB_OK) { ++ if (res == CS_OK) { + print_config_tree(handle, obj_handle, parent_name); + } + } +@@ -308,19 +310,19 @@ + char key_value[OBJ_NAME_SIZE]; + char old_key_value[OBJ_NAME_SIZE]; + int old_key_value_len; +- confdb_error_t res; ++ cs_error_t res; + + /* find the parent object */ + get_parent_name(path_pt, parent_name); + get_key(path_pt, key_name, key_value); + +- if (validate_name(key_name) != CONFDB_OK) { ++ if (validate_name(key_name) != CS_OK) { + fprintf(stderr, "Incorrect key name, can not have \"=\" or \"%c\"\n", SEPERATOR); + exit(EXIT_FAILURE); + } + res = find_object (handle, parent_name, FIND_OBJECT_ONLY, &obj_handle); + +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + fprintf(stderr, "Can't find parent object of \"%s\"\n", path_pt); + exit(EXIT_FAILURE); + } +@@ -333,7 +335,7 @@ + old_key_value, + &old_key_value_len); + +- if (res == CONFDB_OK) { ++ if (res == CS_OK) { + /* replace the current value */ + res = confdb_key_replace (handle, + obj_handle, +@@ -344,7 +346,7 @@ + key_value, + strlen(key_value)); + +- if (res != CONFDB_OK) ++ if (res != CS_OK) + fprintf(stderr, "Failed to replace the key %s=%s. Error %d\n", key_name, key_value, res); + } else { + /* not there, create a new key */ +@@ -354,7 +356,7 @@ + strlen(key_name), + key_value, + strlen(key_value)); +- if (res != CONFDB_OK) ++ if (res != CS_OK) + fprintf(stderr, "Failed to create the key %s=%s. Error %d\n", key_name, key_value, res); + } + +@@ -367,23 +369,23 @@ + uint32_t obj_handle; + uint32_t parent_object_handle = OBJECT_PARENT_HANDLE; + char tmp_name[OBJ_NAME_SIZE]; +- confdb_error_t res; ++ cs_error_t res; + + strncpy (tmp_name, name_pt, OBJ_NAME_SIZE); + obj_name_pt = strtok_r(tmp_name, SEPERATOR_STR, &save_pt); + + while (obj_name_pt != NULL) { + res = confdb_object_find_start(handle, parent_object_handle); +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + fprintf (stderr, "Could not start object_find %d\n", res); + exit (EXIT_FAILURE); + } + + res = confdb_object_find(handle, parent_object_handle, + obj_name_pt, strlen (obj_name_pt), &obj_handle); +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + +- if (validate_name(obj_name_pt) != CONFDB_OK) { ++ if (validate_name(obj_name_pt) != CS_OK) { + fprintf(stderr, "Incorrect object name \"%s\", \"=\" not allowed.\n", + obj_name_pt); + exit(EXIT_FAILURE); +@@ -393,7 +395,7 @@ + obj_name_pt, + strlen (obj_name_pt), + &obj_handle); +- if (res != CONFDB_OK) ++ if (res != CS_OK) + fprintf(stderr, "Failed to create object \"%s\". Error %d.\n", + obj_name_pt, res); + } +@@ -449,10 +451,13 @@ + int result; + fd_set read_fds; + int select_fd; +- SaBoolT quit = SA_FALSE; ++ int quit = CS_FALSE; + + FD_ZERO (&read_fds); +- confdb_fd_get(handle, &select_fd); ++ if (confdb_fd_get (handle, &select_fd) != CS_OK) { ++ printf ("can't get the confdb selector object.\n"); ++ return; ++ } + printf ("Type \"q\" to finish\n"); + do { + FD_SET (select_fd, &read_fds); +@@ -464,35 +469,36 @@ + if (FD_ISSET (STDIN_FILENO, &read_fds)) { + char inbuf[3]; + +- fgets(inbuf, sizeof(inbuf), stdin); +- if (strncmp(inbuf, "q", 1) == 0) +- quit = SA_TRUE; ++ if (fgets(inbuf, sizeof(inbuf), stdin) == NULL) ++ quit = CS_TRUE; ++ else if (strncmp(inbuf, "q", 1) == 0) ++ quit = CS_TRUE; + } + if (FD_ISSET (select_fd, &read_fds)) { +- if (confdb_dispatch (handle, CONFDB_DISPATCH_ALL) != CONFDB_OK) ++ if (confdb_dispatch (handle, CONFDB_DISPATCH_ALL) != CS_OK) + exit(1); + } +- } while (result && quit == SA_FALSE); ++ } while (result && quit == CS_FALSE); + +- confdb_stop_track_changes(handle); ++ (void)confdb_stop_track_changes(handle); + + } + + static void track_object(confdb_handle_t handle, char * name_pt) + { +- confdb_error_t res; ++ cs_error_t res; + uint32_t obj_handle; + + res = find_object (handle, name_pt, FIND_OBJECT_ONLY, &obj_handle); + +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + fprintf (stderr, "Could not find object \"%s\". Error %d\n", + name_pt, res); + return; + } + + res = confdb_track_changes (handle, obj_handle, CONFDB_TRACK_DEPTH_RECURSIVE); +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + fprintf (stderr, "Could not enable tracking on object \"%s\". Error %d\n", + name_pt, res); + return; +@@ -501,10 +507,10 @@ + + static void stop_tracking(confdb_handle_t handle) + { +- confdb_error_t res; ++ cs_error_t res; + + res = confdb_stop_track_changes (handle); +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + fprintf (stderr, "Could not stop tracking. Error %d\n", res); + return; + } +@@ -512,14 +518,14 @@ + + static void delete_object(confdb_handle_t handle, char * name_pt) + { +- confdb_error_t res; ++ cs_error_t res; + uint32_t obj_handle; + res = find_object (handle, name_pt, FIND_OBJECT_ONLY, &obj_handle); + +- if (res == CONFDB_OK) { ++ if (res == CS_OK) { + res = confdb_object_destroy (handle, obj_handle); + +- if (res != CONFDB_OK) ++ if (res != CS_OK) + fprintf(stderr, "Failed to find object \"%s\" to delete. Error %d\n", name_pt, res); + } else { + char parent_name[OBJ_NAME_SIZE]; +@@ -531,7 +537,7 @@ + get_key(name_pt, key_name, key_value); + res = find_object (handle, parent_name, FIND_OBJECT_ONLY, &obj_handle); + +- if (res != CONFDB_OK) { ++ if (res != CS_OK) { + fprintf(stderr, "Failed to find the key's parent object \"%s\". Error %d\n", parent_name, res); + exit (EXIT_FAILURE); + } +@@ -543,7 +549,7 @@ + key_value, + strlen(key_value)); + +- if (res != CONFDB_OK) ++ if (res != CS_OK) + fprintf(stderr, "Failed to delete key \"%s=%s\" from object \"%s\". Error %d\n", + key_name, key_value, parent_name, res); + } +@@ -552,8 +558,8 @@ + + int main (int argc, char *argv[]) { + confdb_handle_t handle; +- confdb_error_t result; +- char c; ++ cs_error_t result; ++ int c; + + action = ACTION_READ; + +@@ -603,7 +609,7 @@ + } + + result = confdb_initialize (&handle, &callbacks); +- if (result != CONFDB_OK) { ++ if (result != CS_OK) { + fprintf (stderr, "Failed to initialize the objdb API. Error %d\n", result); + exit (EXIT_FAILURE); + } +@@ -633,7 +639,7 @@ + } + + result = confdb_finalize (handle); +- if (result != CONFDB_OK) { ++ if (result != CS_OK) { + fprintf (stderr, "Error finalizing objdb API. Error %d\n", result); + exit(EXIT_FAILURE); + } +diff -Naurd corosync-0.92/tools/corosync-pload.c corosync-trunk/tools/corosync-pload.c +--- corosync-0.92/tools/corosync-pload.c 1970-01-01 01:00:00.000000000 +0100 ++++ corosync-trunk/tools/corosync-pload.c 2008-11-06 22:49:07.000000000 +0100 +@@ -0,0 +1,76 @@ ++/* ++ * Copyright (c) 2008 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 ++ ++#define timersub(a, b, result) \ ++do { \ ++ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ ++ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ ++ if ((result)->tv_usec < 0) { \ ++ --(result)->tv_sec; \ ++ (result)->tv_usec += 1000000; \ ++ } \ ++} while (0) ++ ++int main (void) { ++ pload_error_t result; ++ pload_handle_t handle; ++ ++ result = pload_initialize (&handle, NULL); ++ printf ("Init result %d\n", result); ++ result = pload_start ( ++ handle, ++ 0, /* code */ ++ 150000000, /* count */ ++ 300); /* size */ ++ return (0); ++} +diff -Naurd corosync-0.92/tools/Makefile corosync-trunk/tools/Makefile +--- corosync-0.92/tools/Makefile 2008-08-15 08:15:26.000000000 +0200 ++++ corosync-trunk/tools/Makefile 2008-11-11 18:28:22.000000000 +0100 +@@ -41,8 +41,8 @@ + override LDFLAGS += -lnsl -lsocket -lrt + endif + +-LIBS = ../lib/libconfdb.a ../lib/libcfg.a +-BINARIES=corosync-objctl corosync-cfgtool corosync-keygen ++LIBS = ../lib/libconfdb.a ../lib/libcfg.a ../lib/libpload.a ++BINARIES=corosync-objctl corosync-cfgtool corosync-keygen corosync-fplay corosync-pload + APPS_SRC=$(addsuffix .c,$(BINARIES)) + EXTRA_CFLAGS = -I$(srcdir)include + +@@ -57,9 +57,22 @@ + corosync-keygen: corosync-keygen.o + $(CC) $(LDFLAGS) -o $@ $< + ++corosync-fplay: corosync-fplay.o ++ $(CC) $(LDFLAGS) -o $@ $< ++ ++corosync-pload: corosync-pload.o ++ $(CC) $(LDFLAGS) -o $@ $< $(LIBS) ++ + clean: + rm -f *.o $(BINARIES) + ++lint: ++ -splint $(LINT_FLAGS) $(CFLAGS) corosync-objctl.c ++ -splint $(LINT_FLAGS) $(CFLAGS) corosync-cfgtool.c ++ -splint $(LINT_FLAGS) $(CFLAGS) corosync-keygen.c ++ -splint $(LINT_FLAGS) $(CFLAGS) corosync-fplay.c ++ -splint $(LINT_FLAGS) $(CFLAGS) corosync-pload.c ++ + %.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< + diff --git a/corosync.spec b/corosync.spec index bec5820..07f2eba 100644 --- a/corosync.spec +++ b/corosync.spec @@ -1,14 +1,14 @@ -%define alphatag svn1750 +%define alphatag svn1756 Name: corosync Summary: The Corosync Cluster Engine and Application Programming Interfaces Version: 0.92 -Release: 6%{?alphatag:.%{alphatag}}%{?dist} +Release: 7%{?alphatag:.%{alphatag}}%{?dist} License: BSD Group: System Environment/Base URL: http://www.openais.org Source0: http://developer.osdl.org/dev/openais/downloads/corosync-%{version}/corosync-%{version}.tar.gz -Patch0: corosync-trunk-1750.diff +Patch0: corosync-trunk.diff BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires(pre): /usr/sbin/useradd @@ -26,6 +26,7 @@ APIs and libraries, default configuration files, and an init script. Summary: The Corosync Cluster Engine Group: System Environment/Libraries Requires: %{name} = %{version}-%{release} +Requires: pkgconfig %description devel This package contains include files and man pages used to develop using @@ -154,6 +155,7 @@ fi %{_libdir}/corosync/libcoroutil.so %{_libdir}/corosync/libquorum.so %{_libdir}/corosync/libvotequorum.so +%{_libdir}/pkgconfig/*.pc %{_mandir}/man3/cpg_*3* %{_mandir}/man3/evs_*3* %{_mandir}/man3/confdb_*3* @@ -165,6 +167,10 @@ fi %{_mandir}/man8/votequorum_overview.8* %changelog +* Mon Feb 2 2009 Fabio M. Di Nitto - 0.92-7.svn1756 +- Update to svn trunk at revision 1756 from upstream. +- Add support pkgconfig to devel package. + * Tue Jan 27 2009 Fabio M. Di Nitto - 0.92-6.svn1750 - Update to svn trunk at revision 1750 from upstream. - Include new quorum service in the packaging.