Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4832446
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/lrmd/lrmd_alerts.c b/lib/lrmd/lrmd_alerts.c
index ad7eaee05e..487e48c470 100644
--- a/lib/lrmd/lrmd_alerts.c
+++ b/lib/lrmd/lrmd_alerts.c
@@ -1,379 +1,379 @@
/*
* Copyright (c) 2015 David Vossel <davidvossel@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <crm_internal.h>
#include <glib.h>
#include <unistd.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/services.h>
#include <crm/common/mainloop.h>
#include <crm/common/alerts_internal.h>
#include <crm/common/iso8601_internal.h>
#include <crm/lrmd_alerts_internal.h>
#include <crm/pengine/status.h>
#include <crm/cib.h>
#include <crm/lrmd.h>
static lrmd_key_value_t *
alert_key2param(lrmd_key_value_t *head, enum crm_alert_keys_e name,
const char *value)
{
const char **key;
if (value == NULL) {
value = "";
}
for (key = crm_alert_keys[name]; *key; key++) {
crm_trace("Setting alert key %s = '%s'", *key, value);
head = lrmd_key_value_add(head, *key, value);
}
return head;
}
static lrmd_key_value_t *
alert_key2param_int(lrmd_key_value_t *head, enum crm_alert_keys_e name,
int value)
{
char *value_s = crm_itoa(value);
head = alert_key2param(head, name, value_s);
free(value_s);
return head;
}
static void
set_ev_kv(gpointer key, gpointer value, gpointer user_data)
{
lrmd_key_value_t **head = (lrmd_key_value_t **) user_data;
if (value) {
crm_trace("Setting environment variable %s='%s'",
(char*)key, (char*)value);
*head = lrmd_key_value_add(*head, key, value);
}
}
static lrmd_key_value_t *
alert_envvar2params(lrmd_key_value_t *head, crm_alert_entry_t *entry)
{
if (entry->envvars) {
g_hash_table_foreach(entry->envvars, set_ev_kv, &head);
}
return head;
}
/*
* We could use g_strv_contains() instead of this function,
* but that has only been available since glib 2.43.2.
*/
static gboolean
is_target_alert(char **list, const char *value)
{
int target_list_num = 0;
gboolean rc = FALSE;
CRM_CHECK(value != NULL, return FALSE);
if (list == NULL) {
return TRUE;
}
target_list_num = g_strv_length(list);
for (int cnt = 0; cnt < target_list_num; cnt++) {
if (strcmp(list[cnt], value) == 0) {
rc = TRUE;
break;
}
}
return rc;
}
/*!
* \internal
* \brief Execute alert agents for an event
*
* \param[in] alert_list Alerts to execute
* \param[in] lrmd_connect_func Function that returns an LRMD connection
* \param[in] kind Type of event that is being alerted for
* \param[in] attr_name If crm_alert_attribute, the attribute name
* \param[in,out] params Environment variables to pass to agents
*
* \retval pcmk_ok on success
* \retval -1 if some alerts failed
* \retval -2 if all alerts failed
*/
static int
exec_alert_list(GList *alert_list, lrmd_t *(*lrmd_connect_func)(void),
enum crm_alert_flags kind, const char *attr_name,
lrmd_key_value_t *params)
{
bool any_success = FALSE, any_failure = FALSE;
const char *kind_s = crm_alert_flag2text(kind);
crm_time_hr_t *now = NULL;
params = alert_key2param(params, CRM_alert_kind, kind_s);
params = alert_key2param(params, CRM_alert_version, VERSION);
for (GList *iter = g_list_first(alert_list); iter; iter = g_list_next(iter)) {
crm_alert_entry_t *entry = (crm_alert_entry_t *)(iter->data);
lrmd_key_value_t *copy_params = NULL;
lrmd_key_value_t *head = NULL;
lrmd_t *lrmd_conn = NULL;
int rc;
if (is_not_set(entry->flags, kind)) {
crm_trace("Filtering unwanted %s alert to %s via %s",
kind_s, entry->recipient, entry->id);
continue;
}
if ((kind == crm_alert_attribute)
&& !is_target_alert(entry->select_attribute_name, attr_name)) {
crm_trace("Filtering unwanted attribute '%s' alert to %s via %s",
attr_name, entry->recipient, entry->id);
continue;
}
if (now == NULL) {
now = crm_time_hr_new(NULL);
}
crm_info("Sending %s alert via %s to %s",
kind_s, entry->id, entry->recipient);
/* Make a copy of the parameters, because each alert will be unique */
for (head = params; head != NULL; head = head->next) {
copy_params = lrmd_key_value_add(copy_params, head->key, head->value);
}
copy_params = alert_key2param(copy_params, CRM_alert_recipient,
entry->recipient);
if (now) {
char *timestamp = crm_time_format_hr(entry->tstamp_format, now);
if (timestamp) {
copy_params = alert_key2param(copy_params, CRM_alert_timestamp,
timestamp);
free(timestamp);
}
}
copy_params = alert_envvar2params(copy_params, entry);
lrmd_conn = (*lrmd_connect_func)();
if (lrmd_conn == NULL) {
crm_warn("Cannot send alerts: No LRMD connection");
any_failure = TRUE;
goto done;
}
rc = lrmd_conn->cmds->exec_alert(lrmd_conn, entry->id, entry->path,
entry->timeout, copy_params);
if (rc < 0) {
crm_err("Could not execute alert %s: %s " CRM_XS " rc=%d",
entry->id, pcmk_strerror(rc), rc);
any_failure = TRUE;
} else {
any_success = TRUE;
}
}
done:
if (now) {
free(now);
}
if (any_failure) {
return (any_success? -1 : -2);
}
return pcmk_ok;
}
/*!
* \internal
* \brief Send an alert for a node attribute change
*
* \param[in] alert_list List of alert agents to execute
* \param[in] lrmd_connect_func Function that returns an LRMD connection
* \param[in] node Name of node with attribute change
* \param[in] nodeid Node ID of node with attribute change
* \param[in] attr_name Name of attribute that changed
* \param[in] attr_value New value of attribute that changed
*
* \retval pcmk_ok on success
* \retval -1 if some alert agents failed
* \retval -2 if all alert agents failed
*/
int
lrmd_send_attribute_alert(GList *alert_list, lrmd_t *(*lrmd_connect_func)(void),
const char *node, uint32_t nodeid,
const char *attr_name, const char *attr_value)
{
int rc = pcmk_ok;
lrmd_key_value_t *params = NULL;
if (alert_list == NULL) {
return pcmk_ok;
}
params = alert_key2param(params, CRM_alert_node, node);
params = alert_key2param_int(params, CRM_alert_nodeid, nodeid);
params = alert_key2param(params, CRM_alert_attribute_name, attr_name);
params = alert_key2param(params, CRM_alert_attribute_value, attr_value);
rc = exec_alert_list(alert_list, lrmd_connect_func, crm_alert_attribute,
attr_name, params);
lrmd_key_value_freeall(params);
return rc;
}
/*!
* \internal
* \brief Send an alert for a node membership event
*
* \param[in] alert_list List of alert agents to execute
* \param[in] lrmd_connect_func Function that returns an LRMD connection
* \param[in] node Name of node with change
* \param[in] nodeid Node ID of node with change
* \param[in] state New state of node with change
*
* \retval pcmk_ok on success
* \retval -1 if some alert agents failed
* \retval -2 if all alert agents failed
*/
int
lrmd_send_node_alert(GList *alert_list, lrmd_t *(*lrmd_connect_func)(void),
const char *node, uint32_t nodeid, const char *state)
{
int rc = pcmk_ok;
lrmd_key_value_t *params = NULL;
if (alert_list == NULL) {
return pcmk_ok;
}
params = alert_key2param(params, CRM_alert_node, node);
params = alert_key2param(params, CRM_alert_desc, state);
params = alert_key2param_int(params, CRM_alert_nodeid, nodeid);
rc = exec_alert_list(alert_list, lrmd_connect_func, crm_alert_node, NULL,
params);
lrmd_key_value_freeall(params);
return rc;
}
/*!
* \internal
* \brief Send an alert for a fencing event
*
* \param[in] alert_list List of alert agents to execute
* \param[in] lrmd_connect_func Function that returns an LRMD connection
* \param[in] target Name of fence target node
* \param[in] task Type of fencing event that occurred
* \param[in] desc Readable description of event
* \param[in] op_rc Result of fence action
*
* \retval pcmk_ok on success
* \retval -1 if some alert agents failed
* \retval -2 if all alert agents failed
*/
int
lrmd_send_fencing_alert(GList *alert_list, lrmd_t *(*lrmd_connect_func)(void),
const char *target, const char *task, const char *desc,
int op_rc)
{
int rc = pcmk_ok;
lrmd_key_value_t *params = NULL;
if (alert_list == NULL) {
return pcmk_ok;
}
params = alert_key2param(params, CRM_alert_node, target);
params = alert_key2param(params, CRM_alert_task, task);
params = alert_key2param(params, CRM_alert_desc, desc);
params = alert_key2param_int(params, CRM_alert_rc, op_rc);
rc = exec_alert_list(alert_list, lrmd_connect_func, crm_alert_fencing,
NULL, params);
lrmd_key_value_freeall(params);
return rc;
}
/*!
* \internal
* \brief Send an alert for a resource operation
*
* \param[in] alert_list List of alert agents to execute
* \param[in] lrmd_connect_func Function that returns an LRMD connection
* \param[in] node Name of node that executed operation
* \param[in] op Resource operation
*
* \retval pcmk_ok on success
* \retval -1 if some alert agents failed
* \retval -2 if all alert agents failed
*/
int
lrmd_send_resource_alert(GList *alert_list, lrmd_t *(*lrmd_connect_func)(void),
const char *node, lrmd_event_data_t *op)
{
int rc = pcmk_ok;
int target_rc = pcmk_ok;
lrmd_key_value_t *params = NULL;
if (alert_list == NULL) {
return pcmk_ok;
}
target_rc = rsc_op_expected_rc(op);
if ((op->interval == 0) && (target_rc == op->rc)
&& safe_str_eq(op->op_type, RSC_STATUS)) {
/* Don't send alerts for probes with the expected result. Leave it up to
* the agent whether to alert for 'failed' probes. (Even if we find a
* resource running, it was probably because someone did a clean-up of
* the status section.)
*/
return pcmk_ok;
}
params = alert_key2param(params, CRM_alert_node, node);
params = alert_key2param(params, CRM_alert_rsc, op->rsc_id);
params = alert_key2param(params, CRM_alert_task, op->op_type);
params = alert_key2param_int(params, CRM_alert_interval, op->interval);
params = alert_key2param_int(params, CRM_alert_target_rc, target_rc);
params = alert_key2param_int(params, CRM_alert_status, op->op_status);
params = alert_key2param_int(params, CRM_alert_rc, op->rc);
if (op->op_status == PCMK_LRM_OP_DONE) {
- crm_set_alert_key(CRM_alert_desc, services_ocf_exitcode_str(op->rc));
+ params = alert_key2param(params, CRM_alert_desc, services_ocf_exitcode_str(op->rc));
} else {
- crm_set_alert_key(CRM_alert_desc, services_lrm_status_str(op->op_status));
+ params = alert_key2param(params, CRM_alert_desc, services_lrm_status_str(op->op_status));
}
rc = exec_alert_list(alert_list, lrmd_connect_func, crm_alert_resource,
NULL, params);
lrmd_key_value_freeall(params);
return rc;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Jul 20, 7:30 PM (3 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2081333
Default Alt Text
(12 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment