Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4624303
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/pacemaker/pcmk_trans_utils.c b/lib/pacemaker/pcmk_trans_utils.c
index ec090e8146..7e840b9bdf 100644
--- a/lib/pacemaker/pcmk_trans_utils.c
+++ b/lib/pacemaker/pcmk_trans_utils.c
@@ -1,304 +1,303 @@
/*
* Copyright 2004-2019 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#include <crm_internal.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>
#include <pacemaker-internal.h>
extern crm_graph_functions_t *graph_fns;
static gboolean
pseudo_action_dummy(crm_graph_t * graph, crm_action_t * action)
{
static int fail = -1;
if (fail < 0) {
char *fail_s = getenv("PE_fail");
if (fail_s) {
fail = crm_int_helper(fail_s, NULL);
} else {
fail = 0;
}
}
crm_trace("Dummy event handler: action %d executed", action->id);
if (action->id == fail) {
crm_err("Dummy event handler: pretending action %d failed", action->id);
action->failed = TRUE;
graph->abort_priority = INFINITY;
}
action->confirmed = TRUE;
update_graph(graph, action);
return TRUE;
}
crm_graph_functions_t default_fns = {
pseudo_action_dummy,
pseudo_action_dummy,
pseudo_action_dummy,
pseudo_action_dummy
};
void
set_default_graph_functions(void)
{
graph_fns = &default_fns;
}
void
set_graph_functions(crm_graph_functions_t * fns)
{
crm_info("Setting custom graph functions");
graph_fns = fns;
CRM_ASSERT(graph_fns != NULL);
CRM_ASSERT(graph_fns->rsc != NULL);
CRM_ASSERT(graph_fns->crmd != NULL);
CRM_ASSERT(graph_fns->pseudo != NULL);
CRM_ASSERT(graph_fns->stonith != NULL);
}
const char *
transition_status(enum transition_status state)
{
switch (state) {
case transition_active:
return "active";
case transition_pending:
return "pending";
case transition_complete:
return "complete";
case transition_stopped:
return "stopped";
case transition_terminated:
return "terminated";
case transition_action_failed:
return "failed (action)";
case transition_failed:
return "failed";
}
return "unknown";
}
const char *
actiontype2text(action_type_e type)
{
switch (type) {
case action_type_pseudo:
return "pseudo";
case action_type_rsc:
- return "rsc";
+ return "resource";
case action_type_crm:
- return "crm";
-
+ return "cluster";
}
- return "<unknown>";
+ return "invalid";
}
static crm_action_t *
find_action(crm_graph_t * graph, int id)
{
GListPtr sIter = NULL;
if (graph == NULL) {
return NULL;
}
for (sIter = graph->synapses; sIter != NULL; sIter = sIter->next) {
GListPtr aIter = NULL;
synapse_t *synapse = (synapse_t *) sIter->data;
for (aIter = synapse->actions; aIter != NULL; aIter = aIter->next) {
crm_action_t *action = (crm_action_t *) aIter->data;
if (action->id == id) {
return action;
}
}
}
return NULL;
}
static const char *
synapse_state_str(synapse_t *synapse)
{
if (synapse->failed) {
return "Failed";
} else if (synapse->confirmed) {
return "Completed";
} else if (synapse->executed) {
return "In-flight";
} else if (synapse->ready) {
return "Ready";
}
return "Pending";
}
// List action IDs of inputs in graph that haven't completed successfully
static char *
synapse_pending_inputs(crm_graph_t *graph, synapse_t *synapse)
{
char *pending = NULL;
for (GList *lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
crm_action_t *input = (crm_action_t *) lpc->data;
if (input->failed) {
pending = add_list_element(pending, ID(input->xml));
} else if (input->confirmed) {
// Confirmed successful inputs are not pending
} else if (find_action(graph, input->id) != NULL) {
// In-flight or pending
pending = add_list_element(pending, ID(input->xml));
}
}
if (pending == NULL) {
pending = strdup("none");
}
return pending;
}
// Log synapse inputs that aren't in graph
static void
log_unresolved_inputs(unsigned int log_level, crm_graph_t *graph,
synapse_t *synapse)
{
for (GList *lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
crm_action_t *input = (crm_action_t *) lpc->data;
const char *key = crm_element_value(input->xml, XML_LRM_ATTR_TASK_KEY);
const char *host = crm_element_value(input->xml, XML_LRM_ATTR_TARGET);
if (find_action(graph, input->id) == NULL) {
do_crm_log(log_level,
" * [Input %2d]: Unresolved dependency %s op %s%s%s",
input->id, actiontype2text(input->type), key,
(host? " on " : ""), (host? host : ""));
}
}
}
static void
log_synapse_action(unsigned int log_level, synapse_t *synapse,
crm_action_t *action, const char *pending_inputs)
{
const char *key = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY);
const char *host = crm_element_value(action->xml, XML_LRM_ATTR_TARGET);
char *desc = crm_strdup_printf("%s %s op %s",
synapse_state_str(synapse),
actiontype2text(action->type), key);
do_crm_log(log_level,
- "[Action %4d]: %-50s on %s (priority: %d, waiting: %s)",
- action->id, desc, (host? host : "N/A"),
+ "[Action %4d]: %-50s%s%s (priority: %d, waiting: %s)",
+ action->id, desc, (host? " on " : ""), (host? host : ""),
synapse->priority, pending_inputs);
free(desc);
}
static void
print_synapse(unsigned int log_level, crm_graph_t * graph, synapse_t * synapse)
{
char *pending = NULL;
if (!synapse->executed) {
pending = synapse_pending_inputs(graph, synapse);
}
for (GList *lpc = synapse->actions; lpc != NULL; lpc = lpc->next) {
log_synapse_action(log_level, synapse, (crm_action_t *) lpc->data,
pending);
}
free(pending);
if (!synapse->executed) {
log_unresolved_inputs(log_level, graph, synapse);
}
}
void
print_action(int log_level, const char *prefix, crm_action_t * action)
{
print_synapse(log_level, NULL, action->synapse);
}
void
print_graph(unsigned int log_level, crm_graph_t * graph)
{
GListPtr lpc = NULL;
if (graph == NULL || graph->num_actions == 0) {
if (log_level > LOG_DEBUG) {
crm_debug("Empty transition graph");
}
return;
}
do_crm_log(log_level, "Graph %d with %d actions:"
" batch-limit=%d jobs, network-delay=%ums",
graph->id, graph->num_actions,
graph->batch_limit, graph->network_delay);
for (lpc = graph->synapses; lpc != NULL; lpc = lpc->next) {
synapse_t *synapse = (synapse_t *) lpc->data;
print_synapse(log_level, graph, synapse);
}
}
static const char *
abort2text(enum transition_action abort_action)
{
switch (abort_action) {
case tg_done:
return "done";
case tg_stop:
return "stop";
case tg_restart:
return "restart";
case tg_shutdown:
return "shutdown";
}
return "unknown";
}
bool
update_abort_priority(crm_graph_t * graph, int priority,
enum transition_action action, const char *abort_reason)
{
bool change = FALSE;
if (graph == NULL) {
return change;
}
if (graph->abort_priority < priority) {
crm_debug("Abort priority upgraded from %d to %d", graph->abort_priority, priority);
graph->abort_priority = priority;
if (graph->abort_reason != NULL) {
crm_debug("'%s' abort superseded by %s", graph->abort_reason, abort_reason);
}
graph->abort_reason = abort_reason;
change = TRUE;
}
if (graph->completion_action < action) {
crm_debug("Abort action %s superseded by %s: %s",
abort2text(graph->completion_action), abort2text(action), abort_reason);
graph->completion_action = action;
change = TRUE;
}
return change;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:12 PM (21 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2002527
Default Alt Text
(8 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment