504 lines
19 KiB
Diff
504 lines
19 KiB
Diff
|
commit a33aadaf14f1e0cc2fb9d025801a2d86e3732275
|
||
|
Author: Gao,Yan <ygao@suse.com>
|
||
|
Date: Mon Jan 13 20:03:28 2014 +0800
|
||
|
|
||
|
Feature: tools: Display pending state in crm_mon/crm_resource/crm_simulate if --pending/-j is supplied (cl#5178)
|
||
|
|
||
|
diff --git a/include/crm/pengine/common.h b/include/crm/pengine/common.h
|
||
|
index 2477e47..c1901ef 100644
|
||
|
--- a/include/crm/pengine/common.h
|
||
|
+++ b/include/crm/pengine/common.h
|
||
|
@@ -97,6 +97,7 @@ enum pe_print_options {
|
||
|
pe_print_ops = 0x0100,
|
||
|
pe_print_suppres_nl = 0x0200,
|
||
|
pe_print_xml = 0x0400,
|
||
|
+ pe_print_pending = 0x0800,
|
||
|
};
|
||
|
/* *INDENT-ON* */
|
||
|
|
||
|
diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h
|
||
|
index 3f3de17..3a380cc 100644
|
||
|
--- a/include/crm/pengine/status.h
|
||
|
+++ b/include/crm/pengine/status.h
|
||
|
@@ -275,6 +275,8 @@ struct resource_s {
|
||
|
|
||
|
resource_t *container;
|
||
|
GListPtr fillers;
|
||
|
+
|
||
|
+ char *pending_task;
|
||
|
};
|
||
|
|
||
|
struct pe_action_s {
|
||
|
diff --git a/lib/pengine/complex.c b/lib/pengine/complex.c
|
||
|
index 2ada463..a592fc8 100644
|
||
|
--- a/lib/pengine/complex.c
|
||
|
+++ b/lib/pengine/complex.c
|
||
|
@@ -743,5 +743,6 @@ common_free(resource_t * rsc)
|
||
|
free(rsc->clone_name);
|
||
|
free(rsc->allocated_to);
|
||
|
free(rsc->variant_opaque);
|
||
|
+ free(rsc->pending_task);
|
||
|
free(rsc);
|
||
|
}
|
||
|
diff --git a/lib/pengine/native.c b/lib/pengine/native.c
|
||
|
index adfd5ba..be95ba1 100644
|
||
|
--- a/lib/pengine/native.c
|
||
|
+++ b/lib/pengine/native.c
|
||
|
@@ -291,12 +291,60 @@ native_print_attr(gpointer key, gpointer value, gpointer user_data)
|
||
|
status_print("Option: %s = %s\n", (char *)key, (char *)value);
|
||
|
}
|
||
|
|
||
|
+static const char *
|
||
|
+native_pending_state(resource_t * rsc)
|
||
|
+{
|
||
|
+ const char *pending_state = NULL;
|
||
|
+
|
||
|
+ if (safe_str_eq(rsc->pending_task, CRMD_ACTION_START)) {
|
||
|
+ pending_state = "Starting";
|
||
|
+
|
||
|
+ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_STOP)) {
|
||
|
+ pending_state = "Stopping";
|
||
|
+
|
||
|
+ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_MIGRATE)) {
|
||
|
+ pending_state = "Migrating";
|
||
|
+
|
||
|
+ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_MIGRATED)) {
|
||
|
+ /* Work might be done in here. */
|
||
|
+ pending_state = "Migrating";
|
||
|
+
|
||
|
+ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_PROMOTE)) {
|
||
|
+ pending_state = "Promoting";
|
||
|
+
|
||
|
+ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_DEMOTE)) {
|
||
|
+ pending_state = "Demoting";
|
||
|
+ }
|
||
|
+
|
||
|
+ return pending_state;
|
||
|
+}
|
||
|
+
|
||
|
+static const char *
|
||
|
+native_pending_task(resource_t * rsc)
|
||
|
+{
|
||
|
+ const char *pending_task = NULL;
|
||
|
+
|
||
|
+ if (safe_str_eq(rsc->pending_task, CRMD_ACTION_NOTIFY)) {
|
||
|
+ /* "Notifying" is not very useful to be shown. */
|
||
|
+ pending_task = NULL;
|
||
|
+
|
||
|
+ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_STATUS)) {
|
||
|
+ pending_task = "Monitoring";
|
||
|
+
|
||
|
+ } else if (safe_str_eq(rsc->pending_task, "probe")) {
|
||
|
+ pending_task = "Checking";
|
||
|
+ }
|
||
|
+
|
||
|
+ return pending_task;
|
||
|
+}
|
||
|
+
|
||
|
static void
|
||
|
native_print_xml(resource_t * rsc, const char *pre_text, long options, void *print_data)
|
||
|
{
|
||
|
enum rsc_role_e role = rsc->role;
|
||
|
const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
|
||
|
const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
|
||
|
+ const char *rsc_state = NULL;
|
||
|
|
||
|
if(role == RSC_ROLE_STARTED && uber_parent(rsc)->variant == pe_master) {
|
||
|
role = RSC_ROLE_SLAVE;
|
||
|
@@ -308,7 +356,14 @@ native_print_xml(resource_t * rsc, const char *pre_text, long options, void *pri
|
||
|
status_print("resource_agent=\"%s%s%s:%s\" ",
|
||
|
class,
|
||
|
prov ? "::" : "", prov ? prov : "", crm_element_value(rsc->xml, XML_ATTR_TYPE));
|
||
|
- status_print("role=\"%s\" ", role2text(role));
|
||
|
+
|
||
|
+ if (options & pe_print_pending) {
|
||
|
+ rsc_state = native_pending_state(rsc);
|
||
|
+ }
|
||
|
+ if (rsc_state == NULL) {
|
||
|
+ rsc_state = role2text(role);
|
||
|
+ }
|
||
|
+ status_print("role=\"%s\" ", rsc_state);
|
||
|
status_print("active=\"%s\" ", rsc->fns->active(rsc, TRUE) ? "true" : "false");
|
||
|
status_print("orphaned=\"%s\" ", is_set(rsc->flags, pe_rsc_orphan) ? "true" : "false");
|
||
|
status_print("managed=\"%s\" ", is_set(rsc->flags, pe_rsc_managed) ? "true" : "false");
|
||
|
@@ -317,6 +372,14 @@ native_print_xml(resource_t * rsc, const char *pre_text, long options, void *pri
|
||
|
is_set(rsc->flags, pe_rsc_failure_ignored) ? "true" : "false");
|
||
|
status_print("nodes_running_on=\"%d\" ", g_list_length(rsc->running_on));
|
||
|
|
||
|
+ if (options & pe_print_pending) {
|
||
|
+ const char *pending_task = native_pending_task(rsc);
|
||
|
+
|
||
|
+ if (pending_task) {
|
||
|
+ status_print("pending=\"%s\" ", pending_task);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
if (options & pe_print_dev) {
|
||
|
status_print("provisional=\"%s\" ",
|
||
|
is_set(rsc->flags, pe_rsc_provisional) ? "true" : "false");
|
||
|
@@ -423,12 +486,29 @@ native_print(resource_t * rsc, const char *pre_text, long options, void *print_d
|
||
|
} else if(is_set(rsc->flags, pe_rsc_failed)) {
|
||
|
offset += snprintf(buffer + offset, LINE_MAX - offset, "FAILED ");
|
||
|
} else {
|
||
|
- offset += snprintf(buffer + offset, LINE_MAX - offset, "%s ", role2text(rsc->role));
|
||
|
+ const char *rsc_state = NULL;
|
||
|
+
|
||
|
+ if (options & pe_print_pending) {
|
||
|
+ rsc_state = native_pending_state(rsc);
|
||
|
+ }
|
||
|
+ if (rsc_state == NULL) {
|
||
|
+ rsc_state = role2text(rsc->role);
|
||
|
+ }
|
||
|
+ offset += snprintf(buffer + offset, LINE_MAX - offset, "%s ", rsc_state);
|
||
|
}
|
||
|
|
||
|
if(node) {
|
||
|
offset += snprintf(buffer + offset, LINE_MAX - offset, "%s ", node->details->uname);
|
||
|
}
|
||
|
+
|
||
|
+ if (options & pe_print_pending) {
|
||
|
+ const char *pending_task = native_pending_task(rsc);
|
||
|
+
|
||
|
+ if (pending_task) {
|
||
|
+ offset += snprintf(buffer + offset, LINE_MAX - offset, "(%s) ", pending_task);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
if(is_not_set(rsc->flags, pe_rsc_managed)) {
|
||
|
offset += snprintf(buffer + offset, LINE_MAX - offset, "(unmanaged) ");
|
||
|
}
|
||
|
diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c
|
||
|
index aaa9a67..57960cc 100644
|
||
|
--- a/lib/pengine/unpack.c
|
||
|
+++ b/lib/pengine/unpack.c
|
||
|
@@ -2757,6 +2757,7 @@ unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op,
|
||
|
int rc = 0;
|
||
|
int status = PCMK_LRM_OP_PENDING-1;
|
||
|
int target_rc = get_target_rc(xml_op);
|
||
|
+ int interval = 0;
|
||
|
|
||
|
gboolean expired = FALSE;
|
||
|
resource_t *parent = rsc;
|
||
|
@@ -2774,6 +2775,7 @@ unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op,
|
||
|
crm_element_value_int(xml_op, XML_LRM_ATTR_RC, &rc);
|
||
|
crm_element_value_int(xml_op, XML_LRM_ATTR_CALLID, &task_id);
|
||
|
crm_element_value_int(xml_op, XML_LRM_ATTR_OPSTATUS, &status);
|
||
|
+ crm_element_value_int(xml_op, XML_LRM_ATTR_INTERVAL, &interval);
|
||
|
|
||
|
CRM_CHECK(task != NULL, return FALSE);
|
||
|
CRM_CHECK(status <= PCMK_LRM_OP_NOT_INSTALLED, return FALSE);
|
||
|
@@ -2807,7 +2809,6 @@ unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op,
|
||
|
}
|
||
|
|
||
|
if (expired && target_rc != rc) {
|
||
|
- int interval = 0;
|
||
|
const char *magic = crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC);
|
||
|
|
||
|
pe_rsc_debug(rsc, "Expired operation '%s' on %s returned '%s' (%d) instead of the expected value: '%s' (%d)",
|
||
|
@@ -2815,7 +2816,6 @@ unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op,
|
||
|
services_ocf_exitcode_str(rc), rc,
|
||
|
services_ocf_exitcode_str(target_rc), target_rc);
|
||
|
|
||
|
- crm_element_value_int(xml_op, XML_LRM_ATTR_INTERVAL, &interval);
|
||
|
if(interval == 0) {
|
||
|
crm_notice("Ignoring expired calculated failure %s (rc=%d, magic=%s) on %s",
|
||
|
task_key, rc, magic, node->details->uname);
|
||
|
@@ -2858,6 +2858,14 @@ unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op,
|
||
|
stop_action(rsc, target, FALSE);
|
||
|
}
|
||
|
}
|
||
|
+
|
||
|
+ if (safe_str_eq(task, CRMD_ACTION_STATUS) && interval == 0) {
|
||
|
+ /* Temporarily comment this out until cl#5184 is fixed */
|
||
|
+ /*rsc->pending_task = strdup("probe");*/
|
||
|
+
|
||
|
+ } else {
|
||
|
+ rsc->pending_task = strdup(task);
|
||
|
+ }
|
||
|
break;
|
||
|
|
||
|
case PCMK_LRM_OP_DONE:
|
||
|
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
|
||
|
index a9dd1b7..746094f 100644
|
||
|
--- a/tools/crm_mon.c
|
||
|
+++ b/tools/crm_mon.c
|
||
|
@@ -96,6 +96,7 @@ gboolean print_last_change = TRUE;
|
||
|
gboolean print_tickets = FALSE;
|
||
|
gboolean watch_fencing = FALSE;
|
||
|
gboolean hide_headers = FALSE;
|
||
|
+gboolean print_pending = FALSE;
|
||
|
|
||
|
/* FIXME allow, detect, and correctly interpret glob pattern or regex? */
|
||
|
const char *print_neg_location_prefix;
|
||
|
@@ -340,6 +341,7 @@ static struct crm_option long_options[] = {
|
||
|
{"neg-locations", 2, 0, 'L', "Display negative location constraints [optionally filtered by id prefix]"},
|
||
|
{"show-node-attributes", 0, 0, 'A', "Display node attributes" },
|
||
|
{"hide-headers", 0, 0, 'D', "\tHide all headers" },
|
||
|
+ {"pending", 0, 0, 'j', "\t\tDisplay pending state if 'record-pending' is enabled" },
|
||
|
|
||
|
{"-spacer-", 1, 0, '-', "\nAdditional Options:"},
|
||
|
{"interval", 1, 0, 'i', "\tUpdate frequency in seconds" },
|
||
|
@@ -449,6 +451,9 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer unused)
|
||
|
case 'D':
|
||
|
hide_headers = ! hide_headers;
|
||
|
break;
|
||
|
+ case 'j':
|
||
|
+ print_pending = ! print_pending;
|
||
|
+ break;
|
||
|
case '?':
|
||
|
config_mode = TRUE;
|
||
|
break;
|
||
|
@@ -472,6 +477,7 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer unused)
|
||
|
print_as("%c A: \t%s\n", print_nodes_attr ? '*': ' ', get_option_desc('A'));
|
||
|
print_as("%c L: \t%s\n", print_neg_location_prefix ? '*': ' ', get_option_desc('L'));
|
||
|
print_as("%c D: \t%s\n", hide_headers ? '*': ' ', get_option_desc('D'));
|
||
|
+ print_as("%c j: \t%s\n", print_pending ? '*': ' ', get_option_desc('j'));
|
||
|
print_as("\n");
|
||
|
print_as("Toggle fields via field letter, type any other key to return");
|
||
|
}
|
||
|
@@ -550,6 +556,9 @@ main(int argc, char **argv)
|
||
|
case 'L':
|
||
|
print_neg_location_prefix = optarg ?: "";
|
||
|
break;
|
||
|
+ case 'j':
|
||
|
+ print_pending = TRUE;
|
||
|
+ break;
|
||
|
case 'D':
|
||
|
hide_headers = TRUE;
|
||
|
break;
|
||
|
@@ -1159,6 +1168,10 @@ print_status(pe_working_set_t * data_set)
|
||
|
print_opts = pe_print_printf;
|
||
|
}
|
||
|
|
||
|
+ if (print_pending) {
|
||
|
+ print_opts |= pe_print_pending;
|
||
|
+ }
|
||
|
+
|
||
|
updates++;
|
||
|
dc = data_set->dc_node;
|
||
|
|
||
|
@@ -1463,9 +1476,14 @@ print_xml_status(pe_working_set_t * data_set)
|
||
|
xmlNode *stack = NULL;
|
||
|
xmlNode *quorum_node = NULL;
|
||
|
const char *quorum_votes = "unknown";
|
||
|
+ int print_opts = pe_print_xml;
|
||
|
|
||
|
dc = data_set->dc_node;
|
||
|
|
||
|
+ if (print_pending) {
|
||
|
+ print_opts |= pe_print_pending;
|
||
|
+ }
|
||
|
+
|
||
|
fprintf(stream, "<?xml version=\"1.0\"?>\n");
|
||
|
fprintf(stream, "<crm_mon version=\"%s\">\n", VERSION);
|
||
|
|
||
|
@@ -1567,7 +1585,7 @@ print_xml_status(pe_working_set_t * data_set)
|
||
|
for (lpc2 = node->details->running_rsc; lpc2 != NULL; lpc2 = lpc2->next) {
|
||
|
resource_t *rsc = (resource_t *) lpc2->data;
|
||
|
|
||
|
- rsc->fns->print(rsc, " ", pe_print_xml | pe_print_rsconly, stream);
|
||
|
+ rsc->fns->print(rsc, " ", print_opts | pe_print_rsconly, stream);
|
||
|
}
|
||
|
fprintf(stream, " </node>\n");
|
||
|
} else {
|
||
|
@@ -1589,11 +1607,11 @@ print_xml_status(pe_working_set_t * data_set)
|
||
|
|
||
|
} else if (group_by_node == FALSE) {
|
||
|
if (partially_active || inactive_resources) {
|
||
|
- rsc->fns->print(rsc, " ", pe_print_xml, stream);
|
||
|
+ rsc->fns->print(rsc, " ", print_opts, stream);
|
||
|
}
|
||
|
|
||
|
} else if (is_active == FALSE && inactive_resources) {
|
||
|
- rsc->fns->print(rsc, " ", pe_print_xml, stream);
|
||
|
+ rsc->fns->print(rsc, " ", print_opts, stream);
|
||
|
}
|
||
|
}
|
||
|
fprintf(stream, " </resources>\n");
|
||
|
@@ -1614,6 +1632,11 @@ print_html_status(pe_working_set_t * data_set, const char *filename, gboolean we
|
||
|
node_t *dc = NULL;
|
||
|
static int updates = 0;
|
||
|
char *filename_tmp = NULL;
|
||
|
+ int print_opts = pe_print_html;
|
||
|
+
|
||
|
+ if (print_pending) {
|
||
|
+ print_opts |= pe_print_pending;
|
||
|
+ }
|
||
|
|
||
|
if (web_cgi) {
|
||
|
stream = stdout;
|
||
|
@@ -1725,7 +1748,7 @@ print_html_status(pe_working_set_t * data_set, const char *filename, gboolean we
|
||
|
resource_t *rsc = (resource_t *) lpc2->data;
|
||
|
|
||
|
fprintf(stream, "<li>");
|
||
|
- rsc->fns->print(rsc, NULL, pe_print_html | pe_print_rsconly, stream);
|
||
|
+ rsc->fns->print(rsc, NULL, print_opts | pe_print_rsconly, stream);
|
||
|
fprintf(stream, "</li>\n");
|
||
|
}
|
||
|
fprintf(stream, "</ul>\n");
|
||
|
@@ -1752,11 +1775,11 @@ print_html_status(pe_working_set_t * data_set, const char *filename, gboolean we
|
||
|
|
||
|
} else if (group_by_node == FALSE) {
|
||
|
if (partially_active || inactive_resources) {
|
||
|
- rsc->fns->print(rsc, NULL, pe_print_html, stream);
|
||
|
+ rsc->fns->print(rsc, NULL, print_opts, stream);
|
||
|
}
|
||
|
|
||
|
} else if (is_active == FALSE && inactive_resources) {
|
||
|
- rsc->fns->print(rsc, NULL, pe_print_html, stream);
|
||
|
+ rsc->fns->print(rsc, NULL, print_opts, stream);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
|
||
|
index bd576cc..b2cab67 100644
|
||
|
--- a/tools/crm_resource.c
|
||
|
+++ b/tools/crm_resource.c
|
||
|
@@ -64,6 +64,7 @@ char *xml_file = NULL;
|
||
|
int cib_options = cib_sync_call;
|
||
|
int crmd_replies_needed = 1; /* The welcome message */
|
||
|
GMainLoop *mainloop = NULL;
|
||
|
+gboolean print_pending = FALSE;
|
||
|
|
||
|
extern void cleanup_alloc_calculations(pe_working_set_t * data_set);
|
||
|
|
||
|
@@ -284,6 +285,11 @@ do_find_resource_list(pe_working_set_t * data_set, gboolean raw)
|
||
|
int found = 0;
|
||
|
|
||
|
GListPtr lpc = NULL;
|
||
|
+ int opts = pe_print_printf | pe_print_rsconly;
|
||
|
+
|
||
|
+ if (print_pending) {
|
||
|
+ opts |= pe_print_pending;
|
||
|
+ }
|
||
|
|
||
|
for (lpc = data_set->resources; lpc != NULL; lpc = lpc->next) {
|
||
|
resource_t *rsc = (resource_t *) lpc->data;
|
||
|
@@ -292,7 +298,7 @@ do_find_resource_list(pe_working_set_t * data_set, gboolean raw)
|
||
|
&& rsc->fns->active(rsc, TRUE) == FALSE) {
|
||
|
continue;
|
||
|
}
|
||
|
- rsc->fns->print(rsc, NULL, pe_print_printf | pe_print_rsconly, stdout);
|
||
|
+ rsc->fns->print(rsc, NULL, opts, stdout);
|
||
|
found++;
|
||
|
}
|
||
|
|
||
|
@@ -323,11 +329,16 @@ dump_resource(const char *rsc, pe_working_set_t * data_set, gboolean expanded)
|
||
|
{
|
||
|
char *rsc_xml = NULL;
|
||
|
resource_t *the_rsc = find_rsc_or_clone(rsc, data_set);
|
||
|
+ int opts = pe_print_printf;
|
||
|
|
||
|
if (the_rsc == NULL) {
|
||
|
return -ENXIO;
|
||
|
}
|
||
|
- the_rsc->fns->print(the_rsc, NULL, pe_print_printf, stdout);
|
||
|
+
|
||
|
+ if (print_pending) {
|
||
|
+ opts |= pe_print_pending;
|
||
|
+ }
|
||
|
+ the_rsc->fns->print(the_rsc, NULL, opts, stdout);
|
||
|
|
||
|
if (expanded) {
|
||
|
rsc_xml = dump_xml_formatted(the_rsc->xml);
|
||
|
@@ -1088,6 +1099,10 @@ list_resource_operations(const char *rsc_id, const char *host_uname, gboolean ac
|
||
|
GListPtr ops = find_operations(rsc_id, host_uname, active, data_set);
|
||
|
GListPtr lpc = NULL;
|
||
|
|
||
|
+ if (print_pending) {
|
||
|
+ opts |= pe_print_pending;
|
||
|
+ }
|
||
|
+
|
||
|
for (lpc = ops; lpc != NULL; lpc = lpc->next) {
|
||
|
xmlNode *xml_op = (xmlNode *) lpc->data;
|
||
|
|
||
|
@@ -1275,7 +1290,8 @@ static struct crm_option long_options[] = {
|
||
|
{"list-raw", 0, 0, 'l', "\tList the IDs of all instantiated resources (no groups/clones/...)"},
|
||
|
{"list-cts", 0, 0, 'c', NULL, 1},
|
||
|
{"list-operations", 0, 0, 'O', "\tList active resource operations. Optionally filtered by resource (-r) and/or node (-N)"},
|
||
|
- {"list-all-operations", 0, 0, 'o', "List all resource operations. Optionally filtered by resource (-r) and/or node (-N)\n"},
|
||
|
+ {"list-all-operations", 0, 0, 'o', "List all resource operations. Optionally filtered by resource (-r) and/or node (-N)"},
|
||
|
+ {"pending", 0, 0, 'j', "\t\tDisplay pending state if 'record-pending' is enabled\n"},
|
||
|
|
||
|
{"list-standards", 0, 0, 0, "\tList supported standards"},
|
||
|
{"list-ocf-providers", 0, 0, 0, "List all available OCF providers"},
|
||
|
@@ -1598,6 +1614,9 @@ main(int argc, char **argv)
|
||
|
case 'a':
|
||
|
rsc_cmd = flag;
|
||
|
break;
|
||
|
+ case 'j':
|
||
|
+ print_pending = TRUE;
|
||
|
+ break;
|
||
|
case 'p':
|
||
|
case 'g':
|
||
|
case 'd':
|
||
|
diff --git a/tools/crm_simulate.c b/tools/crm_simulate.c
|
||
|
index 61065c4..0956141 100644
|
||
|
--- a/tools/crm_simulate.c
|
||
|
+++ b/tools/crm_simulate.c
|
||
|
@@ -39,6 +39,7 @@ cib_t *global_cib = NULL;
|
||
|
GListPtr op_fail = NULL;
|
||
|
gboolean quiet = FALSE;
|
||
|
gboolean bringing_nodes_online = FALSE;
|
||
|
+gboolean print_pending = FALSE;
|
||
|
|
||
|
#define new_node_template "//"XML_CIB_TAG_NODE"[@uname='%s']"
|
||
|
#define node_template "//"XML_CIB_TAG_STATE"[@uname='%s']"
|
||
|
@@ -528,7 +529,7 @@ exec_stonith_action(crm_graph_t * graph, crm_action_t * action)
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
-print_cluster_status(pe_working_set_t * data_set)
|
||
|
+print_cluster_status(pe_working_set_t * data_set, long options)
|
||
|
{
|
||
|
char *online_nodes = NULL;
|
||
|
char *online_remote_nodes = NULL;
|
||
|
@@ -649,7 +650,7 @@ print_cluster_status(pe_working_set_t * data_set)
|
||
|
&& rsc->role == RSC_ROLE_STOPPED) {
|
||
|
continue;
|
||
|
}
|
||
|
- rsc->fns->print(rsc, NULL, pe_print_printf, stdout);
|
||
|
+ rsc->fns->print(rsc, NULL, pe_print_printf | options, stdout);
|
||
|
}
|
||
|
fprintf(stdout, "\n");
|
||
|
}
|
||
|
@@ -701,7 +702,7 @@ run_simulation(pe_working_set_t * data_set)
|
||
|
data_set->now = get_date();
|
||
|
|
||
|
cluster_status(data_set);
|
||
|
- print_cluster_status(data_set);
|
||
|
+ print_cluster_status(data_set, 0);
|
||
|
}
|
||
|
|
||
|
if (graph_rc != transition_complete) {
|
||
|
@@ -1201,6 +1202,7 @@ static struct crm_option long_options[] = {
|
||
|
{"show-scores", 0, 0, 's', "Show allocation scores"},
|
||
|
{"show-utilization", 0, 0, 'U', "Show utilization information"},
|
||
|
{"profile", 1, 0, 'P', "Run all tests in the named directory to create profiling data"},
|
||
|
+ {"pending", 0, 0, 'j', "\tDisplay pending state if 'record-pending' is enabled"},
|
||
|
|
||
|
{"-spacer-", 0, 0, '-', "\nSynthetic Cluster Events:"},
|
||
|
{"node-up", 1, 0, 'u', "\tBring a node online"},
|
||
|
@@ -1447,6 +1449,9 @@ main(int argc, char **argv)
|
||
|
process = TRUE;
|
||
|
show_utilization = TRUE;
|
||
|
break;
|
||
|
+ case 'j':
|
||
|
+ print_pending = TRUE;
|
||
|
+ break;
|
||
|
case 'S':
|
||
|
process = TRUE;
|
||
|
simulate = TRUE;
|
||
|
@@ -1515,8 +1520,10 @@ main(int argc, char **argv)
|
||
|
cluster_status(&data_set);
|
||
|
|
||
|
if (quiet == FALSE) {
|
||
|
+ int options = print_pending ? pe_print_pending : 0;
|
||
|
+
|
||
|
quiet_log("\nCurrent cluster status:\n");
|
||
|
- print_cluster_status(&data_set);
|
||
|
+ print_cluster_status(&data_set, options);
|
||
|
}
|
||
|
|
||
|
if (modified) {
|