diff --git a/cts/cli/regression.tools.exp b/cts/cli/regression.tools.exp index 2410339..4cc04fa 100644 --- a/cts/cli/regression.tools.exp +++ b/cts/cli/regression.tools.exp @@ -4078,13 +4078,13 @@ Resources colocated with clone: =#=#=#= End test: List guest,remote nodes - OK (0) =#=#=#= * Passed: crmadmin - List guest,remote nodes =#=#=#= Begin test: List a promotable clone resource =#=#=#= -resource promotable-clone is running on: cluster02 resource promotable-clone is running on: cluster01 +resource promotable-clone is running on: cluster02 Master =#=#=#= End test: List a promotable clone resource - OK (0) =#=#=#= * Passed: crm_resource - List a promotable clone resource =#=#=#= Begin test: List the primitive of a promotable clone resource =#=#=#= +resource promotable-rsc is running on: cluster01 resource promotable-rsc is running on: cluster02 Master -resource promotable-rsc is running on: cluster01 Master =#=#=#= End test: List the primitive of a promotable clone resource - OK (0) =#=#=#= * Passed: crm_resource - List the primitive of a promotable clone resource =#=#=#= Begin test: List a single instance of a promotable clone resource =#=#=#= diff --git a/tools/crm_resource.c b/tools/crm_resource.c index 928d7f2..9d9bb88 100644 --- a/tools/crm_resource.c +++ b/tools/crm_resource.c @@ -1899,7 +1899,8 @@ main(int argc, char **argv) case cmd_locate: { GListPtr nodes = cli_resource_search(out, rsc, options.rsc_id, data_set); - rc = out->message(out, "resource-search-list", nodes, rsc, options.rsc_id); + rc = out->message(out, "resource-search-list", nodes, options.rsc_id); + g_list_free_full(nodes, free); break; } diff --git a/tools/crm_resource.h b/tools/crm_resource.h index 5bfadb7..777490a 100644 --- a/tools/crm_resource.h +++ b/tools/crm_resource.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2020 the Pacemaker project contributors + * Copyright 2004-2021 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -23,6 +23,11 @@ #include #include +typedef struct node_info_s { + const char *node_name; + bool promoted; +} node_info_t; + enum resource_check_flags { rsc_remain_stopped = (1 << 0), rsc_unpromotable = (1 << 1), diff --git a/tools/crm_resource_print.c b/tools/crm_resource_print.c index 398fef0..053f806 100644 --- a/tools/crm_resource_print.c +++ b/tools/crm_resource_print.c @@ -276,12 +276,11 @@ resource_check_list_xml(pcmk__output_t *out, va_list args) { return rc; } -PCMK__OUTPUT_ARGS("resource-search-list", "GList *", "pe_resource_t *", "gchar *") +PCMK__OUTPUT_ARGS("resource-search-list", "GList *", "gchar *") static int resource_search_list_default(pcmk__output_t *out, va_list args) { GList *nodes = va_arg(args, GList *); - pe_resource_t *rsc = va_arg(args, pe_resource_t *); gchar *requested_name = va_arg(args, gchar *); bool printed = false; @@ -293,7 +292,7 @@ resource_search_list_default(pcmk__output_t *out, va_list args) } for (GList *lpc = nodes; lpc != NULL; lpc = lpc->next) { - pe_node_t *node = (pe_node_t *) lpc->data; + node_info_t *ni = (node_info_t *) lpc->data; if (!printed) { out->begin_list(out, NULL, NULL, "Nodes"); @@ -302,15 +301,10 @@ resource_search_list_default(pcmk__output_t *out, va_list args) } if (out->is_quiet(out)) { - out->list_item(out, "node", "%s", node->details->uname); + out->list_item(out, "node", "%s", ni->node_name); } else { - const char *state = ""; - - if (!pe_rsc_is_clone(rsc) && rsc->fns->state(rsc, TRUE) == RSC_ROLE_MASTER) { - state = " Master"; - } out->list_item(out, "node", "resource %s is running on: %s%s", - requested_name, node->details->uname, state); + requested_name, ni->node_name, ni->promoted ? " Master" : ""); } } @@ -321,12 +315,11 @@ resource_search_list_default(pcmk__output_t *out, va_list args) return rc; } -PCMK__OUTPUT_ARGS("resource-search-list", "GList *", "pe_resource_t *", "gchar *") +PCMK__OUTPUT_ARGS("resource-search-list", "GList *", "gchar *") static int resource_search_list_xml(pcmk__output_t *out, va_list args) { GList *nodes = va_arg(args, GList *); - pe_resource_t *rsc = va_arg(args, pe_resource_t *); gchar *requested_name = va_arg(args, gchar *); pcmk__output_xml_create_parent(out, "nodes", @@ -334,10 +327,10 @@ resource_search_list_xml(pcmk__output_t *out, va_list args) NULL); for (GList *lpc = nodes; lpc != NULL; lpc = lpc->next) { - pe_node_t *node = (pe_node_t *) lpc->data; - xmlNodePtr sub_node = pcmk__output_create_xml_text_node(out, "node", node->details->uname); + node_info_t *ni = (node_info_t *) lpc->data; + xmlNodePtr sub_node = pcmk__output_create_xml_text_node(out, "node", ni->node_name); - if (!pe_rsc_is_clone(rsc) && rsc->fns->state(rsc, TRUE) == RSC_ROLE_MASTER) { + if (ni->promoted) { crm_xml_add(sub_node, "state", "promoted"); } } diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c index 18e5b6e..373bbe9 100644 --- a/tools/crm_resource_runtime.c +++ b/tools/crm_resource_runtime.c @@ -41,20 +41,37 @@ cli_check_resource(pe_resource_t *rsc, char *role_s, char *managed) return rc; } +static GListPtr +build_node_info_list(pe_resource_t *rsc) +{ + GListPtr retval = NULL; + + for (GListPtr iter = rsc->children; iter != NULL; iter = iter->next) { + pe_resource_t *child = (pe_resource_t *) iter->data; + + for (GListPtr iter2 = child->running_on; iter2 != NULL; iter2 = iter2->next) { + pe_node_t *node = (pe_node_t *) iter2->data; + node_info_t *ni = calloc(1, sizeof(node_info_t)); + ni->node_name = node->details->uname; + ni->promoted = pcmk_is_set(rsc->flags, pe_rsc_promotable) && + child->fns->state(child, TRUE) == RSC_ROLE_MASTER; + + retval = g_list_prepend(retval, ni); + } + } + + return retval; +} + GListPtr cli_resource_search(pcmk__output_t *out, pe_resource_t *rsc, const char *requested_name, pe_working_set_t *data_set) { - GListPtr found = NULL; + GListPtr retval = NULL; pe_resource_t *parent = uber_parent(rsc); if (pe_rsc_is_clone(rsc)) { - for (GListPtr iter = rsc->children; iter != NULL; iter = iter->next) { - GListPtr extra = ((pe_resource_t *) iter->data)->running_on; - if (extra != NULL) { - found = g_list_concat(found, extra); - } - } + retval = build_node_info_list(rsc); /* The anonymous clone children's common ID is supplied */ } else if (pe_rsc_is_clone(parent) @@ -63,18 +80,20 @@ cli_resource_search(pcmk__output_t *out, pe_resource_t *rsc, const char *request && pcmk__str_eq(requested_name, rsc->clone_name, pcmk__str_casei) && !pcmk__str_eq(requested_name, rsc->id, pcmk__str_casei)) { - for (GListPtr iter = parent->children; iter; iter = iter->next) { - GListPtr extra = ((pe_resource_t *) iter->data)->running_on; - if (extra != NULL) { - found = g_list_concat(found, extra); - } - } + retval = build_node_info_list(parent); } else if (rsc->running_on != NULL) { - found = g_list_concat(found, rsc->running_on); + for (GListPtr iter = rsc->running_on; iter != NULL; iter = iter->next) { + pe_node_t *node = (pe_node_t *) iter->data; + node_info_t *ni = calloc(1, sizeof(node_info_t)); + ni->node_name = node->details->uname; + ni->promoted = rsc->fns->state(rsc, TRUE) == RSC_ROLE_MASTER; + + retval = g_list_prepend(retval, ni); + } } - return found; + return retval; } #define XPATH_MAX 1024 @@ -1792,6 +1811,8 @@ cli_resource_execute(pcmk__output_t *out, pe_resource_t *rsc, "the force option"); return CRM_EX_UNSAFE; } + + g_list_free_full(nodes, free); } } else {