static int show_nodes(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type) { int err; int result = EXIT_FAILURE; err = quorum_trackstart(q_handle, CS_TRACK_CURRENT); if (err != CS_OK) { fprintf(stderr, "Unable to start quorum status tracking: %s\n", cs_strerror(err)); goto err_exit; } g_called = 0; while (g_called == 0) { err = quorum_dispatch(q_handle, CS_DISPATCH_ONE); if (err != CS_OK) { fprintf(stderr, "Unable to dispatch quorum status: %s\n", cs_strerror(err)); goto err_exit; } } display_nodes_data(nodeid_format, name_format, sort_type); result = EXIT_SUCCESS; err_exit: return result; }
void process_cluster(int ci) { cs_error_t err; err = quorum_dispatch(qh, CS_DISPATCH_ALL); if (err != CS_OK) cluster_dead(0); }
/* Force re-read of quorum nodes */ void update_cluster(void) { cs_error_t err; err = quorum_dispatch(qh, CS_DISPATCH_ONE); if (err != CS_OK) cluster_dead(0); }
/* * return 1 if quorate * 0 if not quorate * -1 on error */ static int show_status(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type) { int is_quorate; int err; err=quorum_getquorate(q_handle, &is_quorate); if (err != CS_OK) { fprintf(stderr, "Unable to get cluster quorate status: %s\n", cs_strerror(err)); goto quorum_err; } err=quorum_trackstart(q_handle, CS_TRACK_CURRENT); if (err != CS_OK) { fprintf(stderr, "Unable to start quorum status tracking: %s\n", cs_strerror(err)); goto quorum_err; } g_called = 0; while (g_called == 0 && err == CS_OK) { err = quorum_dispatch(q_handle, CS_DISPATCH_ONE); if (err != CS_OK) { fprintf(stderr, "Unable to dispatch quorum status: %s\n", cs_strerror(err)); } } if (quorum_trackstop(q_handle) != CS_OK) { fprintf(stderr, "Unable to stop quorum status tracking: %s\n", cs_strerror(err)); } if (using_votequorum()) { if ( (err=votequorum_trackstart(v_handle, 0LL, CS_TRACK_CURRENT)) != CS_OK) { fprintf(stderr, "Unable to start votequorum status tracking: %s\n", cs_strerror(err)); goto quorum_err; } g_vq_called = 0; while (g_vq_called == 0 && err == CS_OK) { err = votequorum_dispatch(v_handle, CS_DISPATCH_ONE); if (err != CS_OK) { fprintf(stderr, "Unable to dispatch votequorum status: %s\n", cs_strerror(err)); } } } quorum_err: if (err != CS_OK) { return -1; } err = display_quorum_data(is_quorate, nodeid_format, name_format, sort_type, 0); if (err != CS_OK) { return -1; } return is_quorate; }
static int monitor_status(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type) { int err; int loop = 0; if (q_type == QUORUM_FREE) { printf("\nQuorum is not configured - cannot monitor\n"); return show_status(nodeid_format, name_format, sort_type); } err=quorum_trackstart(q_handle, CS_TRACK_CHANGES); if (err != CS_OK) { fprintf(stderr, "Unable to start quorum status tracking: %s\n", cs_strerror(err)); goto quorum_err; } if (using_votequorum()) { if ( (err=votequorum_trackstart(v_handle, 0LL, CS_TRACK_CHANGES)) != CS_OK) { fprintf(stderr, "Unable to start votequorum status tracking: %s\n", cs_strerror(err)); goto quorum_err; } } while (1) { err = quorum_dispatch(q_handle, CS_DISPATCH_ONE); if (err != CS_OK) { fprintf(stderr, "Unable to dispatch quorum status: %s\n", cs_strerror(err)); goto quorum_err; } if (using_votequorum()) { g_vq_called = 0; while (!g_vq_called) { err = votequorum_dispatch(v_handle, CS_DISPATCH_ONE); if (err != CS_OK) { fprintf(stderr, "Unable to dispatch votequorum status: %s\n", cs_strerror(err)); goto quorum_err; } } } err = display_quorum_data(g_quorate, nodeid_format, name_format, sort_type, loop); printf("\n"); loop = 1; if (err != CS_OK) { fprintf(stderr, "Unable to display quorum data: %s\n", cs_strerror(err)); goto quorum_err; } } quorum_err: return -1; }
static int pcmk_quorum_dispatch(gpointer user_data) { int rc = 0; rc = quorum_dispatch(pcmk_quorum_handle, CS_DISPATCH_ALL); if (rc < 0) { crm_err("Connection to the Quorum API failed: %d", rc); pcmk_quorum_handle = 0; return -1; } return 0; }
static int _cs_quorum_dispatch(int fd, int revents, void *data) { cs_error_t err; err = quorum_dispatch(quorum_handle, CS_DISPATCH_ONE); if (err != CS_OK && err != CS_ERR_TRY_AGAIN && err != CS_ERR_TIMEOUT && err != CS_ERR_QUEUE_FULL) { qb_log(LOG_ERR, "Could not dispatch quorum events. Error %u", err); qb_loop_stop(main_loop); return -1; } return 0; }
static int q_dispatch_wrapper_fn ( int fd, int revents, void *data) { cs_error_t error = quorum_dispatch (q_handle, CS_DISPATCH_ALL); if (error != CS_OK) { qb_log (LOG_ERR, "got %s error, disconnecting.", cs_strerror(error)); quorum_finalize(q_handle); q_handle = 0; return -1; } return 0; }
static int show_nodes(nodeid_format_t nodeid_format, name_format_t name_format) { quorum_handle_t q_handle = 0; votequorum_handle_t v_handle = 0; corosync_cfg_handle_t c_handle = 0; corosync_cfg_callbacks_t c_callbacks; int i; int using_vq = 0; quorum_callbacks_t q_callbacks; votequorum_callbacks_t v_callbacks; int err; int result = EXIT_FAILURE; q_callbacks.quorum_notify_fn = quorum_notification_fn; err=quorum_initialize(&q_handle, &q_callbacks); if (err != CS_OK) { fprintf(stderr, "Cannot connect to quorum service, is it loaded?\n"); return result; } v_callbacks.votequorum_notify_fn = NULL; v_callbacks.votequorum_expectedvotes_notify_fn = NULL; using_vq = using_votequorum(); if (using_vq) { if ( (err=votequorum_initialize(&v_handle, &v_callbacks)) != CS_OK) { fprintf(stderr, "votequorum_initialize FAILED: %d, this is probably a configuration error\n", err); v_handle = 0; goto err_exit; } } err = quorum_trackstart(q_handle, CS_TRACK_CURRENT); if (err != CS_OK) { fprintf(stderr, "quorum_trackstart FAILED: %d\n", err); goto err_exit; } g_called = 0; while (g_called == 0) quorum_dispatch(q_handle, CS_DISPATCH_ONE); quorum_finalize(q_handle); q_handle = 0; err = corosync_cfg_initialize(&c_handle, &c_callbacks); if (err != CS_OK) { fprintf(stderr, "Cannot initialise CFG service\n"); c_handle = 0; goto err_exit; } if (using_vq) printf("Nodeid Votes Name\n"); else printf("Nodeid Name\n"); for (i=0; i < g_view_list_entries; i++) { if (nodeid_format == NODEID_FORMAT_DECIMAL) { printf("%4u ", g_view_list[i]); } else { printf("0x%04x ", g_view_list[i]); } if (using_vq) { printf("%3d %s\n", get_votes(v_handle, g_view_list[i]), node_name(c_handle, g_view_list[i], name_format)); } else { printf("%s\n", node_name(c_handle, g_view_list[i], name_format)); } } result = EXIT_SUCCESS; err_exit: if (q_handle != 0) { quorum_finalize (q_handle); } if (using_vq && v_handle != 0) { votequorum_finalize (v_handle); } if (c_handle != 0) { corosync_cfg_finalize (c_handle); } return result; }
static void show_status(void) { quorum_handle_t q_handle; votequorum_handle_t v_handle; votequorum_callbacks_t v_callbacks; quorum_callbacks_t callbacks; struct votequorum_info info; int is_quorate; int err; callbacks.quorum_notify_fn = quorum_notification_fn; err=quorum_initialize(&q_handle, &callbacks); if (err != CS_OK) { fprintf(stderr, "Cannot connect to quorum service, is it loaded?\n"); return; } err=quorum_getquorate(q_handle, &is_quorate); if (err != CS_OK) { fprintf(stderr, "quorum_getquorate FAILED: %d\n", err); return; } err=quorum_trackstart(q_handle, CS_TRACK_CURRENT); if (err != CS_OK) { fprintf(stderr, "quorum_trackstart FAILED: %d\n", err); return; } g_called = 0; while (g_called == 0) quorum_dispatch(q_handle, CS_DISPATCH_ONE); quorum_finalize(q_handle); printf("Version: %s\n", VERSION); printf("Nodes: %d\n", g_view_list_entries); printf("Ring ID: %" PRIu64 "\n", g_ring_id); printf("Quorum type: %s\n", get_quorum_type()); printf("Quorate: %s\n", is_quorate?"Yes":"No"); if (using_votequorum()) { v_callbacks.votequorum_notify_fn = NULL; v_callbacks.votequorum_expectedvotes_notify_fn = NULL; if ( (err=votequorum_initialize(&v_handle, &v_callbacks)) != CS_OK) { fprintf(stderr, "votequorum_initialize FAILED: %d, this is probably a configuration error\n", err); goto err_exit; } if ( (err=votequorum_getinfo(v_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 %s\n", info.quorum, info.flags & VOTEQUORUM_INFO_FLAG_QUORATE?" ":"Activity blocked"); printf("Flags: "); if (info.flags & VOTEQUORUM_INFO_FLAG_HASSTATE) printf("HasState "); if (info.flags & VOTEQUORUM_INFO_FLAG_DISALLOWED) printf("DisallowedNodes "); if (info.flags & VOTEQUORUM_INFO_FLAG_TWONODE) printf("2Node "); if (info.flags & VOTEQUORUM_INFO_FLAG_QUORATE) printf("Quorate "); printf("\n"); } } err_exit: return; }
static cs_error_t sam_parent_wait_for_quorum ( int parent_fd_in, int parent_fd_out) { cs_error_t err; struct pollfd pfds[2]; int poll_err; if (sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_CONFDB) { if ((err = sam_confdb_update_key (SAM_CONFDB_KEY_STATE, SAM_CONFDB_S_Q_WAIT)) != CS_OK) { goto error_reply; } } /* * Update current quorum */ if ((err = quorum_dispatch (sam_internal_data.quorum_handle, CS_DISPATCH_ALL)) != CS_OK) { goto error_reply; } /* * Wait for quorum */ while (!sam_internal_data.quorate) { pfds[0].fd = parent_fd_in; pfds[0].events = 0; pfds[0].revents = 0; pfds[1].fd = sam_internal_data.quorum_fd; pfds[1].events = POLLIN; pfds[1].revents = 0; poll_err = poll (pfds, 2, -1); if (poll_err == -1) { /* * Error in poll * If it is EINTR, continue, otherwise QUIT */ if (errno != EINTR) { err = CS_ERR_LIBRARY; goto error_reply; } } if (pfds[0].revents != 0) { if (pfds[0].revents == POLLERR || pfds[0].revents == POLLHUP ||pfds[0].revents == POLLNVAL) { /* * Child has exited */ return (CS_OK); } } if (pfds[1].revents != 0) { if ((err = quorum_dispatch (sam_internal_data.quorum_handle, CS_DISPATCH_ONE)) != CS_OK) { goto error_reply; } } } if (sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_CONFDB) { if ((err = sam_confdb_update_key (SAM_CONFDB_KEY_STATE, SAM_CONFDB_S_STARTED)) != CS_OK) { goto error_reply; } } return (sam_parent_reply_send (CS_OK, parent_fd_in, parent_fd_out)); error_reply: if (sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_CONFDB) { sam_confdb_update_key (SAM_CONFDB_KEY_STATE, SAM_CONFDB_S_REGISTERED); } return (sam_parent_reply_send (err, parent_fd_in, parent_fd_out)); }
cs_error_t sam_initialize ( int time_interval, sam_recovery_policy_t recovery_policy) { quorum_callbacks_t quorum_callbacks; cs_error_t err; if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_NOT_INITIALIZED) { return (CS_ERR_BAD_HANDLE); } if (SAM_RP_MASK (recovery_policy) != SAM_RECOVERY_POLICY_QUIT && SAM_RP_MASK (recovery_policy) != SAM_RECOVERY_POLICY_RESTART) { return (CS_ERR_INVALID_PARAM); } if (recovery_policy & SAM_RECOVERY_POLICY_QUORUM) { /* * Initialize quorum */ quorum_callbacks.quorum_notify_fn = quorum_notification_fn; if ((err = quorum_initialize (&sam_internal_data.quorum_handle, &quorum_callbacks)) != CS_OK) { goto exit_error; } if ((err = quorum_trackstart (sam_internal_data.quorum_handle, CS_TRACK_CHANGES)) != CS_OK) { goto exit_error_quorum; } if ((err = quorum_fd_get (sam_internal_data.quorum_handle, &sam_internal_data.quorum_fd)) != CS_OK) { goto exit_error_quorum; } /* * Dispatch initial quorate state */ if ((err = quorum_dispatch (sam_internal_data.quorum_handle, CS_DISPATCH_ONE)) != CS_OK) { goto exit_error_quorum; } } sam_internal_data.recovery_policy = recovery_policy; sam_internal_data.time_interval = time_interval; sam_internal_data.internal_status = SAM_INTERNAL_STATUS_INITIALIZED; sam_internal_data.warn_signal = SIGTERM; sam_internal_data.am_i_child = 0; sam_internal_data.user_data = NULL; sam_internal_data.user_data_size = 0; sam_internal_data.user_data_allocated = 0; pthread_mutex_init (&sam_internal_data.lock, NULL); return (CS_OK); exit_error_quorum: quorum_finalize (sam_internal_data.quorum_handle); exit_error: return (err); }
static enum sam_parent_action_t sam_parent_handler ( int parent_fd_in, int parent_fd_out, pid_t child_pid) { int poll_error; int action; int status; ssize_t bytes_read; char command; int time_interval; struct pollfd pfds[2]; nfds_t nfds; cs_error_t err; sam_recovery_policy_t recpol; status = 0; action = SAM_PARENT_ACTION_CONTINUE; recpol = sam_internal_data.recovery_policy; while (action == SAM_PARENT_ACTION_CONTINUE) { pfds[0].fd = parent_fd_in; pfds[0].events = POLLIN; pfds[0].revents = 0; nfds = 1; if (status == 1 && sam_internal_data.time_interval != 0) { time_interval = sam_internal_data.time_interval; } else { time_interval = -1; } if (recpol & SAM_RECOVERY_POLICY_QUORUM) { pfds[nfds].fd = sam_internal_data.quorum_fd; pfds[nfds].events = POLLIN; pfds[nfds].revents = 0; nfds++; } poll_error = poll (pfds, nfds, time_interval); if (poll_error == -1) { /* * Error in poll * If it is EINTR, continue, otherwise QUIT */ if (errno != EINTR) { action = SAM_PARENT_ACTION_ERROR; } } if (poll_error == 0) { /* * Time limit expires */ if (status == 0) { action = SAM_PARENT_ACTION_QUIT; } else { sam_parent_kill_child (&action, child_pid); } } if (poll_error > 0) { if (pfds[0].revents != 0) { /* * We have EOF or command in pipe */ bytes_read = sam_safe_read (parent_fd_in, &command, 1); if (bytes_read == 0) { /* * Handle EOF -> Take recovery action or quit if sam_start wasn't called */ if (status == 0) action = SAM_PARENT_ACTION_QUIT; else action = SAM_PARENT_ACTION_RECOVERY; continue; } if (bytes_read == -1) { action = SAM_PARENT_ACTION_ERROR; goto action_exit; } if (recpol & SAM_RECOVERY_POLICY_CONFDB) { sam_confdb_update_key (SAM_CONFDB_KEY_LAST_HC, NULL); } /* * We have read command */ switch (command) { case SAM_COMMAND_START: if (status == 0) { /* * Not started yet */ if (recpol & SAM_RECOVERY_POLICY_QUORUM) { if (sam_parent_wait_for_quorum (parent_fd_in, parent_fd_out) != CS_OK) { continue; } } if (recpol & SAM_RECOVERY_POLICY_CONFDB) { if (sam_parent_confdb_state_set (parent_fd_in, parent_fd_out, 1) != CS_OK) { continue; } } status = 1; } break; case SAM_COMMAND_STOP: if (status == 1) { /* * Started */ if (recpol & SAM_RECOVERY_POLICY_CONFDB) { if (sam_parent_confdb_state_set (parent_fd_in, parent_fd_out, 0) != CS_OK) { continue; } } status = 0; } break; case SAM_COMMAND_DATA_STORE: sam_parent_data_store (parent_fd_in, parent_fd_out); break; case SAM_COMMAND_WARN_SIGNAL_SET: sam_parent_warn_signal_set (parent_fd_in, parent_fd_out); break; case SAM_COMMAND_MARK_FAILED: status = 1; sam_parent_mark_child_failed (&action, child_pid); break; } } /* if (pfds[0].revents != 0) */ if ((sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_QUORUM) && pfds[1].revents != 0) { /* * Handle quorum change */ err = quorum_dispatch (sam_internal_data.quorum_handle, CS_DISPATCH_ALL); if (status == 1 && (!sam_internal_data.quorate || (err != CS_ERR_TRY_AGAIN && err != CS_OK))) { sam_parent_kill_child (&action, child_pid); } } } /* select_error > 0 */ } /* action == SAM_PARENT_ACTION_CONTINUE */ action_exit: return action; }