20 #include <sys/types.h> 29 static regex_t *notify_migrate_re = NULL;
44 pcmk__op_key(
const char *rsc_id,
const char *op_type, guint interval_ms)
51 static inline gboolean
52 convert_interval(
const char *s, guint *interval_ms)
57 l = strtoul(s, NULL, 10);
63 *interval_ms = (guint) l;
68 try_fast_match(
const char *key,
const char *underbar1,
const char *underbar2,
69 char **rsc_id,
char **op_type, guint *interval_ms)
72 if (!convert_interval(underbar2+1, interval_ms)) {
78 *rsc_id =
strndup(key, underbar1-key);
82 *op_type =
strndup(underbar1+1, underbar2-underbar1-1);
89 try_basic_match(
const char *key,
char **rsc_id,
char **op_type, guint *interval_ms)
91 char *interval_sep = NULL;
92 char *type_sep = NULL;
95 interval_sep = strrchr(key,
'_');
96 if (interval_sep == NULL) {
101 if (!convert_interval(interval_sep+1, interval_ms)) {
106 type_sep = interval_sep-1;
109 if (*type_sep ==
'_') {
111 }
else if (type_sep == key) {
125 *op_type =
strndup(type_sep+1, interval_sep-type_sep-1);
130 *rsc_id =
strndup(key, type_sep-key);
137 try_migrate_notify_match(
const char *key,
char **rsc_id,
char **op_type, guint *interval_ms)
141 regmatch_t pmatch[nmatch];
143 if (notify_migrate_re == NULL) {
145 notify_migrate_re = calloc(1,
sizeof(regex_t));
146 rc = regcomp(notify_migrate_re,
"^(.*)_(migrate_(from|to)|(pre|post)_notify_([a-z]+|migrate_(from|to)))_([0-9]+)$",
151 rc = regexec(notify_migrate_re, key, nmatch, pmatch, 0);
152 if (
rc == REG_NOMATCH) {
157 *rsc_id =
strndup(key+pmatch[1].rm_so, pmatch[1].rm_eo-pmatch[1].rm_so);
161 *op_type =
strndup(key+pmatch[2].rm_so, pmatch[2].rm_eo-pmatch[2].rm_so);
165 if (!convert_interval(key+pmatch[7].rm_so, interval_ms)) {
184 parse_op_key(
const char *key,
char **rsc_id,
char **op_type, guint *interval_ms)
186 char *underbar1 = NULL;
187 char *underbar2 = NULL;
188 char *underbar3 = NULL;
205 underbar1 = strchr(key,
'_');
210 underbar2 = strchr(underbar1+1,
'_');
215 underbar3 = strchr(underbar2+1,
'_');
218 return try_fast_match(key, underbar1, underbar2,
219 rsc_id, op_type, interval_ms);
220 }
else if (try_migrate_notify_match(key, rsc_id, op_type, interval_ms)) {
223 return try_basic_match(key, rsc_id, op_type, interval_ms);
233 CRM_CHECK(notify_type != NULL,
return NULL);
235 rsc_id, notify_type, op_type);
255 int *
op_status,
int *op_rc,
int *target_rc)
259 gboolean result = TRUE;
260 int local_op_status = -1;
261 int local_op_rc = -1;
266 res = sscanf(magic,
"%d:%d;%ms", &local_op_status, &local_op_rc, &key);
268 key = calloc(1, strlen(magic) - 3);
270 res = sscanf(magic,
"%d:%d;%s", &local_op_status, &local_op_rc, key);
273 crm_err(
"Could not decode transition information '%s': %s",
276 }
else if (res < 3) {
277 crm_warn(
"Transition information '%s' incomplete (%d of 3 expected items)",
285 *op_rc = local_op_rc;
300 action_id, transition_id, target_rc, 36, node);
320 int local_transition_id = -1;
321 int local_action_id = -1;
322 int local_target_rc = -1;
323 char local_uuid[37] = {
'\0' };
340 if (sscanf(key,
"%d:%d:%d:%36s", &local_action_id, &local_transition_id,
341 &local_target_rc, local_uuid) != 4) {
342 crm_err(
"Invalid transition key '%s'", key);
345 if (strlen(local_uuid) != 36) {
346 crm_warn(
"Invalid UUID '%s' in transition key '%s'", local_uuid, key);
349 *uuid = strdup(local_uuid);
353 *transition_id = local_transition_id;
356 *action_id = local_action_id;
359 *target_rc = local_target_rc;
375 guint interval_ms = 0;
377 const char *attr_filter[] = {
386 const int meta_len = strlen(
CRM_META);
388 if (param_set == NULL) {
393 for (
int lpc = 0; lpc <
DIMOF(attr_filter); lpc++) {
407 for (xmlAttrPtr xIter = param_set->properties; xIter != NULL; ) {
408 const char *prop_name = (
const char *) (xIter->name);
413 if (strncasecmp(prop_name,
CRM_META, meta_len) == 0) {
418 if ((interval_ms != 0) && (
timeout != NULL)) {
454 if (target_rc != op->
rc) {
475 const char *interval_spec,
const char *
timeout)
479 CRM_CHECK(prefix && task && interval_spec,
return NULL);
508 CRM_CHECK((rsc_class != NULL) || (op != NULL),
return false);
510 if ((rsc_class != NULL)
#define CRM_CHECK(expr, failure_action)
#define CRMD_ACTION_MIGRATED
const char * pcmk_strerror(int rc)
gboolean did_rsc_op_fail(lrmd_event_data_t *op, int target_rc)
#define CRMD_ACTION_NOTIFY
#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
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.
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.
char * strndup(const char *str, size_t len)
char * crm_meta_name(const char *field)
char * pcmk__transition_key(int transition_id, int action_id, int target_rc, const char *node)
#define CRMD_ACTION_START
#define crm_warn(fmt, args...)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
#define CRMD_ACTION_DEMOTE
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Retrieve the millisecond value of an XML attribute.
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Wrappers for and extensions to libxml2.
xmlNode * create_xml_node(xmlNode *parent, const char *name)
void pcmk__filter_op_for_digest(xmlNode *param_set)
uint32_t pcmk_get_ra_caps(const char *standard)
Get capabilities of a resource agent standard.
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
gboolean decode_transition_key(const char *key, char **uuid, int *transition_id, int *action_id, int *target_rc)
Parse a transition key into its constituent parts.
bool crm_op_needs_metadata(const char *rsc_class, const char *op)
Check whether an operation requires resource agent meta-data.
#define CRMD_ACTION_RELOAD
#define XML_LRM_ATTR_TARGET_UUID
int rsc_op_expected_rc(lrmd_event_data_t *op)
#define crm_err(fmt, args...)
void crm_xml_set_id(xmlNode *xml, const char *format,...) __attribute__((__format__(__printf__
void xml_remove_prop(xmlNode *obj, const char *name)
#define XML_LRM_ATTR_INTERVAL_MS
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
#define CRMD_ACTION_MIGRATE
#define XML_ATTR_CRM_VERSION
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
#define XML_LRM_ATTR_TARGET
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
#define CRMD_ACTION_STATUS