From: "Gao,Yan" Date: Wed, 30 Sep 2015 16:59:43 +0200 Subject: [PATCH] Fix: crm_resource: Correctly delete existing meta attributes regardless of their position in the heirarchy Use the same logics as "--set-parameter" for "--delete-parameter". (cherry picked from commit cdee10c7310ab433b006126bc087f6b8dff3843e) Conflicts: tools/crm_resource_runtime.c --- tools/crm_resource_runtime.c | 109 ++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c index 878fd0b..2d51e88 100644 --- a/tools/crm_resource_runtime.c +++ b/tools/crm_resource_runtime.c @@ -190,47 +190,20 @@ find_resource_attr(cib_t * the_cib, const char *attr, const char *rsc, const cha return rc; } -int -cli_resource_update_attribute(const char *rsc_id, const char *attr_set, const char *attr_id, - const char *attr_name, const char *attr_value, bool recursive, - cib_t * cib, pe_working_set_t * data_set) +static resource_t * +find_matching_attr_resource(resource_t * rsc, const char * rsc_id, const char * attr_set, const char * attr_id, + const char * attr_name, cib_t * cib, const char * cmd) { int rc = pcmk_ok; - static bool need_init = TRUE; - char *lookup_id = NULL; char *local_attr_id = NULL; - char *local_attr_set = NULL; - - xmlNode *xml_top = NULL; - xmlNode *xml_obj = NULL; - - bool use_attributes_tag = FALSE; - resource_t *rsc = find_rsc_or_clone(rsc_id, data_set); - - if (rsc == NULL) { - return -ENXIO; - } - - if (safe_str_eq(attr_set_type, XML_TAG_ATTR_SETS)) { - if (do_force == FALSE) { - rc = find_resource_attr(cib, XML_ATTR_ID, uber_parent(rsc)->id, - XML_TAG_META_SETS, attr_set, attr_id, - attr_name, &local_attr_id); - if (rc == pcmk_ok && BE_QUIET == FALSE) { - printf("WARNING: There is already a meta attribute for '%s' called '%s' (id=%s)\n", - uber_parent(rsc)->id, attr_name, local_attr_id); - printf(" Delete '%s' first or use --force to override\n", local_attr_id); - } - return -ENOTUNIQ; - } - } else if(rsc->parent && do_force == FALSE) { + if(rsc->parent && do_force == FALSE) { switch(rsc->parent->variant) { case pe_group: if (BE_QUIET == FALSE) { - printf("Updating '%s' for '%s' will not apply to its peers in '%s'\n", attr_name, rsc_id, rsc->parent->id); + printf("Performing %s of '%s' for '%s' will not apply to its peers in '%s'\n", cmd, attr_name, rsc_id, rsc->parent->id); } break; case pe_master: @@ -242,7 +215,7 @@ cli_resource_update_attribute(const char *rsc_id, const char *attr_set, const ch if(rc != pcmk_ok) { rsc = rsc->parent; if (BE_QUIET == FALSE) { - printf("Updating '%s' on '%s', the parent of '%s'\n", attr_name, rsc->id, rsc_id); + printf("Performing %s of '%s' on '%s', the parent of '%s'\n", cmd, attr_name, rsc->id, rsc_id); } } break; @@ -251,7 +224,7 @@ cli_resource_update_attribute(const char *rsc_id, const char *attr_set, const ch } } else if (rsc->parent && BE_QUIET == FALSE) { - printf("Forcing update of '%s' for '%s' instead of '%s'\n", attr_name, rsc_id, rsc->parent->id); + printf("Forcing %s of '%s' for '%s' instead of '%s'\n", cmd, attr_name, rsc_id, rsc->parent->id); } else if(rsc->parent == NULL && rsc->children) { resource_t *child = rsc->children->data; @@ -263,7 +236,7 @@ cli_resource_update_attribute(const char *rsc_id, const char *attr_set, const ch if(rc == pcmk_ok) { rsc = child; if (BE_QUIET == FALSE) { - printf("A value for '%s' already exists in child '%s', updating that instead of '%s'\n", attr_name, lookup_id, rsc_id); + printf("A value for '%s' already exists in child '%s', performing %s on that instead of '%s'\n", attr_name, lookup_id, cmd, rsc_id); } } @@ -272,6 +245,51 @@ cli_resource_update_attribute(const char *rsc_id, const char *attr_set, const ch } } + return rsc; +} + +int +cli_resource_update_attribute(const char *rsc_id, const char *attr_set, const char *attr_id, + const char *attr_name, const char *attr_value, bool recursive, + cib_t * cib, pe_working_set_t * data_set) +{ + int rc = pcmk_ok; + static bool need_init = TRUE; + + char *lookup_id = NULL; + char *local_attr_id = NULL; + char *local_attr_set = NULL; + + xmlNode *xml_top = NULL; + xmlNode *xml_obj = NULL; + + bool use_attributes_tag = FALSE; + resource_t *rsc = find_rsc_or_clone(rsc_id, data_set); + + if (rsc == NULL) { + return -ENXIO; + } + + if (safe_str_eq(attr_set_type, XML_TAG_ATTR_SETS)) { + if (do_force == FALSE) { + rc = find_resource_attr(cib, XML_ATTR_ID, uber_parent(rsc)->id, + XML_TAG_META_SETS, attr_set, attr_id, + attr_name, &local_attr_id); + if (rc == pcmk_ok && BE_QUIET == FALSE) { + printf("WARNING: There is already a meta attribute for '%s' called '%s' (id=%s)\n", + uber_parent(rsc)->id, attr_name, local_attr_id); + printf(" Delete '%s' first or use --force to override\n", local_attr_id); + } + free(local_attr_id); + if (rc == pcmk_ok) { + return -ENOTUNIQ; + } + } + + } else { + rsc = find_matching_attr_resource(rsc, rsc_id, attr_set, attr_id, attr_name, cib, "update"); + } + lookup_id = clone_strip(rsc->id); /* Could be a cloned group! */ rc = find_resource_attr(cib, XML_ATTR_ID, lookup_id, attr_set_type, attr_set, attr_id, attr_name, &local_attr_id); @@ -401,25 +419,8 @@ cli_resource_delete_attribute(const char *rsc_id, const char *attr_set, const ch return -ENXIO; } - if(rsc->parent && safe_str_eq(attr_set_type, XML_TAG_META_SETS)) { - - switch(rsc->parent->variant) { - case pe_group: - if (BE_QUIET == FALSE) { - printf("Removing '%s' for '%s' will not apply to its peers in '%s'\n", attr_name, rsc_id, rsc->parent->id); - } - break; - case pe_master: - case pe_clone: - rsc = rsc->parent; - if (BE_QUIET == FALSE) { - printf("Removing '%s' from '%s' for '%s'...\n", attr_name, rsc->id, rsc_id); - } - break; - default: - break; - } - + if(safe_str_eq(attr_set_type, XML_TAG_META_SETS)) { + rsc = find_matching_attr_resource(rsc, rsc_id, attr_set, attr_id, attr_name, cib, "delete"); } lookup_id = clone_strip(rsc->id);