root/daemons/controld/controld_transition.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. global_cib_callback
  2. create_blank_graph
  3. do_te_control
  4. do_te_invoke

   1 /*
   2  * Copyright 2004-2022 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU General Public License version 2
   7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <crm/crm.h>
  13 #include <crm/msg_xml.h>
  14 #include <crm/common/xml.h>
  15 
  16 #include <pacemaker-controld.h>
  17 
  18 extern pcmk__graph_functions_t te_graph_fns;
  19 
  20 static void
  21 global_cib_callback(const xmlNode * msg, int callid, int rc, xmlNode * output)
     /* [previous][next][first][last][top][bottom][index][help] */
  22 {
  23 }
  24 
  25 static pcmk__graph_t *
  26 create_blank_graph(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  27 {
  28     pcmk__graph_t *a_graph = pcmk__unpack_graph(NULL, NULL);
  29 
  30     a_graph->complete = true;
  31     a_graph->abort_reason = "DC Takeover";
  32     a_graph->completion_action = pcmk__graph_restart;
  33     return a_graph;
  34 }
  35 
  36 /*       A_TE_START, A_TE_STOP, O_TE_RESTART    */
  37 void
  38 do_te_control(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
  39               enum crmd_fsa_cause cause,
  40               enum crmd_fsa_state cur_state,
  41               enum crmd_fsa_input current_input, fsa_data_t * msg_data)
  42 {
  43     gboolean init_ok = TRUE;
  44 
  45     if (action & A_TE_STOP) {
  46         if (transition_graph) {
  47             pcmk__free_graph(transition_graph);
  48             transition_graph = NULL;
  49         }
  50 
  51         if (fsa_cib_conn) {
  52             fsa_cib_conn->cmds->del_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY,
  53                                                     te_update_diff);
  54         }
  55 
  56         controld_clear_fsa_input_flags(R_TE_CONNECTED);
  57         crm_info("Transitioner is now inactive");
  58     }
  59 
  60     if ((action & A_TE_START) == 0) {
  61         return;
  62 
  63     } else if (pcmk_is_set(fsa_input_register, R_TE_CONNECTED)) {
  64         crm_debug("The transitioner is already active");
  65         return;
  66 
  67     } else if ((action & A_TE_START) && cur_state == S_STOPPING) {
  68         crm_info("Ignoring request to start the transitioner while shutting down");
  69         return;
  70     }
  71 
  72     if (te_uuid == NULL) {
  73         te_uuid = crm_generate_uuid();
  74         crm_info("Registering TE UUID: %s", te_uuid);
  75     }
  76 
  77     if (fsa_cib_conn == NULL) {
  78         crm_err("Could not set CIB callbacks");
  79         init_ok = FALSE;
  80 
  81     } else {
  82 
  83         if (fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn,
  84             T_CIB_DIFF_NOTIFY, te_update_diff) != pcmk_ok) {
  85 
  86             crm_err("Could not set CIB notification callback");
  87             init_ok = FALSE;
  88         }
  89 
  90         if (fsa_cib_conn->cmds->set_op_callback(fsa_cib_conn,
  91             global_cib_callback) != pcmk_ok) {
  92 
  93             crm_err("Could not set CIB global callback");
  94             init_ok = FALSE;
  95         }
  96     }
  97 
  98     if (init_ok) {
  99         pcmk__set_graph_functions(&te_graph_fns);
 100 
 101         if (transition_graph) {
 102             pcmk__free_graph(transition_graph);
 103         }
 104 
 105         /* create a blank one */
 106         crm_debug("Transitioner is now active");
 107         transition_graph = create_blank_graph();
 108         controld_set_fsa_input_flags(R_TE_CONNECTED);
 109     }
 110 }
 111 
 112 /*       A_TE_INVOKE, A_TE_CANCEL       */
 113 void
 114 do_te_invoke(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
 115              enum crmd_fsa_cause cause,
 116              enum crmd_fsa_state cur_state,
 117              enum crmd_fsa_input current_input, fsa_data_t * msg_data)
 118 {
 119 
 120     if (AM_I_DC == FALSE || (fsa_state != S_TRANSITION_ENGINE && (action & A_TE_INVOKE))) {
 121         crm_notice("No need to invoke the TE (%s) in state %s",
 122                    fsa_action2string(action), fsa_state2string(fsa_state));
 123         return;
 124     }
 125 
 126     if (action & A_TE_CANCEL) {
 127         crm_debug("Cancelling the transition: %s",
 128                   transition_graph->complete ? "inactive" : "active");
 129         abort_transition(INFINITY, pcmk__graph_restart, "Peer Cancelled", NULL);
 130         if (!transition_graph->complete) {
 131             crmd_fsa_stall(FALSE);
 132         }
 133 
 134     } else if (action & A_TE_HALT) {
 135         abort_transition(INFINITY, pcmk__graph_wait, "Peer Halt", NULL);
 136         if (!transition_graph->complete) {
 137             crmd_fsa_stall(FALSE);
 138         }
 139 
 140     } else if (action & A_TE_INVOKE) {
 141         const char *value = NULL;
 142         xmlNode *graph_data = NULL;
 143         ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg);
 144         const char *ref = crm_element_value(input->msg, XML_ATTR_REFERENCE);
 145         const char *graph_file = crm_element_value(input->msg, F_CRM_TGRAPH);
 146         const char *graph_input = crm_element_value(input->msg, F_CRM_TGRAPH_INPUT);
 147 
 148         if (graph_file == NULL && input->xml == NULL) {
 149             crm_log_xml_err(input->msg, "Bad command");
 150             register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
 151             return;
 152         }
 153 
 154         if (!transition_graph->complete) {
 155             crm_info("Another transition is already active");
 156             abort_transition(INFINITY, pcmk__graph_restart, "Transition Active",
 157                              NULL);
 158             return;
 159         }
 160 
 161         if ((fsa_pe_ref == NULL)
 162             || !pcmk__str_eq(fsa_pe_ref, ref, pcmk__str_none)) {
 163             crm_info("Transition is redundant: %s expected but %s received",
 164                      pcmk__s(fsa_pe_ref, "no reference"),
 165                      pcmk__s(ref, "no reference"));
 166             abort_transition(INFINITY, pcmk__graph_restart,
 167                              "Transition Redundant", NULL);
 168         }
 169 
 170         graph_data = input->xml;
 171 
 172         if (graph_data == NULL && graph_file != NULL) {
 173             graph_data = filename2xml(graph_file);
 174         }
 175 
 176         if (is_timer_started(transition_timer)) {
 177             crm_debug("The transitioner wait for a transition timer");
 178             return;
 179         }
 180 
 181         CRM_CHECK(graph_data != NULL,
 182                   crm_err("Input raised by %s is invalid", msg_data->origin);
 183                   crm_log_xml_err(input->msg, "Bad command");
 184                   return);
 185 
 186         pcmk__free_graph(transition_graph);
 187         transition_graph = pcmk__unpack_graph(graph_data, graph_input);
 188         CRM_CHECK(transition_graph != NULL,
 189                   transition_graph = create_blank_graph(); return);
 190         crm_info("Processing graph %d (ref=%s) derived from %s", transition_graph->id, ref,
 191                  graph_input);
 192 
 193         te_reset_job_counts();
 194         value = crm_element_value(graph_data, "failed-stop-offset");
 195         if (value) {
 196             free(failed_stop_offset);
 197             failed_stop_offset = strdup(value);
 198         }
 199 
 200         value = crm_element_value(graph_data, "failed-start-offset");
 201         if (value) {
 202             free(failed_start_offset);
 203             failed_start_offset = strdup(value);
 204         }
 205 
 206         if ((crm_element_value_epoch(graph_data, "recheck-by", &recheck_by)
 207             != pcmk_ok) || (recheck_by < 0)) {
 208             recheck_by = 0;
 209         }
 210 
 211         trigger_graph();
 212         pcmk__log_graph(LOG_TRACE, transition_graph);
 213 
 214         if (graph_data != input->xml) {
 215             free_xml(graph_data);
 216         }
 217     }
 218 }

/* [previous][next][first][last][top][bottom][index][help] */