|
rpm-build |
3ee90c |
/*
|
|
rpm-build |
3ee90c |
* Copyright 2004-2019 the Pacemaker project contributors
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* The version control history for this file may have further details.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* This source code is licensed under the GNU General Public License version 2
|
|
rpm-build |
3ee90c |
* or later (GPLv2+) WITHOUT ANY WARRANTY.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <crm_internal.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <crm/crm.h>
|
|
rpm-build |
3ee90c |
#include <crm/msg_xml.h>
|
|
rpm-build |
3ee90c |
#include <crm/common/xml.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <pacemaker-controld.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
extern crm_graph_functions_t te_graph_fns;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static void
|
|
rpm-build |
3ee90c |
global_cib_callback(const xmlNode * msg, int callid, int rc, xmlNode * output)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static crm_graph_t *
|
|
rpm-build |
3ee90c |
create_blank_graph(void)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
crm_graph_t *a_graph = unpack_graph(NULL, NULL);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
a_graph->complete = TRUE;
|
|
rpm-build |
3ee90c |
a_graph->abort_reason = "DC Takeover";
|
|
rpm-build |
3ee90c |
a_graph->completion_action = tg_restart;
|
|
rpm-build |
3ee90c |
return a_graph;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* A_TE_START, A_TE_STOP, O_TE_RESTART */
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
do_te_control(long long action,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_cause cause,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_state cur_state,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_input current_input, fsa_data_t * msg_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
gboolean init_ok = TRUE;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (action & A_TE_STOP) {
|
|
rpm-build |
3ee90c |
if (transition_graph) {
|
|
rpm-build |
3ee90c |
destroy_graph(transition_graph);
|
|
rpm-build |
3ee90c |
transition_graph = NULL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (fsa_cib_conn) {
|
|
rpm-build |
3ee90c |
fsa_cib_conn->cmds->del_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY,
|
|
rpm-build |
3ee90c |
te_update_diff);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
clear_bit(fsa_input_register, R_TE_CONNECTED);
|
|
rpm-build |
3ee90c |
crm_info("Transitioner is now inactive");
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if ((action & A_TE_START) == 0) {
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (is_set(fsa_input_register, R_TE_CONNECTED)) {
|
|
rpm-build |
3ee90c |
crm_debug("The transitioner is already active");
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if ((action & A_TE_START) && cur_state == S_STOPPING) {
|
|
rpm-build |
3ee90c |
crm_info("Ignoring request to start the transitioner while shutting down");
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (te_uuid == NULL) {
|
|
rpm-build |
3ee90c |
te_uuid = crm_generate_uuid();
|
|
rpm-build |
3ee90c |
crm_info("Registering TE UUID: %s", te_uuid);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (fsa_cib_conn == NULL) {
|
|
rpm-build |
3ee90c |
crm_err("Could not set CIB callbacks");
|
|
rpm-build |
3ee90c |
init_ok = FALSE;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn,
|
|
rpm-build |
3ee90c |
T_CIB_DIFF_NOTIFY, te_update_diff) != pcmk_ok) {
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_err("Could not set CIB notification callback");
|
|
rpm-build |
3ee90c |
init_ok = FALSE;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (fsa_cib_conn->cmds->set_op_callback(fsa_cib_conn,
|
|
rpm-build |
3ee90c |
global_cib_callback) != pcmk_ok) {
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_err("Could not set CIB global callback");
|
|
rpm-build |
3ee90c |
init_ok = FALSE;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (init_ok) {
|
|
rpm-build |
3ee90c |
set_graph_functions(&te_graph_fns);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (transition_graph) {
|
|
rpm-build |
3ee90c |
destroy_graph(transition_graph);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* create a blank one */
|
|
rpm-build |
3ee90c |
crm_debug("Transitioner is now active");
|
|
rpm-build |
3ee90c |
transition_graph = create_blank_graph();
|
|
rpm-build |
3ee90c |
set_bit(fsa_input_register, R_TE_CONNECTED);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* A_TE_INVOKE, A_TE_CANCEL */
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
do_te_invoke(long long action,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_cause cause,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_state cur_state,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_input current_input, fsa_data_t * msg_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (AM_I_DC == FALSE || (fsa_state != S_TRANSITION_ENGINE && (action & A_TE_INVOKE))) {
|
|
rpm-build |
3ee90c |
crm_notice("No need to invoke the TE (%s) in state %s",
|
|
rpm-build |
3ee90c |
fsa_action2string(action), fsa_state2string(fsa_state));
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (action & A_TE_CANCEL) {
|
|
rpm-build |
3ee90c |
crm_debug("Cancelling the transition: %s",
|
|
rpm-build |
3ee90c |
transition_graph->complete ? "inactive" : "active");
|
|
rpm-build |
3ee90c |
abort_transition(INFINITY, tg_restart, "Peer Cancelled", NULL);
|
|
rpm-build |
3ee90c |
if (transition_graph->complete == FALSE) {
|
|
rpm-build |
3ee90c |
crmd_fsa_stall(FALSE);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (action & A_TE_HALT) {
|
|
rpm-build |
3ee90c |
crm_debug("Halting the transition: %s", transition_graph->complete ? "inactive" : "active");
|
|
rpm-build |
3ee90c |
abort_transition(INFINITY, tg_stop, "Peer Halt", NULL);
|
|
rpm-build |
3ee90c |
if (transition_graph->complete == FALSE) {
|
|
rpm-build |
3ee90c |
crmd_fsa_stall(FALSE);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (action & A_TE_INVOKE) {
|
|
rpm-build |
3ee90c |
const char *value = NULL;
|
|
rpm-build |
3ee90c |
xmlNode *graph_data = NULL;
|
|
rpm-build |
3ee90c |
ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg);
|
|
rpm-build |
3ee90c |
const char *ref = crm_element_value(input->msg, XML_ATTR_REFERENCE);
|
|
rpm-build |
3ee90c |
const char *graph_file = crm_element_value(input->msg, F_CRM_TGRAPH);
|
|
rpm-build |
3ee90c |
const char *graph_input = crm_element_value(input->msg, F_CRM_TGRAPH_INPUT);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (graph_file == NULL && input->xml == NULL) {
|
|
rpm-build |
3ee90c |
crm_log_xml_err(input->msg, "Bad command");
|
|
rpm-build |
3ee90c |
register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (transition_graph->complete == FALSE) {
|
|
rpm-build |
3ee90c |
crm_info("Another transition is already active");
|
|
rpm-build |
3ee90c |
abort_transition(INFINITY, tg_restart, "Transition Active", NULL);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (fsa_pe_ref == NULL || safe_str_neq(fsa_pe_ref, ref)) {
|
|
rpm-build |
3ee90c |
crm_info("Transition is redundant: %s vs. %s", crm_str(fsa_pe_ref), crm_str(ref));
|
|
rpm-build |
3ee90c |
abort_transition(INFINITY, tg_restart, "Transition Redundant", NULL);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
graph_data = input->xml;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (graph_data == NULL && graph_file != NULL) {
|
|
rpm-build |
3ee90c |
graph_data = filename2xml(graph_file);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (is_timer_started(transition_timer)) {
|
|
rpm-build |
3ee90c |
crm_debug("The transitioner wait for a transition timer");
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
CRM_CHECK(graph_data != NULL,
|
|
rpm-build |
3ee90c |
crm_err("Input raised by %s is invalid", msg_data->origin);
|
|
rpm-build |
3ee90c |
crm_log_xml_err(input->msg, "Bad command");
|
|
rpm-build |
3ee90c |
return);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
destroy_graph(transition_graph);
|
|
rpm-build |
3ee90c |
transition_graph = unpack_graph(graph_data, graph_input);
|
|
rpm-build |
3ee90c |
if (transition_graph == NULL) {
|
|
rpm-build |
3ee90c |
CRM_CHECK(transition_graph != NULL,);
|
|
rpm-build |
3ee90c |
transition_graph = create_blank_graph();
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
crm_info("Processing graph %d (ref=%s) derived from %s", transition_graph->id, ref,
|
|
rpm-build |
3ee90c |
graph_input);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
te_reset_job_counts();
|
|
rpm-build |
3ee90c |
value = crm_element_value(graph_data, "failed-stop-offset");
|
|
rpm-build |
3ee90c |
if (value) {
|
|
rpm-build |
3ee90c |
free(failed_stop_offset);
|
|
rpm-build |
3ee90c |
failed_stop_offset = strdup(value);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
value = crm_element_value(graph_data, "failed-start-offset");
|
|
rpm-build |
3ee90c |
if (value) {
|
|
rpm-build |
3ee90c |
free(failed_start_offset);
|
|
rpm-build |
3ee90c |
failed_start_offset = strdup(value);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if ((crm_element_value_epoch(graph_data, "recheck-by", &recheck_by)
|
|
rpm-build |
3ee90c |
!= pcmk_ok) || (recheck_by < 0)) {
|
|
rpm-build |
3ee90c |
recheck_by = 0;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
trigger_graph();
|
|
rpm-build |
3ee90c |
print_graph(LOG_TRACE, transition_graph);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (graph_data != input->xml) {
|
|
rpm-build |
3ee90c |
free_xml(graph_data);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|