pacemaker  2.0.2-debe490
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
operations.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2019 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 
12 #ifndef _GNU_SOURCE
13 # define _GNU_SOURCE
14 #endif
15 
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <ctype.h>
20 
21 #include <crm/crm.h>
22 #include <crm/lrmd.h>
23 #include <crm/msg_xml.h>
24 #include <crm/common/xml.h>
25 #include <crm/common/util.h>
26 
38 char *
39 generate_op_key(const char *rsc_id, const char *op_type, guint interval_ms)
40 {
41  CRM_ASSERT(rsc_id != NULL);
42  CRM_ASSERT(op_type != NULL);
43  return crm_strdup_printf(CRM_OP_FMT, rsc_id, op_type, interval_ms);
44 }
45 
46 gboolean
47 parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
48 {
49  char *notify = NULL;
50  char *mutable_key = NULL;
51  char *mutable_key_ptr = NULL;
52  size_t len = 0, offset = 0;
53  unsigned long long ch = 0;
54  guint local_interval_ms = 0;
55 
56  // Initialize output variables in case of early return
57  if (rsc_id) {
58  *rsc_id = NULL;
59  }
60  if (op_type) {
61  *op_type = NULL;
62  }
63  if (interval_ms) {
64  *interval_ms = 0;
65  }
66 
67  CRM_CHECK(key && *key, return FALSE);
68 
69  // Parse interval at end of string
70  len = strlen(key);
71  offset = len - 1;
72  while ((offset > 0) && isdigit(key[offset])) {
73  ch = key[offset] - '0';
74  for (int digits = len - offset; digits > 1; --digits) {
75  ch = ch * 10;
76  }
77  local_interval_ms += ch;
78  offset--;
79  }
80  crm_trace("Operation key '%s' has interval %ums", key, local_interval_ms);
81  if (interval_ms) {
82  *interval_ms = local_interval_ms;
83  }
84 
85  CRM_CHECK((offset != (len - 1)) && (key[offset] == '_'), return FALSE);
86 
87  mutable_key = strndup(key, offset);
88  offset--;
89 
90  while (offset > 0 && key[offset] != '_') {
91  offset--;
92  }
93 
94  CRM_CHECK(key[offset] == '_',
95  free(mutable_key); return FALSE);
96 
97  mutable_key_ptr = mutable_key + offset + 1;
98 
99  crm_trace(" Action: %s", mutable_key_ptr);
100  if (op_type) {
101  *op_type = strdup(mutable_key_ptr);
102  }
103 
104  mutable_key[offset] = 0;
105  offset--;
106 
107  notify = strstr(mutable_key, "_post_notify");
108  if (notify && safe_str_eq(notify, "_post_notify")) {
109  notify[0] = 0;
110  }
111 
112  notify = strstr(mutable_key, "_pre_notify");
113  if (notify && safe_str_eq(notify, "_pre_notify")) {
114  notify[0] = 0;
115  }
116 
117  crm_trace(" Resource: %s", mutable_key);
118  if (rsc_id) {
119  *rsc_id = mutable_key;
120  } else {
121  free(mutable_key);
122  }
123 
124  return TRUE;
125 }
126 
127 char *
128 generate_notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
129 {
130  CRM_CHECK(rsc_id != NULL, return NULL);
131  CRM_CHECK(op_type != NULL, return NULL);
132  CRM_CHECK(notify_type != NULL, return NULL);
133  return crm_strdup_printf("%s_%s_notify_%s_0",
134  rsc_id, notify_type, op_type);
135 }
136 
137 static char *
138 generate_transition_magic(const char *transition_key, int op_status, int op_rc)
139 {
140  CRM_CHECK(transition_key != NULL, return NULL);
141  return crm_strdup_printf("%d:%d;%s", op_status, op_rc, transition_key);
142 }
143 
159 gboolean
160 decode_transition_magic(const char *magic, char **uuid, int *transition_id, int *action_id,
161  int *op_status, int *op_rc, int *target_rc)
162 {
163  int res = 0;
164  char *key = NULL;
165  gboolean result = TRUE;
166  int local_op_status = -1;
167  int local_op_rc = -1;
168 
169  CRM_CHECK(magic != NULL, return FALSE);
170 
171 #ifdef SSCANF_HAS_M
172  res = sscanf(magic, "%d:%d;%ms", &local_op_status, &local_op_rc, &key);
173 #else
174  key = calloc(1, strlen(magic) - 3); // magic must have >=4 other characters
175  CRM_ASSERT(key);
176  res = sscanf(magic, "%d:%d;%s", &local_op_status, &local_op_rc, key);
177 #endif
178  if (res == EOF) {
179  crm_err("Could not decode transition information '%s': %s",
180  magic, pcmk_strerror(errno));
181  result = FALSE;
182  } else if (res < 3) {
183  crm_warn("Transition information '%s' incomplete (%d of 3 expected items)",
184  magic, res);
185  result = FALSE;
186  } else {
187  if (op_status) {
188  *op_status = local_op_status;
189  }
190  if (op_rc) {
191  *op_rc = local_op_rc;
192  }
193  result = decode_transition_key(key, uuid, transition_id, action_id,
194  target_rc);
195  }
196  free(key);
197  return result;
198 }
199 
200 char *
201 generate_transition_key(int transition_id, int action_id, int target_rc, const char *node)
202 {
203  CRM_CHECK(node != NULL, return NULL);
204  return crm_strdup_printf("%d:%d:%d:%-*s",
205  action_id, transition_id, target_rc, 36, node);
206 }
207 
221 gboolean
222 decode_transition_key(const char *key, char **uuid, int *transition_id, int *action_id,
223  int *target_rc)
224 {
225  int local_transition_id = -1;
226  int local_action_id = -1;
227  int local_target_rc = -1;
228  char local_uuid[37] = { '\0' };
229 
230  // Initialize any supplied output arguments
231  if (uuid) {
232  *uuid = NULL;
233  }
234  if (transition_id) {
235  *transition_id = -1;
236  }
237  if (action_id) {
238  *action_id = -1;
239  }
240  if (target_rc) {
241  *target_rc = -1;
242  }
243 
244  CRM_CHECK(key != NULL, return FALSE);
245  if (sscanf(key, "%d:%d:%d:%36s", &local_action_id, &local_transition_id,
246  &local_target_rc, local_uuid) != 4) {
247  crm_err("Invalid transition key '%s'", key);
248  return FALSE;
249  }
250  if (strlen(local_uuid) != 36) {
251  crm_warn("Invalid UUID '%s' in transition key '%s'", local_uuid, key);
252  }
253  if (uuid) {
254  *uuid = strdup(local_uuid);
255  CRM_ASSERT(*uuid);
256  }
257  if (transition_id) {
258  *transition_id = local_transition_id;
259  }
260  if (action_id) {
261  *action_id = local_action_id;
262  }
263  if (target_rc) {
264  *target_rc = local_target_rc;
265  }
266  return TRUE;
267 }
268 
269 void
270 filter_action_parameters(xmlNode * param_set, const char *version)
271 {
272  char *key = NULL;
273  char *timeout = NULL;
274  char *interval_ms_s = NULL;
275 
276  const char *attr_filter[] = {
277  XML_ATTR_ID,
282  "pcmk_external_ip"
283  };
284 
285  gboolean do_delete = FALSE;
286  int lpc = 0;
287  static int meta_len = 0;
288 
289  if (meta_len == 0) {
290  meta_len = strlen(CRM_META);
291  }
292 
293  if (param_set == NULL) {
294  return;
295  }
296 
297  for (lpc = 0; lpc < DIMOF(attr_filter); lpc++) {
298  xml_remove_prop(param_set, attr_filter[lpc]);
299  }
300 
302  interval_ms_s = crm_element_value_copy(param_set, key);
303  free(key);
304 
306  timeout = crm_element_value_copy(param_set, key);
307 
308  if (param_set) {
309  xmlAttrPtr xIter = param_set->properties;
310 
311  while (xIter) {
312  const char *prop_name = (const char *)xIter->name;
313 
314  xIter = xIter->next;
315  do_delete = FALSE;
316  if (strncasecmp(prop_name, CRM_META, meta_len) == 0) {
317  do_delete = TRUE;
318  }
319 
320  if (do_delete) {
321  xml_remove_prop(param_set, prop_name);
322  }
323  }
324  }
325 
326  if (interval_ms_s && strcmp(interval_ms_s, "0")) {
327  /* Re-instate the operation's timeout value */
328  if (timeout != NULL) {
329  crm_xml_add(param_set, key, timeout);
330  }
331  }
332 
333  free(interval_ms_s);
334  free(timeout);
335  free(key);
336 }
337 
338 #define FAKE_TE_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
339 static void
340 append_digest(lrmd_event_data_t * op, xmlNode * update, const char *version, const char *magic,
341  int level)
342 {
343  /* this will enable us to later determine that the
344  * resource's parameters have changed and we should force
345  * a restart
346  */
347  char *digest = NULL;
348  xmlNode *args_xml = NULL;
349 
350  if (op->params == NULL) {
351  return;
352  }
353 
354  args_xml = create_xml_node(NULL, XML_TAG_PARAMS);
355  g_hash_table_foreach(op->params, hash2field, args_xml);
356  filter_action_parameters(args_xml, version);
357  digest = calculate_operation_digest(args_xml, version);
358 
359 #if 0
360  if (level < get_crm_log_level()
361  && op->interval_ms == 0 && crm_str_eq(op->op_type, CRMD_ACTION_START, TRUE)) {
362  char *digest_source = dump_xml_unformatted(args_xml);
363 
364  do_crm_log(level, "Calculated digest %s for %s (%s). Source: %s\n",
365  digest, ID(update), magic, digest_source);
366  free(digest_source);
367  }
368 #endif
369  crm_xml_add(update, XML_LRM_ATTR_OP_DIGEST, digest);
370 
371  free_xml(args_xml);
372  free(digest);
373 }
374 
375 int
377 {
378  int rc = 0;
379 
380  if (op && op->user_data) {
381  decode_transition_key(op->user_data, NULL, NULL, NULL, &rc);
382  }
383  return rc;
384 }
385 
386 gboolean
387 did_rsc_op_fail(lrmd_event_data_t * op, int target_rc)
388 {
389  switch (op->op_status) {
391  case PCMK_LRM_OP_PENDING:
392  return FALSE;
393  break;
394 
396  case PCMK_LRM_OP_TIMEOUT:
397  case PCMK_LRM_OP_ERROR:
398  return TRUE;
399  break;
400 
401  default:
402  if (target_rc != op->rc) {
403  return TRUE;
404  }
405  }
406 
407  return FALSE;
408 }
409 
421 xmlNode *
422 crm_create_op_xml(xmlNode *parent, const char *prefix, const char *task,
423  const char *interval_spec, const char *timeout)
424 {
425  xmlNode *xml_op;
426 
427  CRM_CHECK(prefix && task && interval_spec, return NULL);
428 
429  xml_op = create_xml_node(parent, XML_ATTR_OP);
430  crm_xml_set_id(xml_op, "%s-%s-%s", prefix, task, interval_spec);
431  crm_xml_add(xml_op, XML_LRM_ATTR_INTERVAL, interval_spec);
432  crm_xml_add(xml_op, "name", task);
433  if (timeout) {
434  crm_xml_add(xml_op, XML_ATTR_TIMEOUT, timeout);
435  }
436  return xml_op;
437 }
438 
439 xmlNode *
440 create_operation_update(xmlNode * parent, lrmd_event_data_t * op, const char * caller_version,
441  int target_rc, const char * node, const char * origin, int level)
442 {
443  char *key = NULL;
444  char *magic = NULL;
445  char *op_id = NULL;
446  char *op_id_additional = NULL;
447  char *local_user_data = NULL;
448  const char *exit_reason = NULL;
449 
450  xmlNode *xml_op = NULL;
451  const char *task = NULL;
452 
453  CRM_CHECK(op != NULL, return NULL);
454  do_crm_log(level, "%s: Updating resource %s after %s op %s (interval=%u)",
455  origin, op->rsc_id, op->op_type, services_lrm_status_str(op->op_status),
456  op->interval_ms);
457 
458  crm_trace("DC version: %s", caller_version);
459 
460  task = op->op_type;
461 
462  /* Record a successful reload as a start, and a failed reload as a monitor,
463  * to make life easier for the scheduler when determining the current state.
464  */
465  if (crm_str_eq(task, "reload", TRUE)) {
466  if (op->op_status == PCMK_LRM_OP_DONE) {
467  task = CRMD_ACTION_START;
468  } else {
469  task = CRMD_ACTION_STATUS;
470  }
471  }
472 
473  key = generate_op_key(op->rsc_id, task, op->interval_ms);
474  if (crm_str_eq(task, CRMD_ACTION_NOTIFY, TRUE)) {
475  const char *n_type = crm_meta_value(op->params, "notify_type");
476  const char *n_task = crm_meta_value(op->params, "notify_operation");
477 
478  CRM_LOG_ASSERT(n_type != NULL);
479  CRM_LOG_ASSERT(n_task != NULL);
480  op_id = generate_notify_key(op->rsc_id, n_type, n_task);
481 
482  if (op->op_status != PCMK_LRM_OP_PENDING) {
483  /* Ignore notify errors.
484  *
485  * @TODO It might be better to keep the correct result here, and
486  * ignore it in process_graph_event().
487  */
489  op->rc = 0;
490  }
491 
492  } else if (did_rsc_op_fail(op, target_rc)) {
493  op_id = generate_op_key(op->rsc_id, "last_failure", 0);
494  if (op->interval_ms == 0) {
495  // Ensure 'last' gets updated, in case record-pending is true
496  op_id_additional = generate_op_key(op->rsc_id, "last", 0);
497  }
498  exit_reason = op->exit_reason;
499 
500  } else if (op->interval_ms > 0) {
501  op_id = strdup(key);
502 
503  } else {
504  op_id = generate_op_key(op->rsc_id, "last", 0);
505  }
506 
507  again:
508  xml_op = find_entity(parent, XML_LRM_TAG_RSC_OP, op_id);
509  if (xml_op == NULL) {
510  xml_op = create_xml_node(parent, XML_LRM_TAG_RSC_OP);
511  }
512 
513  if (op->user_data == NULL) {
514  crm_debug("Generating fake transition key for: " CRM_OP_FMT " %d from %s",
515  op->rsc_id, op->op_type, op->interval_ms,
516  op->call_id, origin);
517  local_user_data = generate_transition_key(-1, op->call_id, target_rc, FAKE_TE_ID);
518  op->user_data = local_user_data;
519  }
520 
521  if(magic == NULL) {
522  magic = generate_transition_magic(op->user_data, op->op_status, op->rc);
523  }
524 
525  crm_xml_add(xml_op, XML_ATTR_ID, op_id);
526  crm_xml_add(xml_op, XML_LRM_ATTR_TASK_KEY, key);
527  crm_xml_add(xml_op, XML_LRM_ATTR_TASK, task);
528  crm_xml_add(xml_op, XML_ATTR_ORIGIN, origin);
529  crm_xml_add(xml_op, XML_ATTR_CRM_VERSION, caller_version);
531  crm_xml_add(xml_op, XML_ATTR_TRANSITION_MAGIC, magic);
532  crm_xml_add(xml_op, XML_LRM_ATTR_EXIT_REASON, exit_reason == NULL ? "" : exit_reason);
533  crm_xml_add(xml_op, XML_LRM_ATTR_TARGET, node); /* For context during triage */
534 
536  crm_xml_add_int(xml_op, XML_LRM_ATTR_RC, op->rc);
539 
540  if (compare_version("2.1", caller_version) <= 0) {
541  if (op->t_run || op->t_rcchange || op->exec_time || op->queue_time) {
542  crm_trace("Timing data (" CRM_OP_FMT "): last=%u change=%u exec=%u queue=%u",
543  op->rsc_id, op->op_type, op->interval_ms,
544  op->t_run, op->t_rcchange, op->exec_time, op->queue_time);
545 
546  if (op->interval_ms == 0) {
547  /* The values are the same for non-recurring ops */
550 
551  } else if(op->t_rcchange) {
552  /* last-run is not accurate for recurring ops */
554 
555  } else {
556  /* ...but is better than nothing otherwise */
558  }
559 
562  }
563  }
564 
565  if (crm_str_eq(op->op_type, CRMD_ACTION_MIGRATE, TRUE)
566  || crm_str_eq(op->op_type, CRMD_ACTION_MIGRATED, TRUE)) {
567  /*
568  * Record migrate_source and migrate_target always for migrate ops.
569  */
570  const char *name = XML_LRM_ATTR_MIGRATE_SOURCE;
571 
572  crm_xml_add(xml_op, name, crm_meta_value(op->params, name));
573 
575  crm_xml_add(xml_op, name, crm_meta_value(op->params, name));
576  }
577 
578  append_digest(op, xml_op, caller_version, magic, LOG_DEBUG);
579 
580  if (op_id_additional) {
581  free(op_id);
582  op_id = op_id_additional;
583  op_id_additional = NULL;
584  goto again;
585  }
586 
587  if (local_user_data) {
588  free(local_user_data);
589  op->user_data = NULL;
590  }
591  free(magic);
592  free(op_id);
593  free(key);
594  return xml_op;
595 }
596 
606 bool
607 crm_op_needs_metadata(const char *rsc_class, const char *op)
608 {
609  /* Agent meta-data is used to determine whether a reload is possible, and to
610  * evaluate versioned parameters -- so if this op is not relevant to those
611  * features, we don't need the meta-data.
612  */
613 
614  CRM_CHECK(rsc_class || op, return FALSE);
615 
616  if (rsc_class
617  && is_not_set(pcmk_get_ra_caps(rsc_class), pcmk_ra_cap_params)) {
618  /* Meta-data is only needed for resource classes that use parameters */
619  return FALSE;
620  }
621 
622  /* Meta-data is only needed for these actions */
623  if (op
624  && strcmp(op, CRMD_ACTION_START)
625  && strcmp(op, CRMD_ACTION_STATUS)
626  && strcmp(op, CRMD_ACTION_PROMOTE)
627  && strcmp(op, CRMD_ACTION_DEMOTE)
628  && strcmp(op, CRMD_ACTION_RELOAD)
629  && strcmp(op, CRMD_ACTION_MIGRATE)
630  && strcmp(op, CRMD_ACTION_MIGRATED)
631  && strcmp(op, CRMD_ACTION_NOTIFY)) {
632  return FALSE;
633  }
634 
635  return TRUE;
636 }
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:156
#define XML_RSC_OP_LAST_CHANGE
Definition: msg_xml.h:280
A dumping ground.
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
Definition: operations.c:47
xmlNode * crm_create_op_xml(xmlNode *parent, const char *prefix, const char *task, const char *interval_spec, const char *timeout)
Create a CIB XML element for an operation.
Definition: operations.c:422
#define CRMD_ACTION_MIGRATED
Definition: crm.h:147
const char * pcmk_strerror(int rc)
Definition: results.c:188
const char * user_data
Definition: lrmd.h:206
void hash2field(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry.
Definition: nvpair.c:615
const char * rsc_id
Definition: lrmd.h:202
const char * crm_xml_add_ms(xmlNode *node, const char *name, guint ms)
Create an XML attribute with specified name and unsigned value.
Definition: nvpair.c:405
#define XML_ATTR_TRANSITION_MAGIC
Definition: msg_xml.h:356
int rsc_op_expected_rc(lrmd_event_data_t *event)
Definition: operations.c:376
unsigned int queue_time
Definition: lrmd.h:232
#define FAKE_TE_ID
Definition: operations.c:338
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
Definition: nvpair.c:383
#define CRMD_ACTION_NOTIFY
Definition: crm.h:160
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
Definition: xml.c:1743
#define XML_RSC_OP_T_EXEC
Definition: msg_xml.h:282
const char * crm_meta_value(GHashTable *hash, const char *field)
Definition: utils.c:756
#define XML_LRM_ATTR_INTERVAL
Definition: msg_xml.h:254
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:275
#define XML_LRM_ATTR_OP_DIGEST
Definition: msg_xml.h:273
#define XML_ATTR_TIMEOUT
Definition: msg_xml.h:90
#define CRMD_ACTION_PROMOTE
Definition: crm.h:155
Resource agent executor.
unsigned int t_rcchange
Definition: lrmd.h:228
bool crm_op_needs_metadata(const char *rsc_class, const char *op)
Check whether an operation requires resource agent meta-data.
Definition: operations.c:607
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:142
enum ocf_exitcode rc
Definition: lrmd.h:220
#define XML_RSC_OP_T_QUEUE
Definition: msg_xml.h:283
char * strndup(const char *str, size_t len)
char * crm_meta_name(const char *field)
Definition: utils.c:734
gboolean decode_transition_key(const char *key, char **uuid, int *action, int *transition_id, int *target_rc)
Parse a transition key into its constituent parts.
Definition: operations.c:222
unsigned int exec_time
Definition: lrmd.h:230
char * generate_transition_key(int action, int transition_id, int target_rc, const char *node)
Definition: operations.c:201
#define XML_ATTR_ORIGIN
Definition: msg_xml.h:91
#define CRMD_ACTION_START
Definition: crm.h:149
#define XML_LRM_ATTR_TASK_KEY
Definition: msg_xml.h:261
#define XML_LRM_ATTR_TASK
Definition: msg_xml.h:260
void * params
Definition: lrmd.h:239
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
Definition: digest.c:176
#define crm_warn(fmt, args...)
Definition: logging.h:241
op_status
Definition: services.h:118
#define CRMD_ACTION_DEMOTE
Definition: crm.h:157
const char * exit_reason
Definition: lrmd.h:247
#define XML_ATTR_OP
Definition: msg_xml.h:101
#define CRM_OP_FMT
Definition: crm_internal.h:133
#define crm_debug(fmt, args...)
Definition: logging.h:245
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:556
Utility functions.
#define XML_ATTR_ID
Definition: msg_xml.h:96
#define crm_trace(fmt, args...)
Definition: logging.h:246
#define do_crm_log(level, fmt, args...)
Log a message.
Definition: logging.h:121
xmlNode * create_operation_update(xmlNode *parent, lrmd_event_data_t *event, const char *caller_version, int target_rc, const char *node, const char *origin, int level)
Definition: operations.c:440
Wrappers for and extensions to libxml2.
char * generate_notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
Definition: operations.c:128
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1890
uint32_t pcmk_get_ra_caps(const char *standard)
Get capabilities of a resource agent standard.
Definition: agents.c:29
#define XML_LRM_ATTR_MIGRATE_TARGET
Definition: msg_xml.h:286
#define XML_LRM_ATTR_EXIT_REASON
Definition: msg_xml.h:278
void free_xml(xmlNode *child)
Definition: xml.c:2014
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
Definition: strings.c:220
const char * op_type
Definition: lrmd.h:204
#define CRMD_ACTION_RELOAD
Definition: crm.h:145
#define XML_LRM_ATTR_TARGET_UUID
Definition: msg_xml.h:263
unsigned int t_run
Definition: lrmd.h:226
#define XML_ATTR_TRANSITION_KEY
Definition: msg_xml.h:357
unsigned int get_crm_log_level(void)
Definition: logging.c:979
gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc)
Definition: operations.c:387
#define CRM_META
Definition: crm.h:49
#define crm_err(fmt, args...)
Definition: logging.h:240
#define CRM_ASSERT(expr)
Definition: results.h:42
void crm_xml_set_id(xmlNode *xml, const char *format,...) __attribute__((__format__(__printf__
void xml_remove_prop(xmlNode *obj, const char *name)
Definition: xml.c:3215
int compare_version(const char *version1, const char *version2)
Definition: utils.c:461
#define XML_LRM_ATTR_INTERVAL_MS
Definition: msg_xml.h:258
char * dump_xml_unformatted(xmlNode *msg)
Definition: xml.c:3196
#define DIMOF(a)
Definition: crm.h:35
#define XML_LRM_ATTR_CALLID
Definition: msg_xml.h:272
#define CRMD_ACTION_MIGRATE
Definition: crm.h:146
#define XML_LRM_ATTR_OPSTATUS
Definition: msg_xml.h:270
#define XML_ATTR_CRM_VERSION
Definition: msg_xml.h:79
gboolean decode_transition_magic(const char *magic, char **uuid, int *transition_id, int *action_id, int *op_status, int *op_rc, int *target_rc)
Parse a transition magic string into its constituent parts.
Definition: operations.c:160
#define XML_LRM_ATTR_RC
Definition: msg_xml.h:271
void filter_action_parameters(xmlNode *param_set, const char *version)
Definition: operations.c:270
#define XML_LRM_ATTR_TARGET
Definition: msg_xml.h:262
#define XML_LRM_TAG_RSC_OP
Definition: msg_xml.h:228
#define XML_RSC_OP_LAST_RUN
Definition: msg_xml.h:281
#define ID(x)
Definition: msg_xml.h:414
#define safe_str_eq(a, b)
Definition: util.h:59
#define XML_LRM_ATTR_MIGRATE_SOURCE
Definition: msg_xml.h:285
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
#define XML_TAG_PARAMS
Definition: msg_xml.h:169
char * generate_op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key.
Definition: operations.c:39
uint32_t version
Definition: remote.c:146
guint interval_ms
Definition: lrmd.h:213
#define CRMD_ACTION_STATUS
Definition: crm.h:163