Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F1842446
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/include/pcmki/pcmki_transition.h b/include/pcmki/pcmki_transition.h
index ee66fae724..12c87ecdc0 100644
--- a/include/pcmki/pcmki_transition.h
+++ b/include/pcmki/pcmki_transition.h
@@ -1,143 +1,143 @@
/*
- * Copyright 2004-2019 the Pacemaker project contributors
+ * Copyright 2004-2021 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.
*/
#ifndef CRM_TRANSITION__H
# define CRM_TRANSITION__H
#ifdef __cplusplus
extern "C" {
#endif
#include <glib.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>
typedef enum {
action_type_pseudo,
action_type_rsc,
action_type_crm
} action_type_e;
typedef struct te_timer_s crm_action_timer_t;
typedef struct crm_graph_s crm_graph_t;
typedef struct synapse_s {
int id;
int priority;
gboolean ready;
gboolean failed;
gboolean executed;
gboolean confirmed;
GListPtr actions; /* crm_action_t* */
GListPtr inputs; /* crm_action_t* */
} synapse_t;
typedef struct crm_action_s {
int id;
int timeout;
guint interval_ms;
GHashTable *params;
action_type_e type;
crm_action_timer_t *timer;
synapse_t *synapse;
gboolean sent_update; /* sent to the CIB */
gboolean executed; /* sent to the CRM */
gboolean confirmed;
gboolean failed;
- gboolean can_fail;
+ gboolean can_fail; //! \deprecated Will be removed in a future release
xmlNode *xml;
} crm_action_t;
struct te_timer_s {
int source_id;
int timeout;
crm_action_t *action;
};
/* order matters here */
enum transition_action {
tg_done,
tg_stop,
tg_restart,
tg_shutdown,
};
struct crm_graph_s {
int id;
char *source;
int abort_priority;
gboolean complete;
const char *abort_reason;
enum transition_action completion_action;
int num_actions;
int num_synapses;
int batch_limit;
guint network_delay;
guint stonith_timeout;
int fired;
int pending;
int skipped;
int completed;
int incomplete;
GListPtr synapses; /* synapse_t* */
int migration_limit;
};
typedef struct crm_graph_functions_s {
gboolean(*pseudo) (crm_graph_t * graph, crm_action_t * action);
gboolean(*rsc) (crm_graph_t * graph, crm_action_t * action);
gboolean(*crmd) (crm_graph_t * graph, crm_action_t * action);
gboolean(*stonith) (crm_graph_t * graph, crm_action_t * action);
gboolean(*allowed) (crm_graph_t * graph, crm_action_t * action);
} crm_graph_functions_t;
enum transition_status {
transition_active,
transition_pending, /* active but no actions performed this time */
transition_complete,
transition_stopped,
transition_terminated,
transition_action_failed,
transition_failed,
};
void set_default_graph_functions(void);
void set_graph_functions(crm_graph_functions_t * fns);
crm_graph_t *unpack_graph(xmlNode * xml_graph, const char *reference);
int run_graph(crm_graph_t * graph);
gboolean update_graph(crm_graph_t * graph, crm_action_t * action);
void destroy_graph(crm_graph_t * graph);
const char *transition_status(enum transition_status state);
void print_graph(unsigned int log_level, crm_graph_t * graph);
void print_action(int log_level, const char *prefix, crm_action_t * action);
bool update_abort_priority(crm_graph_t * graph, int priority,
enum transition_action action, const char *abort_reason);
const char *actiontype2text(action_type_e type);
lrmd_event_data_t *convert_graph_action(xmlNode * resource, crm_action_t * action, int status,
int rc);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/lib/pacemaker/pcmk_trans_unpack.c b/lib/pacemaker/pcmk_trans_unpack.c
index db7dadd516..bf9d6baaf0 100644
--- a/lib/pacemaker/pcmk_trans_unpack.c
+++ b/lib/pacemaker/pcmk_trans_unpack.c
@@ -1,338 +1,344 @@
/*
- * 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.
*
* 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 <sys/param.h>
#include <sys/stat.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>
#include <crm/common/xml_internal.h>
#include <pacemaker-internal.h>
static crm_action_t *
unpack_action(synapse_t * parent, xmlNode * xml_action)
{
crm_action_t *action = NULL;
const char *value = crm_element_value(xml_action, XML_ATTR_ID);
if (value == NULL) {
crm_err("Actions must have an id!");
crm_log_xml_trace(xml_action, "Action with missing id");
return NULL;
}
action = calloc(1, sizeof(crm_action_t));
if (action == NULL) {
crm_perror(LOG_CRIT, "Cannot unpack action");
crm_log_xml_trace(xml_action, "Lost action");
return NULL;
}
action->id = crm_parse_int(value, NULL);
action->type = action_type_rsc;
action->xml = copy_xml(xml_action);
action->synapse = parent;
if (pcmk__str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_RSC_OP, pcmk__str_casei)) {
action->type = action_type_rsc;
} else if (pcmk__str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_PSEUDO_EVENT, pcmk__str_casei)) {
action->type = action_type_pseudo;
} else if (pcmk__str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_CRM_EVENT, pcmk__str_casei)) {
action->type = action_type_crm;
}
action->params = xml2list(action->xml);
value = g_hash_table_lookup(action->params, "CRM_meta_timeout");
if (value != NULL) {
action->timeout = crm_parse_int(value, NULL);
}
/* Take start-delay into account for the timeout of the action timer */
value = g_hash_table_lookup(action->params, "CRM_meta_start_delay");
if (value != NULL) {
action->timeout += crm_parse_int(value, NULL);
}
if (pcmk__guint_from_hash(action->params,
CRM_META "_" XML_LRM_ATTR_INTERVAL, 0,
&(action->interval_ms)) != pcmk_rc_ok) {
action->interval_ms = 0;
}
value = g_hash_table_lookup(action->params, "CRM_meta_can_fail");
if (value != NULL) {
crm_str_to_boolean(value, &(action->can_fail));
+#ifndef PCMK__COMPAT_2_0
+ if (action->can_fail) {
+ crm_warn("Support for the can_fail meta-attribute is deprecated"
+ " and will be removed in a future release");
+ }
+#endif
}
crm_trace("Action %d has timer set to %dms", action->id, action->timeout);
return action;
}
static synapse_t *
unpack_synapse(crm_graph_t * new_graph, xmlNode * xml_synapse)
{
const char *value = NULL;
xmlNode *inputs = NULL;
xmlNode *action_set = NULL;
synapse_t *new_synapse = NULL;
CRM_CHECK(xml_synapse != NULL, return NULL);
crm_trace("looking in synapse %s", ID(xml_synapse));
new_synapse = calloc(1, sizeof(synapse_t));
new_synapse->id = crm_parse_int(ID(xml_synapse), NULL);
value = crm_element_value(xml_synapse, XML_CIB_ATTR_PRIORITY);
if (value != NULL) {
new_synapse->priority = crm_parse_int(value, NULL);
}
CRM_CHECK(new_synapse->id >= 0, free(new_synapse);
return NULL);
new_graph->num_synapses++;
crm_trace("look for actions in synapse %s", crm_element_value(xml_synapse, XML_ATTR_ID));
for (action_set = pcmk__xml_first_child(xml_synapse); action_set != NULL;
action_set = pcmk__xml_next(action_set)) {
if (pcmk__str_eq((const char *)action_set->name, "action_set",
pcmk__str_none)) {
xmlNode *action = NULL;
for (action = pcmk__xml_first_child(action_set); action != NULL;
action = pcmk__xml_next(action)) {
crm_action_t *new_action = unpack_action(new_synapse, action);
if (new_action == NULL) {
continue;
}
new_graph->num_actions++;
crm_trace("Adding action %d to synapse %d", new_action->id, new_synapse->id);
new_synapse->actions = g_list_append(new_synapse->actions, new_action);
}
}
}
crm_trace("look for inputs in synapse %s", ID(xml_synapse));
for (inputs = pcmk__xml_first_child(xml_synapse); inputs != NULL;
inputs = pcmk__xml_next(inputs)) {
if (pcmk__str_eq((const char *)inputs->name, "inputs", pcmk__str_none)) {
xmlNode *trigger = NULL;
for (trigger = pcmk__xml_first_child(inputs); trigger != NULL;
trigger = pcmk__xml_next(trigger)) {
xmlNode *input = NULL;
for (input = pcmk__xml_first_child(trigger); input != NULL;
input = pcmk__xml_next(input)) {
crm_action_t *new_input = unpack_action(new_synapse, input);
if (new_input == NULL) {
continue;
}
crm_trace("Adding input %d to synapse %d", new_input->id, new_synapse->id);
new_synapse->inputs = g_list_append(new_synapse->inputs, new_input);
}
}
}
}
return new_synapse;
}
static void destroy_action(crm_action_t * action);
crm_graph_t *
unpack_graph(xmlNode * xml_graph, const char *reference)
{
/*
<transition_graph>
<synapse>
<action_set>
<rsc_op id="2"
...
<inputs>
<rsc_op id="2"
...
*/
crm_graph_t *new_graph = NULL;
const char *t_id = NULL;
const char *time = NULL;
xmlNode *synapse = NULL;
new_graph = calloc(1, sizeof(crm_graph_t));
new_graph->id = -1;
new_graph->abort_priority = 0;
new_graph->network_delay = 0;
new_graph->stonith_timeout = 0;
new_graph->completion_action = tg_done;
if (reference) {
new_graph->source = strdup(reference);
} else {
new_graph->source = strdup("unknown");
}
if (xml_graph != NULL) {
t_id = crm_element_value(xml_graph, "transition_id");
CRM_CHECK(t_id != NULL, free(new_graph);
return NULL);
new_graph->id = crm_parse_int(t_id, "-1");
time = crm_element_value(xml_graph, "cluster-delay");
CRM_CHECK(time != NULL, free(new_graph);
return NULL);
new_graph->network_delay = crm_parse_interval_spec(time);
time = crm_element_value(xml_graph, "stonith-timeout");
if (time == NULL) {
new_graph->stonith_timeout = new_graph->network_delay;
} else {
new_graph->stonith_timeout = crm_parse_interval_spec(time);
}
t_id = crm_element_value(xml_graph, "batch-limit");
new_graph->batch_limit = crm_parse_int(t_id, "0");
t_id = crm_element_value(xml_graph, "migration-limit");
new_graph->migration_limit = crm_parse_int(t_id, "-1");
}
for (synapse = pcmk__xml_first_child(xml_graph); synapse != NULL;
synapse = pcmk__xml_next(synapse)) {
if (pcmk__str_eq((const char *)synapse->name, "synapse", pcmk__str_none)) {
synapse_t *new_synapse = unpack_synapse(new_graph, synapse);
if (new_synapse != NULL) {
new_graph->synapses = g_list_append(new_graph->synapses, new_synapse);
}
}
}
crm_debug("Unpacked transition %d: %d actions in %d synapses",
new_graph->id, new_graph->num_actions, new_graph->num_synapses);
return new_graph;
}
static void
destroy_action(crm_action_t * action)
{
if (action->timer && action->timer->source_id != 0) {
crm_warn("Cancelling timer for action %d (src=%d)", action->id, action->timer->source_id);
g_source_remove(action->timer->source_id);
}
if (action->params) {
g_hash_table_destroy(action->params);
}
free_xml(action->xml);
free(action->timer);
free(action);
}
static void
destroy_synapse(synapse_t * synapse)
{
while (synapse->actions != NULL) {
crm_action_t *action = g_list_nth_data(synapse->actions, 0);
synapse->actions = g_list_remove(synapse->actions, action);
destroy_action(action);
}
while (synapse->inputs != NULL) {
crm_action_t *action = g_list_nth_data(synapse->inputs, 0);
synapse->inputs = g_list_remove(synapse->inputs, action);
destroy_action(action);
}
free(synapse);
}
void
destroy_graph(crm_graph_t * graph)
{
if (graph == NULL) {
return;
}
while (graph->synapses != NULL) {
synapse_t *synapse = g_list_nth_data(graph->synapses, 0);
graph->synapses = g_list_remove(graph->synapses, synapse);
destroy_synapse(synapse);
}
free(graph->source);
free(graph);
}
lrmd_event_data_t *
convert_graph_action(xmlNode * resource, crm_action_t * action, int status, int rc)
{
xmlNode *xop = NULL;
lrmd_event_data_t *op = NULL;
GHashTableIter iter;
const char *name = NULL;
const char *value = NULL;
xmlNode *action_resource = NULL;
CRM_CHECK(action != NULL, return NULL);
CRM_CHECK(action->type == action_type_rsc, return NULL);
action_resource = first_named_child(action->xml, XML_CIB_TAG_RESOURCE);
CRM_CHECK(action_resource != NULL, crm_log_xml_warn(action->xml, "Bad");
return NULL);
op = lrmd_new_event(ID(action_resource),
crm_element_value(action->xml, XML_LRM_ATTR_TASK),
action->interval_ms);
op->rc = rc;
op->op_status = status;
op->t_run = time(NULL);
op->t_rcchange = op->t_run;
op->params = g_hash_table_new_full(crm_str_hash, g_str_equal, free, free);
g_hash_table_iter_init(&iter, action->params);
while (g_hash_table_iter_next(&iter, (void **)&name, (void **)&value)) {
g_hash_table_insert(op->params, strdup(name), strdup(value));
}
for (xop = pcmk__xml_first_child(resource); xop != NULL;
xop = pcmk__xml_next(xop)) {
int tmp = 0;
crm_element_value_int(xop, XML_LRM_ATTR_CALLID, &tmp);
crm_debug("Got call_id=%d for %s", tmp, ID(resource));
if (tmp > op->call_id) {
op->call_id = tmp;
}
}
op->call_id++;
return op;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 23, 4:48 PM (13 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018954
Default Alt Text
(14 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment