pacemaker  1.1.18-7fdfbbe
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
utils.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <crm_internal.h>
20 
21 #include <crm/crm.h>
22 #include <crm/msg_xml.h>
23 #include <crm/common/xml.h>
24 #include <crm/transition.h>
25 /* #include <sys/param.h> */
26 /* */
27 
29 
30 static gboolean
31 pseudo_action_dummy(crm_graph_t * graph, crm_action_t * action)
32 {
33  static int fail = -1;
34 
35  if (fail < 0) {
36  char *fail_s = getenv("PE_fail");
37 
38  if (fail_s) {
39  fail = crm_int_helper(fail_s, NULL);
40  } else {
41  fail = 0;
42  }
43  }
44 
45  crm_trace("Dummy event handler: action %d executed", action->id);
46  if (action->id == fail) {
47  crm_err("Dummy event handler: pretending action %d failed", action->id);
48  action->failed = TRUE;
49  graph->abort_priority = INFINITY;
50  }
51  action->confirmed = TRUE;
52  update_graph(graph, action);
53  return TRUE;
54 }
55 
57  pseudo_action_dummy,
58  pseudo_action_dummy,
59  pseudo_action_dummy,
60  pseudo_action_dummy
61 };
62 
63 void
65 {
66  graph_fns = &default_fns;
67 }
68 
69 void
71 {
72  crm_info("Setting custom graph functions");
73  graph_fns = fns;
74 
75  CRM_ASSERT(graph_fns != NULL);
76  CRM_ASSERT(graph_fns->rsc != NULL);
77  CRM_ASSERT(graph_fns->crmd != NULL);
78  CRM_ASSERT(graph_fns->pseudo != NULL);
79  CRM_ASSERT(graph_fns->stonith != NULL);
80 }
81 
82 const char *
84 {
85  switch (state) {
86  case transition_active:
87  return "active";
88  case transition_pending:
89  return "pending";
91  return "complete";
92  case transition_stopped:
93  return "stopped";
95  return "terminated";
97  return "failed (action)";
98  case transition_failed:
99  return "failed";
100  }
101  return "unknown";
102 }
103 
104 const char *
106 {
107  switch (type) {
108  case action_type_pseudo:
109  return "pseudo";
110  case action_type_rsc:
111  return "rsc";
112  case action_type_crm:
113  return "crm";
114 
115  }
116  return "<unknown>";
117 }
118 
119 static crm_action_t *
120 find_action(crm_graph_t * graph, int id)
121 {
122  GListPtr sIter = NULL;
123 
124  if (graph == NULL) {
125  return NULL;
126  }
127 
128  for (sIter = graph->synapses; sIter != NULL; sIter = sIter->next) {
129  GListPtr aIter = NULL;
130  synapse_t *synapse = (synapse_t *) sIter->data;
131 
132  for (aIter = synapse->actions; aIter != NULL; aIter = aIter->next) {
133  crm_action_t *action = (crm_action_t *) aIter->data;
134 
135  if (action->id == id) {
136  return action;
137  }
138  }
139  }
140  return NULL;
141 }
142 
143 static void
144 print_synapse(unsigned int log_level, crm_graph_t * graph, synapse_t * synapse)
145 {
146  GListPtr lpc = NULL;
147  char *pending = NULL;
148  const char *state = "Pending";
149 
150  if (synapse->failed) {
151  state = "Failed";
152 
153  } else if (synapse->confirmed) {
154  state = "Completed";
155 
156  } else if (synapse->executed) {
157  state = "In-flight";
158 
159  } else if (synapse->ready) {
160  state = "Ready";
161  }
162 
163  if (synapse->executed == FALSE) {
164  for (lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
165  crm_action_t *input = (crm_action_t *) lpc->data;
166  const char *id_string = crm_element_value(input->xml, XML_ATTR_ID);
167 
168  if (input->failed) {
169  pending = add_list_element(pending, id_string);
170 
171  } else if (input->confirmed) {
172  /* Confirmed, skip */
173 
174  } else if (find_action(graph, input->id)) {
175  /* In-flight or pending */
176  pending = add_list_element(pending, id_string);
177  }
178  }
179  }
180 
181  for (lpc = synapse->actions; lpc != NULL; lpc = lpc->next) {
182  crm_action_t *action = (crm_action_t *) lpc->data;
183  const char *key = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY);
184  const char *host = crm_element_value(action->xml, XML_LRM_ATTR_TARGET);
185  char *desc = crm_strdup_printf("%s %s op %s", state, actiontype2text(action->type), key);
186 
187  do_crm_log(log_level,
188  "[Action %4d]: %-50s on %s (priority: %d, waiting: %s)",
189  action->id, desc, host ? host : "N/A",
190  synapse->priority, pending ? pending : "none");
191 
192  free(desc);
193  }
194 
195  if (synapse->executed == FALSE) {
196  for (lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
197  crm_action_t *input = (crm_action_t *) lpc->data;
198  const char *key = crm_element_value(input->xml, XML_LRM_ATTR_TASK_KEY);
199  const char *host = crm_element_value(input->xml, XML_LRM_ATTR_TARGET);
200 
201  if (find_action(graph, input->id) == NULL) {
202  if (host == NULL) {
203  do_crm_log(log_level, " * [Input %2d]: Unresolved dependency %s op %s",
204  input->id, actiontype2text(input->type), key);
205  } else {
206  do_crm_log(log_level, " * [Input %2d]: Unresolved dependency %s op %s on %s",
207  input->id, actiontype2text(input->type), key, host);
208  }
209  }
210  }
211  }
212 
213  free(pending);
214 }
215 
216 void
217 print_action(int log_level, const char *prefix, crm_action_t * action)
218 {
219  print_synapse(log_level, NULL, action->synapse);
220 }
221 
222 void
223 print_graph(unsigned int log_level, crm_graph_t * graph)
224 {
225  GListPtr lpc = NULL;
226 
227  if (graph == NULL || graph->num_actions == 0) {
228  if (log_level > LOG_DEBUG) {
229  crm_debug("Empty transition graph");
230  }
231  return;
232  }
233 
234  do_crm_log(log_level, "Graph %d with %d actions:"
235  " batch-limit=%d jobs, network-delay=%dms",
236  graph->id, graph->num_actions,
237  graph->batch_limit, graph->network_delay);
238 
239  for (lpc = graph->synapses; lpc != NULL; lpc = lpc->next) {
240  synapse_t *synapse = (synapse_t *) lpc->data;
241 
242  print_synapse(log_level, graph, synapse);
243  }
244 }
245 
246 static const char *
247 abort2text(enum transition_action abort_action)
248 {
249  switch (abort_action) {
250  case tg_done:
251  return "done";
252  case tg_stop:
253  return "stop";
254  case tg_restart:
255  return "restart";
256  case tg_shutdown:
257  return "shutdown";
258  }
259  return "unknown";
260 }
261 
262 bool
263 update_abort_priority(crm_graph_t * graph, int priority,
264  enum transition_action action, const char *abort_reason)
265 {
266  bool change = FALSE;
267 
268  if (graph == NULL) {
269  return change;
270  }
271 
272  if (graph->abort_priority < priority) {
273  crm_debug("Abort priority upgraded from %d to %d", graph->abort_priority, priority);
274  graph->abort_priority = priority;
275  if (graph->abort_reason != NULL) {
276  crm_debug("'%s' abort superseded by %s", graph->abort_reason, abort_reason);
277  }
278  graph->abort_reason = abort_reason;
279  change = TRUE;
280  }
281 
282  if (graph->completion_action < action) {
283  crm_debug("Abort action %s superseded by %s: %s",
284  abort2text(graph->completion_action), abort2text(action), abort_reason);
285  graph->completion_action = action;
286  change = TRUE;
287  }
288 
289  return change;
290 }
gboolean(* pseudo)(crm_graph_t *graph, crm_action_t *action)
Definition: transition.h:121
GListPtr actions
Definition: transition.h:43
gboolean confirmed
Definition: transition.h:41
A dumping ground.
action_type_e type
Definition: transition.h:52
bool update_abort_priority(crm_graph_t *graph, int priority, enum transition_action action, const char *abort_reason)
Definition: utils.c:263
#define INFINITY
Definition: crm.h:83
enum transition_action completion_action
Definition: transition.h:99
xmlNode * xml
Definition: transition.h:64
void print_action(int log_level, const char *prefix, crm_action_t *action)
Definition: utils.c:217
long long crm_int_helper(const char *text, char **end_text)
Definition: strings.c:80
gboolean(* rsc)(crm_graph_t *graph, crm_action_t *action)
Definition: transition.h:122
const char * actiontype2text(action_type_e type)
Definition: utils.c:105
void set_graph_functions(crm_graph_functions_t *fns)
Definition: utils.c:70
AIS_Host host
Definition: internal.h:52
transition_action
Definition: transition.h:85
gboolean ready
Definition: transition.h:38
#define XML_LRM_ATTR_TASK_KEY
Definition: msg_xml.h:285
int priority
Definition: transition.h:36
crm_graph_functions_t default_fns
Definition: utils.c:56
#define crm_debug(fmt, args...)
Definition: logging.h:253
char * add_list_element(char *list, const char *value)
Definition: strings.c:394
void set_default_graph_functions(void)
Definition: utils.c:64
#define XML_ATTR_ID
Definition: msg_xml.h:102
void print_graph(unsigned int log_level, crm_graph_t *graph)
Definition: utils.c:223
#define crm_trace(fmt, args...)
Definition: logging.h:254
#define do_crm_log(level, fmt, args...)
Log a message.
Definition: logging.h:129
Wrappers for and extensions to libxml2.
const char * crm_element_value(xmlNode *data, const char *name)
Definition: xml.c:5165
gboolean(* crmd)(crm_graph_t *graph, crm_action_t *action)
Definition: transition.h:123
transition_status
Definition: transition.h:128
GListPtr synapses
Definition: transition.h:115
gboolean update_graph(crm_graph_t *graph, crm_action_t *action)
Definition: graph.c:102
int batch_limit
Definition: transition.h:104
GListPtr inputs
Definition: transition.h:44
gboolean failed
Definition: transition.h:39
int network_delay
Definition: transition.h:105
int num_actions
Definition: transition.h:101
gboolean failed
Definition: transition.h:61
crm_graph_functions_t * graph_fns
Definition: graph.c:28
#define crm_err(fmt, args...)
Definition: logging.h:248
gboolean(* stonith)(crm_graph_t *graph, crm_action_t *action)
Definition: transition.h:124
int abort_priority
Definition: transition.h:95
#define CRM_ASSERT(expr)
Definition: error.h:35
gboolean confirmed
Definition: transition.h:59
#define XML_LRM_ATTR_TARGET
Definition: msg_xml.h:286
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
action_type_e
Definition: transition.h:25
gboolean executed
Definition: transition.h:40
GList * GListPtr
Definition: crm.h:218
#define crm_info(fmt, args...)
Definition: logging.h:251
synapse_t * synapse
Definition: transition.h:55
const char * abort_reason
Definition: transition.h:98
enum crm_ais_msg_types type
Definition: internal.h:51