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