File bug-909286_pacemaker-crm_mon-repair-notification-delivery.patch of Package pacemaker.9287
From 3df6aff2d72d508c7c3eeb5ccc48856d624e86a6 Mon Sep 17 00:00:00 2001
From: Andrew Beekhof <andrew@beekhof.net>
Date: Fri, 25 Jul 2014 15:01:45 +1000
Subject: [PATCH] Fix: crm_mon: Repair notification delivery when the v2 patch
format is in use
---
tools/crm_mon.c | 183 ++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 161 insertions(+), 22 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 3f79c46d7e..79b2ef2f23 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -2384,7 +2384,7 @@ send_smtp_trap(const char *node, const char *rsc, const char *task, int target_r
}
static void
-handle_rsc_op(xmlNode * rsc_op)
+handle_rsc_op(xmlNode * xml, const char *node)
{
int rc = -1;
int status = -1;
@@ -2397,13 +2397,24 @@ handle_rsc_op(xmlNode * rsc_op)
char *rsc = NULL;
char *task = NULL;
const char *desc = NULL;
- const char *node = NULL;
const char *magic = NULL;
- const char *id = crm_element_value(rsc_op, XML_LRM_ATTR_TASK_KEY);
+ const char *id = NULL;
char *update_te_uuid = NULL;
- xmlNode *n = rsc_op;
+ xmlNode *n = xml;
+ xmlNode * rsc_op = xml;
+ if(strcmp((const char*)xml->name, XML_LRM_TAG_RSC_OP) != 0) {
+ xmlNode *cIter;
+
+ for(cIter = xml->children; cIter; cIter = cIter->next) {
+ handle_rsc_op(cIter, node);
+ }
+
+ return;
+ }
+
+ id = crm_element_value(rsc_op, XML_LRM_ATTR_TASK_KEY);
if (id == NULL) {
/* Compatability with <= 1.1.5 */
id = ID(rsc_op);
@@ -2430,10 +2441,14 @@ handle_rsc_op(xmlNode * rsc_op)
n = n->parent;
}
- node = crm_element_value(n, XML_ATTR_UNAME);
+ if(node == NULL) {
+ node = crm_element_value(n, XML_ATTR_UNAME);
+ }
+
if (node == NULL) {
node = ID(n);
}
+
if (node == NULL) {
crm_err("No node detected for event %s (%s)", magic, id);
goto bail;
@@ -2478,6 +2493,132 @@ mon_trigger_refresh(gpointer user_data)
return FALSE;
}
+#define NODE_PATT "/lrm[@id="
+static char *get_node_from_xpath(const char *xpath)
+{
+ char *nodeid = NULL;
+ char *tmp = strstr(xpath, NODE_PATT);
+
+ if(tmp) {
+ tmp += strlen(NODE_PATT);
+ tmp += 1;
+
+ nodeid = strdup(tmp);
+ tmp = strstr(nodeid, "\'");
+ CRM_ASSERT(tmp);
+ tmp[0] = 0;
+ }
+ return nodeid;
+}
+
+static void crm_diff_update_v2(const char *event, xmlNode * msg)
+{
+ xmlNode *change = NULL;
+ xmlNode *diff = get_message_xml(msg, F_CIB_UPDATE_RESULT);
+
+ for (change = __xml_first_child(diff); change != NULL; change = __xml_next(change)) {
+ const char *name = NULL;
+ const char *op = crm_element_value(change, XML_DIFF_OP);
+ const char *xpath = crm_element_value(change, XML_DIFF_PATH);
+ xmlNode *match = NULL;
+ const char *node = NULL;
+
+ if(op == NULL) {
+ continue;
+
+ } else if(strcmp(op, "create") == 0) {
+ match = change->children;
+
+ } else if(strcmp(op, "move") == 0) {
+ continue;
+
+ } else if(strcmp(op, "delete") == 0) {
+ continue;
+
+ } else if(strcmp(op, "modify") == 0) {
+ match = first_named_child(change, XML_DIFF_RESULT);
+ if(match) {
+ match = match->children;
+ }
+ }
+
+ if(match) {
+ name = (const char *)match->name;
+ }
+
+ crm_trace("Handling %s operation for %s %p, %s", op, xpath, match, name);
+ if(xpath == NULL) {
+ /* Version field, ignore */
+
+ } else if(name == NULL) {
+ crm_debug("No result for %s operation to %s", op, xpath);
+ CRM_ASSERT(strcmp(op, "delete") == 0 || strcmp(op, "move") == 0);
+
+ } else if(strcmp(name, XML_TAG_CIB) == 0) {
+ xmlNode *state = NULL;
+ xmlNode *status = first_named_child(match, XML_CIB_TAG_STATUS);
+
+ for (state = __xml_first_child(status); state != NULL; state = __xml_next(state)) {
+ node = ID(state);
+ handle_rsc_op(state, node);
+ }
+
+ } else if(strcmp(name, XML_CIB_TAG_STATUS) == 0) {
+ xmlNode *state = NULL;
+
+ for (state = __xml_first_child(match); state != NULL; state = __xml_next(state)) {
+ node = ID(state);
+ handle_rsc_op(state, node);
+ }
+
+ } else if(strcmp(name, XML_CIB_TAG_STATE) == 0) {
+ node = ID(match);
+ handle_rsc_op(match, node);
+
+ } else if(strcmp(name, XML_CIB_TAG_LRM) == 0) {
+ node = ID(match);
+ handle_rsc_op(match, node);
+
+ } else if(strcmp(name, XML_LRM_TAG_RESOURCES) == 0) {
+ char *local_node = get_node_from_xpath(xpath);
+
+ handle_rsc_op(match, local_node);
+ free(local_node);
+
+ } else if(strcmp(name, XML_LRM_TAG_RESOURCE) == 0) {
+ char *local_node = get_node_from_xpath(xpath);
+
+ handle_rsc_op(match, local_node);
+ free(local_node);
+
+ } else if(strcmp(name, XML_LRM_TAG_RSC_OP) == 0) {
+ char *local_node = get_node_from_xpath(xpath);
+
+ handle_rsc_op(match, local_node);
+ free(local_node);
+
+ } else {
+ crm_err("Ignoring %s operation for %s %p, %s", op, xpath, match, name);
+ }
+ }
+}
+
+static void crm_diff_update_v1(const char *event, xmlNode * msg)
+{
+ /* Process operation updates */
+ xmlXPathObject *xpathObj = xpath_search(msg,
+ "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED
+ "//" XML_LRM_TAG_RSC_OP);
+ int lpc = 0, max = numXpathResults(xpathObj);
+
+ for (lpc = 0; lpc < max; lpc++) {
+ xmlNode *rsc_op = getXpathResult(xpathObj, lpc);
+
+ handle_rsc_op(rsc_op, NULL);
+ }
+ freeXpathObject(xpathObj);
+}
+
void
crm_diff_update(const char *event, xmlNode * msg)
{
@@ -2486,6 +2627,7 @@ crm_diff_update(const char *event, xmlNode * msg)
static bool stale = FALSE;
static int updates = 0;
static mainloop_timer_t *refresh_timer = NULL;
+ xmlNode *diff = get_message_xml(msg, F_CIB_UPDATE_RESULT);
print_dot();
@@ -2494,23 +2636,20 @@ crm_diff_update(const char *event, xmlNode * msg)
}
if (current_cib != NULL) {
- xmlNode *cib_last = current_cib;
-
- current_cib = NULL;
-
- rc = cib_apply_patch_event(msg, cib_last, ¤t_cib, LOG_DEBUG);
- free_xml(cib_last);
+ rc = xml_apply_patchset(current_cib, diff, TRUE);
switch (rc) {
case -pcmk_err_diff_resync:
case -pcmk_err_diff_failed:
crm_notice("[%s] Patch aborted: %s (%d)", event, pcmk_strerror(rc), rc);
+ free_xml(current_cib); current_cib = NULL;
break;
case pcmk_ok:
updates++;
break;
default:
crm_notice("[%s] ABORTED: %s (%d)", event, pcmk_strerror(rc), rc);
+ free_xml(current_cib); current_cib = NULL;
}
}
@@ -2520,18 +2659,18 @@ crm_diff_update(const char *event, xmlNode * msg)
}
if (crm_mail_to || snmp_target || external_agent) {
- /* Process operation updates */
- xmlXPathObject *xpathObj = xpath_search(msg,
- "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED
- "//" XML_LRM_TAG_RSC_OP);
- int lpc = 0, max = numXpathResults(xpathObj);
-
- for (lpc = 0; lpc < max; lpc++) {
- xmlNode *rsc_op = getXpathResult(xpathObj, lpc);
-
- handle_rsc_op(rsc_op);
+ int format = 0;
+ crm_element_value_int(diff, "format", &format);
+ switch(format) {
+ case 1:
+ crm_diff_update_v1(event, msg);
+ break;
+ case 2:
+ crm_diff_update_v2(event, msg);
+ break;
+ default:
+ crm_err("Unknown patch format: %d", format);
}
- freeXpathObject(xpathObj);
}
if (current_cib == NULL) {