|
rpm-build |
3ee90c |
/*
|
|
rpm-build |
3ee90c |
* Copyright 2006-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 <crm/crm.h>
|
|
rpm-build |
3ee90c |
#include <crm/attrd.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 crm_ipc_t *attrd_ipc = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
controld_close_attrd_ipc()
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
if (attrd_ipc) {
|
|
rpm-build |
3ee90c |
crm_trace("Closing connection to pacemaker-attrd");
|
|
rpm-build |
3ee90c |
crm_ipc_close(attrd_ipc);
|
|
rpm-build |
3ee90c |
crm_ipc_destroy(attrd_ipc);
|
|
rpm-build |
3ee90c |
attrd_ipc = NULL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static void
|
|
rpm-build |
3ee90c |
log_attrd_error(const char *host, const char *name, const char *value,
|
|
rpm-build |
3ee90c |
gboolean is_remote, char command, int rc)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
const char *node_type = (is_remote? "Pacemaker Remote" : "cluster");
|
|
rpm-build |
3ee90c |
gboolean shutting_down = is_set(fsa_input_register, R_SHUTDOWN);
|
|
rpm-build |
3ee90c |
const char *when = (shutting_down? " at shutdown" : "");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
switch (command) {
|
|
rpm-build |
3ee90c |
case 0:
|
|
rpm-build |
3ee90c |
crm_err("Could not clear failure attributes for %s on %s node %s%s: %s "
|
|
rpm-build |
3ee90c |
CRM_XS " rc=%d", (name? name : "all resources"), node_type,
|
|
rpm-build |
3ee90c |
host, when, pcmk_strerror(rc), rc);
|
|
rpm-build |
3ee90c |
break;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
case 'C':
|
|
rpm-build |
3ee90c |
crm_err("Could not purge %s node %s in attribute manager%s: %s "
|
|
rpm-build |
3ee90c |
CRM_XS " rc=%d",
|
|
rpm-build |
3ee90c |
node_type, host, when, pcmk_strerror(rc), rc);
|
|
rpm-build |
3ee90c |
break;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
case 'U':
|
|
rpm-build |
3ee90c |
/* We weren't able to update an attribute after several retries,
|
|
rpm-build |
3ee90c |
* so something is horribly wrong with the attribute manager or the
|
|
rpm-build |
3ee90c |
* underlying system.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
do_crm_log(AM_I_DC? LOG_CRIT : LOG_ERR,
|
|
rpm-build |
3ee90c |
"Could not update attribute %s=%s for %s node %s%s: %s "
|
|
rpm-build |
3ee90c |
CRM_XS " rc=%d", name, value, node_type, host, when,
|
|
rpm-build |
3ee90c |
pcmk_strerror(rc), rc);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (AM_I_DC) {
|
|
rpm-build |
3ee90c |
/* We are unable to provide accurate information to the
|
|
rpm-build |
3ee90c |
* scheduler, so allow another node to take over DC.
|
|
rpm-build |
3ee90c |
* @TODO Should we do this unconditionally on any failure?
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
crmd_exit(CRM_EX_FATAL);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (shutting_down) {
|
|
rpm-build |
3ee90c |
// Fast-track shutdown since unable to request via attribute
|
|
rpm-build |
3ee90c |
register_fsa_input(C_FSA_INTERNAL, I_FAIL, NULL);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
break;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static void
|
|
rpm-build |
3ee90c |
update_attrd_helper(const char *host, const char *name, const char *value,
|
|
rpm-build |
3ee90c |
const char *interval_spec, const char *user_name,
|
|
rpm-build |
3ee90c |
gboolean is_remote_node, char command)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
int rc;
|
|
rpm-build |
3ee90c |
int attrd_opts = attrd_opt_none;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (is_remote_node) {
|
|
rpm-build |
3ee90c |
attrd_opts |= attrd_opt_remote;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (attrd_ipc == NULL) {
|
|
rpm-build |
3ee90c |
attrd_ipc = crm_ipc_new(T_ATTRD, 0);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
for (int attempt = 1; attempt <= 4; ++attempt) {
|
|
rpm-build |
3ee90c |
rc = pcmk_ok;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
// If we're not already connected, try to connect
|
|
rpm-build |
3ee90c |
if (crm_ipc_connected(attrd_ipc) == FALSE) {
|
|
rpm-build |
3ee90c |
if (attempt == 1) {
|
|
rpm-build |
3ee90c |
// Start with a clean slate
|
|
rpm-build |
3ee90c |
crm_ipc_close(attrd_ipc);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
if (crm_ipc_connect(attrd_ipc) == FALSE) {
|
|
rpm-build |
3ee90c |
rc = errno;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
crm_debug("Attribute manager connection attempt %d of 4: %s (%d)",
|
|
rpm-build |
3ee90c |
attempt, pcmk_strerror(rc), rc);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (rc == pcmk_ok) {
|
|
rpm-build |
3ee90c |
rc = command?
|
|
rpm-build |
3ee90c |
attrd_update_delegate(attrd_ipc, command, host, name, value,
|
|
rpm-build |
3ee90c |
XML_CIB_TAG_STATUS, NULL, NULL,
|
|
rpm-build |
3ee90c |
user_name, attrd_opts)
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* No command means clear fail count (name/value is really
|
|
rpm-build |
3ee90c |
* resource/operation)
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
: attrd_clear_delegate(attrd_ipc, host, name, value,
|
|
rpm-build |
3ee90c |
interval_spec, user_name, attrd_opts);
|
|
rpm-build |
3ee90c |
crm_debug("Attribute manager request attempt %d of 4: %s (%d)",
|
|
rpm-build |
3ee90c |
attempt, pcmk_strerror(rc), rc);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (rc == pcmk_ok) {
|
|
rpm-build |
3ee90c |
// Success, we're done
|
|
rpm-build |
3ee90c |
break;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if ((rc != EAGAIN) && (rc != EALREADY)) {
|
|
rpm-build |
3ee90c |
/* EAGAIN or EALREADY indicates a temporary block, so just try
|
|
rpm-build |
3ee90c |
* again. Otherwise, close the connection for a clean slate.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
crm_ipc_close(attrd_ipc);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* @TODO If the attribute manager remains unavailable the entire time,
|
|
rpm-build |
3ee90c |
* this function takes more than 6 seconds. Maybe set a timer for
|
|
rpm-build |
3ee90c |
* retries, to let the main loop do other work.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
if (attempt < 4) {
|
|
rpm-build |
3ee90c |
sleep(attempt);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (rc != pcmk_ok) {
|
|
rpm-build |
3ee90c |
log_attrd_error(host, name, value, is_remote_node, command, rc);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
update_attrd(const char *host, const char *name, const char *value,
|
|
rpm-build |
3ee90c |
const char *user_name, gboolean is_remote_node)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
update_attrd_helper(host, name, value, NULL, user_name, is_remote_node,
|
|
rpm-build |
3ee90c |
'U');
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
update_attrd_remote_node_removed(const char *host, const char *user_name)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
crm_trace("Asking attribute manager to purge Pacemaker Remote node %s",
|
|
rpm-build |
3ee90c |
host);
|
|
rpm-build |
3ee90c |
update_attrd_helper(host, NULL, NULL, NULL, user_name, TRUE, 'C');
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
update_attrd_clear_failures(const char *host, const char *rsc, const char *op,
|
|
rpm-build |
3ee90c |
const char *interval_spec, gboolean is_remote_node)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
const char *op_desc = NULL;
|
|
rpm-build |
3ee90c |
const char *interval_desc = NULL;
|
|
rpm-build |
3ee90c |
const char *node_type = is_remote_node? "Pacemaker Remote" : "cluster";
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (op) {
|
|
rpm-build |
3ee90c |
interval_desc = interval_spec? interval_spec : "nonrecurring";
|
|
rpm-build |
3ee90c |
op_desc = op;
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
interval_desc = "all";
|
|
rpm-build |
3ee90c |
op_desc = "operations";
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
crm_info("Asking pacemaker-attrd to clear failure of %s %s for %s on %s node %s",
|
|
rpm-build |
3ee90c |
interval_desc, op_desc, rsc, node_type, host);
|
|
rpm-build |
3ee90c |
update_attrd_helper(host, rsc, op, interval_spec, NULL, is_remote_node, 0);
|
|
rpm-build |
3ee90c |
}
|