pacemaker  2.0.1-57cc9c14bf
Scalable High-Availability cluster resource manager
alerts.c
Go to the documentation of this file.
1 /*
2  * Copyright 2015-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 #include <crm/crm.h>
10 #include <crm/lrmd.h>
11 #include <crm/msg_xml.h>
13 #include <crm/cib/internal.h> /* for F_CIB_UPDATE_RESULT */
14 
15 /*
16  * to allow script compatibility we can have more than one
17  * set of environment variables
18  */
20 {
21  [CRM_alert_recipient] = {"CRM_notify_recipient", "CRM_alert_recipient", NULL},
22  [CRM_alert_node] = {"CRM_notify_node", "CRM_alert_node", NULL},
23  [CRM_alert_nodeid] = {"CRM_notify_nodeid", "CRM_alert_nodeid", NULL},
24  [CRM_alert_rsc] = {"CRM_notify_rsc", "CRM_alert_rsc", NULL},
25  [CRM_alert_task] = {"CRM_notify_task", "CRM_alert_task", NULL},
26  [CRM_alert_interval] = {"CRM_notify_interval", "CRM_alert_interval", NULL},
27  [CRM_alert_desc] = {"CRM_notify_desc", "CRM_alert_desc", NULL},
28  [CRM_alert_status] = {"CRM_notify_status", "CRM_alert_status", NULL},
29  [CRM_alert_target_rc] = {"CRM_notify_target_rc", "CRM_alert_target_rc", NULL},
30  [CRM_alert_rc] = {"CRM_notify_rc", "CRM_alert_rc", NULL},
31  [CRM_alert_kind] = {"CRM_notify_kind", "CRM_alert_kind", NULL},
32  [CRM_alert_version] = {"CRM_notify_version", "CRM_alert_version", NULL},
33  [CRM_alert_node_sequence] = {"CRM_notify_node_sequence", CRM_ALERT_NODE_SEQUENCE, NULL},
34  [CRM_alert_timestamp] = {"CRM_notify_timestamp", "CRM_alert_timestamp", NULL},
35  [CRM_alert_attribute_name] = {"CRM_notify_attribute_name", "CRM_alert_attribute_name", NULL},
36  [CRM_alert_attribute_value] = {"CRM_notify_attribute_value", "CRM_alert_attribute_value", NULL},
37  [CRM_alert_timestamp_epoch] = {"CRM_notify_timestamp_epoch", "CRM_alert_timestamp_epoch", NULL},
38  [CRM_alert_timestamp_usec] = {"CRM_notify_timestamp_usec", "CRM_alert_timestamp_usec", NULL},
39  [CRM_alert_exec_time] = {"CRM_notify_exec_time", "CRM_alert_exec_time", NULL}
40 };
41 
42 void
44 {
45  free(entry->name);
46  free(entry->value);
47  free(entry);
48 }
49 
62 crm_alert_entry_new(const char *id, const char *path)
63 {
64  crm_alert_entry_t *entry = calloc(1, sizeof(crm_alert_entry_t));
65 
66  CRM_ASSERT(entry && id && path);
67  entry->id = strdup(id);
68  entry->path = strdup(path);
70  entry->flags = crm_alert_default;
71  return entry;
72 }
73 
74 void
76 {
77  if (entry) {
78  free(entry->id);
79  free(entry->path);
80  free(entry->tstamp_format);
81  free(entry->recipient);
82 
83  g_strfreev(entry->select_attribute_name);
84  if (entry->envvars) {
85  g_hash_table_destroy(entry->envvars);
86  }
87  free(entry);
88  }
89 }
90 
93 {
94  crm_alert_envvar_t *dst = calloc(1, sizeof(crm_alert_envvar_t));
95 
96  CRM_ASSERT(dst);
97  dst->name = strdup(src->name);
98  dst->value = src->value?strdup(src->value):NULL;
99  return dst;
100 }
101 
112 {
113  crm_alert_entry_t *new_entry = crm_alert_entry_new(entry->id, entry->path);
114 
115  new_entry->timeout = entry->timeout;
116  new_entry->flags = entry->flags;
117  new_entry->envvars = crm_str_table_dup(entry->envvars);
118  if (entry->tstamp_format) {
119  new_entry->tstamp_format = strdup(entry->tstamp_format);
120  }
121  if (entry->recipient) {
122  new_entry->recipient = strdup(entry->recipient);
123  }
124  if (entry->select_attribute_name) {
125  new_entry->select_attribute_name = g_strdupv(entry->select_attribute_name);
126  }
127  return new_entry;
128 }
129 
130 void
132 {
133  const char **key;
134  enum crm_alert_keys_e name;
135 
136  for(name = 0; name < DIMOF(crm_alert_keys); name++) {
137  for(key = crm_alert_keys[name]; *key; key++) {
138  crm_trace("Unsetting alert key %s", *key);
139  unsetenv(*key);
140  }
141  }
142 }
143 
144 void
145 crm_insert_alert_key(GHashTable *table, enum crm_alert_keys_e name,
146  const char *value)
147 {
148  for (const char **key = crm_alert_keys[name]; *key; key++) {
149  crm_trace("Inserting alert key %s = '%s'", *key, value);
150  if (value) {
151  g_hash_table_insert(table, strdup(*key), strdup(value));
152  } else {
153  g_hash_table_remove(table, *key);
154  }
155  }
156 }
157 
158 void
159 crm_insert_alert_key_int(GHashTable *table, enum crm_alert_keys_e name,
160  int value)
161 {
162  for (const char **key = crm_alert_keys[name]; *key; key++) {
163  crm_trace("Inserting alert key %s = %d", *key, value);
164  g_hash_table_insert(table, strdup(*key), crm_itoa(value));
165  }
166 }
167 
168 static void
169 set_envvar(gpointer key, gpointer value, gpointer user_data)
170 {
171  gboolean always_unset = GPOINTER_TO_INT(user_data);
172 
173  crm_trace("%s environment variable %s='%s'",
174  (value? "Setting" : "Unsetting"),
175  (char*)key, (value? (char*)value : ""));
176  if (value && !always_unset) {
177  setenv(key, value, 1);
178  } else {
179  unsetenv(key);
180  }
181 }
182 
183 void
185 {
186  if (entry->envvars) {
187  g_hash_table_foreach(entry->envvars, set_envvar, GINT_TO_POINTER(FALSE));
188  }
189 }
190 
191 /*
192  * \note We have no way of restoring a previous value if one was set.
193  */
194 void
196 {
197  if (entry->envvars) {
198  g_hash_table_foreach(entry->envvars, set_envvar, GINT_TO_POINTER(TRUE));
199  }
200 }
201 
202 #define XPATH_PATCHSET1_DIFF "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED
203 
204 #define XPATH_PATCHSET1_CRMCONFIG XPATH_PATCHSET1_DIFF "//" XML_CIB_TAG_CRMCONFIG
205 #define XPATH_PATCHSET1_ALERTS XPATH_PATCHSET1_DIFF "//" XML_CIB_TAG_ALERTS
206 
207 #define XPATH_PATCHSET1_EITHER \
208  XPATH_PATCHSET1_CRMCONFIG " | " XPATH_PATCHSET1_ALERTS
209 
210 #define XPATH_CONFIG "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION
211 
212 #define XPATH_CRMCONFIG XPATH_CONFIG "/" XML_CIB_TAG_CRMCONFIG "/"
213 #define XPATH_ALERTS XPATH_CONFIG "/" XML_CIB_TAG_ALERTS
214 
224 bool
225 crm_patchset_contains_alert(xmlNode *msg, bool config)
226 {
227  int rc = -1;
228  int format= 1;
229  xmlNode *patchset = get_message_xml(msg, F_CIB_UPDATE_RESULT);
230  xmlNode *change = NULL;
231  xmlXPathObject *xpathObj = NULL;
232 
233  CRM_CHECK(msg != NULL, return FALSE);
234 
235  crm_element_value_int(msg, F_CIB_RC, &rc);
236  if (rc < pcmk_ok) {
237  crm_trace("Ignore failed CIB update: %s (%d)", pcmk_strerror(rc), rc);
238  return FALSE;
239  }
240 
241  crm_element_value_int(patchset, "format", &format);
242  if (format == 1) {
243  const char *diff = (config? XPATH_PATCHSET1_EITHER : XPATH_PATCHSET1_ALERTS);
244 
245  if ((xpathObj = xpath_search(msg, diff)) != NULL) {
246  freeXpathObject(xpathObj);
247  return TRUE;
248  }
249  } else if (format == 2) {
250  for (change = __xml_first_child(patchset); change != NULL; change = __xml_next(change)) {
251  const char *xpath = crm_element_value(change, XML_DIFF_PATH);
252 
253  if (xpath == NULL) {
254  continue;
255  }
256 
257  if ((!config || !strstr(xpath, XPATH_CRMCONFIG))
258  && !strstr(xpath, XPATH_ALERTS)) {
259 
260  /* this is not a change to an existing section ... */
261 
262  xmlNode *section = NULL;
263  const char *name = NULL;
264 
265  if ((strcmp(xpath, XPATH_CONFIG) != 0) ||
266  ((section = __xml_first_child(change)) == NULL) ||
267  ((name = crm_element_name(section)) == NULL) ||
268  (strcmp(name, XML_CIB_TAG_ALERTS) != 0)) {
269 
270  /* ... nor is it a newly added alerts section */
271  continue;
272  }
273  }
274 
275  return TRUE;
276  }
277 
278  } else {
279  crm_warn("Unknown patch format: %d", format);
280  }
281  return FALSE;
282 }
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:165
void crm_unset_envvar_list(crm_alert_entry_t *entry)
Definition: alerts.c:195
A dumping ground.
xmlNode * get_message_xml(xmlNode *msg, const char *field)
Definition: xml.c:2629
const char * pcmk_strerror(int rc)
Definition: results.c:184
crm_alert_entry_t * crm_alert_entry_new(const char *id, const char *path)
Create a new alert entry structure.
Definition: alerts.c:62
#define XPATH_ALERTS
Definition: alerts.c:213
#define CRM_ALERT_DEFAULT_TIMEOUT_MS
GHashTable * envvars
void crm_insert_alert_key_int(GHashTable *table, enum crm_alert_keys_e name, int value)
Definition: alerts.c:159
char * recipient
Resource agent executor.
#define XPATH_CRMCONFIG
Definition: alerts.c:212
crm_alert_envvar_t * crm_dup_alert_envvar(crm_alert_envvar_t *src)
Definition: alerts.c:92
uint32_t flags
char * tstamp_format
#define XPATH_PATCHSET1_EITHER
Definition: alerts.c:207
#define crm_warn(fmt, args...)
Definition: logging.h:250
char * id
#define XPATH_PATCHSET1_ALERTS
Definition: alerts.c:205
void crm_unset_alert_keys()
Definition: alerts.c:131
#define F_CIB_RC
Definition: internal.h:38
#define XPATH_CONFIG
Definition: alerts.c:210
#define crm_trace(fmt, args...)
Definition: logging.h:255
int setenv(const char *name, const char *value, int why)
const char * crm_alert_keys[CRM_ALERT_INTERNAL_KEY_MAX][3]
Definition: alerts.c:19
#define CRM_ALERT_NODE_SEQUENCE
#define F_CIB_UPDATE_RESULT
Definition: internal.h:49
crm_alert_entry_t * crm_dup_alert_entry(crm_alert_entry_t *entry)
Definition: alerts.c:111
const char * crm_element_value(const xmlNode *data, const char *name)
Definition: xml.c:4641
#define XML_DIFF_PATH
Definition: msg_xml.h:407
void crm_insert_alert_key(GHashTable *table, enum crm_alert_keys_e name, const char *value)
Definition: alerts.c:145
bool crm_patchset_contains_alert(xmlNode *msg, bool config)
Definition: alerts.c:225
#define CRM_ASSERT(expr)
Definition: results.h:20
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
Definition: xpath.c:145
GHashTable * crm_str_table_dup(GHashTable *old_table)
Definition: strings.c:380
char ** select_attribute_name
int timeout
#define DIMOF(a)
Definition: crm.h:33
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Definition: xml.c:3310
crm_alert_keys_e
char * path
#define pcmk_ok
Definition: results.h:35
void crm_free_alert_envvar(crm_alert_envvar_t *entry)
Definition: alerts.c:43
#define XML_CIB_TAG_ALERTS
Definition: msg_xml.h:146
void crm_set_envvar_list(crm_alert_entry_t *entry)
Definition: alerts.c:184
void freeXpathObject(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:45
void crm_free_alert_entry(crm_alert_entry_t *entry)
Definition: alerts.c:75
#define CRM_ALERT_INTERNAL_KEY_MAX