From 7e49054aad07a3d04311c183bc89dd159f75e7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 12 Aug 2016 13:52:15 +0200 Subject: [PATCH 1/5] Refactor: xml.c: merge two identical branches --- lib/common/xml.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/common/xml.c b/lib/common/xml.c index a20e73e..ff819a2 100644 --- a/lib/common/xml.c +++ b/lib/common/xml.c @@ -5668,16 +5668,11 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g crm_trace("Stopping at %s", known_schemas[lpc].name); break; - } else if (max > 0 && lpc == max) { + } else if (max > 0 && (lpc == max || next > max)) { crm_trace("Upgrade limit reached at %s (lpc=%d, next=%d, max=%d)", known_schemas[lpc].name, lpc, next, max); break; - } else if (max > 0 && next > max) { - crm_debug("Upgrade limit reached at %s (lpc=%d, next=%d, max=%d)", - known_schemas[lpc].name, lpc, next, max); - break; - } else if (known_schemas[lpc].transform == NULL) { crm_debug("%s-style configuration is also valid for %s", known_schemas[lpc].name, known_schemas[next].name); -- 1.8.3.1 From d83ffab1e6acb5049b8634ed20e156573307162a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 12 Aug 2016 13:53:24 +0200 Subject: [PATCH 2/5] Med: xml.c: internal self-or-less reference inflicted infloop guard --- lib/common/xml.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/common/xml.c b/lib/common/xml.c index ff819a2..4e019b5 100644 --- a/lib/common/xml.c +++ b/lib/common/xml.c @@ -329,7 +329,7 @@ static void __xml_schema_add( known_schemas[last].transform = strdup(transform); } if(after_transform == 0) { - after_transform = xml_schema_max; + after_transform = xml_schema_max; /* upgrade is a one-way */ } known_schemas[last].after_transform = after_transform; @@ -5664,7 +5664,7 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g xmlNode *upgrade = NULL; int next = known_schemas[lpc].after_transform; - if (next < 0) { + if (next < 0 || next <= lpc) { crm_trace("Stopping at %s", known_schemas[lpc].name); break; -- 1.8.3.1 From 35fadfd89ee59edb999ed828b7e39e8449fd99b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 12 Aug 2016 14:13:51 +0200 Subject: [PATCH 3/5] High: fix infloop when no schema validates on update_validation Test case: $ ./autogen.sh; ./configure; make # if not already $ sed -i.orig 's|"promote"|"infloop"|' \ pengine/test10/use-after-free-merge.xml $ PCMK_schema_directory=$(pwd)/xml \ tools/crm_simulate -x pengine/test10/use-after-free-merge.xml -S BEFORE: Entity: line 54: element rsc_colocation: Relax-NG validity error : Invalid attribute then-action for element rsc_order Entity: line 49: element rsc_location: Relax-NG validity error : Element constraints has extra content: rsc_location [...infloop...] AFTER: Entity: line 54: element rsc_colocation: Relax-NG validity error : Invalid attribute then-action for element rsc_order Entity: line 49: element rsc_location: Relax-NG validity error : Element constraints has extra content: rsc_location [several times] --- lib/common/xml.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/common/xml.c b/lib/common/xml.c index 4e019b5..26d76f2 100644 --- a/lib/common/xml.c +++ b/lib/common/xml.c @@ -5647,20 +5647,27 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g } while(lpc <= max_stable_schemas) { - gboolean valid = TRUE; - crm_debug("Testing '%s' validation (%d of %d)", known_schemas[lpc].name ? known_schemas[lpc].name : "", lpc, max_stable_schemas); - valid = validate_with(xml, lpc, to_logs); - if (valid) { - *best = lpc; - } else { + if (validate_with(xml, lpc, to_logs) == FALSE) { crm_trace("%s validation failed", known_schemas[lpc].name ? known_schemas[lpc].name : ""); + if (*best) { + /* we've satisfied the validation, no need to check further */ + break; + } + rc = -pcmk_err_schema_validation; + + } else { + rc = pcmk_ok; } - if (valid && transform) { + if (rc == pcmk_ok) { + *best = lpc; + } + + if (rc == pcmk_ok && transform) { xmlNode *upgrade = NULL; int next = known_schemas[lpc].after_transform; @@ -5716,6 +5723,11 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g } } } + + if (transform == FALSE || rc != pcmk_ok) { + /* we need some progress! */ + lpc++; + } } if (*best > match) { -- 1.8.3.1 From e41267c3fd4958d61d6833385d86f354b10264b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 12 Aug 2016 14:35:47 +0200 Subject: [PATCH 4/5] Refactor: xml.c: avoid repeated validate_with call on happy path --- lib/common/xml.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/common/xml.c b/lib/common/xml.c index 26d76f2..fc1fe7f 100644 --- a/lib/common/xml.c +++ b/lib/common/xml.c @@ -5617,6 +5617,7 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g char *value = NULL; int max_stable_schemas = xml_latest_schema_index(); int lpc = 0, match = -1, rc = pcmk_ok; + int next = -1; /* -1 denotes "inactive" value */ CRM_CHECK(best != NULL, return -EINVAL); CRM_CHECK(xml_blob != NULL, return -EINVAL); @@ -5652,7 +5653,12 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g lpc, max_stable_schemas); if (validate_with(xml, lpc, to_logs) == FALSE) { - crm_trace("%s validation failed", known_schemas[lpc].name ? known_schemas[lpc].name : ""); + if (next != -1) { + crm_info("Configuration not valid for schema: %s", known_schemas[lpc].name); + next = -1; + } else { + crm_trace("%s validation failed", known_schemas[lpc].name ? known_schemas[lpc].name : ""); + } if (*best) { /* we've satisfied the validation, no need to check further */ break; @@ -5660,6 +5666,10 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g rc = -pcmk_err_schema_validation; } else { + if (next != -1) { + crm_debug("Configuration valid for schema: %s", known_schemas[next].name); + next = -1; + } rc = pcmk_ok; } @@ -5669,7 +5679,7 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g if (rc == pcmk_ok && transform) { xmlNode *upgrade = NULL; - int next = known_schemas[lpc].after_transform; + next = known_schemas[lpc].after_transform; if (next < 0 || next <= lpc) { crm_trace("Stopping at %s", known_schemas[lpc].name); @@ -5684,15 +5694,7 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g crm_debug("%s-style configuration is also valid for %s", known_schemas[lpc].name, known_schemas[next].name); - if (validate_with(xml, next, to_logs)) { - crm_debug("Configuration valid for schema: %s", known_schemas[next].name); - lpc = next; - *best = next; - rc = pcmk_ok; - - } else { - crm_info("Configuration not valid for schema: %s", known_schemas[next].name); - } + lpc = next; } else { crm_debug("Upgrading %s-style configuration to %s with %s", @@ -5721,6 +5723,7 @@ update_validation(xmlNode ** xml_blob, int *best, int max, gboolean transform, g free_xml(upgrade); rc = -pcmk_err_schema_validation; } + next = -1; } } -- 1.8.3.1 From e4b9f340d54310251576c0f862a99149e846235b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Fri, 12 Aug 2016 14:38:42 +0200 Subject: [PATCH 5/5] Low: xml.c: better info in cli_config_update on no validation success This commit turns [error message] from testcase at 35fadfd commit's message from > Your current configuration could only be upgraded to pacemaker-1.0... > the minimum requirement is pacemaker-2.0. into > Your current configuration could not validate with any schema in > range [pacemaker-1.0, pacemaker-2.6] --- lib/common/xml.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/common/xml.c b/lib/common/xml.c index fc1fe7f..e4574fb 100644 --- a/lib/common/xml.c +++ b/lib/common/xml.c @@ -5752,6 +5752,7 @@ cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs) const char *value = crm_element_value(*xml, XML_ATTR_VALIDATION); int version = get_schema_version(value); + int orig_version = version; int min_version = xml_minimum_schema_index(); if (version < min_version) { @@ -5762,7 +5763,19 @@ cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs) value = crm_element_value(converted, XML_ATTR_VALIDATION); if (version < min_version) { - if (to_logs) { + if (version < orig_version) { + if (to_logs) { + crm_config_err("Your current configuration could not validate" + " with any schema in range [%s, %s]\n", + get_schema_name(orig_version), + xml_latest_schema()); + } else { + fprintf(stderr, "Your current configuration could not validate" + " with any schema in range [%s, %s]\n", + get_schema_name(orig_version), + xml_latest_schema()); + } + } else if (to_logs) { crm_config_err("Your current configuration could only be upgraded to %s... " "the minimum requirement is %s.\n", crm_str(value), get_schema_name(min_version)); -- 1.8.3.1