pacemaker  2.1.3-ea053b43a
Scalable High-Availability cluster resource manager
alerts.c
Go to the documentation of this file.
1 /*
2  * Copyright 2015-2022 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 #include <crm/crm.h>
12 #include <crm/lrmd.h>
13 #include <crm/msg_xml.h>
16 #include <crm/cib/internal.h> /* for F_CIB_UPDATE_RESULT */
17 
18 /*
19  * to allow script compatibility we can have more than one
20  * set of environment variables
21  */
23 {
25  "CRM_notify_recipient", "CRM_alert_recipient", NULL
26  },
28  "CRM_notify_node", "CRM_alert_node", NULL
29  },
31  "CRM_notify_nodeid", "CRM_alert_nodeid", NULL
32  },
34  "CRM_notify_rsc", "CRM_alert_rsc", NULL
35  },
37  "CRM_notify_task", "CRM_alert_task", NULL
38  },
40  "CRM_notify_interval", "CRM_alert_interval", NULL
41  },
43  "CRM_notify_desc", "CRM_alert_desc", NULL
44  },
46  "CRM_notify_status", "CRM_alert_status", NULL
47  },
49  "CRM_notify_target_rc", "CRM_alert_target_rc", NULL
50  },
51  [PCMK__alert_key_rc] = {
52  "CRM_notify_rc", "CRM_alert_rc", NULL
53  },
55  "CRM_notify_kind", "CRM_alert_kind", NULL
56  },
58  "CRM_notify_version", "CRM_alert_version", NULL
59  },
61  "CRM_notify_node_sequence", PCMK__ALERT_NODE_SEQUENCE, NULL
62  },
64  "CRM_notify_timestamp", "CRM_alert_timestamp", NULL
65  },
67  "CRM_notify_attribute_name", "CRM_alert_attribute_name", NULL
68  },
70  "CRM_notify_attribute_value", "CRM_alert_attribute_value", NULL
71  },
73  "CRM_notify_timestamp_epoch", "CRM_alert_timestamp_epoch", NULL
74  },
76  "CRM_notify_timestamp_usec", "CRM_alert_timestamp_usec", NULL
77  },
79  "CRM_notify_exec_time", "CRM_alert_exec_time", NULL
80  }
81 };
82 
95 pcmk__alert_new(const char *id, const char *path)
96 {
97  pcmk__alert_t *entry = calloc(1, sizeof(pcmk__alert_t));
98 
99  CRM_ASSERT(entry && id && path);
100  entry->id = strdup(id);
101  entry->path = strdup(path);
103  entry->flags = pcmk__alert_default;
104  return entry;
105 }
106 
107 void
109 {
110  if (entry) {
111  free(entry->id);
112  free(entry->path);
113  free(entry->tstamp_format);
114  free(entry->recipient);
115 
116  g_strfreev(entry->select_attribute_name);
117  if (entry->envvars) {
118  g_hash_table_destroy(entry->envvars);
119  }
120  free(entry);
121  }
122 }
123 
134 {
135  pcmk__alert_t *new_entry = pcmk__alert_new(entry->id, entry->path);
136 
137  new_entry->timeout = entry->timeout;
138  new_entry->flags = entry->flags;
139  new_entry->envvars = pcmk__str_table_dup(entry->envvars);
140  pcmk__str_update(&new_entry->tstamp_format, entry->tstamp_format);
141  pcmk__str_update(&new_entry->recipient, entry->recipient);
142  if (entry->select_attribute_name) {
143  new_entry->select_attribute_name = g_strdupv(entry->select_attribute_name);
144  }
145  return new_entry;
146 }
147 
148 void
150  const char *value)
151 {
152  for (const char **key = pcmk__alert_keys[name]; *key; key++) {
153  crm_trace("Inserting alert key %s = '%s'", *key, value);
154  if (value) {
155  g_hash_table_insert(table, strdup(*key), strdup(value));
156  } else {
157  g_hash_table_remove(table, *key);
158  }
159  }
160 }
161 
162 void
164  int value)
165 {
166  for (const char **key = pcmk__alert_keys[name]; *key; key++) {
167  crm_trace("Inserting alert key %s = %d", *key, value);
168  g_hash_table_insert(table, strdup(*key), pcmk__itoa(value));
169  }
170 }
171 
172 #define XPATH_PATCHSET1_DIFF "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED
173 
174 #define XPATH_PATCHSET1_CRMCONFIG XPATH_PATCHSET1_DIFF "//" XML_CIB_TAG_CRMCONFIG
175 #define XPATH_PATCHSET1_ALERTS XPATH_PATCHSET1_DIFF "//" XML_CIB_TAG_ALERTS
176 
177 #define XPATH_PATCHSET1_EITHER \
178  XPATH_PATCHSET1_CRMCONFIG " | " XPATH_PATCHSET1_ALERTS
179 
180 #define XPATH_CONFIG "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION
181 
182 #define XPATH_CRMCONFIG XPATH_CONFIG "/" XML_CIB_TAG_CRMCONFIG "/"
183 #define XPATH_ALERTS XPATH_CONFIG "/" XML_CIB_TAG_ALERTS
184 
194 bool
195 pcmk__alert_in_patchset(xmlNode *msg, bool config)
196 {
197  int rc = -1;
198  int format= 1;
199  xmlNode *patchset = get_message_xml(msg, F_CIB_UPDATE_RESULT);
200  xmlNode *change = NULL;
201  xmlXPathObject *xpathObj = NULL;
202 
203  CRM_CHECK(msg != NULL, return FALSE);
204 
205  crm_element_value_int(msg, F_CIB_RC, &rc);
206  if (rc < pcmk_ok) {
207  crm_trace("Ignore failed CIB update: %s (%d)", pcmk_strerror(rc), rc);
208  return FALSE;
209  }
210 
211  crm_element_value_int(patchset, "format", &format);
212  if (format == 1) {
213  const char *diff = (config? XPATH_PATCHSET1_EITHER : XPATH_PATCHSET1_ALERTS);
214 
215  if ((xpathObj = xpath_search(msg, diff)) != NULL) {
216  freeXpathObject(xpathObj);
217  return TRUE;
218  }
219  } else if (format == 2) {
220  for (change = pcmk__xml_first_child(patchset); change != NULL;
221  change = pcmk__xml_next(change)) {
222  const char *xpath = crm_element_value(change, XML_DIFF_PATH);
223 
224  if (xpath == NULL) {
225  continue;
226  }
227 
228  if ((!config || !strstr(xpath, XPATH_CRMCONFIG))
229  && !strstr(xpath, XPATH_ALERTS)) {
230 
231  /* this is not a change to an existing section ... */
232 
233  xmlNode *section = NULL;
234  const char *name = NULL;
235 
236  if ((strcmp(xpath, XPATH_CONFIG) != 0) ||
237  ((section = pcmk__xml_first_child(change)) == NULL) ||
238  ((name = crm_element_name(section)) == NULL) ||
239  (strcmp(name, XML_CIB_TAG_ALERTS) != 0)) {
240 
241  /* ... nor is it a newly added alerts section */
242  continue;
243  }
244  }
245 
246  return TRUE;
247  }
248 
249  } else {
250  crm_warn("Unknown patch format: %d", format);
251  }
252  return FALSE;
253 }
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:226
const char * pcmk__alert_keys[PCMK__ALERT_INTERNAL_KEY_MAX][3]
Definition: alerts.c:22
A dumping ground.
xmlNode * get_message_xml(xmlNode *msg, const char *field)
Definition: messages.c:154
const char * pcmk_strerror(int rc)
Definition: results.c:58
void pcmk__free_alert(pcmk__alert_t *entry)
Definition: alerts.c:108
#define XPATH_ALERTS
Definition: alerts.c:183
const char * name
Definition: cib.c:24
#define PCMK__ALERT_INTERNAL_KEY_MAX
char ** select_attribute_name
char * tstamp_format
Resource agent executor.
#define PCMK__ALERT_NODE_SEQUENCE
pcmk__alert_keys_e
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
Definition: nvpair.c:565
#define XPATH_CRMCONFIG
Definition: alerts.c:182
#define XPATH_PATCHSET1_EITHER
Definition: alerts.c:177
#define crm_warn(fmt, args...)
Definition: logging.h:359
#define XPATH_PATCHSET1_ALERTS
Definition: alerts.c:175
#define F_CIB_RC
Definition: internal.h:41
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:529
void pcmk__add_alert_key(GHashTable *table, enum pcmk__alert_keys_e name, const char *value)
Definition: alerts.c:149
#define XPATH_CONFIG
Definition: alerts.c:180
#define crm_trace(fmt, args...)
Definition: logging.h:364
#define F_CIB_UPDATE_RESULT
Definition: internal.h:52
void pcmk__str_update(char **str, const char *value)
Definition: strings.c:1188
void pcmk__add_alert_key_int(GHashTable *table, enum pcmk__alert_keys_e name, int value)
Definition: alerts.c:163
GHashTable * envvars
pcmk__alert_t * pcmk__dup_alert(pcmk__alert_t *entry)
Definition: alerts.c:133
#define XML_DIFF_PATH
Definition: msg_xml.h:457
const char * path
Definition: cib.c:26
#define CRM_ASSERT(expr)
Definition: results.h:42
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
Definition: xpath.c:139
GHashTable * pcmk__str_table_dup(GHashTable *old_table)
Definition: strings.c:675
#define pcmk_ok
Definition: results.h:68
bool pcmk__alert_in_patchset(xmlNode *msg, bool config)
Definition: alerts.c:195
#define XML_CIB_TAG_ALERTS
Definition: msg_xml.h:194
void freeXpathObject(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:39
pcmk__alert_t * pcmk__alert_new(const char *id, const char *path)
Create a new alert entry structure.
Definition: alerts.c:95
#define PCMK__ALERT_DEFAULT_TIMEOUT_MS