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