Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3686874
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/include/crm/common/alerts_internal.h b/include/crm/common/alerts_internal.h
index ef64fab1d6..03619f53d6 100644
--- a/include/crm/common/alerts_internal.h
+++ b/include/crm/common/alerts_internal.h
@@ -1,92 +1,92 @@
/*
* Copyright 2015-2022 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#ifndef PCMK__ALERT_INTERNAL__H
#define PCMK__ALERT_INTERNAL__H
#include <glib.h>
#include <stdbool.h>
/* Default-Timeout to use before killing a alerts script (in milliseconds) */
# define PCMK__ALERT_DEFAULT_TIMEOUT_MS (30000)
/* Default-Format-String used to pass timestamps to the alerts scripts */
# define PCMK__ALERT_DEFAULT_TSTAMP_FORMAT "%H:%M:%S.%06N"
enum pcmk__alert_flags {
pcmk__alert_none = 0,
pcmk__alert_node = (1 << 0),
pcmk__alert_fencing = (1 << 1),
pcmk__alert_resource = (1 << 2),
pcmk__alert_attribute = (1 << 3),
pcmk__alert_default = pcmk__alert_node|pcmk__alert_fencing|
pcmk__alert_resource,
};
typedef struct {
char *id;
char *path;
char *tstamp_format;
char *recipient;
char **select_attribute_name;
GHashTable *envvars;
int timeout;
uint32_t flags;
} pcmk__alert_t;
enum pcmk__alert_keys_e {
PCMK__alert_key_recipient = 0,
PCMK__alert_key_node,
PCMK__alert_key_nodeid,
PCMK__alert_key_rsc,
PCMK__alert_key_task,
PCMK__alert_key_interval,
PCMK__alert_key_desc,
PCMK__alert_key_status,
PCMK__alert_key_target_rc,
PCMK__alert_key_rc,
PCMK__alert_key_kind,
PCMK__alert_key_version,
PCMK__alert_key_node_sequence,
PCMK__alert_key_timestamp,
PCMK__alert_key_attribute_name,
PCMK__alert_key_attribute_value,
PCMK__alert_key_timestamp_epoch,
PCMK__alert_key_timestamp_usec,
PCMK__alert_key_exec_time,
PCMK__alert_key_select_kind,
PCMK__alert_key_select_attribute_name
};
#define PCMK__ALERT_INTERNAL_KEY_MAX 19
#define PCMK__ALERT_NODE_SEQUENCE "CRM_alert_node_sequence"
extern const char *pcmk__alert_keys[PCMK__ALERT_INTERNAL_KEY_MAX][3];
pcmk__alert_t *pcmk__dup_alert(const pcmk__alert_t *entry);
pcmk__alert_t *pcmk__alert_new(const char *id, const char *path);
void pcmk__free_alert(pcmk__alert_t *entry);
void pcmk__add_alert_key(GHashTable *table, enum pcmk__alert_keys_e name,
const char *value);
void pcmk__add_alert_key_int(GHashTable *table, enum pcmk__alert_keys_e name,
int value);
-bool pcmk__alert_in_patchset(xmlNode *msg, bool config);
+bool pcmk__alert_in_patchset(const xmlNode *msg, bool config);
static inline const char *
pcmk__alert_flag2text(enum pcmk__alert_flags flag)
{
switch (flag) {
case pcmk__alert_node: return "node";
case pcmk__alert_fencing: return "fencing";
case pcmk__alert_resource: return "resource";
case pcmk__alert_attribute: return "attribute";
default: return "unknown";
}
}
#endif
diff --git a/lib/common/alerts.c b/lib/common/alerts.c
index b8e46dba28..32eb6dba40 100644
--- a/lib/common/alerts.c
+++ b/lib/common/alerts.c
@@ -1,251 +1,277 @@
/*
* Copyright 2015-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#include <crm_internal.h>
#include <crm/crm.h>
#include <crm/lrmd.h>
#include <crm/msg_xml.h>
#include <crm/common/alerts_internal.h>
+#include <crm/common/cib_internal.h>
#include <crm/common/xml_internal.h>
#include <crm/cib/internal.h> /* for F_CIB_UPDATE_RESULT */
/*
* to allow script compatibility we can have more than one
* set of environment variables
*/
const char *pcmk__alert_keys[PCMK__ALERT_INTERNAL_KEY_MAX][3] =
{
[PCMK__alert_key_recipient] = {
"CRM_notify_recipient", "CRM_alert_recipient", NULL
},
[PCMK__alert_key_node] = {
"CRM_notify_node", "CRM_alert_node", NULL
},
[PCMK__alert_key_nodeid] = {
"CRM_notify_nodeid", "CRM_alert_nodeid", NULL
},
[PCMK__alert_key_rsc] = {
"CRM_notify_rsc", "CRM_alert_rsc", NULL
},
[PCMK__alert_key_task] = {
"CRM_notify_task", "CRM_alert_task", NULL
},
[PCMK__alert_key_interval] = {
"CRM_notify_interval", "CRM_alert_interval", NULL
},
[PCMK__alert_key_desc] = {
"CRM_notify_desc", "CRM_alert_desc", NULL
},
[PCMK__alert_key_status] = {
"CRM_notify_status", "CRM_alert_status", NULL
},
[PCMK__alert_key_target_rc] = {
"CRM_notify_target_rc", "CRM_alert_target_rc", NULL
},
[PCMK__alert_key_rc] = {
"CRM_notify_rc", "CRM_alert_rc", NULL
},
[PCMK__alert_key_kind] = {
"CRM_notify_kind", "CRM_alert_kind", NULL
},
[PCMK__alert_key_version] = {
"CRM_notify_version", "CRM_alert_version", NULL
},
[PCMK__alert_key_node_sequence] = {
"CRM_notify_node_sequence", PCMK__ALERT_NODE_SEQUENCE, NULL
},
[PCMK__alert_key_timestamp] = {
"CRM_notify_timestamp", "CRM_alert_timestamp", NULL
},
[PCMK__alert_key_attribute_name] = {
"CRM_notify_attribute_name", "CRM_alert_attribute_name", NULL
},
[PCMK__alert_key_attribute_value] = {
"CRM_notify_attribute_value", "CRM_alert_attribute_value", NULL
},
[PCMK__alert_key_timestamp_epoch] = {
"CRM_notify_timestamp_epoch", "CRM_alert_timestamp_epoch", NULL
},
[PCMK__alert_key_timestamp_usec] = {
"CRM_notify_timestamp_usec", "CRM_alert_timestamp_usec", NULL
},
[PCMK__alert_key_exec_time] = {
"CRM_notify_exec_time", "CRM_alert_exec_time", NULL
}
};
/*!
* \brief Create a new alert entry structure
*
* \param[in] id ID to use
* \param[in] path Path to alert agent executable
*
* \return Pointer to newly allocated alert entry
* \note Non-string fields will be filled in with defaults.
* It is the caller's responsibility to free the result,
* using pcmk__free_alert().
*/
pcmk__alert_t *
pcmk__alert_new(const char *id, const char *path)
{
pcmk__alert_t *entry = calloc(1, sizeof(pcmk__alert_t));
CRM_ASSERT(entry && id && path);
entry->id = strdup(id);
entry->path = strdup(path);
entry->timeout = PCMK__ALERT_DEFAULT_TIMEOUT_MS;
entry->flags = pcmk__alert_default;
return entry;
}
void
pcmk__free_alert(pcmk__alert_t *entry)
{
if (entry) {
free(entry->id);
free(entry->path);
free(entry->tstamp_format);
free(entry->recipient);
g_strfreev(entry->select_attribute_name);
if (entry->envvars) {
g_hash_table_destroy(entry->envvars);
}
free(entry);
}
}
/*!
* \internal
* \brief Duplicate an alert entry
*
* \param[in] entry Alert entry to duplicate
*
* \return Duplicate of alert entry
*/
pcmk__alert_t *
pcmk__dup_alert(const pcmk__alert_t *entry)
{
pcmk__alert_t *new_entry = pcmk__alert_new(entry->id, entry->path);
new_entry->timeout = entry->timeout;
new_entry->flags = entry->flags;
new_entry->envvars = pcmk__str_table_dup(entry->envvars);
pcmk__str_update(&new_entry->tstamp_format, entry->tstamp_format);
pcmk__str_update(&new_entry->recipient, entry->recipient);
if (entry->select_attribute_name) {
new_entry->select_attribute_name = g_strdupv(entry->select_attribute_name);
}
return new_entry;
}
void
pcmk__add_alert_key(GHashTable *table, enum pcmk__alert_keys_e name,
const char *value)
{
for (const char **key = pcmk__alert_keys[name]; *key; key++) {
crm_trace("Inserting alert key %s = '%s'", *key, value);
if (value) {
g_hash_table_insert(table, strdup(*key), strdup(value));
} else {
g_hash_table_remove(table, *key);
}
}
}
void
pcmk__add_alert_key_int(GHashTable *table, enum pcmk__alert_keys_e name,
int value)
{
for (const char **key = pcmk__alert_keys[name]; *key; key++) {
crm_trace("Inserting alert key %s = %d", *key, value);
g_hash_table_insert(table, strdup(*key), pcmk__itoa(value));
}
}
-#define XPATH_PATCHSET1_DIFF "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED
+#define XPATH_DIFF_V1 "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED
+#define XPATH_CRMCONFIG_V1 XPATH_DIFF_V1 "//" XML_CIB_TAG_CRMCONFIG
+#define XPATH_ALERTS_V1 XPATH_DIFF_V1 "//" XML_CIB_TAG_ALERTS
+#define XPATH_EITHER_V1 XPATH_CRMCONFIG_V1 "|" XPATH_ALERTS_V1
-#define XPATH_PATCHSET1_CRMCONFIG XPATH_PATCHSET1_DIFF "//" XML_CIB_TAG_CRMCONFIG
-#define XPATH_PATCHSET1_ALERTS XPATH_PATCHSET1_DIFF "//" XML_CIB_TAG_ALERTS
+/*!
+ * \internal
+ * \brief Check whether a CIB update affects alerts (using v1 diff)
+ *
+ * \param[in] patchset XML containing CIB update
+ * \param[in] config Whether to check for crmconfig change as well
+ *
+ * \return \c true if the update affects alerts, or \c false otherwise
+ */
+static bool
+alert_in_patchset_v1(const xmlNode *patchset, bool config)
+{
+ const char *xpath = config? XPATH_EITHER_V1 : XPATH_ALERTS_V1;
+ xmlXPathObject *xpath_obj = xpath_search(patchset, xpath);
-#define XPATH_PATCHSET1_EITHER \
- XPATH_PATCHSET1_CRMCONFIG " | " XPATH_PATCHSET1_ALERTS
+ if (xpath_obj != NULL) {
+ freeXpathObject(xpath_obj);
+ return true;
+ }
+ return false;
+}
-#define XPATH_CONFIG "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION
+/*!
+ * \internal
+ * \brief Check whether a CIB update affects alerts (using v2 diff)
+ *
+ * \param[in] patchset XML containing CIB update
+ * \param[in] config Whether to check for crmconfig change as well
+ *
+ * \return \c true if the update affects alerts, or \c false otherwise
+ */
+static bool
+alert_in_patchset_v2(const xmlNode *patchset, bool config)
+{
+ const char *xpath_alerts = pcmk__cib_abs_xpath_for(XML_CIB_TAG_ALERTS);
+ const char *xpath_parent = pcmk_cib_parent_name_for(XML_CIB_TAG_ALERTS);
+ const char *xpath_crmconfig =
+ pcmk__cib_abs_xpath_for(XML_CIB_TAG_CRMCONFIG);
+
+ for (const xmlNode *change = first_named_child(patchset, XML_DIFF_CHANGE);
+ change != NULL; change = crm_next_same_xml(change)) {
-#define XPATH_CRMCONFIG XPATH_CONFIG "/" XML_CIB_TAG_CRMCONFIG "/"
-#define XPATH_ALERTS XPATH_CONFIG "/" XML_CIB_TAG_ALERTS
+ const char *xpath = crm_element_value(change, XML_DIFF_PATH);
+
+ if (pcmk__starts_with(xpath, xpath_alerts)
+ || (config && pcmk__starts_with(xpath, xpath_crmconfig))) {
+
+ // Change to an existing alerts or crm_config section
+ return true;
+ }
+
+ if (pcmk__str_eq(xpath, xpath_parent, pcmk__str_none)
+ && pcmk__xe_is(pcmk__xml_first_child(change), XML_CIB_TAG_ALERTS)) {
+
+ // Newly added alerts section in a create operation
+ return true;
+ }
+ }
+ return false;
+}
/*!
* \internal
* \brief Check whether a CIB update affects alerts
*
* \param[in] msg XML containing CIB update
* \param[in] config Whether to check for crmconfig change as well
*
- * \return TRUE if update affects alerts, FALSE otherwise
+ * \return \c true if the update affects alerts, or \c false otherwise
*/
bool
-pcmk__alert_in_patchset(xmlNode *msg, bool config)
+pcmk__alert_in_patchset(const xmlNode *msg, bool config)
{
- int rc = -1;
- int format= 1;
- xmlNode *patchset = get_message_xml(msg, F_CIB_UPDATE_RESULT);
- xmlNode *change = NULL;
- xmlXPathObject *xpathObj = NULL;
+ int rc = pcmk_err_generic;
+ int format = 1;
+ xmlNode *patchset = NULL;
- CRM_CHECK(msg != NULL, return FALSE);
+ CRM_CHECK(msg != NULL, return false);
- crm_element_value_int(msg, F_CIB_RC, &rc);
- if (rc < pcmk_ok) {
+ if ((crm_element_value_int(msg, F_CIB_RC, &rc) != 0) || (rc != pcmk_ok)) {
crm_trace("Ignore failed CIB update: %s (%d)", pcmk_strerror(rc), rc);
- return FALSE;
+ return false;
}
- crm_element_value_int(patchset, "format", &format);
- if (format == 1) {
- const char *diff = (config? XPATH_PATCHSET1_EITHER : XPATH_PATCHSET1_ALERTS);
-
- if ((xpathObj = xpath_search(msg, diff)) != NULL) {
- freeXpathObject(xpathObj);
- return TRUE;
- }
- } else if (format == 2) {
- for (change = pcmk__xml_first_child(patchset); change != NULL;
- change = pcmk__xml_next(change)) {
- const char *xpath = crm_element_value(change, XML_DIFF_PATH);
-
- if (xpath == NULL) {
- continue;
- }
-
- if ((!config || !strstr(xpath, XPATH_CRMCONFIG))
- && !strstr(xpath, XPATH_ALERTS)) {
-
- /* this is not a change to an existing section ... */
+ patchset = get_message_xml(msg, F_CIB_UPDATE_RESULT);
+ CRM_CHECK(patchset != NULL, return false);
- xmlNode *section = NULL;
-
- if ((strcmp(xpath, XPATH_CONFIG) != 0) ||
- ((section = pcmk__xml_first_child(change)) == NULL) ||
- !pcmk__xe_is(section, XML_CIB_TAG_ALERTS)) {
-
- /* ... nor is it a newly added alerts section */
- continue;
- }
- }
+ crm_element_value_int(patchset, "format", &format);
+ switch (format) {
+ case 1:
+ return alert_in_patchset_v1(patchset, config);
- return TRUE;
- }
+ case 2:
+ return alert_in_patchset_v2(patchset, config);
- } else {
- crm_warn("Unknown patch format: %d", format);
+ default:
+ crm_warn("Unknown patch format: %d", format);
+ return false;
}
- return FALSE;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Apr 21, 6:09 PM (1 d, 4 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1665096
Default Alt Text
(14 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment