root/crmd/election.c

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

DEFINITIONS

This source file includes following definitions.
  1. do_election_vote
  2. do_election_check
  3. do_election_count_vote
  4. do_election_timer_ctrl
  5. feature_update_callback
  6. do_dc_takeover
  7. do_dc_release

   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 #include <crm_internal.h>
  19 
  20 #include <sys/time.h>
  21 #include <sys/resource.h>
  22 
  23 #include <crm/msg_xml.h>
  24 #include <crm/common/xml.h>
  25 
  26 #include <crm/cluster/internal.h>
  27 #include <crm/cluster/election.h>
  28 #include <crm/crm.h>
  29 #include <crmd_fsa.h>
  30 #include <crmd_messages.h>
  31 #include <crmd_callbacks.h>
  32 #include <tengine.h>
  33 
  34 /*      A_ELECTION_VOTE */
  35 void
  36 do_election_vote(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     gboolean not_voting = FALSE;
  42 
  43     /* don't vote if we're in one of these states or wanting to shut down */
  44     switch (cur_state) {
  45         case S_STARTING:
  46         case S_RECOVERY:
  47         case S_STOPPING:
  48         case S_TERMINATE:
  49             crm_warn("Not voting in election, we're in state %s", fsa_state2string(cur_state));
  50             not_voting = TRUE;
  51             break;
  52         case S_ELECTION:
  53         case S_INTEGRATION:
  54         case S_RELEASE_DC:
  55             break;
  56         default:
  57             crm_err("Broken? Voting in state %s", fsa_state2string(cur_state));
  58             break;
  59     }
  60 
  61     if (not_voting == FALSE) {
  62         if (is_set(fsa_input_register, R_STARTING)) {
  63             not_voting = TRUE;
  64         }
  65     }
  66 
  67     if (not_voting) {
  68         if (AM_I_DC) {
  69             register_fsa_input(C_FSA_INTERNAL, I_RELEASE_DC, NULL);
  70 
  71         } else {
  72             register_fsa_input(C_FSA_INTERNAL, I_PENDING, NULL);
  73         }
  74         return;
  75     }
  76 
  77     election_vote(fsa_election);
  78     return;
  79 }
  80 
  81 void
  82 do_election_check(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
  83                   enum crmd_fsa_cause cause,
  84                   enum crmd_fsa_state cur_state,
  85                   enum crmd_fsa_input current_input, fsa_data_t * msg_data)
  86 {
  87     if (fsa_state != S_ELECTION) {
  88         crm_debug("Ignoring election check because we are not in an election");
  89 
  90     } else if(election_check(fsa_election)) {
  91         register_fsa_input(C_FSA_INTERNAL, I_ELECTION_DC, NULL);
  92     }
  93 
  94     return;
  95 }
  96 
  97 #define loss_dampen 2           /* in seconds */
  98 
  99 /*      A_ELECTION_COUNT        */
 100 void
 101 do_election_count_vote(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
 102                        enum crmd_fsa_cause cause,
 103                        enum crmd_fsa_state cur_state,
 104                        enum crmd_fsa_input current_input, fsa_data_t * msg_data)
 105 {
 106     enum election_result rc = 0;
 107     ha_msg_input_t *vote = fsa_typed_data(fsa_dt_ha_msg);
 108 
 109     if(crm_peer_cache == NULL) {
 110         if(is_not_set(fsa_input_register, R_SHUTDOWN)) {
 111             crm_err("Internal error, no peer cache");
 112         }
 113         return;
 114     }
 115 
 116     rc = election_count_vote(fsa_election, vote->msg, cur_state != S_STARTING);
 117     switch(rc) {
 118         case election_start:
 119             election_reset(fsa_election);
 120             register_fsa_input(C_FSA_INTERNAL, I_ELECTION, NULL);
 121             break;
 122 
 123         case election_lost:
 124             update_dc(NULL);
 125 
 126             if (fsa_input_register & R_THE_DC) {
 127                 register_fsa_input(C_FSA_INTERNAL, I_RELEASE_DC, NULL);
 128                 fsa_cib_conn->cmds->set_slave(fsa_cib_conn, cib_scope_local);
 129 
 130             } else if (cur_state != S_STARTING) {
 131                 register_fsa_input(C_FSA_INTERNAL, I_PENDING, NULL);
 132             }
 133             break;
 134 
 135         case election_in_progress:
 136             break;
 137         default:
 138             crm_err("Unhandled election result: %d", rc);
 139     }
 140 }
 141 
 142 /*      A_ELECT_TIMER_START, A_ELECTION_TIMEOUT         */
 143 /* we won */
 144 void
 145 do_election_timer_ctrl(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
 146                        enum crmd_fsa_cause cause,
 147                        enum crmd_fsa_state cur_state,
 148                        enum crmd_fsa_input current_input, fsa_data_t * msg_data)
 149 {
 150 }
 151 
 152 static void
 153 feature_update_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 154 {
 155     if (rc != pcmk_ok) {
 156         fsa_data_t *msg_data = NULL;
 157 
 158         crm_notice("Feature update failed: %s "CRM_XS" rc=%d",
 159                    pcmk_strerror(rc), rc);
 160         register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
 161     }
 162 }
 163 
 164 /*       A_DC_TAKEOVER  */
 165 void
 166 do_dc_takeover(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
 167                enum crmd_fsa_cause cause,
 168                enum crmd_fsa_state cur_state,
 169                enum crmd_fsa_input current_input, fsa_data_t * msg_data)
 170 {
 171     int rc = pcmk_ok;
 172     xmlNode *cib = NULL;
 173     const char *cluster_type = name_for_cluster_type(get_cluster_type());
 174     pid_t watchdog = pcmk_locate_sbd();
 175 
 176     crm_info("Taking over DC status for this partition");
 177     set_bit(fsa_input_register, R_THE_DC);
 178     execute_stonith_cleanup();
 179 
 180 #if SUPPORT_COROSYNC
 181     if (is_classic_ais_cluster()) {
 182         send_cluster_text(crm_class_quorum, NULL, TRUE, NULL, crm_msg_ais);
 183     }
 184 #endif
 185 
 186     election_reset(fsa_election);
 187     set_bit(fsa_input_register, R_JOIN_OK);
 188     set_bit(fsa_input_register, R_INVOKE_PE);
 189 
 190     fsa_cib_conn->cmds->set_master(fsa_cib_conn, cib_scope_local);
 191 
 192     cib = create_xml_node(NULL, XML_TAG_CIB);
 193     crm_xml_add(cib, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET);
 194     fsa_cib_update(XML_TAG_CIB, cib, cib_quorum_override, rc, NULL);
 195     fsa_register_cib_callback(rc, FALSE, NULL, feature_update_callback);
 196 
 197     update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL,
 198                          XML_ATTR_HAVE_WATCHDOG, watchdog?"true":"false", FALSE, NULL, NULL);
 199 
 200     update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL,
 201                          "dc-version", PACEMAKER_VERSION "-" BUILD_VERSION, FALSE, NULL, NULL);
 202 
 203     update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL,
 204                          "cluster-infrastructure", cluster_type, FALSE, NULL, NULL);
 205 
 206 #if SUPPORT_COROSYNC
 207 #  if !SUPPORT_PLUGIN
 208     if (fsa_cluster_name == NULL && is_corosync_cluster()) {
 209         char *cluster_name = corosync_cluster_name();
 210 
 211         if (cluster_name) {
 212             update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL,
 213                                  "cluster-name", cluster_name, FALSE, NULL, NULL);
 214         }
 215         free(cluster_name);
 216     }
 217 #  endif
 218 #endif
 219 
 220     mainloop_set_trigger(config_read);
 221     free_xml(cib);
 222 }
 223 
 224 /*       A_DC_RELEASE   */
 225 void
 226 do_dc_release(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
 227               enum crmd_fsa_cause cause,
 228               enum crmd_fsa_state cur_state,
 229               enum crmd_fsa_input current_input, fsa_data_t * msg_data)
 230 {
 231     if (action & A_DC_RELEASE) {
 232         crm_debug("Releasing the role of DC");
 233         clear_bit(fsa_input_register, R_THE_DC);
 234 
 235     } else if (action & A_DC_RELEASED) {
 236         crm_info("DC role released");
 237 #if 0
 238         if (are there errors) {
 239             /* we can't stay up if not healthy */
 240             /* or perhaps I_ERROR and go to S_RECOVER? */
 241             result = I_SHUTDOWN;
 242         }
 243 #endif
 244         if (is_set(fsa_input_register, R_SHUTDOWN)) {
 245             xmlNode *update = NULL;
 246             crm_node_t *node = crm_get_peer(0, fsa_our_uname);
 247 
 248             crm_update_peer_expected(__FUNCTION__, node, CRMD_JOINSTATE_DOWN);
 249             update = create_node_state_update(node, node_update_expected, NULL,
 250                                               __FUNCTION__);
 251             fsa_cib_anon_update(XML_CIB_TAG_STATUS, update,
 252                                 cib_scope_local | cib_quorum_override | cib_can_create);
 253             free_xml(update);
 254         }
 255         register_fsa_input(C_FSA_INTERNAL, I_RELEASE_SUCCESS, NULL);
 256 
 257     } else {
 258         crm_err("Unknown DC action %s", fsa_action2string(action));
 259     }
 260 
 261     crm_trace("Am I still the DC? %s", AM_I_DC ? XML_BOOLEAN_YES : XML_BOOLEAN_NO);
 262 
 263 }

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