commit be75b5b7a32a495d71dd80bfe5e39a63fef2cc43
Author: Andrew Beekhof <andrew@beekhof.net>
Date:   Tue May 12 14:36:03 2015 +1000

    Fix: Fencing: Gracefully handle invalid metadata from agents

diff --git a/lib/common/xml.c b/lib/common/xml.c
index 716f053..a8f4bae 100644
--- a/lib/common/xml.c
+++ b/lib/common/xml.c
@@ -3790,6 +3790,10 @@ dump_xml_comment(xmlNode * data, int options, char **buffer, int *offset, int *m
 void
 crm_xml_dump(xmlNode * data, int options, char **buffer, int *offset, int *max, int depth)
 {
+    if(data == NULL) {
+        *offset = 0;
+        *max = 0;
+    }
 #if 0
     if (is_not_set(options, xml_log_option_filtered)) {
         /* Turning this code on also changes the PE tests for some reason
diff --git a/lib/fencing/st_client.c b/lib/fencing/st_client.c
index a7f2a35..5cb471d 100644
--- a/lib/fencing/st_client.c
+++ b/lib/fencing/st_client.c
@@ -1100,57 +1100,62 @@ stonith_api_device_metadata(stonith_t * stonith, int call_options, const char *a
     if (safe_str_eq(provider, "redhat")) {
         stonith_action_t *action = stonith_action_create(agent, "metadata", NULL, 0, 5, NULL, NULL);
         int exec_rc = stonith_action_execute(action, &rc, &buffer);
+        xmlNode *xml = NULL;
+        xmlNode *actions = NULL;
+        xmlXPathObject *xpathObj = NULL;
 
         if (exec_rc < 0 || rc != 0 || buffer == NULL) {
+            crm_warn("Could not obtain metadata for %s", agent);
             crm_debug("Query failed: %d %d: %s", exec_rc, rc, crm_str(buffer));
             free(buffer);       /* Just in case */
             return -EINVAL;
+        }
 
-        } else {
-
-            xmlNode *xml = string2xml(buffer);
-            xmlNode *actions = NULL;
-            xmlXPathObject *xpathObj = NULL;
+        xml = string2xml(buffer);
+        if(xml == NULL) {
+            crm_warn("Metadata for %s is invalid", agent);
+            free(buffer);
+            return -EINVAL;
+        }
 
-            xpathObj = xpath_search(xml, "//actions");
-            if (numXpathResults(xpathObj) > 0) {
-                actions = getXpathResult(xpathObj, 0);
-            }
+        xpathObj = xpath_search(xml, "//actions");
+        if (numXpathResults(xpathObj) > 0) {
+            actions = getXpathResult(xpathObj, 0);
+        }
 
-            freeXpathObject(xpathObj);
+        freeXpathObject(xpathObj);
 
-            /* Now fudge the metadata so that the start/stop actions appear */
-            xpathObj = xpath_search(xml, "//action[@name='stop']");
-            if (numXpathResults(xpathObj) <= 0) {
-                xmlNode *tmp = NULL;
+        /* Now fudge the metadata so that the start/stop actions appear */
+        xpathObj = xpath_search(xml, "//action[@name='stop']");
+        if (numXpathResults(xpathObj) <= 0) {
+            xmlNode *tmp = NULL;
 
-                tmp = create_xml_node(actions, "action");
-                crm_xml_add(tmp, "name", "stop");
-                crm_xml_add(tmp, "timeout", "20s");
+            tmp = create_xml_node(actions, "action");
+            crm_xml_add(tmp, "name", "stop");
+            crm_xml_add(tmp, "timeout", "20s");
 
-                tmp = create_xml_node(actions, "action");
-                crm_xml_add(tmp, "name", "start");
-                crm_xml_add(tmp, "timeout", "20s");
-            }
+            tmp = create_xml_node(actions, "action");
+            crm_xml_add(tmp, "name", "start");
+            crm_xml_add(tmp, "timeout", "20s");
+        }
 
-            freeXpathObject(xpathObj);
+        freeXpathObject(xpathObj);
 
-            /* Now fudge the metadata so that the port isn't required in the configuration */
-            xpathObj = xpath_search(xml, "//parameter[@name='port']");
-            if (numXpathResults(xpathObj) > 0) {
-                /* We'll fill this in */
-                xmlNode *tmp = getXpathResult(xpathObj, 0);
+        /* Now fudge the metadata so that the port isn't required in the configuration */
+        xpathObj = xpath_search(xml, "//parameter[@name='port']");
+        if (numXpathResults(xpathObj) > 0) {
+            /* We'll fill this in */
+            xmlNode *tmp = getXpathResult(xpathObj, 0);
 
-                crm_xml_add(tmp, "required", "0");
-            }
+            crm_xml_add(tmp, "required", "0");
+        }
 
-            freeXpathObject(xpathObj);
-            free(buffer);
-            buffer = dump_xml_formatted(xml);
-            free_xml(xml);
-            if (!buffer) {
-                return -EINVAL;
-            }
+        freeXpathObject(xpathObj);
+        free(buffer);
+        buffer = dump_xml_formatted(xml);
+        free_xml(xml);
+        if (!buffer) {
+            return -EINVAL;
         }
 
     } else {
