45#include <qb/qbipc_common.h>
75static uint8_t qdevice_can_operate = 1;
76static void *qdevice_reg_conn =
NULL;
77static uint8_t qdevice_master_wins = 0;
82static uint8_t wait_for_all_status = 0;
83static uint8_t wait_for_all_autoset = 0;
86static int lowest_node_id = -1;
87static int highest_node_id = -1;
89#define DEFAULT_LMS_WIN 10000
90static uint8_t last_man_standing = 0;
93static uint8_t allow_downscale = 0;
97static uint32_t ev_tracking_barrier = 0;
98static int ev_tracking_fd = -1;
144#define MESSAGE_REQ_EXEC_VOTEQUORUM_NODEINFO 0
145#define MESSAGE_REQ_EXEC_VOTEQUORUM_RECONFIGURE 1
146#define MESSAGE_REQ_EXEC_VOTEQUORUM_QDEVICE_REG 2
147#define MESSAGE_REQ_EXEC_VOTEQUORUM_QDEVICE_RECONFIGURE 3
149static void votequorum_exec_send_expectedvotes_notification(
void);
150static int votequorum_exec_send_quorum_notification(
void *conn,
uint64_t context);
151static int votequorum_exec_send_nodelist_notification(
void *conn,
uint64_t context);
153#define VOTEQUORUM_RECONFIG_PARAM_EXPECTED_VOTES 1
154#define VOTEQUORUM_RECONFIG_PARAM_NODE_VOTES 2
155#define VOTEQUORUM_RECONFIG_PARAM_CANCEL_WFA 3
162#define VOTEQUORUM_QDEVICE_OPERATION_UNREGISTER 0
163#define VOTEQUORUM_QDEVICE_OPERATION_REGISTER 1
169#define NODE_FLAGS_QUORATE 1
170#define NODE_FLAGS_LEAVING 2
171#define NODE_FLAGS_WFASTATUS 4
172#define NODE_FLAGS_FIRST 8
173#define NODE_FLAGS_QDEVICE_REGISTERED 16
174#define NODE_FLAGS_QDEVICE_ALIVE 32
175#define NODE_FLAGS_QDEVICE_CAST_VOTE 64
176#define NODE_FLAGS_QDEVICE_MASTER_WINS 128
198static uint8_t cluster_is_quorate;
209static int quorum_members_entries = 0;
210static int previous_quorum_members_entries = 0;
211static int atb_nodelist_entries = 0;
218static int cluster_nodes_entries = 0;
238static int qdevice_timer_set = 0;
240static int last_man_standing_timer_set = 0;
241static int sync_nodeinfo_sent = 0;
242static int sync_wait_for_poll_or_timeout = 0;
248static int sync_in_progress = 0;
250static void votequorum_sync_init (
253 const unsigned int *member_list,
254 size_t member_list_entries,
257static int votequorum_sync_process (
void);
258static void votequorum_sync_activate (
void);
259static void votequorum_sync_abort (
void);
268static int votequorum_exec_exit_fn (
void);
271static void message_handler_req_exec_votequorum_nodeinfo (
274static void exec_votequorum_nodeinfo_endian_convert (
void *
message);
276static void message_handler_req_exec_votequorum_reconfigure (
279static void exec_votequorum_reconfigure_endian_convert (
void *
message);
281static void message_handler_req_exec_votequorum_qdevice_reg (
284static void exec_votequorum_qdevice_reg_endian_convert (
void *
message);
286static void message_handler_req_exec_votequorum_qdevice_reconfigure (
289static void exec_votequorum_qdevice_reconfigure_endian_convert (
void *
message);
295 .exec_endian_convert_fn = exec_votequorum_nodeinfo_endian_convert
298 .exec_handler_fn = message_handler_req_exec_votequorum_reconfigure,
299 .exec_endian_convert_fn = exec_votequorum_reconfigure_endian_convert
302 .exec_handler_fn = message_handler_req_exec_votequorum_qdevice_reg,
303 .exec_endian_convert_fn = exec_votequorum_qdevice_reg_endian_convert
306 .exec_handler_fn = message_handler_req_exec_votequorum_qdevice_reconfigure,
307 .exec_endian_convert_fn = exec_votequorum_qdevice_reconfigure_endian_convert
315static int quorum_lib_init_fn (
void *conn);
317static int quorum_lib_exit_fn (
void *conn);
319static void qdevice_timer_fn(
void *
arg);
321static void message_handler_req_lib_votequorum_getinfo (
void *conn,
324static void message_handler_req_lib_votequorum_setexpected (
void *conn,
327static void message_handler_req_lib_votequorum_setvotes (
void *conn,
330static void message_handler_req_lib_votequorum_trackstart (
void *conn,
333static void message_handler_req_lib_votequorum_trackstop (
void *conn,
336static void message_handler_req_lib_votequorum_qdevice_register (
void *conn,
339static void message_handler_req_lib_votequorum_qdevice_unregister (
void *conn,
342static void message_handler_req_lib_votequorum_qdevice_update (
void *conn,
345static void message_handler_req_lib_votequorum_qdevice_poll (
void *conn,
348static void message_handler_req_lib_votequorum_qdevice_master_wins (
void *conn,
358 .lib_handler_fn = message_handler_req_lib_votequorum_setexpected,
362 .lib_handler_fn = message_handler_req_lib_votequorum_setvotes,
366 .lib_handler_fn = message_handler_req_lib_votequorum_trackstart,
370 .lib_handler_fn = message_handler_req_lib_votequorum_trackstop,
374 .lib_handler_fn = message_handler_req_lib_votequorum_qdevice_register,
378 .lib_handler_fn = message_handler_req_lib_votequorum_qdevice_unregister,
382 .lib_handler_fn = message_handler_req_lib_votequorum_qdevice_update,
386 .lib_handler_fn = message_handler_req_lib_votequorum_qdevice_poll,
390 .lib_handler_fn = message_handler_req_lib_votequorum_qdevice_master_wins,
396 .
name =
"corosync vote quorum service v1.0",
399 .private_data_size =
sizeof (
struct quorum_pd),
402 .lib_init_fn = quorum_lib_init_fn,
403 .lib_exit_fn = quorum_lib_exit_fn,
404 .lib_engine = quorum_lib_service,
406 .exec_init_fn = votequorum_exec_init_fn,
407 .exec_exit_fn = votequorum_exec_exit_fn,
408 .exec_engine = votequorum_exec_engine,
410 .sync_init = votequorum_sync_init,
411 .sync_process = votequorum_sync_process,
412 .sync_activate = votequorum_sync_activate,
413 .sync_abort = votequorum_sync_abort
418 return (&votequorum_service_engine);
423 .
name =
"corosync_votequorum",
433#define max(a,b) (((a) > (b)) ? (a) : (b))
466 cl = (
struct cluster_node *)&cluster_nodes[cluster_nodes_entries];
467 cluster_nodes_entries++;
488 node_add_ordered(
cl);
526static void get_lowest_node_id(
void)
538 (
node->node_id < lowest_node_id)) {
539 lowest_node_id =
node->node_id;
548static void get_highest_node_id(
void)
560 (
node->node_id > highest_node_id)) {
561 highest_node_id =
node->node_id;
570static int check_low_node_id_partition(
void)
581 (
node->node_id == lowest_node_id)) {
590static int check_high_node_id_partition(
void)
601 (
node->node_id == highest_node_id)) {
610static int is_in_nodelist(
int nodeid,
unsigned int *
members,
int entries)
615 for (
i=0;
i<entries;
i++) {
638static int check_auto_tie_breaker(
void)
645 res = check_low_node_id_partition();
651 res = check_high_node_id_partition();
658 for (
i=0;
i < atb_nodelist_entries;
i++) {
659 if (is_in_nodelist(atb_nodelist[
i], quorum_members, quorum_members_entries)) {
666 for (
j=0;
j<
i;
j++) {
667 if (is_in_nodelist(atb_nodelist[
j], previous_quorum_members, previous_quorum_members_entries)) {
710 atb_nodelist_entries = 0;
716 atb_nodelist[atb_nodelist_entries++] =
num;
720 if (atb_nodelist_entries) {
729 log_printf(
LOGSYS_LEVEL_WARNING,
"auto_tie_breaker_nodes is not valid. It must be 'lowest', 'highest' or a space-separated list of node IDs. auto_tie_breaker is disabled");
735static int check_qdevice_master(
void)
761 "flags: quorate: %s Leaving: %s WFA Status: %s First: %s Qdevice: %s QdeviceAlive: %s QdeviceCastVote: %s QdeviceMasterWins: %s",
777static int load_ev_tracking_barrier(
void)
787 if (ev_tracking_fd != -1) {
789 close(ev_tracking_fd);
796 ev_tracking_barrier = 0;
799 if (ev_tracking_fd != -1) {
805 close(ev_tracking_fd);
810 "Unable to create %s file",
filename);
822 if (wait_for_all_status) {
828 wait_for_all_status);
833static void update_two_node(
void)
856 qdevice_can_operate =
status;
857 icmap_set_uint8(
"runtime.votequorum.qdevice_can_operate", qdevice_can_operate);
862static void update_qdevice_master_wins(
uint8_t allow)
866 qdevice_master_wins = allow;
867 icmap_set_uint8(
"runtime.votequorum.qdevice_master_wins", qdevice_master_wins);
879 icmap_set_uint32(
"runtime.votequorum.ev_tracking_barrier", ev_tracking_barrier);
883 "Unable to update ev_tracking_barrier on disk data!!!");
891 "Unable to update ev_tracking_barrier on disk data!!!");
896 fsync(ev_tracking_fd);
910 unsigned int total_votes = 0;
911 unsigned int highest_expected = 0;
928 highest_expected =
max(highest_expected,
node->expected_votes);
929 total_votes +=
node->votes;
936 total_votes += qdevice->
votes;
948 q1 = (highest_expected + 2) / 2;
949 q2 = (total_votes + 2) / 2;
995static void are_we_quorate(
unsigned int total_votes)
1006 if ((wait_for_all) && (wait_for_all_status)) {
1009 "Waiting for all cluster members. "
1010 "Current votes: %d expected_votes: %d",
1012 assert(!cluster_is_quorate);
1015 update_wait_for_all_status(0);
1018 if (quorum > total_votes) {
1022 get_lowest_node_id();
1023 get_highest_node_id();
1026 if ((auto_tie_breaker !=
ATB_NONE) &&
1030 (previous_quorum_members_entries - quorum_members_entries < quorum) &&
1031 (check_auto_tie_breaker() == 1)) {
1035 if ((qdevice_master_wins) &&
1037 (check_qdevice_master() == 1)) {
1042 if (cluster_is_quorate && !
quorate) {
1046 if (!cluster_is_quorate &&
quorate) {
1052 if (cluster_is_quorate) {
1060 update_wait_for_all_status(0);
1062 update_wait_for_all_status(1);
1067 (sync_in_progress == 0)) {
1068 quorum_callback(quorum_members, quorum_members_entries,
1069 cluster_is_quorate, &quorum_ringid);
1070 votequorum_exec_send_quorum_notification(
NULL, 0
L);
1078 unsigned int total_votes = 0;
1089 total_votes +=
node->votes;
1093 if (qdevice->
votes) {
1094 total_votes += qdevice->
votes;
1109 unsigned int total_votes = 0;
1126 votequorum_exec_send_expectedvotes_notification();
1129 if ((ev_tracking) &&
1137 are_we_quorate(total_votes);
1146static int votequorum_read_nodelist_configuration(
uint32_t *
votes,
1163 "No nodelist defined or our node is not in the nodelist");
1196 *
votes = node_votes;
1210static int votequorum_qdevice_is_configured(
uint32_t *qdevice_votes)
1220 *qdevice_votes = -1;
1228 update_qdevice_can_operate(1);
1240#define VOTEQUORUM_READCONFIG_STARTUP 0
1241#define VOTEQUORUM_READCONFIG_RUNTIME 1
1243static char *votequorum_readconfig(
int runtime)
1245 uint32_t node_votes = 0, qdevice_votes = 0;
1268 auto_tie_breaker = initial_auto_tie_breaker;
1277 have_qdevice = votequorum_qdevice_is_configured(&qdevice_votes);
1286 error = (
char *)
"configuration error: nodelist or quorum.expected_votes must be configured!";
1301 error = (
char *)
"configuration error: two_node and quorum device cannot be configured at the same time!";
1310 update_qdevice_can_operate(0);
1321 wait_for_all_autoset = 1;
1338 "auto_tie_breaker_node: is meaningless if auto_tie_breaker is set to 0");
1346 initial_auto_tie_breaker = auto_tie_breaker;
1349 if (allow_downscale) {
1354 if (load_ev_tracking_barrier() < 0) {
1356 return ((
char *)
"Unable to load ev_tracking file!");
1358 update_ev_tracking_barrier(ev_tracking_barrier);
1368 if (wait_for_all_autoset) {
1369 wait_for_all = two_node;
1375 if (two_node && auto_tie_breaker !=
ATB_NONE) {
1385 if ((auto_tie_breaker !=
ATB_NONE) && (node_expected_votes % 2) &&
1387 if (last_man_standing) {
1396 error = (
char *)
"configuration error: auto_tie_breaker & last_man_standing not available in odd sized cluster";
1417 error = (
char *)
"configuration error: quorum.device is not compatible with last_man_standing";
1422 update_qdevice_can_operate(0);
1428 error = (
char *)
"configuration error: quorum.device is not compatible with auto_tie_breaker";
1433 update_qdevice_can_operate(0);
1439 error = (
char *)
"configuration error: quorum.device is not compatible with allow_downscale";
1444 update_qdevice_can_operate(0);
1455 error = (
char *)
"configuration error: quorum.device.votes must be specified when quorum.expected_votes is set";
1460 update_qdevice_can_operate(0);
1470 (qdevice_votes == -1) &&
1474 error = (
char *)
"configuration error: quorum.device.votes must be specified when not all nodes votes 1";
1479 update_qdevice_can_operate(0);
1491 error = (
char *)
"configuration error: quorum.device.votes is too high or expected_votes is too low";
1496 update_qdevice_can_operate(0);
1506 (qdevice_votes == -1) &&
1510 qdevice_votes = node_expected_votes - 1;
1511 node_expected_votes = node_expected_votes + qdevice_votes;
1524 us->
votes = node_votes;
1543 if (qdevice_votes != -1) {
1544 qdevice->
votes = qdevice_votes;
1551 update_wait_for_all_status(1);
1553 }
else if (wait_for_all_autoset && wait_for_all_status) {
1558 update_wait_for_all_status(0);
1566static void votequorum_refresh_config(
1568 const char *key_name,
1589 if ( (
strcmp(key_name,
"config.totemconfig_reload_in_progress") == 0) &&
1596 if (
strcmp(key_name,
"quorum.cancel_wait_for_all") == 0 &&
1617 votequorum_exec_send_nodeinfo(us->
node_id);
1635static void votequorum_exec_add_config_notification(
void)
1645 votequorum_refresh_config,
1651 votequorum_refresh_config,
1657 votequorum_refresh_config,
1715 decode_flags(
node->flags);
1730static int votequorum_exec_send_qdevice_reconfigure(
const char *
oldname,
const char *
newname)
1780static int votequorum_exec_send_quorum_notification(
void *conn,
uint64_t context)
1843static int votequorum_exec_send_nodelist_notification(
void *
conn,
uint64_t context)
1863 for (
i=0;
i<quorum_members_entries;
i++) {
1891static void votequorum_exec_send_expectedvotes_notification(
void)
1916static void exec_votequorum_qdevice_reconfigure_endian_convert (
void *
message)
1923static void message_handler_req_exec_votequorum_qdevice_reconfigure (
1950static void exec_votequorum_qdevice_reg_endian_convert (
void *
message)
1961static void message_handler_req_exec_votequorum_qdevice_reg (
1982 if (!
strlen(qdevice_name)) {
2003 if (!qdevice_reg_conn) {
2012 if (!
strlen(qdevice_name)) {
2023 votequorum_exec_send_nodeinfo(us->
node_id);
2026 "A new qdevice with different name (new: %s old: %s) is trying to register!",
2035 qdevice_reg_conn =
NULL;
2055static void exec_votequorum_nodeinfo_endian_convert (
void *
message)
2069static void message_handler_req_exec_votequorum_nodeinfo (
2071 unsigned int sender_nodeid)
2125 if ((!cluster_is_quorate) &&
2145 if ((!cluster_is_quorate) &&
2157 if ((last_man_standing) && (
node->votes > 1)) {
2159 "cluster nodes votes are set to 1. Disabling LMS.");
2160 last_man_standing = 0;
2161 if (last_man_standing_timer_set) {
2163 last_man_standing_timer_set = 0;
2178 if ((wait_for_all) &&
2181 update_wait_for_all_status(0);
2187static void exec_votequorum_reconfigure_endian_convert (
void *
message)
2199static void message_handler_req_exec_votequorum_reconfigure (
2215 votequorum_exec_send_expectedvotes_notification();
2220 recalculate_quorum(1, 0);
2230 recalculate_quorum(1, 0);
2234 update_wait_for_all_status(0);
2237 recalculate_quorum(0, 0);
2246static int votequorum_exec_exit_fn (
void)
2256 if (allow_downscale) {
2258 ret = votequorum_exec_send_nodeinfo(us->
node_id);
2261 if ((ev_tracking) && (ev_tracking_fd != -1)) {
2262 close(ev_tracking_fd);
2270static void votequorum_set_icmap_ro_keys(
void)
2294 memset(cluster_nodes, 0,
sizeof(cluster_nodes));
2302 return ((
char *)
"Could not allocate node.");
2313 return ((
char *)
"Could not allocate node.");
2326 recalculate_quorum(0, 0);
2331 votequorum_set_icmap_ro_keys();
2336 votequorum_exec_add_config_notification();
2341 votequorum_exec_send_nodeinfo(us->
node_id);
2352static void votequorum_last_man_standing_timer_fn(
void *
arg)
2356 last_man_standing_timer_set = 0;
2357 if (cluster_is_quorate) {
2358 recalculate_quorum(1,1);
2364static void votequorum_sync_init (
2366 const unsigned int *member_list,
size_t member_list_entries,
2376 sync_in_progress = 1;
2377 sync_nodeinfo_sent = 0;
2378 sync_wait_for_poll_or_timeout = 0;
2380 if (member_list_entries > 1) {
2390 for (
i = 0;
i < quorum_members_entries;
i++) {
2392 for (
j = 0;
j < member_list_entries;
j++) {
2393 if (quorum_members[
i] == member_list[
j]) {
2400 node = find_node_by_nodeid(quorum_members[
i]);
2407 if (last_man_standing) {
2408 if (((member_list_entries >= quorum) && (
left_nodes)) ||
2409 ((member_list_entries <= quorum) && (auto_tie_breaker !=
ATB_NONE) && (check_low_node_id_partition() == 1))) {
2410 if (last_man_standing_timer_set) {
2412 last_man_standing_timer_set = 0;
2414 corosync_api->
timer_add_duration((
unsigned long long)last_man_standing_window*1000000,
2415 NULL, votequorum_last_man_standing_timer_fn,
2416 &last_man_standing_timer);
2417 last_man_standing_timer_set = 1;
2421 memcpy(previous_quorum_members, quorum_members,
sizeof(
unsigned int) * quorum_members_entries);
2422 previous_quorum_members_entries = quorum_members_entries;
2424 memcpy(quorum_members, member_list,
sizeof(
unsigned int) * member_list_entries);
2425 quorum_members_entries = member_list_entries;
2432 if (qdevice_timer_set) {
2435 corosync_api->
timer_add_duration((
unsigned long long)qdevice_sync_timeout*1000000, qdevice,
2436 qdevice_timer_fn, &qdevice_timer);
2437 qdevice_timer_set = 1;
2438 sync_wait_for_poll_or_timeout = 1;
2441 qdevice_name, qdevice_sync_timeout);
2447static int votequorum_sync_process (
void)
2449 if (!sync_nodeinfo_sent) {
2450 votequorum_exec_send_nodeinfo(us->
node_id);
2452 if (
strlen(qdevice_name)) {
2456 votequorum_exec_send_nodelist_notification(
NULL, 0
LL);
2457 sync_nodeinfo_sent = 1;
2471static void votequorum_sync_activate (
void)
2473 recalculate_quorum(0, 0);
2474 quorum_callback(quorum_members, quorum_members_entries,
2475 cluster_is_quorate, &quorum_ringid);
2476 votequorum_exec_send_quorum_notification(
NULL, 0
L);
2478 sync_in_progress = 0;
2481static void votequorum_sync_abort (
void)
2494 return ((
char *)
"Quorate function not set");
2501 &votequorum_service[0]);
2515static int quorum_lib_init_fn (
void *conn)
2528static int quorum_lib_exit_fn (
void *
conn)
2548static void qdevice_timer_fn(
void *
arg)
2553 (!qdevice_timer_set)) {
2561 votequorum_exec_send_nodeinfo(us->
node_id);
2563 qdevice_timer_set = 0;
2564 sync_wait_for_poll_or_timeout = 0;
2573static void message_handler_req_lib_votequorum_getinfo (
void *
conn,
const void *
message)
2578 unsigned int highest_expected = 0;
2579 unsigned int total_votes = 0;
2607 total_votes += qdevice->
votes;
2610 switch(
node->state) {
2637 if (cluster_is_quorate) {
2643 if (last_man_standing) {
2646 if (auto_tie_breaker !=
ATB_NONE) {
2649 if (allow_downscale) {
2682static void message_handler_req_lib_votequorum_setexpected (
void *conn,
const void *
message)
2688 unsigned int total_votes;
2694 allow_downscale = 0;
2706 (cluster_is_quorate && (
newquorum > total_votes))) {
2726static void message_handler_req_lib_votequorum_setvotes (
void *conn,
const void *
message)
2732 unsigned int total_votes;
2752 newquorum = calculate_quorum(1, 0, &total_votes);
2775static void message_handler_req_lib_votequorum_trackstart (
void *conn,
2823static void message_handler_req_lib_votequorum_trackstop (
void *
conn,
2849static void message_handler_req_lib_votequorum_qdevice_register (
void *
conn,
2858 if (!qdevice_can_operate) {
2859 log_printf(
LOGSYS_LEVEL_INFO,
"Registration of quorum device is disabled by incorrect corosync.conf. See logs for more information");
2870 "A new qdevice with different name (new: %s old: %s) is trying to re-register!",
2876 if (qdevice_reg_conn !=
NULL) {
2878 "Registration request already in progress");
2882 qdevice_reg_conn = conn;
2886 "Unable to send qdevice registration request to cluster");
2888 qdevice_reg_conn =
NULL;
2905static void message_handler_req_lib_votequorum_qdevice_unregister (
void *conn,
2919 if (qdevice_timer_set) {
2921 qdevice_timer_set = 0;
2922 sync_wait_for_poll_or_timeout = 0;
2928 votequorum_exec_send_nodeinfo(us->
node_id);
2944static void message_handler_req_lib_votequorum_qdevice_update (
void *conn,
2973static void message_handler_req_lib_votequorum_qdevice_poll (
void *conn,
2983 if (!qdevice_can_operate) {
2994 quorum_ringid.
nodeid, quorum_ringid.
seq);
3003 if (qdevice_timer_set) {
3005 qdevice_timer_set = 0;
3019 votequorum_exec_send_nodeinfo(us->
node_id);
3022 corosync_api->
timer_add_duration((
unsigned long long)qdevice_timeout*1000000, qdevice,
3023 qdevice_timer_fn, &qdevice_timer);
3024 qdevice_timer_set = 1;
3025 sync_wait_for_poll_or_timeout = 0;
3039static void message_handler_req_lib_votequorum_qdevice_master_wins (
void *conn,
3049 if (!qdevice_can_operate) {
3067 votequorum_exec_send_nodeinfo(us->
node_id);
#define SERVICE_ID_MAKE(a, b)
qb_loop_timer_handle corosync_timer_handle_t
corosync_timer_handle_t
#define COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
#define COROSYNC_LIB_FLOW_CONTROL_REQUIRED
#define PROCESSOR_COUNT_MAX
#define CS_TRACK_CHANGES_ONLY
cs_error_t
The cs_error_t enum.
void(* quorum_set_quorate_fn_t)(const unsigned int *view_list, size_t view_list_entries, int quorate, struct memb_ring_id *)
struct corosync_service_engine * votequorum_get_service_engine_ver0(void)
#define VOTEQUORUM_RECONFIG_PARAM_CANCEL_WFA
#define NODE_FLAGS_QUORATE
#define VOTEQUORUM_RECONFIG_PARAM_NODE_VOTES
char * votequorum_init(struct corosync_api_v1 *api, quorum_set_quorate_fn_t q_set_quorate_fn)
#define VOTEQUORUM_RECONFIG_PARAM_EXPECTED_VOTES
#define VOTEQUORUM_QDEVICE_OPERATION_UNREGISTER
char oldname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
#define NODE_FLAGS_QDEVICE_REGISTERED
#define MESSAGE_REQ_EXEC_VOTEQUORUM_QDEVICE_RECONFIGURE
char newname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
#define NODE_FLAGS_QDEVICE_CAST_VOTE
#define MESSAGE_REQ_EXEC_VOTEQUORUM_RECONFIGURE
#define NODE_FLAGS_QDEVICE_MASTER_WINS
#define VOTEQUORUM_READCONFIG_STARTUP
#define NODE_FLAGS_LEAVING
#define NODE_FLAGS_QDEVICE_ALIVE
#define NODE_FLAGS_WFASTATUS
#define MESSAGE_REQ_EXEC_VOTEQUORUM_QDEVICE_REG
#define VOTEQUORUM_QDEVICE_OPERATION_REGISTER
#define MESSAGE_REQ_EXEC_VOTEQUORUM_NODEINFO
#define VOTEQUORUM_READCONFIG_RUNTIME
cs_error_t icmap_get_uint8(const char *key_name, uint8_t *u8)
#define ICMAP_TRACK_MODIFY
cs_error_t icmap_get_uint32(const char *key_name, uint32_t *u32)
cs_error_t icmap_set_uint8(const char *key_name, uint8_t value)
cs_error_t icmap_set_ro_access(const char *key_name, int prefix, int ro_access)
Set read-only access for given key (key_name) or prefix, If prefix is set.
#define ICMAP_TRACK_DELETE
cs_error_t icmap_track_add(const char *key_name, int32_t track_type, icmap_notify_fn_t notify_fn, void *user_data, icmap_track_t *icmap_track)
Add tracking function for given key_name.
#define ICMAP_TRACK_PREFIX
Whole prefix is tracked, instead of key only (so "totem." tracking means that "totem....
icmap_iter_t icmap_iter_init(const char *prefix)
Initialize iterator with given prefix.
const char * icmap_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type)
Return next item in iterator iter.
qb_map_iter_t * icmap_iter_t
Itterator type.
void icmap_iter_finalize(icmap_iter_t iter)
Finalize iterator.
cs_error_t icmap_get_int32(const char *key_name, int32_t *i32)
#define ICMAP_KEYNAME_MAXLEN
Maximum length of key in icmap.
cs_error_t icmap_set_uint32(const char *key_name, uint32_t value)
cs_error_t icmap_get_string(const char *key_name, char **str)
Shortcut for icmap_get for string type.
#define VOTEQUORUM_QDEVICE_DEFAULT_SYNC_TIMEOUT
#define VOTEQUORUM_INFO_AUTO_TIE_BREAKER
#define VOTEQUORUM_INFO_QDEVICE_ALIVE
#define VOTEQUORUM_NODESTATE_MEMBER
#define VOTEQUORUM_NODESTATE_DEAD
#define VOTEQUORUM_INFO_ALLOW_DOWNSCALE
@ MESSAGE_RES_VOTEQUORUM_NODELIST_NOTIFICATION
@ MESSAGE_RES_VOTEQUORUM_EXPECTEDVOTES_NOTIFICATION
@ MESSAGE_RES_VOTEQUORUM_STATUS
@ MESSAGE_RES_VOTEQUORUM_QUORUM_NOTIFICATION
@ MESSAGE_RES_VOTEQUORUM_GETINFO
#define VOTEQUORUM_INFO_QDEVICE_MASTER_WINS
#define VOTEQUORUM_NODESTATE_LEAVING
#define VOTEQUORUM_INFO_TWONODE
#define VOTEQUORUM_INFO_WAIT_FOR_ALL
#define VOTEQUORUM_INFO_QUORATE
#define VOTEQUORUM_INFO_QDEVICE_REGISTERED
#define VOTEQUORUM_INFO_LAST_MAN_STANDING
#define VOTEQUORUM_QDEVICE_MAX_NAME_LEN
#define VOTEQUORUM_QDEVICE_NODEID
#define VOTEQUORUM_INFO_QDEVICE_CAST_VOTE
#define VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT
#define LOGSYS_LEVEL_ERROR
#define log_printf(level, format, args...)
#define LOGSYS_LEVEL_INFO
#define LOGSYS_LEVEL_CRIT
#define LOGSYS_LEVEL_NOTICE
#define LOGSYS_DECLARE_SUBSYS(subsys)
The LOGSYS_DECLARE_SUBSYS macro.
#define LOGSYS_LEVEL_WARNING
#define LOGSYS_LEVEL_DEBUG
char * corosync_service_link_and_init(struct corosync_api_v1 *corosync_api, struct default_service *service)
Link and initialize a service.
The corosync_api_v1 struct.
int(* timer_add_duration)(unsigned long long nanoseconds_in_future, void *data, void(*timer_nf)(void *data), corosync_timer_handle_t *handle)
int(* totem_mcast)(const struct iovec *iovec, unsigned int iov_len, unsigned int guarantee)
void *(* ipc_private_data_get)(void *conn)
void(* timer_delete)(corosync_timer_handle_t timer_handle)
unsigned int(* totem_nodeid_get)(void)
int(* ipc_dispatch_send)(void *conn, const void *msg, size_t mlen)
int(* ipc_response_send)(void *conn, const void *msg, size_t mlen)
void(* error_memory_failure)(void) __attribute__((noreturn))
The corosync_exec_handler struct.
void(* exec_handler_fn)(const void *msg, unsigned int nodeid)
The corosync_lib_handler struct.
void(* lib_handler_fn)(void *conn, const void *msg)
The corosync_service_engine struct.
Structure passed as new_value and old_value in change callback.
unsigned char track_flags
uint64_t tracking_context
char qdevice_name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
The req_lib_votequorum_getinfo struct.
The req_lib_votequorum_qdevice_master_wins struct.
char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
The req_lib_votequorum_qdevice_poll struct.
char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
The req_lib_votequorum_qdevice_register struct.
char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
The req_lib_votequorum_qdevice_unregister struct.
char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
The req_lib_votequorum_qdevice_update struct.
char newname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
char oldname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
The req_lib_votequorum_setexpected struct.
unsigned int expected_votes
The req_lib_votequorum_setvotes struct.
The req_lib_votequorum_trackstart struct.
The res_lib_votequorum_expectedvotes_notification struct.
The res_lib_votequorum_getinfo struct.
unsigned int highest_expected
char qdevice_name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
unsigned int expected_votes
unsigned int qdevice_votes
The res_lib_votequorum_quorum_notification struct.
The res_lib_votequorum_status struct.
The votequorum_node struct.
#define swab32(x)
The swab32 macro.
struct memb_ring_id ring_id
struct totem_message_header header
const char * get_state_dir(void)