|
rpm-build |
3ee90c |
/*
|
|
rpm-build |
3ee90c |
* Copyright 2004-2019 the Pacemaker project contributors
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* The version control history for this file may have further details.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* This source code is licensed under the GNU General Public License version 2
|
|
rpm-build |
3ee90c |
* or later (GPLv2+) WITHOUT ANY WARRANTY.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <crm_internal.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <unistd.h> /* pid_t, sleep, ssize_t */
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <crm/cib.h>
|
|
rpm-build |
3ee90c |
#include <crm/cluster.h>
|
|
rpm-build |
3ee90c |
#include <crm/common/xml.h>
|
|
rpm-build |
3ee90c |
#include <crm/crm.h>
|
|
rpm-build |
3ee90c |
#include <crm/msg_xml.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <pacemaker-controld.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static mainloop_io_t *pe_subsystem = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*!
|
|
rpm-build |
3ee90c |
* \internal
|
|
rpm-build |
3ee90c |
* \brief Close any scheduler connection and free associated memory
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
pe_subsystem_free(void)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
clear_bit(fsa_input_register, R_PE_REQUIRED);
|
|
rpm-build |
3ee90c |
if (pe_subsystem) {
|
|
rpm-build |
3ee90c |
controld_expect_sched_reply(NULL);
|
|
rpm-build |
3ee90c |
mainloop_del_ipc_client(pe_subsystem);
|
|
rpm-build |
3ee90c |
pe_subsystem = NULL;
|
|
rpm-build |
3ee90c |
clear_bit(fsa_input_register, R_PE_CONNECTED);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*!
|
|
rpm-build |
3ee90c |
* \internal
|
|
rpm-build |
3ee90c |
* \brief Save CIB query result to file, raising FSA error
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \param[in] msg Ignored
|
|
rpm-build |
3ee90c |
* \param[in] call_id Call ID of CIB query
|
|
rpm-build |
3ee90c |
* \param[in] rc Return code of CIB query
|
|
rpm-build |
3ee90c |
* \param[in] output Result of CIB query
|
|
rpm-build |
3ee90c |
* \param[in] user_data Unique identifier for filename (will be freed)
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \note This is intended to be called after a scheduler connection fails.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
static void
|
|
rpm-build |
3ee90c |
save_cib_contents(xmlNode *msg, int call_id, int rc, xmlNode *output,
|
|
rpm-build |
3ee90c |
void *user_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
char *id = user_data;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
register_fsa_error_adv(C_FSA_INTERNAL, I_ERROR, NULL, NULL, __FUNCTION__);
|
|
rpm-build |
3ee90c |
CRM_CHECK(id != NULL, return);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (rc == pcmk_ok) {
|
|
rpm-build |
3ee90c |
char *filename = crm_strdup_printf(PE_STATE_DIR "/pe-core-%s.bz2", id);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (write_xml_file(output, filename, TRUE) < 0) {
|
|
rpm-build |
3ee90c |
crm_err("Could not save Cluster Information Base to %s after scheduler crash",
|
|
rpm-build |
3ee90c |
filename);
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
crm_notice("Saved Cluster Information Base to %s after scheduler crash",
|
|
rpm-build |
3ee90c |
filename);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
free(filename);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*!
|
|
rpm-build |
3ee90c |
* \internal
|
|
rpm-build |
3ee90c |
* \brief Respond to scheduler connection failure
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \param[in] user_data Ignored
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
static void
|
|
rpm-build |
3ee90c |
pe_ipc_destroy(gpointer user_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
// If we aren't connected to the scheduler, we can't expect a reply
|
|
rpm-build |
3ee90c |
controld_expect_sched_reply(NULL);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (is_set(fsa_input_register, R_PE_REQUIRED)) {
|
|
rpm-build |
3ee90c |
int rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
char *uuid_str = crm_generate_uuid();
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_crit("Connection to the scheduler failed "
|
|
rpm-build |
3ee90c |
CRM_XS " uuid=%s", uuid_str);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*
|
|
rpm-build |
3ee90c |
* The scheduler died...
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Save the current CIB so that we have a chance of
|
|
rpm-build |
3ee90c |
* figuring out what killed it.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Delay raising the I_ERROR until the query below completes or
|
|
rpm-build |
3ee90c |
* 5s is up, whichever comes first.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
rc = fsa_cib_conn->cmds->query(fsa_cib_conn, NULL, NULL, cib_scope_local);
|
|
rpm-build |
3ee90c |
fsa_register_cib_callback(rc, FALSE, uuid_str, save_cib_contents);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
crm_info("Connection to the scheduler released");
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
clear_bit(fsa_input_register, R_PE_CONNECTED);
|
|
rpm-build |
3ee90c |
pe_subsystem = NULL;
|
|
rpm-build |
3ee90c |
mainloop_set_trigger(fsa_source);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*!
|
|
rpm-build |
3ee90c |
* \internal
|
|
rpm-build |
3ee90c |
* \brief Handle message from scheduler connection
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \param[in] buffer XML message (will be freed)
|
|
rpm-build |
3ee90c |
* \param[in] length Ignored
|
|
rpm-build |
3ee90c |
* \param[in] userdata Ignored
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \return 0
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
static int
|
|
rpm-build |
3ee90c |
pe_ipc_dispatch(const char *buffer, ssize_t length, gpointer userdata)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
xmlNode *msg = string2xml(buffer);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (msg) {
|
|
rpm-build |
3ee90c |
route_message(C_IPC_MESSAGE, msg);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
free_xml(msg);
|
|
rpm-build |
3ee90c |
return 0;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*!
|
|
rpm-build |
3ee90c |
* \internal
|
|
rpm-build |
3ee90c |
* \brief Make new connection to scheduler
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \return TRUE on success, FALSE otherwise
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
static bool
|
|
rpm-build |
3ee90c |
pe_subsystem_new()
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
static struct ipc_client_callbacks pe_callbacks = {
|
|
rpm-build |
3ee90c |
.dispatch = pe_ipc_dispatch,
|
|
rpm-build |
3ee90c |
.destroy = pe_ipc_destroy
|
|
rpm-build |
3ee90c |
};
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
set_bit(fsa_input_register, R_PE_REQUIRED);
|
|
rpm-build |
3ee90c |
pe_subsystem = mainloop_add_ipc_client(CRM_SYSTEM_PENGINE,
|
|
rpm-build |
3ee90c |
G_PRIORITY_DEFAULT,
|
|
rpm-build |
3ee90c |
5 * 1024 * 1024 /* 5MB */,
|
|
rpm-build |
3ee90c |
NULL, &pe_callbacks);
|
|
rpm-build |
3ee90c |
if (pe_subsystem == NULL) {
|
|
rpm-build |
3ee90c |
return FALSE;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
set_bit(fsa_input_register, R_PE_CONNECTED);
|
|
rpm-build |
3ee90c |
return TRUE;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*!
|
|
rpm-build |
3ee90c |
* \internal
|
|
rpm-build |
3ee90c |
* \brief Send an XML message to the PE
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \param[in] cmd XML message to send
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \return pcmk_ok on success, -errno otherwise
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
static int
|
|
rpm-build |
3ee90c |
pe_subsystem_send(xmlNode *cmd)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
if (pe_subsystem) {
|
|
rpm-build |
3ee90c |
int sent = crm_ipc_send(mainloop_get_ipc_client(pe_subsystem), cmd,
|
|
rpm-build |
3ee90c |
0, 0, NULL);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (sent == 0) {
|
|
rpm-build |
3ee90c |
sent = -ENODATA;
|
|
rpm-build |
3ee90c |
} else if (sent > 0) {
|
|
rpm-build |
3ee90c |
sent = pcmk_ok;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
return sent;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
return -ENOTCONN;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static void do_pe_invoke_callback(xmlNode *msg, int call_id, int rc,
|
|
rpm-build |
3ee90c |
xmlNode *output, void *user_data);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* A_PE_START, A_PE_STOP, O_PE_RESTART */
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
do_pe_control(long long action,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_cause cause,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_state cur_state,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_input current_input, fsa_data_t * msg_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
if (action & A_PE_STOP) {
|
|
rpm-build |
3ee90c |
pe_subsystem_free();
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
if ((action & A_PE_START)
|
|
rpm-build |
3ee90c |
&& (is_not_set(fsa_input_register, R_PE_CONNECTED))) {
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (cur_state == S_STOPPING) {
|
|
rpm-build |
3ee90c |
crm_info("Ignoring request to connect to scheduler while shutting down");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (!pe_subsystem_new()) {
|
|
rpm-build |
3ee90c |
crm_warn("Could not connect to scheduler");
|
|
rpm-build |
3ee90c |
register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
int fsa_pe_query = 0;
|
|
rpm-build |
3ee90c |
char *fsa_pe_ref = NULL;
|
|
rpm-build |
3ee90c |
static mainloop_timer_t *controld_sched_timer = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
// @TODO Make this a configurable cluster option if there's demand for it
|
|
rpm-build |
3ee90c |
#define SCHED_TIMEOUT_MS (120000)
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*!
|
|
rpm-build |
3ee90c |
* \internal
|
|
rpm-build |
3ee90c |
* \brief Handle a timeout waiting for scheduler reply
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \param[in] user_data Ignored
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \return FALSE (indicating that timer should not be restarted)
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
static gboolean
|
|
rpm-build |
3ee90c |
controld_sched_timeout(gpointer user_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
if (AM_I_DC) {
|
|
rpm-build |
3ee90c |
/* If this node is the DC but can't communicate with the scheduler, just
|
|
rpm-build |
3ee90c |
* exit (and likely get fenced) so this node doesn't interfere with any
|
|
rpm-build |
3ee90c |
* further DC elections.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* @TODO We could try something less drastic first, like disconnecting
|
|
rpm-build |
3ee90c |
* and reconnecting to the scheduler, but something is likely going
|
|
rpm-build |
3ee90c |
* seriously wrong, so perhaps it's better to just fail as quickly as
|
|
rpm-build |
3ee90c |
* possible.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
crmd_exit(CRM_EX_FATAL);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
return FALSE;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
controld_stop_sched_timer()
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
if (controld_sched_timer && fsa_pe_ref) {
|
|
rpm-build |
3ee90c |
crm_trace("Stopping timer for scheduler reply %s", fsa_pe_ref);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
mainloop_timer_stop(controld_sched_timer);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*!
|
|
rpm-build |
3ee90c |
* \internal
|
|
rpm-build |
3ee90c |
* \brief Set the scheduler request currently being waited on
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \param[in] msg Request to expect reply to (or NULL for none)
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
controld_expect_sched_reply(xmlNode *msg)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
char *ref = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (msg) {
|
|
rpm-build |
3ee90c |
ref = crm_element_value_copy(msg, XML_ATTR_REFERENCE);
|
|
rpm-build |
3ee90c |
CRM_ASSERT(ref != NULL);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (controld_sched_timer == NULL) {
|
|
rpm-build |
3ee90c |
controld_sched_timer = mainloop_timer_add("scheduler_reply_timer",
|
|
rpm-build |
3ee90c |
SCHED_TIMEOUT_MS, FALSE,
|
|
rpm-build |
3ee90c |
controld_sched_timeout,
|
|
rpm-build |
3ee90c |
NULL);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
mainloop_timer_start(controld_sched_timer);
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
controld_stop_sched_timer();
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
free(fsa_pe_ref);
|
|
rpm-build |
3ee90c |
fsa_pe_ref = ref;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*!
|
|
rpm-build |
3ee90c |
* \internal
|
|
rpm-build |
3ee90c |
* \brief Free the scheduler reply timer
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
controld_free_sched_timer()
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
if (controld_sched_timer != NULL) {
|
|
rpm-build |
3ee90c |
mainloop_timer_del(controld_sched_timer);
|
|
rpm-build |
3ee90c |
controld_sched_timer = NULL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* A_PE_INVOKE */
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
do_pe_invoke(long long action,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_cause cause,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_state cur_state,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_input current_input, fsa_data_t * msg_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
if (AM_I_DC == FALSE) {
|
|
rpm-build |
3ee90c |
crm_err("Not invoking scheduler because not DC: %s",
|
|
rpm-build |
3ee90c |
fsa_action2string(action));
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (is_set(fsa_input_register, R_PE_CONNECTED) == FALSE) {
|
|
rpm-build |
3ee90c |
if (is_set(fsa_input_register, R_SHUTDOWN)) {
|
|
rpm-build |
3ee90c |
crm_err("Cannot shut down gracefully without the scheduler");
|
|
rpm-build |
3ee90c |
register_fsa_input_before(C_FSA_INTERNAL, I_TERMINATE, NULL);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
crm_info("Waiting for the scheduler to connect");
|
|
rpm-build |
3ee90c |
crmd_fsa_stall(FALSE);
|
|
rpm-build |
3ee90c |
register_fsa_action(A_PE_START);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (cur_state != S_POLICY_ENGINE) {
|
|
rpm-build |
3ee90c |
crm_notice("Not invoking scheduler because in state %s",
|
|
rpm-build |
3ee90c |
fsa_state2string(cur_state));
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
if (is_set(fsa_input_register, R_HAVE_CIB) == FALSE) {
|
|
rpm-build |
3ee90c |
crm_err("Attempted to invoke scheduler without consistent Cluster Information Base!");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* start the join from scratch */
|
|
rpm-build |
3ee90c |
register_fsa_input_before(C_FSA_INTERNAL, I_ELECTION, NULL);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
fsa_pe_query = fsa_cib_conn->cmds->query(fsa_cib_conn, NULL, NULL, cib_scope_local);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_debug("Query %d: Requesting the current CIB: %s", fsa_pe_query,
|
|
rpm-build |
3ee90c |
fsa_state2string(fsa_state));
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
controld_expect_sched_reply(NULL);
|
|
rpm-build |
3ee90c |
fsa_register_cib_callback(fsa_pe_query, FALSE, NULL, do_pe_invoke_callback);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static void
|
|
rpm-build |
3ee90c |
force_local_option(xmlNode *xml, const char *attr_name, const char *attr_value)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
int max = 0;
|
|
rpm-build |
3ee90c |
int lpc = 0;
|
|
rpm-build |
3ee90c |
char *xpath_string = NULL;
|
|
rpm-build |
3ee90c |
xmlXPathObjectPtr xpathObj = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
xpath_string = crm_strdup_printf("%.128s//%s//nvpair[@name='%.128s']",
|
|
rpm-build |
3ee90c |
get_object_path(XML_CIB_TAG_CRMCONFIG),
|
|
rpm-build |
3ee90c |
XML_CIB_TAG_PROPSET, attr_name);
|
|
rpm-build |
3ee90c |
xpathObj = xpath_search(xml, xpath_string);
|
|
rpm-build |
3ee90c |
max = numXpathResults(xpathObj);
|
|
rpm-build |
3ee90c |
free(xpath_string);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
for (lpc = 0; lpc < max; lpc++) {
|
|
rpm-build |
3ee90c |
xmlNode *match = getXpathResult(xpathObj, lpc);
|
|
rpm-build |
3ee90c |
crm_trace("Forcing %s/%s = %s", ID(match), attr_name, attr_value);
|
|
rpm-build |
3ee90c |
crm_xml_add(match, XML_NVPAIR_ATTR_VALUE, attr_value);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if(max == 0) {
|
|
rpm-build |
3ee90c |
xmlNode *configuration = NULL;
|
|
rpm-build |
3ee90c |
xmlNode *crm_config = NULL;
|
|
rpm-build |
3ee90c |
xmlNode *cluster_property_set = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_trace("Creating %s-%s for %s=%s",
|
|
rpm-build |
3ee90c |
CIB_OPTIONS_FIRST, attr_name, attr_name, attr_value);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
configuration = find_entity(xml, XML_CIB_TAG_CONFIGURATION, NULL);
|
|
rpm-build |
3ee90c |
if (configuration == NULL) {
|
|
rpm-build |
3ee90c |
configuration = create_xml_node(xml, XML_CIB_TAG_CONFIGURATION);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_config = find_entity(configuration, XML_CIB_TAG_CRMCONFIG, NULL);
|
|
rpm-build |
3ee90c |
if (crm_config == NULL) {
|
|
rpm-build |
3ee90c |
crm_config = create_xml_node(configuration, XML_CIB_TAG_CRMCONFIG);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
cluster_property_set = find_entity(crm_config, XML_CIB_TAG_PROPSET, NULL);
|
|
rpm-build |
3ee90c |
if (cluster_property_set == NULL) {
|
|
rpm-build |
3ee90c |
cluster_property_set = create_xml_node(crm_config, XML_CIB_TAG_PROPSET);
|
|
rpm-build |
3ee90c |
crm_xml_add(cluster_property_set, XML_ATTR_ID, CIB_OPTIONS_FIRST);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
xml = create_xml_node(cluster_property_set, XML_CIB_TAG_NVPAIR);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_xml_set_id(xml, "%s-%s", CIB_OPTIONS_FIRST, attr_name);
|
|
rpm-build |
3ee90c |
crm_xml_add(xml, XML_NVPAIR_ATTR_NAME, attr_name);
|
|
rpm-build |
3ee90c |
crm_xml_add(xml, XML_NVPAIR_ATTR_VALUE, attr_value);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
freeXpathObject(xpathObj);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static void
|
|
rpm-build |
3ee90c |
do_pe_invoke_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
xmlNode *cmd = NULL;
|
|
rpm-build |
3ee90c |
pid_t watchdog = pcmk_locate_sbd();
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (rc != pcmk_ok) {
|
|
rpm-build |
3ee90c |
crm_err("Could not retrieve the Cluster Information Base: %s "
|
|
rpm-build |
3ee90c |
CRM_XS " rc=%d call=%d", pcmk_strerror(rc), rc, call_id);
|
|
rpm-build |
3ee90c |
register_fsa_error_adv(C_FSA_INTERNAL, I_ERROR, NULL, NULL, __FUNCTION__);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (call_id != fsa_pe_query) {
|
|
rpm-build |
3ee90c |
crm_trace("Skipping superseded CIB query: %d (current=%d)", call_id, fsa_pe_query);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (AM_I_DC == FALSE || is_set(fsa_input_register, R_PE_CONNECTED) == FALSE) {
|
|
rpm-build |
3ee90c |
crm_debug("No need to invoke the scheduler anymore");
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (fsa_state != S_POLICY_ENGINE) {
|
|
rpm-build |
3ee90c |
crm_debug("Discarding scheduler request in state: %s",
|
|
rpm-build |
3ee90c |
fsa_state2string(fsa_state));
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* this callback counts as 1 */
|
|
rpm-build |
3ee90c |
} else if (num_cib_op_callbacks() > 1) {
|
|
rpm-build |
3ee90c |
crm_debug("Re-asking for the CIB: %d other peer updates still pending",
|
|
rpm-build |
3ee90c |
(num_cib_op_callbacks() - 1));
|
|
rpm-build |
3ee90c |
sleep(1);
|
|
rpm-build |
3ee90c |
register_fsa_action(A_PE_INVOKE);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (fsa_state != S_POLICY_ENGINE) {
|
|
rpm-build |
3ee90c |
crm_err("Invoking scheduler in state: %s", fsa_state2string(fsa_state));
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
CRM_LOG_ASSERT(output != NULL);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Refresh the remote node cache and the known node cache when the
|
|
rpm-build |
3ee90c |
* scheduler is invoked */
|
|
rpm-build |
3ee90c |
crm_peer_caches_refresh(output);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_xml_add(output, XML_ATTR_DC_UUID, fsa_our_uuid);
|
|
rpm-build |
3ee90c |
crm_xml_add_int(output, XML_ATTR_HAVE_QUORUM, fsa_has_quorum);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
force_local_option(output, XML_ATTR_HAVE_WATCHDOG, watchdog?"true":"false");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (ever_had_quorum && crm_have_quorum == FALSE) {
|
|
rpm-build |
3ee90c |
crm_xml_add_int(output, XML_ATTR_QUORUM_PANIC, 1);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
cmd = create_request(CRM_OP_PECALC, output, NULL, CRM_SYSTEM_PENGINE, CRM_SYSTEM_DC, NULL);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
rc = pe_subsystem_send(cmd);
|
|
rpm-build |
3ee90c |
if (rc < 0) {
|
|
rpm-build |
3ee90c |
crm_err("Could not contact the scheduler: %s " CRM_XS " rc=%d",
|
|
rpm-build |
3ee90c |
pcmk_strerror(rc), rc);
|
|
rpm-build |
3ee90c |
register_fsa_error_adv(C_FSA_INTERNAL, I_ERROR, NULL, NULL, __FUNCTION__);
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
controld_expect_sched_reply(cmd);
|
|
rpm-build |
3ee90c |
crm_debug("Invoking the scheduler: query=%d, ref=%s, seq=%llu, quorate=%d",
|
|
rpm-build |
3ee90c |
fsa_pe_query, fsa_pe_ref, crm_peer_seq, fsa_has_quorum);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
free_xml(cmd);
|
|
rpm-build |
3ee90c |
}
|