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 static void
  19 global_cib_callback(const xmlNode * msg, int callid, int rc, xmlNode * output)
     /* [previous][next][first][last][top][bottom][index][help] */
  20 {
  21 }
  22 
  23 static pcmk__graph_t *
  24 create_blank_graph(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  25 {
  26     pcmk__graph_t *a_graph = pcmk__unpack_graph(NULL, NULL);
  27 
  28     a_graph->complete = true;
  29     a_graph->abort_reason = "DC Takeover";
  30     a_graph->completion_action = pcmk__graph_restart;
  31     return a_graph;
  32 }
  33 
  34 /*       A_TE_START, A_TE_STOP, O_TE_RESTART    */
  35 void
  36 do_te_control(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
  37               enum crmd_fsa_cause cause,
  38               enum crmd_fsa_state cur_state,
  39               enum crmd_fsa_input current_input, fsa_data_t * msg_data)
  40 {
  41     cib_t *cib_conn = controld_globals.cib_conn;
  42     gboolean init_ok = TRUE;
  43 
  44     if (pcmk_is_set(action, A_TE_STOP)) {
  45         pcmk__free_graph(controld_globals.transition_graph);
  46         controld_globals.transition_graph = NULL;
  47 
  48         if (cib_conn != NULL) {
  49             cib_conn->cmds->del_notify_callback(cib_conn, T_CIB_DIFF_NOTIFY,
  50                                                 te_update_diff);
  51         }
  52 
  53         controld_clear_fsa_input_flags(R_TE_CONNECTED);
  54         crm_info("Transitioner is now inactive");
  55     }
  56 
  57     if ((action & A_TE_START) == 0) {
  58         return;
  59 
  60     } else if (pcmk_is_set(controld_globals.fsa_input_register,
  61                            R_TE_CONNECTED)) {
  62         crm_debug("The transitioner is already active");
  63         return;
  64 
  65     } else if ((action & A_TE_START) && cur_state == S_STOPPING) {
  66         crm_info("Ignoring request to start the transitioner while shutting down");
  67         return;
  68     }
  69 
  70     if (controld_globals.te_uuid == NULL) {
  71         controld_globals.te_uuid = crm_generate_uuid();
  72         crm_info("Registering TE UUID: %s", controld_globals.te_uuid);
  73     }
  74 
  75     if (cib_conn == NULL) {
  76         crm_err("Could not set CIB callbacks");
  77         init_ok = FALSE;
  78 
  79     } else {
  80         if (cib_conn->cmds->add_notify_callback(cib_conn, T_CIB_DIFF_NOTIFY,
  81                                                 te_update_diff) != pcmk_ok) {
  82             crm_err("Could not set CIB notification callback");
  83             init_ok = FALSE;
  84         }
  85 
  86         if (cib_conn->cmds->set_op_callback(cib_conn,
  87                                             global_cib_callback) != pcmk_ok) {
  88             crm_err("Could not set CIB global callback");
  89             init_ok = FALSE;
  90         }
  91     }
  92 
  93     if (init_ok) {
  94         controld_register_graph_functions();
  95         pcmk__free_graph(controld_globals.transition_graph);
  96 
  97         /* create a blank one */
  98         crm_debug("Transitioner is now active");
  99         controld_globals.transition_graph = create_blank_graph();
 100         controld_set_fsa_input_flags(R_TE_CONNECTED);
 101     }
 102 }
 103 
 104 /*       A_TE_INVOKE, A_TE_CANCEL       */
 105 void
 106 do_te_invoke(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
 107              enum crmd_fsa_cause cause,
 108              enum crmd_fsa_state cur_state,
 109              enum crmd_fsa_input current_input, fsa_data_t * msg_data)
 110 {
 111 
 112     if (!AM_I_DC
 113         || ((controld_globals.fsa_state != S_TRANSITION_ENGINE)
 114             && pcmk_is_set(action, A_TE_INVOKE))) {
 115         crm_notice("No need to invoke the TE (%s) in state %s",
 116                    fsa_action2string(action),
 117                    fsa_state2string(controld_globals.fsa_state));
 118         return;
 119     }
 120 
 121     if (action & A_TE_CANCEL) {
 122         crm_debug("Cancelling the transition: %sactive",
 123                   controld_globals.transition_graph->complete? "in" : "");
 124         abort_transition(INFINITY, pcmk__graph_restart, "Peer Cancelled", NULL);
 125         if (!controld_globals.transition_graph->complete) {
 126             crmd_fsa_stall(FALSE);
 127         }
 128 
 129     } else if (action & A_TE_HALT) {
 130         abort_transition(INFINITY, pcmk__graph_wait, "Peer Halt", NULL);
 131         if (!controld_globals.transition_graph->complete) {
 132             crmd_fsa_stall(FALSE);
 133         }
 134 
 135     } else if (action & A_TE_INVOKE) {
 136         ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg);
 137         xmlNode *graph_data = input->xml;
 138         const char *ref = crm_element_value(input->msg, XML_ATTR_REFERENCE);
 139         const char *graph_file = crm_element_value(input->msg, F_CRM_TGRAPH);
 140         const char *graph_input = crm_element_value(input->msg, F_CRM_TGRAPH_INPUT);
 141 
 142         if (graph_file == NULL && graph_data == NULL) {
 143             crm_log_xml_err(input->msg, "Bad command");
 144             register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
 145             return;
 146         }
 147 
 148         if (!controld_globals.transition_graph->complete) {
 149             crm_info("Another transition is already active");
 150             abort_transition(INFINITY, pcmk__graph_restart, "Transition Active",
 151                              NULL);
 152             return;
 153         }
 154 
 155         if ((controld_globals.fsa_pe_ref == NULL)
 156             || !pcmk__str_eq(controld_globals.fsa_pe_ref, ref,
 157                              pcmk__str_none)) {
 158             crm_info("Transition is redundant: %s expected but %s received",
 159                      pcmk__s(controld_globals.fsa_pe_ref, "no reference"),
 160                      pcmk__s(ref, "no reference"));
 161             abort_transition(INFINITY, pcmk__graph_restart,
 162                              "Transition Redundant", NULL);
 163         }
 164 
 165         if (graph_data == NULL && graph_file != NULL) {
 166             graph_data = filename2xml(graph_file);
 167         }
 168 
 169         if (controld_is_started_transition_timer()) {
 170             crm_debug("The transitioner wait for a transition timer");
 171             return;
 172         }
 173 
 174         CRM_CHECK(graph_data != NULL,
 175                   crm_err("Input raised by %s is invalid", msg_data->origin);
 176                   crm_log_xml_err(input->msg, "Bad command");
 177                   return);
 178 
 179         pcmk__free_graph(controld_globals.transition_graph);
 180         controld_globals.transition_graph = pcmk__unpack_graph(graph_data,
 181                                                                graph_input);
 182         CRM_CHECK(controld_globals.transition_graph != NULL,
 183                   controld_globals.transition_graph = create_blank_graph();
 184                   return);
 185         crm_info("Processing graph %d (ref=%s) derived from %s",
 186                  controld_globals.transition_graph->id, ref, graph_input);
 187 
 188         te_reset_job_counts();
 189 
 190         trigger_graph();
 191         pcmk__log_graph(LOG_TRACE, controld_globals.transition_graph);
 192 
 193         if (graph_data != input->xml) {
 194             free_xml(graph_data);
 195         }
 196     }
 197 }

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