root/crmd/cib.c

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

DEFINITIONS

This source file includes following definitions.
  1. do_cib_updated
  2. revision_check_callback
  3. do_cib_replaced
  4. do_cib_control
  5. crmd_cib_smart_opt

   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 <unistd.h>  /* sleep */
  22 
  23 #include <crm/common/alerts_internal.h>
  24 #include <crm/common/xml.h>
  25 #include <crm/crm.h>
  26 #include <crm/msg_xml.h>
  27 
  28 #include <crmd.h>
  29 #include <crmd_callbacks.h>  /* crmd_cib_connection_destroy */
  30 #include <crmd_fsa.h>
  31 #include <crmd_messages.h>
  32 
  33 
  34 struct crm_subsystem_s *cib_subsystem = NULL;
  35 
  36 int cib_retries = 0;
  37 
  38 static void
  39 do_cib_updated(const char *event, xmlNode * msg)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41     if (crm_patchset_contains_alert(msg, TRUE)) {
  42         mainloop_set_trigger(config_read);
  43     }
  44 }
  45 
  46 static void
  47 revision_check_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49     int cmp = -1;
  50     xmlNode *generation = NULL;
  51     const char *revision = NULL;
  52 
  53     if (rc != pcmk_ok) {
  54         fsa_data_t *msg_data = NULL;
  55 
  56         register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
  57         return;
  58     }
  59 
  60     generation = output;
  61     CRM_CHECK(safe_str_eq(crm_element_name(generation), XML_TAG_CIB),
  62               crm_log_xml_err(output, __FUNCTION__); return);
  63 
  64     crm_trace("Checking our feature revision %s is allowed", CRM_FEATURE_SET);
  65 
  66     revision = crm_element_value(generation, XML_ATTR_CRM_VERSION);
  67     cmp = compare_version(revision, CRM_FEATURE_SET);
  68 
  69     if (cmp > 0) {
  70         crm_err("Shutting down because the current configuration is not supported by this version "
  71                 CRM_XS " build=%s supported=%s current=%s",
  72                 PACEMAKER_VERSION, CRM_FEATURE_SET, revision);
  73         /* go into a stall state */
  74         register_fsa_error_adv(C_FSA_INTERNAL, I_SHUTDOWN, NULL, NULL, __FUNCTION__);
  75         return;
  76     }
  77 }
  78 
  79 static void
  80 do_cib_replaced(const char *event, xmlNode * msg)
     /* [previous][next][first][last][top][bottom][index][help] */
  81 {
  82     crm_debug("Updating the CIB after a replace: DC=%s", AM_I_DC ? "true" : "false");
  83     if (AM_I_DC == FALSE) {
  84         return;
  85 
  86     } else if (fsa_state == S_FINALIZE_JOIN && is_set(fsa_input_register, R_CIB_ASKED)) {
  87         /* no need to restart the join - we asked for this replace op */
  88         return;
  89     }
  90 
  91     /* start the join process again so we get everyone's LRM status */
  92     populate_cib_nodes(node_update_quick|node_update_all, __FUNCTION__);
  93     register_fsa_input(C_FSA_INTERNAL, I_ELECTION, NULL);
  94 }
  95 
  96 /* A_CIB_STOP, A_CIB_START, O_CIB_RESTART */
  97 void
  98 do_cib_control(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
  99                enum crmd_fsa_cause cause,
 100                enum crmd_fsa_state cur_state,
 101                enum crmd_fsa_input current_input, fsa_data_t * msg_data)
 102 {
 103     CRM_ASSERT(fsa_cib_conn != NULL);
 104 
 105     if (action & A_CIB_STOP) {
 106 
 107         if (fsa_cib_conn->state != cib_disconnected && last_resource_update != 0) {
 108             crm_info("Waiting for resource update %d to complete", last_resource_update);
 109             crmd_fsa_stall(FALSE);
 110             return;
 111         }
 112 
 113         crm_info("Disconnecting CIB");
 114         clear_bit(fsa_input_register, R_CIB_CONNECTED);
 115 
 116         fsa_cib_conn->cmds->del_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY, do_cib_updated);
 117 
 118         if (fsa_cib_conn->state != cib_disconnected) {
 119             fsa_cib_conn->cmds->set_slave(fsa_cib_conn, cib_scope_local);
 120             fsa_cib_conn->cmds->signoff(fsa_cib_conn);
 121         }
 122         crm_notice("Disconnected from the CIB");
 123     }
 124 
 125     if (action & A_CIB_START) {
 126         int rc = pcmk_ok;
 127 
 128         if (cur_state == S_STOPPING) {
 129             crm_err("Ignoring request to start the CIB after shutdown");
 130             return;
 131         }
 132 
 133         rc = fsa_cib_conn->cmds->signon(fsa_cib_conn, CRM_SYSTEM_CRMD, cib_command_nonblocking);
 134 
 135         if (rc != pcmk_ok) {
 136             /* a short wait that usually avoids stalling the FSA */
 137             sleep(1);
 138             rc = fsa_cib_conn->cmds->signon(fsa_cib_conn, CRM_SYSTEM_CRMD, cib_command_nonblocking);
 139         }
 140 
 141         if (rc != pcmk_ok) {
 142             crm_info("Could not connect to the CIB service: %s", pcmk_strerror(rc));
 143 
 144         } else if (pcmk_ok !=
 145                    fsa_cib_conn->cmds->set_connection_dnotify(fsa_cib_conn,
 146                                                               crmd_cib_connection_destroy)) {
 147             crm_err("Could not set dnotify callback");
 148 
 149         } else if (pcmk_ok !=
 150                    fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn, T_CIB_REPLACE_NOTIFY,
 151                                                            do_cib_replaced)) {
 152             crm_err("Could not set CIB notification callback (replace)");
 153 
 154         } else if (pcmk_ok !=
 155                    fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY,
 156                                                            do_cib_updated)) {
 157             crm_err("Could not set CIB notification callback (update)");
 158 
 159         } else {
 160             set_bit(fsa_input_register, R_CIB_CONNECTED);
 161         }
 162 
 163         if (is_set(fsa_input_register, R_CIB_CONNECTED) == FALSE) {
 164 
 165             cib_retries++;
 166             crm_warn("Couldn't complete CIB registration %d"
 167                      " times... pause and retry", cib_retries);
 168 
 169             if (cib_retries < 30) {
 170                 crm_timer_start(wait_timer);
 171                 crmd_fsa_stall(FALSE);
 172 
 173             } else {
 174                 crm_err("Could not complete CIB"
 175                         " registration  %d times..." " hard error", cib_retries);
 176                 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
 177             }
 178         } else {
 179             int call_id = 0;
 180 
 181             crm_info("CIB connection established");
 182 
 183             call_id = fsa_cib_conn->cmds->query(fsa_cib_conn, NULL, NULL, cib_scope_local);
 184 
 185             fsa_register_cib_callback(call_id, FALSE, NULL, revision_check_callback);
 186             cib_retries = 0;
 187         }
 188     }
 189 }
 190 
 191 /*!
 192  * \internal
 193  * \brief Get CIB call options to use local scope if master unavailable
 194  *
 195  * \return CIB call options
 196  */
 197 int crmd_cib_smart_opt()
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199     int call_opt = cib_quorum_override;
 200 
 201     if (fsa_state == S_ELECTION || fsa_state == S_PENDING) {
 202         crm_info("Sending update to local CIB in state: %s", fsa_state2string(fsa_state));
 203         call_opt |= cib_scope_local;
 204     }
 205     return call_opt;
 206 }

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