pacemaker  1.1.18-7fdfbbe
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 (C) 2004-2017 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This source code is licensed under the GNU Lesser General Public License
5  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
6  */
7 
8 #include <crm_internal.h>
9 
10 #ifndef _GNU_SOURCE
11 # define _GNU_SOURCE
12 #endif
13 
14 #include <stdio.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #include <ctype.h>
18 
19 #include <crm/crm.h>
20 #include <crm/lrmd.h>
21 #include <crm/msg_xml.h>
22 #include <crm/common/xml.h>
23 #include <crm/common/util.h>
24 
36 char *
37 generate_op_key(const char *rsc_id, const char *op_type, int interval)
38 {
39  CRM_ASSERT(rsc_id != NULL);
40  CRM_ASSERT(op_type != NULL);
41  CRM_ASSERT(interval >= 0);
42  return crm_strdup_printf("%s_%s_%d", rsc_id, op_type, interval);
43 }
44 
45 gboolean
46 parse_op_key(const char *key, char **rsc_id, char **op_type, int *interval)
47 {
48  char *notify = NULL;
49  char *mutable_key = NULL;
50  char *mutable_key_ptr = NULL;
51  int len = 0, offset = 0, ch = 0;
52 
53  CRM_CHECK(key != NULL, return FALSE);
54 
55  *interval = 0;
56  len = strlen(key);
57  offset = len - 1;
58 
59  crm_trace("Source: %s", key);
60 
61  while (offset > 0 && isdigit(key[offset])) {
62  int digits = len - offset;
63 
64  ch = key[offset] - '0';
65  CRM_CHECK(ch < 10, return FALSE);
66  CRM_CHECK(ch >= 0, return FALSE);
67  while (digits > 1) {
68  digits--;
69  ch = ch * 10;
70  }
71  *interval += ch;
72  offset--;
73  }
74 
75  crm_trace(" Interval: %d", *interval);
76  CRM_CHECK(key[offset] == '_', return FALSE);
77 
78  mutable_key = strdup(key);
79  mutable_key[offset] = 0;
80  offset--;
81 
82  while (offset > 0 && key[offset] != '_') {
83  offset--;
84  }
85 
86  CRM_CHECK(key[offset] == '_', free(mutable_key);
87  return FALSE);
88 
89  mutable_key_ptr = mutable_key + offset + 1;
90 
91  crm_trace(" Action: %s", mutable_key_ptr);
92 
93  *op_type = strdup(mutable_key_ptr);
94 
95  mutable_key[offset] = 0;
96  offset--;
97 
98  CRM_CHECK(mutable_key != mutable_key_ptr, free(mutable_key);
99  return FALSE);
100 
101  notify = strstr(mutable_key, "_post_notify");
102  if (notify && safe_str_eq(notify, "_post_notify")) {
103  notify[0] = 0;
104  }
105 
106  notify = strstr(mutable_key, "_pre_notify");
107  if (notify && safe_str_eq(notify, "_pre_notify")) {
108  notify[0] = 0;
109  }
110 
111  crm_trace(" Resource: %s", mutable_key);
112  *rsc_id = mutable_key;
113 
114  return TRUE;
115 }
116 
117 char *
118 generate_notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
119 {
120  int len = 12;
121  char *op_id = NULL;
122 
123  CRM_CHECK(rsc_id != NULL, return NULL);
124  CRM_CHECK(op_type != NULL, return NULL);
125  CRM_CHECK(notify_type != NULL, return NULL);
126 
127  len += strlen(op_type);
128  len += strlen(rsc_id);
129  len += strlen(notify_type);
130  if(len > 0) {
131  op_id = malloc(len);
132  }
133  if (op_id != NULL) {
134  sprintf(op_id, "%s_%s_notify_%s_0", rsc_id, notify_type, op_type);
135  }
136  return op_id;
137 }
138 
139 char *
140 generate_transition_magic_v202(const char *transition_key, int op_status)
141 {
142  int len = 80;
143  char *fail_state = NULL;
144 
145  CRM_CHECK(transition_key != NULL, return NULL);
146 
147  len += strlen(transition_key);
148 
149  fail_state = malloc(len);
150  if (fail_state != NULL) {
151  snprintf(fail_state, len, "%d:%s", op_status, transition_key);
152  }
153  return fail_state;
154 }
155 
156 char *
157 generate_transition_magic(const char *transition_key, int op_status, int op_rc)
158 {
159  int len = 80;
160  char *fail_state = NULL;
161 
162  CRM_CHECK(transition_key != NULL, return NULL);
163 
164  len += strlen(transition_key);
165 
166  fail_state = malloc(len);
167  if (fail_state != NULL) {
168  snprintf(fail_state, len, "%d:%d;%s", op_status, op_rc, transition_key);
169  }
170  return fail_state;
171 }
172 
173 gboolean
174 decode_transition_magic(const char *magic, char **uuid, int *transition_id, int *action_id,
175  int *op_status, int *op_rc, int *target_rc)
176 {
177  int res = 0;
178  char *key = NULL;
179  gboolean result = TRUE;
180 
181  CRM_CHECK(magic != NULL, return FALSE);
182  CRM_CHECK(op_rc != NULL, return FALSE);
183  CRM_CHECK(op_status != NULL, return FALSE);
184 
185  key = calloc(1, strlen(magic) + 1);
186  res = sscanf(magic, "%d:%d;%s", op_status, op_rc, key);
187  if (res != 3) {
188  crm_warn("Only found %d items in: '%s'", res, magic);
189  free(key);
190  return FALSE;
191  }
192 
193  CRM_CHECK(decode_transition_key(key, uuid, transition_id, action_id, target_rc), result = FALSE);
194 
195  free(key);
196  return result;
197 }
198 
199 char *
200 generate_transition_key(int transition_id, int action_id, int target_rc, const char *node)
201 {
202  int len = 40;
203  char *fail_state = NULL;
204 
205  CRM_CHECK(node != NULL, return NULL);
206 
207  len += strlen(node);
208 
209  fail_state = malloc(len);
210  if (fail_state != NULL) {
211  snprintf(fail_state, len, "%d:%d:%d:%-*s", action_id, transition_id, target_rc, 36, node);
212  }
213  return fail_state;
214 }
215 
216 gboolean
217 decode_transition_key(const char *key, char **uuid, int *transition_id, int *action_id,
218  int *target_rc)
219 {
220  int res = 0;
221  gboolean done = FALSE;
222 
223  CRM_CHECK(uuid != NULL, return FALSE);
224  CRM_CHECK(target_rc != NULL, return FALSE);
225  CRM_CHECK(action_id != NULL, return FALSE);
226  CRM_CHECK(transition_id != NULL, return FALSE);
227 
228  *uuid = calloc(1, 37);
229  res = sscanf(key, "%d:%d:%d:%36s", action_id, transition_id, target_rc, *uuid);
230  switch (res) {
231  case 4:
232  /* Post Pacemaker 0.6 */
233  done = TRUE;
234  break;
235  case 3:
236  case 2:
237  /* this can be tricky - the UUID might start with an integer */
238 
239  /* Until Pacemaker 0.6 */
240  done = TRUE;
241  *target_rc = -1;
242  res = sscanf(key, "%d:%d:%36s", action_id, transition_id, *uuid);
243  if (res == 2) {
244  *action_id = -1;
245  res = sscanf(key, "%d:%36s", transition_id, *uuid);
246  CRM_CHECK(res == 2, done = FALSE);
247 
248  } else if (res != 3) {
249  CRM_CHECK(res == 3, done = FALSE);
250  }
251  break;
252 
253  case 1:
254  /* Prior to Heartbeat 2.0.8 */
255  done = TRUE;
256  *action_id = -1;
257  *target_rc = -1;
258  res = sscanf(key, "%d:%36s", transition_id, *uuid);
259  CRM_CHECK(res == 2, done = FALSE);
260  break;
261  default:
262  crm_crit("Unhandled sscanf result (%d) for %s", res, key);
263  }
264 
265  if (strlen(*uuid) != 36) {
266  crm_warn("Bad UUID (%s) in sscanf result (%d) for %s", *uuid, res, key);
267  }
268 
269  if (done == FALSE) {
270  crm_err("Cannot decode '%s' rc=%d", key, res);
271 
272  free(*uuid);
273  *uuid = NULL;
274  *target_rc = -1;
275  *action_id = -1;
276  *transition_id = -1;
277  }
278 
279  return done;
280 }
281 
282 void
283 filter_action_parameters(xmlNode * param_set, const char *version)
284 {
285  char *key = NULL;
286  char *timeout = NULL;
287  char *interval = NULL;
288 
289  const char *attr_filter[] = {
290  XML_ATTR_ID,
295  "pcmk_external_ip"
296  };
297 
298  gboolean do_delete = FALSE;
299  int lpc = 0;
300  static int meta_len = 0;
301 
302  if (meta_len == 0) {
303  meta_len = strlen(CRM_META);
304  }
305 
306  if (param_set == NULL) {
307  return;
308  }
309 
310  for (lpc = 0; lpc < DIMOF(attr_filter); lpc++) {
311  xml_remove_prop(param_set, attr_filter[lpc]);
312  }
313 
315  interval = crm_element_value_copy(param_set, key);
316  free(key);
317 
319  timeout = crm_element_value_copy(param_set, key);
320 
321  if (param_set) {
322  xmlAttrPtr xIter = param_set->properties;
323 
324  while (xIter) {
325  const char *prop_name = (const char *)xIter->name;
326 
327  xIter = xIter->next;
328  do_delete = FALSE;
329  if (strncasecmp(prop_name, CRM_META, meta_len) == 0) {
330  do_delete = TRUE;
331  }
332 
333  if (do_delete) {
334  xml_remove_prop(param_set, prop_name);
335  }
336  }
337  }
338 
339  if (crm_get_msec(interval) > 0 && compare_version(version, "1.0.8") > 0) {
340  /* Re-instate the operation's timeout value */
341  if (timeout != NULL) {
342  crm_xml_add(param_set, key, timeout);
343  }
344  }
345 
346  free(interval);
347  free(timeout);
348  free(key);
349 }
350 
351 #define FAKE_TE_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
352 static void
353 append_digest(lrmd_event_data_t * op, xmlNode * update, const char *version, const char *magic,
354  int level)
355 {
356  /* this will enable us to later determine that the
357  * resource's parameters have changed and we should force
358  * a restart
359  */
360  char *digest = NULL;
361  xmlNode *args_xml = NULL;
362 
363  if (op->params == NULL) {
364  return;
365  }
366 
367  args_xml = create_xml_node(NULL, XML_TAG_PARAMS);
368  g_hash_table_foreach(op->params, hash2field, args_xml);
369  filter_action_parameters(args_xml, version);
370  digest = calculate_operation_digest(args_xml, version);
371 
372 #if 0
373  if (level < get_crm_log_level()
374  && op->interval == 0 && crm_str_eq(op->op_type, CRMD_ACTION_START, TRUE)) {
375  char *digest_source = dump_xml_unformatted(args_xml);
376 
377  do_crm_log(level, "Calculated digest %s for %s (%s). Source: %s\n",
378  digest, ID(update), magic, digest_source);
379  free(digest_source);
380  }
381 #endif
382  crm_xml_add(update, XML_LRM_ATTR_OP_DIGEST, digest);
383 
384  free_xml(args_xml);
385  free(digest);
386 }
387 
388 int
390 {
391  int rc = 0;
392 
393  if (op && op->user_data) {
394  int dummy = 0;
395  char *uuid = NULL;
396 
397  decode_transition_key(op->user_data, &uuid, &dummy, &dummy, &rc);
398  free(uuid);
399  }
400  return rc;
401 }
402 
403 gboolean
404 did_rsc_op_fail(lrmd_event_data_t * op, int target_rc)
405 {
406  switch (op->op_status) {
408  case PCMK_LRM_OP_PENDING:
409  return FALSE;
410  break;
411 
413  case PCMK_LRM_OP_TIMEOUT:
414  case PCMK_LRM_OP_ERROR:
415  return TRUE;
416  break;
417 
418  default:
419  if (target_rc != op->rc) {
420  return TRUE;
421  }
422  }
423 
424  return FALSE;
425 }
426 
438 xmlNode *
439 crm_create_op_xml(xmlNode *parent, const char *prefix, const char *task,
440  const char *interval, const char *timeout)
441 {
442  xmlNode *xml_op;
443 
444  CRM_CHECK(prefix && task && interval, return NULL);
445 
446  xml_op = create_xml_node(parent, XML_ATTR_OP);
447  crm_xml_set_id(xml_op, "%s-%s-%s", prefix, task, interval);
448  crm_xml_add(xml_op, XML_LRM_ATTR_INTERVAL, interval);
449  crm_xml_add(xml_op, "name", task);
450  if (timeout) {
451  crm_xml_add(xml_op, XML_ATTR_TIMEOUT, timeout);
452  }
453  return xml_op;
454 }
455 
456 xmlNode *
457 create_operation_update(xmlNode * parent, lrmd_event_data_t * op, const char * caller_version,
458  int target_rc, const char * node, const char * origin, int level)
459 {
460  char *key = NULL;
461  char *magic = NULL;
462  char *op_id = NULL;
463  char *op_id_additional = NULL;
464  char *local_user_data = NULL;
465  const char *exit_reason = NULL;
466 
467  xmlNode *xml_op = NULL;
468  const char *task = NULL;
469  gboolean dc_munges_migrate_ops = (compare_version(caller_version, "3.0.3") < 0);
470  gboolean dc_needs_unique_ops = (compare_version(caller_version, "3.0.6") < 0);
471 
472  CRM_CHECK(op != NULL, return NULL);
473  do_crm_log(level, "%s: Updating resource %s after %s op %s (interval=%d)",
474  origin, op->rsc_id, op->op_type, services_lrm_status_str(op->op_status),
475  op->interval);
476 
477  crm_trace("DC version: %s", caller_version);
478 
479  task = op->op_type;
480  /* remap the task name under various scenarios
481  * this makes life easier for the PE when trying determine the current state
482  */
483  if (crm_str_eq(task, "reload", TRUE)) {
484  if (op->op_status == PCMK_LRM_OP_DONE) {
485  task = CRMD_ACTION_START;
486  } else {
487  task = CRMD_ACTION_STATUS;
488  }
489 
490  } else if (dc_munges_migrate_ops && crm_str_eq(task, CRMD_ACTION_MIGRATE, TRUE)) {
491  /* if the migrate_from fails it will have enough info to do the right thing */
492  if (op->op_status == PCMK_LRM_OP_DONE) {
493  task = CRMD_ACTION_STOP;
494  } else {
495  task = CRMD_ACTION_STATUS;
496  }
497 
498  } else if (dc_munges_migrate_ops
499  && op->op_status == PCMK_LRM_OP_DONE
500  && crm_str_eq(task, CRMD_ACTION_MIGRATED, TRUE)) {
501  task = CRMD_ACTION_START;
502  }
503 
504  key = generate_op_key(op->rsc_id, task, op->interval);
505  if (dc_needs_unique_ops && op->interval > 0) {
506  op_id = strdup(key);
507 
508  } else if (crm_str_eq(task, CRMD_ACTION_NOTIFY, TRUE)) {
509  const char *n_type = crm_meta_value(op->params, "notify_type");
510  const char *n_task = crm_meta_value(op->params, "notify_operation");
511 
512  CRM_LOG_ASSERT(n_type != NULL);
513  CRM_LOG_ASSERT(n_task != NULL);
514  op_id = generate_notify_key(op->rsc_id, n_type, n_task);
515 
516  /* these are not yet allowed to fail */
518  op->rc = 0;
519 
520  } else if (did_rsc_op_fail(op, target_rc)) {
521  op_id = generate_op_key(op->rsc_id, "last_failure", 0);
522  if (op->interval == 0) {
523  /* Ensure 'last' gets updated too in case recording-pending="true" */
524  op_id_additional = generate_op_key(op->rsc_id, "last", 0);
525  }
526  exit_reason = op->exit_reason;
527 
528  } else if (op->interval > 0) {
529  op_id = strdup(key);
530 
531  } else {
532  op_id = generate_op_key(op->rsc_id, "last", 0);
533  }
534 
535  again:
536  xml_op = find_entity(parent, XML_LRM_TAG_RSC_OP, op_id);
537  if (xml_op == NULL) {
538  xml_op = create_xml_node(parent, XML_LRM_TAG_RSC_OP);
539  }
540 
541  if (op->user_data == NULL) {
542  crm_debug("Generating fake transition key for:"
543  " %s_%s_%d %d from %s",
544  op->rsc_id, op->op_type, op->interval, op->call_id, origin);
545  local_user_data = generate_transition_key(-1, op->call_id, target_rc, FAKE_TE_ID);
546  op->user_data = local_user_data;
547  }
548 
549  if(magic == NULL) {
550  magic = generate_transition_magic(op->user_data, op->op_status, op->rc);
551  }
552 
553  crm_xml_add(xml_op, XML_ATTR_ID, op_id);
554  crm_xml_add(xml_op, XML_LRM_ATTR_TASK_KEY, key);
555  crm_xml_add(xml_op, XML_LRM_ATTR_TASK, task);
556  crm_xml_add(xml_op, XML_ATTR_ORIGIN, origin);
557  crm_xml_add(xml_op, XML_ATTR_CRM_VERSION, caller_version);
559  crm_xml_add(xml_op, XML_ATTR_TRANSITION_MAGIC, magic);
560  crm_xml_add(xml_op, XML_LRM_ATTR_EXIT_REASON, exit_reason == NULL ? "" : exit_reason);
561  crm_xml_add(xml_op, XML_LRM_ATTR_TARGET, node); /* For context during triage */
562 
564  crm_xml_add_int(xml_op, XML_LRM_ATTR_RC, op->rc);
567 
568  if (compare_version("2.1", caller_version) <= 0) {
569  if (op->t_run || op->t_rcchange || op->exec_time || op->queue_time) {
570  crm_trace("Timing data (%s_%s_%d): last=%u change=%u exec=%u queue=%u",
571  op->rsc_id, op->op_type, op->interval,
572  op->t_run, op->t_rcchange, op->exec_time, op->queue_time);
573 
574  if (op->interval == 0) {
575  /* The values are the same for non-recurring ops */
578 
579  } else if(op->t_rcchange) {
580  /* last-run is not accurate for recurring ops */
582 
583  } else {
584  /* ...but is better than nothing otherwise */
586  }
587 
590  }
591  }
592 
593  if (crm_str_eq(op->op_type, CRMD_ACTION_MIGRATE, TRUE)
594  || crm_str_eq(op->op_type, CRMD_ACTION_MIGRATED, TRUE)) {
595  /*
596  * Record migrate_source and migrate_target always for migrate ops.
597  */
598  const char *name = XML_LRM_ATTR_MIGRATE_SOURCE;
599 
600  crm_xml_add(xml_op, name, crm_meta_value(op->params, name));
601 
603  crm_xml_add(xml_op, name, crm_meta_value(op->params, name));
604  }
605 
606  append_digest(op, xml_op, caller_version, magic, LOG_DEBUG);
607 
608  if (op_id_additional) {
609  free(op_id);
610  op_id = op_id_additional;
611  op_id_additional = NULL;
612  goto again;
613  }
614 
615  if (local_user_data) {
616  free(local_user_data);
617  op->user_data = NULL;
618  }
619  free(magic);
620  free(op_id);
621  free(key);
622  return xml_op;
623 }
624 
634 bool
635 crm_op_needs_metadata(const char *rsc_class, const char *op)
636 {
637  /* Agent meta-data is used to determine whether a reload is possible, and to
638  * evaluate versioned parameters -- so if this op is not relevant to those
639  * features, we don't need the meta-data.
640  */
641 
642  CRM_CHECK(rsc_class || op, return FALSE);
643 
644  if (rsc_class
645  && strcmp(rsc_class, PCMK_RESOURCE_CLASS_OCF)
646  && strcmp(rsc_class, PCMK_RESOURCE_CLASS_STONITH)) {
647 
648  /* Meta-data is only needed for resource classes that use parameters */
649  return FALSE;
650  }
651 
652  /* Meta-data is only needed for these actions */
653  if (op
654  && strcmp(op, CRMD_ACTION_START)
655  && strcmp(op, CRMD_ACTION_STATUS)
656  && strcmp(op, CRMD_ACTION_PROMOTE)
657  && strcmp(op, CRMD_ACTION_DEMOTE)
658  && strcmp(op, CRMD_ACTION_RELOAD)
659  && strcmp(op, CRMD_ACTION_MIGRATE)
660  && strcmp(op, CRMD_ACTION_MIGRATED)
661  && strcmp(op, CRMD_ACTION_NOTIFY)) {
662  return FALSE;
663  }
664 
665  return TRUE;
666 }
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:164
#define XML_RSC_OP_LAST_CHANGE
Definition: msg_xml.h:304
char * generate_transition_magic(const char *transition_key, int op_status, int op_rc)
Definition: operations.c:157
A dumping ground.
#define CRMD_ACTION_MIGRATED
Definition: crm.h:173
#define crm_crit(fmt, args...)
Definition: logging.h:247
const char * user_data
Definition: lrmd.h:213
const char * rsc_id
Definition: lrmd.h:209
#define XML_ATTR_TRANSITION_MAGIC
Definition: msg_xml.h:384
int rsc_op_expected_rc(lrmd_event_data_t *event)
Definition: operations.c:389
unsigned int queue_time
Definition: lrmd.h:239
#define FAKE_TE_ID
Definition: operations.c:351
#define CRMD_ACTION_NOTIFY
Definition: crm.h:186
long long crm_get_msec(const char *input)
Definition: utils.c:598
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
Definition: xml.c:2268
#define XML_RSC_OP_T_EXEC
Definition: msg_xml.h:306
char * generate_transition_magic_v202(const char *transition_key, int op_status)
Definition: operations.c:140
const char * crm_meta_value(GHashTable *hash, const char *field)
Definition: utils.c:949
#define XML_LRM_ATTR_INTERVAL
Definition: msg_xml.h:283
#define XML_LRM_ATTR_OP_DIGEST
Definition: msg_xml.h:297
#define XML_ATTR_TIMEOUT
Definition: msg_xml.h:96
#define CRMD_ACTION_PROMOTE
Definition: crm.h:181
char * crm_element_value_copy(xmlNode *data, const char *name)
Definition: xml.c:3869
Local Resource Manager.
unsigned int t_rcchange
Definition: lrmd.h:235
bool crm_op_needs_metadata(const char *rsc_class, const char *op)
Check whether an operation requires resource agent meta-data.
Definition: operations.c:635
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:150
char * generate_notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
Definition: operations.c:118
enum ocf_exitcode rc
Definition: lrmd.h:227
void filter_action_parameters(xmlNode *param_set, const char *version)
Definition: operations.c:283
#define XML_RSC_OP_T_QUEUE
Definition: msg_xml.h:307
char * crm_meta_name(const char *field)
Definition: utils.c:927
char version[256]
Definition: plugin.c:84
gboolean decode_transition_key(const char *key, char **uuid, int *action, int *transition_id, int *target_rc)
Definition: operations.c:217
unsigned int exec_time
Definition: lrmd.h:237
#define XML_ATTR_ORIGIN
Definition: msg_xml.h:97
#define CRMD_ACTION_START
Definition: crm.h:175
#define XML_LRM_ATTR_TASK_KEY
Definition: msg_xml.h:285
#define XML_LRM_ATTR_TASK
Definition: msg_xml.h:284
void hash2field(gpointer key, gpointer value, gpointer user_data)
Definition: xml.c:4892
#define CRMD_ACTION_STOP
Definition: crm.h:178
void * params
Definition: lrmd.h:246
char * generate_transition_key(int action, int transition_id, int target_rc, const char *node)
Definition: operations.c:200
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
Definition: digest.c:175
#define crm_warn(fmt, args...)
Definition: logging.h:249
op_status
Definition: services.h:133
#define CRMD_ACTION_DEMOTE
Definition: crm.h:183
const char * exit_reason
Definition: lrmd.h:254
#define PCMK_RESOURCE_CLASS_OCF
Definition: services.h:57
#define XML_ATTR_OP
Definition: msg_xml.h:110
#define crm_debug(fmt, args...)
Definition: logging.h:253
Utility functions.
#define XML_ATTR_ID
Definition: msg_xml.h:102
#define crm_trace(fmt, args...)
Definition: logging.h:254
#define do_crm_log(level, fmt, args...)
Log a message.
Definition: logging.h:129
xmlNode * crm_create_op_xml(xmlNode *parent, const char *prefix, const char *task, const char *interval, const char *timeout)
Create a CIB XML element for an operation.
Definition: operations.c:439
Wrappers for and extensions to libxml2.
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:2588
#define XML_LRM_ATTR_MIGRATE_TARGET
Definition: msg_xml.h:310
#define XML_LRM_ATTR_EXIT_REASON
Definition: msg_xml.h:302
void free_xml(xmlNode *child)
Definition: xml.c:2706
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
Definition: strings.c:213
const char * op_type
Definition: lrmd.h:211
#define CRMD_ACTION_RELOAD
Definition: crm.h:171
#define XML_LRM_ATTR_TARGET_UUID
Definition: msg_xml.h:287
unsigned int t_run
Definition: lrmd.h:233
#define XML_ATTR_TRANSITION_KEY
Definition: msg_xml.h:385
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Definition: xml.c:2490
#define PCMK_RESOURCE_CLASS_STONITH
Definition: services.h:64
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Definition: xml.c:2578
unsigned int get_crm_log_level(void)
Definition: logging.c:942
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, int *interval)
Definition: operations.c:46
gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc)
Definition: operations.c:404
#define CRM_META
Definition: crm.h:53
#define crm_err(fmt, args...)
Definition: logging.h:248
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:3881
int compare_version(const char *version1, const char *version2)
Definition: utils.c:486
char * dump_xml_unformatted(xmlNode *msg)
Definition: xml.c:3825
#define DIMOF(a)
Definition: crm.h:39
#define XML_LRM_ATTR_CALLID
Definition: msg_xml.h:296
#define CRMD_ACTION_MIGRATE
Definition: crm.h:172
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:457
#define CRM_ASSERT(expr)
Definition: error.h:35
#define XML_LRM_ATTR_OPSTATUS
Definition: msg_xml.h:294
#define XML_ATTR_CRM_VERSION
Definition: msg_xml.h:84
gboolean decode_transition_magic(const char *magic, char **uuid, int *transition_id, int *action_id, int *op_status, int *op_rc, int *target_rc)
Definition: operations.c:174
#define XML_LRM_ATTR_RC
Definition: msg_xml.h:295
#define XML_LRM_ATTR_TARGET
Definition: msg_xml.h:286
#define XML_LRM_TAG_RSC_OP
Definition: msg_xml.h:252
#define XML_RSC_OP_LAST_RUN
Definition: msg_xml.h:305
#define ID(x)
Definition: msg_xml.h:446
char * generate_op_key(const char *rsc_id, const char *op_type, int interval)
Generate an operation key.
Definition: operations.c:37
#define safe_str_eq(a, b)
Definition: util.h:72
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
#define XML_LRM_ATTR_MIGRATE_SOURCE
Definition: msg_xml.h:309
#define XML_TAG_PARAMS
Definition: msg_xml.h:190
#define CRMD_ACTION_STATUS
Definition: crm.h:189