root/crmd/tengine.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 (C) 2004 Andrew Beekhof <andrew@beekhof.net>
   3  * 
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public
   6  * License as published by the Free Software Foundation; either
   7  * version 2 of the License, or (at your option) any later version.
   8  * 
   9  * This software is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12  * General Public License for more details.
  13  * 
  14  * You should have received a copy of the GNU General Public
  15  * License along with this library; if not, write to the Free Software
  16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17  */
  18 
  19 #include <crm_internal.h>
  20 
  21 #include <crm/crm.h>
  22 #include <crm/msg_xml.h>
  23 #include <crm/common/xml.h>
  24 
  25 #include <crmd.h>
  26 #include <crmd_fsa.h>
  27 #include <crmd_messages.h>
  28 #include <te_callbacks.h>  /* te_update_diff */
  29 #include <tengine.h>
  30 
  31 
  32 extern crm_graph_functions_t te_graph_fns;
  33 struct crm_subsystem_s *te_subsystem = NULL;
  34 stonith_t *stonith_api = NULL;
  35 
  36 static void
  37 global_cib_callback(const xmlNode * msg, int callid, int rc, xmlNode * output)
     /* [previous][next][first][last][top][bottom][index][help] */
  38 {
  39 }
  40 
  41 static crm_graph_t *
  42 create_blank_graph(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  43 {
  44     crm_graph_t *a_graph = unpack_graph(NULL, NULL);
  45 
  46     a_graph->complete = TRUE;
  47     a_graph->abort_reason = "DC Takeover";
  48     a_graph->completion_action = tg_restart;
  49     return a_graph;
  50 }
  51 
  52 /*       A_TE_START, A_TE_STOP, O_TE_RESTART    */
  53 void
  54 do_te_control(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
  55               enum crmd_fsa_cause cause,
  56               enum crmd_fsa_state cur_state,
  57               enum crmd_fsa_input current_input, fsa_data_t * msg_data)
  58 {
  59     gboolean init_ok = TRUE;
  60 
  61     if (action & A_TE_STOP) {
  62         if (transition_graph) {
  63             destroy_graph(transition_graph);
  64             transition_graph = NULL;
  65         }
  66 
  67         if (fsa_cib_conn) {
  68             fsa_cib_conn->cmds->del_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY,
  69                                                     te_update_diff);
  70         }
  71 
  72         clear_bit(fsa_input_register, te_subsystem->flag_connected);
  73         crm_info("Transitioner is now inactive");
  74     }
  75 
  76     if ((action & A_TE_START) == 0) {
  77         return;
  78 
  79     } else if (is_set(fsa_input_register, te_subsystem->flag_connected)) {
  80         crm_debug("The transitioner is already active");
  81         return;
  82 
  83     } else if ((action & A_TE_START) && cur_state == S_STOPPING) {
  84         crm_info("Ignoring request to start %s while shutting down", te_subsystem->name);
  85         return;
  86     }
  87 
  88     te_uuid = crm_generate_uuid();
  89     crm_info("Registering TE UUID: %s", te_uuid);
  90 
  91     if (fsa_cib_conn == NULL) {
  92         crm_err("Could not set CIB callbacks");
  93         init_ok = FALSE;
  94 
  95     } else {
  96 
  97         if (fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn,
  98             T_CIB_DIFF_NOTIFY, te_update_diff) != pcmk_ok) {
  99 
 100             crm_err("Could not set CIB notification callback");
 101             init_ok = FALSE;
 102         }
 103 
 104         if (fsa_cib_conn->cmds->set_op_callback(fsa_cib_conn,
 105             global_cib_callback) != pcmk_ok) {
 106 
 107             crm_err("Could not set CIB global callback");
 108             init_ok = FALSE;
 109         }
 110     }
 111 
 112     if (init_ok) {
 113         set_graph_functions(&te_graph_fns);
 114 
 115         if (transition_graph) {
 116             destroy_graph(transition_graph);
 117         }
 118 
 119         /* create a blank one */
 120         crm_debug("Transitioner is now active");
 121         transition_graph = create_blank_graph();
 122         set_bit(fsa_input_register, te_subsystem->flag_connected);
 123     }
 124 }
 125 
 126 /*       A_TE_INVOKE, A_TE_CANCEL       */
 127 void
 128 do_te_invoke(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
 129              enum crmd_fsa_cause cause,
 130              enum crmd_fsa_state cur_state,
 131              enum crmd_fsa_input current_input, fsa_data_t * msg_data)
 132 {
 133 
 134     if (AM_I_DC == FALSE || (fsa_state != S_TRANSITION_ENGINE && (action & A_TE_INVOKE))) {
 135         crm_notice("No need to invoke the TE (%s) in state %s",
 136                    fsa_action2string(action), fsa_state2string(fsa_state));
 137         return;
 138     }
 139 
 140     if (action & A_TE_CANCEL) {
 141         crm_debug("Cancelling the transition: %s",
 142                   transition_graph->complete ? "inactive" : "active");
 143         abort_transition(INFINITY, tg_restart, "Peer Cancelled", NULL);
 144         if (transition_graph->complete == FALSE) {
 145             crmd_fsa_stall(FALSE);
 146         }
 147 
 148     } else if (action & A_TE_HALT) {
 149         crm_debug("Halting the transition: %s", transition_graph->complete ? "inactive" : "active");
 150         abort_transition(INFINITY, tg_stop, "Peer Halt", NULL);
 151         if (transition_graph->complete == FALSE) {
 152             crmd_fsa_stall(FALSE);
 153         }
 154 
 155     } else if (action & A_TE_INVOKE) {
 156         const char *value = NULL;
 157         xmlNode *graph_data = NULL;
 158         ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg);
 159         const char *ref = crm_element_value(input->msg, XML_ATTR_REFERENCE);
 160         const char *graph_file = crm_element_value(input->msg, F_CRM_TGRAPH);
 161         const char *graph_input = crm_element_value(input->msg, F_CRM_TGRAPH_INPUT);
 162 
 163         if (graph_file == NULL && input->xml == NULL) {
 164             crm_log_xml_err(input->msg, "Bad command");
 165             register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
 166             return;
 167         }
 168 
 169         if (transition_graph->complete == FALSE) {
 170             crm_info("Another transition is already active");
 171             abort_transition(INFINITY, tg_restart, "Transition Active", NULL);
 172             return;
 173         }
 174 
 175         if (fsa_pe_ref == NULL || safe_str_neq(fsa_pe_ref, ref)) {
 176             crm_info("Transition is redundant: %s vs. %s", crm_str(fsa_pe_ref), crm_str(ref));
 177             abort_transition(INFINITY, tg_restart, "Transition Redundant", NULL);
 178         }
 179 
 180         graph_data = input->xml;
 181 
 182         if (graph_data == NULL && graph_file != NULL) {
 183             graph_data = filename2xml(graph_file);
 184         }
 185 
 186         if (is_timer_started(transition_timer)) {
 187             crm_debug("The transitioner wait for a transition timer");
 188             return;
 189         }
 190 
 191         CRM_CHECK(graph_data != NULL,
 192                   crm_err("Input raised by %s is invalid", msg_data->origin);
 193                   crm_log_xml_err(input->msg, "Bad command");
 194                   return);
 195 
 196         destroy_graph(transition_graph);
 197         transition_graph = unpack_graph(graph_data, graph_input);
 198         CRM_CHECK(transition_graph != NULL, transition_graph = create_blank_graph(); return);
 199         crm_info("Processing graph %d (ref=%s) derived from %s", transition_graph->id, ref,
 200                  graph_input);
 201 
 202         te_reset_job_counts();
 203         value = crm_element_value(graph_data, "failed-stop-offset");
 204         if (value) {
 205             free(failed_stop_offset);
 206             failed_stop_offset = strdup(value);
 207         }
 208 
 209         value = crm_element_value(graph_data, "failed-start-offset");
 210         if (value) {
 211             free(failed_start_offset);
 212             failed_start_offset = strdup(value);
 213         }
 214 
 215         trigger_graph();
 216         print_graph(LOG_DEBUG_2, transition_graph);
 217 
 218         if (graph_data != input->xml) {
 219             free_xml(graph_data);
 220         }
 221     }
 222 }

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