pacemaker/bug-809635_pacemaker-xml-digest.patch

130 lines
3.9 KiB
Diff
Raw Normal View History

diff --git a/lib/common/xml.c b/lib/common/xml.c
index b6df79f..33a9abf 100644
--- a/lib/common/xml.c
+++ b/lib/common/xml.c
@@ -2275,6 +2275,7 @@ calculate_xml_digest_v1(xmlNode * input, gboolean sort, gboolean ignored)
return digest;
}
+#if 0
static char *
calculate_xml_digest_v2(xmlNode * source, gboolean do_filter)
{
@@ -2324,6 +2325,116 @@ calculate_xml_digest_v2(xmlNode * source, gboolean do_filter)
crm_trace("End digest");
return digest;
}
+#endif
+
+static void
+filter_xml(xmlNode *data, filter_t *filter, int filter_len, gboolean recursive)
+{
+ int lpc = 0;
+ xmlNode *child = NULL;
+
+ for(lpc = 0; lpc < filter_len; lpc++) {
+ xml_remove_prop(data, filter[lpc].string);
+ }
+
+ if(recursive == FALSE || filter_len == 0) {
+ return;
+ }
+
+ for(child = __xml_first_child(data); child != NULL; child = __xml_next(child)) {
+ filter_xml(child, filter, filter_len, recursive);
+ }
+}
+
+static char *
+calculate_xml_digest_v2(xmlNode *source, gboolean do_filter)
+{
+ char *digest = NULL;
+
+ int buffer_len = 0;
+ int filter_size = DIMOF(filter);
+
+ xmlDoc *doc = NULL;
+ xmlNode *copy = NULL;
+ xmlNode *input = source;
+ xmlBuffer *xml_buffer = NULL;
+ static struct qb_log_callsite *digest_cs = NULL;
+
+ crm_trace("Begin digest");
+ if(do_filter && BEST_EFFORT_STATUS) {
+ /* Exclude the status calculation from the digest
+ *
+ * This doesn't mean it wont be sync'd, we just wont be paranoid
+ * about it being an _exact_ copy
+ *
+ * We don't need it to be exact, since we throw it away and regenerate
+ * from our peers whenever a new DC is elected anyway
+ *
+ * Importantly, this reduces the amount of XML to copy+export as
+ * well as the amount of data for MD5 needs to operate on
+ */
+ xmlNode *child = NULL;
+ xmlAttrPtr pIter = NULL;
+ copy = create_xml_node(NULL, XML_TAG_CIB);
+ for(pIter = crm_first_attr(input); pIter != NULL; pIter = pIter->next) {
+ const char *p_name = (const char *)pIter->name;
+ const char *p_value = crm_attr_value(pIter);
+
+ xmlSetProp(copy, (const xmlChar*)p_name, (const xmlChar*)p_value);
+ }
+
+ xml_remove_prop(copy, XML_ATTR_ORIGIN);
+ xml_remove_prop(copy, XML_CIB_ATTR_WRITTEN);
+
+ /* We just did all the filtering */
+
+ for(child = __xml_first_child(input); child != NULL; child = __xml_next(child)) {
+ if(safe_str_neq(crm_element_name(child), XML_CIB_TAG_STATUS)) {
+ add_node_copy(copy, child);
+ }
+ }
+
+ } else if(do_filter) {
+ copy = copy_xml(input);
+ filter_xml(copy, filter, filter_size, TRUE);
+ input = copy;
+ }
+
+ crm_trace("Dumping");
+ doc = getDocPtr(input);
+ xml_buffer = xmlBufferCreate();
+
+ CRM_ASSERT(xml_buffer != NULL);
+ CRM_CHECK(doc != NULL, return NULL); /* doc will only be NULL if an_xml_node is */
+
+ buffer_len = xmlNodeDump(xml_buffer, doc, input, 0, FALSE);
+ CRM_CHECK(xml_buffer->content != NULL && buffer_len > 0, goto done);
+
+ digest = crm_md5sum((char *)xml_buffer->content);
+
+ if(digest_cs == NULL) {
+ digest_cs = qb_log_callsite_get(
+ __func__, __FILE__, "cib-digest", LOG_TRACE, __LINE__,
+ crm_trace_nonlog);
+ }
+ if (digest_cs && digest_cs->targets) {
+ char *trace_file = crm_concat("/tmp/cib-digest", digest, '-');
+ crm_trace("Saving %s.%s.%s to %s",
+ crm_element_value(input, XML_ATTR_GENERATION_ADMIN),
+ crm_element_value(input, XML_ATTR_GENERATION),
+ crm_element_value(input, XML_ATTR_NUMUPDATES),
+ trace_file);
+ save_xml_to_file(source, "digest input", trace_file);
+ free(trace_file);
+ }
+
+ done:
+ xmlBufferFree(xml_buffer);
+ free_xml(copy);
+
+ crm_trace("End digest");
+ return digest;
+}
char *
calculate_on_disk_digest(xmlNode * input)