46 parse_op_key(
const char *key,
char **rsc_id,
char **op_type,
int *interval)
49 char *mutable_key = NULL;
50 char *mutable_key_ptr = NULL;
51 int len = 0, offset = 0, ch = 0;
52 int local_interval_ms = 0;
73 while (offset > 0 && isdigit(key[offset])) {
74 int digits = len - offset;
76 ch = key[offset] -
'0';
83 local_interval_ms += ch;
86 crm_trace(
"Operation key '%s' has interval %ums", key, local_interval_ms);
88 *interval = local_interval_ms;
91 CRM_CHECK((offset != (len - 1)) && (key[offset] ==
'_'),
return FALSE);
93 mutable_key =
strndup(key, offset);
96 while (offset > 0 && key[offset] !=
'_') {
101 free(mutable_key);
return FALSE);
103 mutable_key_ptr = mutable_key + offset + 1;
105 crm_trace(
" Action: %s", mutable_key_ptr);
107 *op_type = strdup(mutable_key_ptr);
110 mutable_key[offset] = 0;
113 notify = strstr(mutable_key,
"_post_notify");
114 if (notify &&
safe_str_eq(notify,
"_post_notify")) {
118 notify = strstr(mutable_key,
"_pre_notify");
119 if (notify &&
safe_str_eq(notify,
"_pre_notify")) {
125 *rsc_id = mutable_key;
141 CRM_CHECK(notify_type != NULL,
return NULL);
143 len += strlen(op_type);
144 len += strlen(rsc_id);
145 len += strlen(notify_type);
150 sprintf(op_id,
"%s_%s_notify_%s_0", rsc_id, notify_type, op_type);
159 char *fail_state = NULL;
161 CRM_CHECK(transition_key != NULL,
return NULL);
163 len += strlen(transition_key);
165 fail_state = malloc(len);
166 if (fail_state != NULL) {
167 snprintf(fail_state, len,
"%d:%s", op_status, transition_key);
176 char *fail_state = NULL;
178 CRM_CHECK(transition_key != NULL,
return NULL);
180 len += strlen(transition_key);
182 fail_state = malloc(len);
183 if (fail_state != NULL) {
184 snprintf(fail_state, len,
"%d:%d;%s", op_status, op_rc, transition_key);
191 int *
op_status,
int *op_rc,
int *target_rc)
195 gboolean result = TRUE;
199 CRM_CHECK(op_status != NULL,
return FALSE);
201 key = calloc(1, strlen(magic) + 1);
202 res = sscanf(magic,
"%d:%d;%s", op_status, op_rc, key);
204 crm_warn(
"Only found %d items in: '%s'", res, magic);
219 char *fail_state = NULL;
225 fail_state = malloc(len);
226 if (fail_state != NULL) {
227 snprintf(fail_state, len,
"%d:%d:%d:%-*s", action_id, transition_id, target_rc, 36, node);
237 gboolean done = FALSE;
240 CRM_CHECK(target_rc != NULL,
return FALSE);
241 CRM_CHECK(action_id != NULL,
return FALSE);
242 CRM_CHECK(transition_id != NULL,
return FALSE);
244 *uuid = calloc(1, 37);
245 res = sscanf(key,
"%d:%d:%d:%36s", action_id, transition_id, target_rc, *uuid);
258 res = sscanf(key,
"%d:%d:%36s", action_id, transition_id, *uuid);
261 res = sscanf(key,
"%d:%36s", transition_id, *uuid);
264 }
else if (res != 3) {
274 res = sscanf(key,
"%d:%36s", transition_id, *uuid);
278 crm_crit(
"Unhandled sscanf result (%d) for %s", res, key);
281 if (strlen(*uuid) != 36) {
282 crm_warn(
"Bad UUID (%s) in sscanf result (%d) for %s", *uuid, res, key);
286 crm_err(
"Cannot decode '%s' rc=%d", key, res);
302 char *timeout = NULL;
303 char *interval = NULL;
305 const char *attr_filter[] = {
314 gboolean do_delete = FALSE;
316 static int meta_len = 0;
322 if (param_set == NULL) {
326 for (lpc = 0; lpc <
DIMOF(attr_filter); lpc++) {
338 xmlAttrPtr xIter = param_set->properties;
341 const char *prop_name = (
const char *)xIter->name;
345 if (strncasecmp(prop_name,
CRM_META, meta_len) == 0) {
357 if (timeout != NULL) {
367 #define FAKE_TE_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 377 xmlNode *args_xml = NULL;
393 do_crm_log(level,
"Calculated digest %s for %s (%s). Source: %s\n",
394 digest,
ID(update), magic, digest_source);
435 if (target_rc != op->
rc) {
456 const char *interval,
const char *timeout)
460 CRM_CHECK(prefix && task && interval,
return NULL);
474 int target_rc,
const char * node,
const char * origin,
int level)
479 char *op_id_additional = NULL;
480 char *local_user_data = NULL;
481 const char *exit_reason = NULL;
483 xmlNode *xml_op = NULL;
484 const char *task = NULL;
485 gboolean dc_munges_migrate_ops = (
compare_version(caller_version,
"3.0.3") < 0);
486 gboolean dc_needs_unique_ops = (
compare_version(caller_version,
"3.0.6") < 0);
489 do_crm_log(level,
"%s: Updating resource %s after %s op %s (interval=%d)",
493 crm_trace(
"DC version: %s", caller_version);
514 }
else if (dc_munges_migrate_ops
521 if (dc_needs_unique_ops && op->
interval > 0) {
559 if (xml_op == NULL) {
564 crm_debug(
"Generating fake transition key for:" 565 " %s_%s_%d %d from %s",
592 crm_trace(
"Timing data (%s_%s_%d): last=%u change=%u exec=%u queue=%u",
628 append_digest(op, xml_op, caller_version, magic, LOG_DEBUG);
630 if (op_id_additional) {
632 op_id = op_id_additional;
633 op_id_additional = NULL;
637 if (local_user_data) {
638 free(local_user_data);
664 CRM_CHECK(rsc_class || op,
return FALSE);
#define CRM_CHECK(expr, failure_action)
#define XML_RSC_OP_LAST_CHANGE
char * generate_transition_magic_v202(const char *transition_key, int op_status)
#define CRMD_ACTION_MIGRATED
#define crm_crit(fmt, args...)
void hash2field(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry.
#define XML_ATTR_TRANSITION_MAGIC
gboolean did_rsc_op_fail(lrmd_event_data_t *op, int target_rc)
char * generate_transition_magic(const char *transition_key, int op_status, int op_rc)
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
#define CRMD_ACTION_NOTIFY
long long crm_get_msec(const char *input)
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
#define XML_RSC_OP_T_EXEC
const char * crm_meta_value(GHashTable *hash, const char *field)
#define XML_LRM_ATTR_INTERVAL
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define XML_LRM_ATTR_OP_DIGEST
#define CRMD_ACTION_PROMOTE
#define CRM_LOG_ASSERT(expr)
gboolean decode_transition_magic(const char *magic, char **uuid, int *transition_id, int *action_id, int *op_status, int *op_rc, int *target_rc)
#define XML_RSC_OP_T_QUEUE
char * strndup(const char *str, size_t len)
char * crm_meta_name(const char *field)
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.
#define CRMD_ACTION_START
#define XML_LRM_ATTR_TASK_KEY
#define XML_LRM_ATTR_TASK
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
#define crm_warn(fmt, args...)
char * generate_notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
#define CRMD_ACTION_DEMOTE
#define crm_debug(fmt, args...)
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
void filter_action_parameters(xmlNode *param_set, const char *version)
#define crm_trace(fmt, args...)
#define do_crm_log(level, fmt, args...)
Log a message.
Wrappers for and extensions to libxml2.
xmlNode * create_xml_node(xmlNode *parent, const char *name)
uint32_t pcmk_get_ra_caps(const char *standard)
Get capabilities of a resource agent standard.
#define XML_LRM_ATTR_MIGRATE_TARGET
#define XML_LRM_ATTR_EXIT_REASON
void free_xml(xmlNode *child)
gboolean decode_transition_key(const char *key, char **uuid, int *transition_id, int *action_id, int *target_rc)
bool crm_op_needs_metadata(const char *rsc_class, const char *op)
Check whether an operation requires resource agent meta-data.
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
char * generate_transition_key(int transition_id, int action_id, int target_rc, const char *node)
#define CRMD_ACTION_RELOAD
#define XML_LRM_ATTR_TARGET_UUID
int rsc_op_expected_rc(lrmd_event_data_t *op)
#define XML_ATTR_TRANSITION_KEY
unsigned int get_crm_log_level(void)
#define crm_err(fmt, args...)
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, int *interval)
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)
void crm_xml_set_id(xmlNode *xml, const char *format,...) __attribute__((__format__(__printf__
void xml_remove_prop(xmlNode *obj, const char *name)
int compare_version(const char *version1, const char *version2)
char * dump_xml_unformatted(xmlNode *msg)
#define XML_LRM_ATTR_CALLID
#define CRMD_ACTION_MIGRATE
#define XML_LRM_ATTR_OPSTATUS
#define XML_ATTR_CRM_VERSION
#define XML_LRM_ATTR_TARGET
#define XML_LRM_TAG_RSC_OP
#define XML_RSC_OP_LAST_RUN
#define safe_str_eq(a, b)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
char * generate_op_key(const char *rsc_id, const char *op_type, int interval)
Generate an operation key.
#define XML_LRM_ATTR_MIGRATE_SOURCE
#define CRMD_ACTION_STATUS