pacemaker  2.1.2-ada5c3b36
Scalable High-Availability cluster resource manager
pcmk_simulate.c
Go to the documentation of this file.
1 /*
2  * Copyright 2021 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU Lesser General Public License
7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 #include <crm/cib/internal.h>
12 #include <crm/common/output.h>
13 #include <crm/common/results.h>
14 #include <crm/pengine/pe_types.h>
15 #include <pacemaker-internal.h>
16 #include <pacemaker.h>
17 
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 
22 static char *
23 create_action_name(pe_action_t *action, bool verbose)
24 {
25  char *action_name = NULL;
26  const char *prefix = "";
27  const char *action_host = NULL;
28  const char *clone_name = NULL;
29  const char *task = action->task;
30 
31  if (action->node) {
32  action_host = action->node->details->uname;
33  } else if (!pcmk_is_set(action->flags, pe_action_pseudo)) {
34  action_host = "<none>";
35  }
36 
37  if (pcmk__str_eq(action->task, RSC_CANCEL, pcmk__str_casei)) {
38  prefix = "Cancel ";
39  task = action->cancel_task;
40  }
41 
42  if (action->rsc && action->rsc->clone_name) {
43  clone_name = action->rsc->clone_name;
44  }
45 
46  if (clone_name) {
47  char *key = NULL;
48  guint interval_ms = 0;
49 
50  if (pcmk__guint_from_hash(action->meta,
52  &interval_ms) != pcmk_rc_ok) {
53  interval_ms = 0;
54  }
55 
57  const char *n_type = g_hash_table_lookup(action->meta, "notify_key_type");
58  const char *n_task = g_hash_table_lookup(action->meta, "notify_key_operation");
59 
60  CRM_ASSERT(n_type != NULL);
61  CRM_ASSERT(n_task != NULL);
62  key = pcmk__notify_key(clone_name, n_type, n_task);
63 
64  } else {
65  key = pcmk__op_key(clone_name, task, interval_ms);
66  }
67 
68  if (action_host) {
69  action_name = crm_strdup_printf("%s%s %s", prefix, key, action_host);
70  } else {
71  action_name = crm_strdup_printf("%s%s", prefix, key);
72  }
73  free(key);
74 
75  } else if (pcmk__str_eq(action->task, CRM_OP_FENCE, pcmk__str_casei)) {
76  const char *op = g_hash_table_lookup(action->meta, "stonith_action");
77 
78  action_name = crm_strdup_printf("%s%s '%s' %s", prefix, action->task, op, action_host);
79 
80  } else if (action->rsc && action_host) {
81  action_name = crm_strdup_printf("%s%s %s", prefix, action->uuid, action_host);
82 
83  } else if (action_host) {
84  action_name = crm_strdup_printf("%s%s %s", prefix, action->task, action_host);
85 
86  } else {
87  action_name = crm_strdup_printf("%s", action->uuid);
88  }
89 
90  if (verbose) {
91  char *with_id = crm_strdup_printf("%s (%d)", action_name, action->id);
92 
93  free(action_name);
94  action_name = with_id;
95  }
96  return action_name;
97 }
98 
99 static void
100 print_cluster_status(pe_working_set_t * data_set, unsigned int show_opts,
101  unsigned int section_opts, const char *title, bool print_spacer)
102 {
103  pcmk__output_t *out = data_set->priv;
104  GList *all = NULL;
105 
106  section_opts |= pcmk_section_nodes | pcmk_section_resources;
107 
108  all = g_list_prepend(all, (gpointer) "*");
109 
110  PCMK__OUTPUT_SPACER_IF(out, print_spacer);
111  out->begin_list(out, NULL, NULL, "%s", title);
112  out->message(out, "cluster-status", data_set, 0, NULL, FALSE,
113  section_opts,
115  NULL, all, all);
116  out->end_list(out);
117 
118  g_list_free(all);
119 }
120 
121 static void
122 print_transition_summary(pe_working_set_t *data_set, bool print_spacer)
123 {
124  pcmk__output_t *out = data_set->priv;
125 
126  PCMK__OUTPUT_SPACER_IF(out, print_spacer);
127  out->begin_list(out, NULL, NULL, "Transition Summary");
128  LogNodeActions(data_set);
129  g_list_foreach(data_set->resources, (GFunc) LogActions, data_set);
130  out->end_list(out);
131 }
132 
133 static void
134 reset(pe_working_set_t *data_set, xmlNodePtr input, pcmk__output_t *out,
135  char *use_date, unsigned int flags)
136 {
137  data_set->input = input;
138  data_set->priv = out;
139  pcmk__set_effective_date(data_set, true, use_date);
142  }
145  }
148  }
149 }
150 
151 int
152 pcmk__write_sim_dotfile(pe_working_set_t *data_set, const char *dot_file,
153  bool all_actions, bool verbose)
154 {
155  GList *gIter = NULL;
156  FILE *dot_strm = fopen(dot_file, "w");
157 
158  if (dot_strm == NULL) {
159  return errno;
160  }
161 
162  fprintf(dot_strm, " digraph \"g\" {\n");
163  for (gIter = data_set->actions; gIter != NULL; gIter = gIter->next) {
164  pe_action_t *action = (pe_action_t *) gIter->data;
165  const char *style = "dashed";
166  const char *font = "black";
167  const char *color = "black";
168  char *action_name = create_action_name(action, verbose);
169 
170  if (pcmk_is_set(action->flags, pe_action_pseudo)) {
171  font = "orange";
172  }
173 
174  if (pcmk_is_set(action->flags, pe_action_dumped)) {
175  style = "bold";
176  color = "green";
177 
178  } else if ((action->rsc != NULL)
179  && !pcmk_is_set(action->rsc->flags, pe_rsc_managed)) {
180  color = "red";
181  font = "purple";
182  if (!all_actions) {
183  goto do_not_write;
184  }
185 
186  } else if (pcmk_is_set(action->flags, pe_action_optional)) {
187  color = "blue";
188  if (!all_actions) {
189  goto do_not_write;
190  }
191 
192  } else {
193  color = "red";
195  }
196 
198  fprintf(dot_strm, "\"%s\" [ style=%s color=\"%s\" fontcolor=\"%s\"]\n",
199  action_name, style, color, font);
200  do_not_write:
201  free(action_name);
202  }
203 
204  for (gIter = data_set->actions; gIter != NULL; gIter = gIter->next) {
205  pe_action_t *action = (pe_action_t *) gIter->data;
206 
207  GList *gIter2 = NULL;
208 
209  for (gIter2 = action->actions_before; gIter2 != NULL; gIter2 = gIter2->next) {
210  pe_action_wrapper_t *before = (pe_action_wrapper_t *) gIter2->data;
211 
212  char *before_name = NULL;
213  char *after_name = NULL;
214  const char *style = "dashed";
215  bool optional = true;
216 
217  if (before->state == pe_link_dumped) {
218  optional = false;
219  style = "bold";
220  } else if (pcmk_is_set(action->flags, pe_action_pseudo)
221  && (before->type & pe_order_stonith_stop)) {
222  continue;
223  } else if (before->type == pe_order_none) {
224  continue;
225  } else if (pcmk_is_set(before->action->flags, pe_action_dumped)
227  && before->type != pe_order_load) {
228  optional = false;
229  }
230 
231  if (all_actions || !optional) {
232  before_name = create_action_name(before->action, verbose);
233  after_name = create_action_name(action, verbose);
234  fprintf(dot_strm, "\"%s\" -> \"%s\" [ style = %s]\n",
235  before_name, after_name, style);
236  free(before_name);
237  free(after_name);
238  }
239  }
240  }
241 
242  fprintf(dot_strm, "}\n");
243  fflush(dot_strm);
244  fclose(dot_strm);
245  return pcmk_rc_ok;
246 }
247 
248 void
249 pcmk__profile_file(const char *xml_file, long long repeat, pe_working_set_t *data_set, char *use_date)
250 {
251  pcmk__output_t *out = data_set->priv;
252  xmlNode *cib_object = NULL;
253  clock_t start = 0;
254  clock_t end;
255 
256  CRM_ASSERT(out != NULL);
257 
258  cib_object = filename2xml(xml_file);
259  start = clock();
260 
261  if (get_object_root(XML_CIB_TAG_STATUS, cib_object) == NULL) {
262  create_xml_node(cib_object, XML_CIB_TAG_STATUS);
263  }
264 
265  if (cli_config_update(&cib_object, NULL, FALSE) == FALSE) {
266  free_xml(cib_object);
267  return;
268  }
269 
270  if (validate_xml(cib_object, NULL, FALSE) != TRUE) {
271  free_xml(cib_object);
272  return;
273  }
274 
275  for (int i = 0; i < repeat; ++i) {
276  xmlNode *input = (repeat == 1)? cib_object : copy_xml(cib_object);
277 
278  data_set->input = input;
279  pcmk__set_effective_date(data_set, false, use_date);
280  pcmk__schedule_actions(data_set, input, NULL);
281  pe_reset_working_set(data_set);
282  }
283 
284  end = clock();
285  out->message(out, "profile", xml_file, start, end);
286 }
287 
288 void
289 pcmk__profile_dir(const char *dir, long long repeat, pe_working_set_t *data_set, char *use_date)
290 {
291  pcmk__output_t *out = data_set->priv;
292  struct dirent **namelist;
293 
294  int file_num = scandir(dir, &namelist, 0, alphasort);
295 
296  CRM_ASSERT(out != NULL);
297 
298  if (file_num > 0) {
299  struct stat prop;
300  char buffer[FILENAME_MAX];
301 
302  out->begin_list(out, NULL, NULL, "Timings");
303 
304  while (file_num--) {
305  if ('.' == namelist[file_num]->d_name[0]) {
306  free(namelist[file_num]);
307  continue;
308 
309  } else if (!pcmk__ends_with_ext(namelist[file_num]->d_name,
310  ".xml")) {
311  free(namelist[file_num]);
312  continue;
313  }
314  snprintf(buffer, sizeof(buffer), "%s/%s", dir, namelist[file_num]->d_name);
315  if (stat(buffer, &prop) == 0 && S_ISREG(prop.st_mode)) {
316  pcmk__profile_file(buffer, repeat, data_set, use_date);
317  }
318  free(namelist[file_num]);
319  }
320  free(namelist);
321 
322  out->end_list(out);
323  }
324 }
325 
326 void
327 pcmk__set_effective_date(pe_working_set_t *data_set, bool print_original, char *use_date)
328 {
329  pcmk__output_t *out = data_set->priv;
330  time_t original_date = 0;
331 
332  CRM_ASSERT(out != NULL);
333 
334  crm_element_value_epoch(data_set->input, "execution-date", &original_date);
335 
336  if (use_date) {
337  data_set->now = crm_time_new(use_date);
338  out->info(out, "Setting effective cluster time: %s", use_date);
339  crm_time_log(LOG_NOTICE, "Pretending 'now' is", data_set->now,
341 
342  } else if (original_date) {
343 
344  data_set->now = crm_time_new(NULL);
345  crm_time_set_timet(data_set->now, &original_date);
346 
347  if (print_original) {
348  char *when = crm_time_as_string(data_set->now,
350 
351  out->info(out, "Using the original execution date of: %s", when);
352  free(when);
353  }
354  }
355 }
356 
357 int
359  unsigned int flags, unsigned int section_opts, char *use_date,
360  char *input_file, char *graph_file, char *dot_file)
361 {
362  int printed = pcmk_rc_no_output;
363  int rc = pcmk_rc_ok;
364  xmlNodePtr input = NULL;
365  cib_t *cib = NULL;
366  bool modified = false;
367 
368  rc = cib__signon_query(&cib, &input);
369  if (rc != pcmk_rc_ok) {
370  goto simulate_done;
371  }
372 
373  reset(data_set, input, out, use_date, flags);
374  cluster_status(data_set);
375 
376  if (!out->is_quiet(out)) {
377  if (pcmk_is_set(data_set->flags, pe_flag_maintenance_mode)) {
378  printed = out->message(out, "maint-mode", data_set->flags);
379  }
380 
381  if (data_set->disabled_resources || data_set->blocked_resources) {
382  PCMK__OUTPUT_SPACER_IF(out, printed == pcmk_rc_ok);
383  printed = out->info(out, "%d of %d resource instances DISABLED and %d BLOCKED "
384  "from further action due to failure",
385  data_set->disabled_resources, data_set->ninstances,
386  data_set->blocked_resources);
387  }
388 
389  /* Most formatted output headers use caps for each word, but this one
390  * only has the first word capitalized for compatibility with pcs.
391  */
392  print_cluster_status(data_set, pcmk_is_set(flags, pcmk_sim_show_pending) ? pcmk_show_pending : 0,
393  section_opts, "Current cluster status", printed == pcmk_rc_ok);
394  printed = pcmk_rc_ok;
395  }
396 
397  modified = injections->node_down != NULL || injections->node_fail != NULL ||
398  injections->node_up != NULL || injections->op_inject != NULL ||
399  injections->ticket_activate != NULL || injections->ticket_grant != NULL ||
400  injections->ticket_revoke != NULL || injections->ticket_standby != NULL ||
401  injections->watchdog != NULL || injections->watchdog != NULL;
402 
403  if (modified) {
404  PCMK__OUTPUT_SPACER_IF(out, printed == pcmk_rc_ok);
405  modify_configuration(data_set, cib, injections);
406  printed = pcmk_rc_ok;
407 
408  rc = cib->cmds->query(cib, NULL, &input, cib_sync_call);
409  if (rc != pcmk_rc_ok) {
410  rc = pcmk_legacy2rc(rc);
411  goto simulate_done;
412  }
413 
414  cleanup_calculations(data_set);
415  reset(data_set, input, out, use_date, flags);
416  cluster_status(data_set);
417  }
418 
419  if (input_file != NULL) {
420  rc = write_xml_file(input, input_file, FALSE);
421  if (rc < 0) {
422  rc = pcmk_legacy2rc(rc);
423  goto simulate_done;
424  }
425  }
426 
427  if (pcmk_any_flags_set(flags, pcmk_sim_process | pcmk_sim_simulate)) {
428  crm_time_t *local_date = NULL;
429  pcmk__output_t *logger_out = NULL;
430 
431  if (pcmk_all_flags_set(data_set->flags, pe_flag_show_scores|pe_flag_show_utilization)) {
432  PCMK__OUTPUT_SPACER_IF(out, printed == pcmk_rc_ok);
433  out->begin_list(out, NULL, NULL, "Allocation Scores and Utilization Information");
434  printed = pcmk_rc_ok;
435  } else if (pcmk_is_set(data_set->flags, pe_flag_show_scores)) {
436  PCMK__OUTPUT_SPACER_IF(out, printed == pcmk_rc_ok);
437  out->begin_list(out, NULL, NULL, "Allocation Scores");
438  printed = pcmk_rc_ok;
439  } else if (pcmk_is_set(data_set->flags, pe_flag_show_utilization)) {
440  PCMK__OUTPUT_SPACER_IF(out, printed == pcmk_rc_ok);
441  out->begin_list(out, NULL, NULL, "Utilization Information");
442  printed = pcmk_rc_ok;
443  } else {
444  logger_out = pcmk__new_logger();
445  if (logger_out == NULL) {
446  rc = pcmk_rc_error;
447  goto simulate_done;
448  }
449 
450  data_set->priv = logger_out;
451  }
452 
453  pcmk__schedule_actions(data_set, input, local_date);
454 
455  if (logger_out == NULL) {
456  out->end_list(out);
457  } else {
458  logger_out->finish(logger_out, CRM_EX_OK, true, NULL);
459  pcmk__output_free(logger_out);
460  data_set->priv = out;
461  }
462 
463  input = NULL; /* Don't try and free it twice */
464 
465  if (graph_file != NULL) {
466  rc = write_xml_file(data_set->graph, graph_file, FALSE);
467  if (rc < 0) {
469  goto simulate_done;
470  }
471  }
472 
473  if (dot_file != NULL) {
474  rc = pcmk__write_sim_dotfile(data_set, dot_file,
477  if (rc != pcmk_rc_ok) {
479  goto simulate_done;
480  }
481  }
482 
483  if (!out->is_quiet(out)) {
484  print_transition_summary(data_set, printed == pcmk_rc_ok);
485  }
486  }
487 
488  rc = pcmk_rc_ok;
489 
491  PCMK__OUTPUT_SPACER_IF(out, printed == pcmk_rc_ok);
492  if (run_simulation(data_set, cib, injections->op_fail) != transition_complete) {
494  }
495 
496  if (!out->is_quiet(out)) {
497  pcmk__set_effective_date(data_set, true, use_date);
498 
501  }
504  }
505 
506  cluster_status(data_set);
507  print_cluster_status(data_set, 0, section_opts, "Revised Cluster Status", true);
508  }
509  }
510 
511 simulate_done:
512  if (cib) {
513  cib->cmds->signoff(cib);
514  cib_delete(cib);
515  }
516 
517  return rc;
518 }
519 
520 int
521 pcmk_simulate(xmlNodePtr *xml, pe_working_set_t *data_set, pcmk_injections_t *injections,
522  unsigned int flags, unsigned int section_opts, char *use_date,
523  char *input_file, char *graph_file, char *dot_file)
524 {
525  pcmk__output_t *out = NULL;
526  int rc = pcmk_rc_ok;
527 
528  rc = pcmk__out_prologue(&out, xml);
529  if (rc != pcmk_rc_ok) {
530  return rc;
531  }
532 
535 
536  rc = pcmk__simulate(data_set, out, injections, flags, section_opts,
537  use_date, input_file, graph_file, dot_file);
538  pcmk__out_epilogue(out, xml, rc);
539  return rc;
540 }
void(* end_list)(pcmk__output_t *out)
enum pe_link_state state
Definition: pe_types.h:533
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:225
GList * op_inject
Definition: pacemaker.h:59
#define pe__set_action_flags(action, flags_to_set)
Definition: internal.h:59
Control output from tools.
#define CRM_OP_FENCE
Definition: crm.h:145
#define crm_time_log_timeofday
Definition: iso8601.h:67
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:931
int(* message)(pcmk__output_t *out, const char *message_id,...)
struct crm_time_s crm_time_t
Definition: iso8601.h:32
#define RSC_NOTIFIED
Definition: crm.h:213
GList * ticket_activate
Definition: pacemaker.h:72
int(* signoff)(cib_t *cib)
Definition: cib_types.h:76
xmlNode * get_object_root(const char *object_type, xmlNode *the_root)
Definition: cib_utils.c:145
Internal tracking for transition graph creation.
Definition: pe_types.h:472
#define pe_flag_maintenance_mode
Definition: pe_types.h:96
bool(* is_quiet)(pcmk__output_t *out)
int alphasort(const void *dirent1, const void *dirent2)
int pcmk__simulate(pe_working_set_t *data_set, pcmk__output_t *out, pcmk_injections_t *injections, unsigned int flags, unsigned int section_opts, char *use_date, char *input_file, char *graph_file, char *dot_file)
Simulate a cluster&#39;s response to events.
GList * node_up
Definition: pacemaker.h:50
int write_xml_file(xmlNode *xml_node, const char *filename, gboolean compress)
Write XML to a file.
Definition: xml.c:1299
High Level API.
GList * actions
Definition: pe_types.h:164
int(* info)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
GList * ticket_grant
Definition: pacemaker.h:66
xmlNode * filename2xml(const char *filename)
Definition: xml.c:1044
xmlNode * pcmk__schedule_actions(pe_working_set_t *data_set, xmlNode *xml_input, crm_time_t *now)
pe_action_t * action
Definition: pe_types.h:534
void cib_delete(cib_t *cib)
Free all memory used by CIB connection.
Definition: cib_client.c:451
#define RSC_NOTIFY
Definition: crm.h:212
void pcmk__profile_file(const char *xml_file, long long repeat, pe_working_set_t *data_set, char *use_date)
Profile the configuration updates and scheduler actions in a single CIB file, printing the profiling ...
const char * action
Definition: pcmk_fence.c:30
gboolean validate_xml(xmlNode *xml_blob, const char *validation, gboolean to_logs)
Definition: schemas.c:700
GList * resources
Definition: pe_types.h:158
int pcmk__out_prologue(pcmk__output_t **out, xmlNodePtr *xml)
#define PCMK__OUTPUT_SPACER_IF(out_obj, cond)
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:830
int cib__signon_query(cib_t **cib, xmlNode **cib_object)
Definition: cib_utils.c:790
void pe_reset_working_set(pe_working_set_t *data_set)
Reset a working set to default state without freeing it.
Definition: status.c:329
void cleanup_calculations(pe_working_set_t *data_set)
Reset working set to default state without freeing it or constraints.
Definition: status.c:270
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
Definition: operations.c:229
int pcmk__guint_from_hash(GHashTable *table, const char *key, guint default_val, guint *result)
Definition: strings.c:311
int rc
Definition: pcmk_fence.c:35
cib_api_operations_t * cmds
Definition: cib_types.h:147
#define pe_flag_sanitized
Definition: pe_types.h:120
int pcmk_simulate(xmlNodePtr *xml, pe_working_set_t *data_set, pcmk_injections_t *injections, unsigned int flags, unsigned int section_opts, char *use_date, char *input_file, char *graph_file, char *dot_file)
Simulate a cluster&#39;s response to events.
pcmk__output_t * pcmk__new_logger(void)
int pcmk__write_sim_dotfile(pe_working_set_t *data_set, const char *dot_file, bool all_actions, bool verbose)
Write out a file in dot(1) format describing the actions that will be taken by the scheduler in respo...
void pcmk__set_effective_date(pe_working_set_t *data_set, bool print_original, char *use_date)
Set the date of the cluster, either to the value given by use_date, or to the "execution-date" value ...
void pcmk__profile_dir(const char *dir, long long repeat, pe_working_set_t *data_set, char *use_date)
Profile the configuration updates and scheduler actions in every CIB file in a given directory...
GList * ticket_standby
Definition: pacemaker.h:70
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
void crm_time_set_timet(crm_time_t *target, time_t *source)
Definition: iso8601.c:1254
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:114
int blocked_resources
Definition: pe_types.h:182
void pcmk__register_lib_messages(pcmk__output_t *out)
Definition: pcmk_output.c:1844
void(* finish)(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest)
void LogActions(pe_resource_t *rsc, pe_working_set_t *data_set)
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:696
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
Definition: cib_types.h:92
int crm_element_value_epoch(const xmlNode *xml, const char *name, time_t *dest)
Retrieve the seconds-since-epoch value of an XML attribute.
Definition: nvpair.c:650
#define crm_time_log(level, prefix, dt, flags)
Definition: iso8601.h:60
Success.
Definition: results.h:239
int pcmk_legacy2rc(int legacy_rc)
Definition: results.c:462
void modify_configuration(pe_working_set_t *data_set, cib_t *cib, pcmk_injections_t *injections)
void pe__register_messages(pcmk__output_t *out)
Definition: pe_output.c:2850
void free_xml(xmlNode *child)
Definition: xml.c:824
xmlNode * input
Definition: pe_types.h:137
void pcmk__out_epilogue(pcmk__output_t *out, xmlNodePtr *xml, int retval)
void LogNodeActions(pe_working_set_t *data_set)
enum transition_status run_simulation(pe_working_set_t *data_set, cib_t *cib, GList *op_fail_list)
Function and executable result codes.
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
Definition: operations.c:45
char * crm_time_as_string(crm_time_t *dt, int flags)
Definition: iso8601.c:496
void pcmk__output_free(pcmk__output_t *out)
Definition: output.c:19
#define pe_flag_show_utilization
Definition: pe_types.h:134
GList * ticket_revoke
Definition: pacemaker.h:68
#define CRM_ASSERT(expr)
Definition: results.h:42
int disabled_resources
Definition: pe_types.h:183
gboolean cluster_status(pe_working_set_t *data_set)
Definition: status.c:71
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:92
Synthetic cluster events that can be injected into the cluster for running simulations.
Definition: pacemaker.h:48
GList * node_fail
Definition: pacemaker.h:54
This structure contains everything that makes up a single output formatter.
#define XML_LRM_ATTR_INTERVAL_MS
Definition: msg_xml.h:295
void(* begin_list)(pcmk__output_t *out, const char *singular_noun, const char *plural_noun, const char *format,...) G_GNUC_PRINTF(4
#define pe__set_working_set_flags(working_set, flags_to_set)
Definition: internal.h:35
enum pe_action_flags flags
Definition: pe_types.h:419
GList * op_fail
Definition: pacemaker.h:64
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:179
Data types for cluster status.
#define RSC_CANCEL
Definition: crm.h:196
unsigned long long flags
Definition: pe_types.h:146
gboolean cli_config_update(xmlNode **xml, int *best_version, gboolean to_logs)
Definition: schemas.c:1196
enum pe_ordering type
Definition: pe_types.h:532
#define pe_flag_show_scores
Definition: pe_types.h:133
crm_time_t * now
Definition: pe_types.h:138
#define pe_rsc_managed
Definition: pe_types.h:249
#define crm_time_log_date
Definition: iso8601.h:66
bool pcmk__ends_with_ext(const char *s, const char *match)
Definition: strings.c:563
GList * node_down
Definition: pacemaker.h:52
uint64_t flags
Definition: remote.c:149
xmlNode * graph
Definition: pe_types.h:176