root/daemons/controld/controld_transition.c

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

DEFINITIONS

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

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

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