pacemaker  1.1.17-b36b869ca8
Scalable High-Availability cluster resource manager
alerts.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This software is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <crm_internal.h>
20 #include <crm/crm.h>
21 #include <crm/msg_xml.h>
23 
24 typedef struct {
25  char *name;
26  char *value;
27 } envvar_t;
28 
31 
32 /*
33  * to allow script compatibility we can have more than one
34  * set of environment variables
35  */
36 const char *crm_alert_keys[14][3] =
37 {
38  [CRM_alert_recipient] = {"CRM_notify_recipient", "CRM_alert_recipient", NULL},
39  [CRM_alert_node] = {"CRM_notify_node", "CRM_alert_node", NULL},
40  [CRM_alert_nodeid] = {"CRM_notify_nodeid", "CRM_alert_nodeid", NULL},
41  [CRM_alert_rsc] = {"CRM_notify_rsc", "CRM_alert_rsc", NULL},
42  [CRM_alert_task] = {"CRM_notify_task", "CRM_alert_task", NULL},
43  [CRM_alert_interval] = {"CRM_notify_interval", "CRM_alert_interval", NULL},
44  [CRM_alert_desc] = {"CRM_notify_desc", "CRM_alert_desc", NULL},
45  [CRM_alert_status] = {"CRM_notify_status", "CRM_alert_status", NULL},
46  [CRM_alert_target_rc] = {"CRM_notify_target_rc", "CRM_alert_target_rc", NULL},
47  [CRM_alert_rc] = {"CRM_notify_rc", "CRM_alert_rc", NULL},
48  [CRM_alert_kind] = {"CRM_notify_kind", "CRM_alert_kind", NULL},
49  [CRM_alert_version] = {"CRM_notify_version", "CRM_alert_version", NULL},
50  [CRM_alert_node_sequence] = {"CRM_notify_node_sequence", "CRM_alert_node_sequence", NULL},
51  [CRM_alert_timestamp] = {"CRM_notify_timestamp", "CRM_alert_timestamp", NULL}
52 };
53 
54 static void
55 free_envvar_entry(envvar_t *entry)
56 {
57  free(entry->name);
58  free(entry->value);
59  free(entry);
60 }
61 
62 static void
63 crm_free_alert_list_entry(crm_alert_entry_t *entry)
64 {
65  free(entry->id);
66  free(entry->path);
67  free(entry->tstamp_format);
68  free(entry->recipient);
69  if (entry->envvars) {
70  g_list_free_full(entry->envvars,
71  (GDestroyNotify) free_envvar_entry);
72  }
73  free(entry);
74 }
75 
76 void
78 {
79  if (crm_alert_list) {
80  g_list_free_full(crm_alert_list, (GDestroyNotify) crm_free_alert_list_entry);
81  crm_alert_list = NULL;
82  }
83 }
84 
85 static gpointer
86 copy_envvar_entry(envvar_t * src,
87  gpointer data)
88 {
89  envvar_t *dst = calloc(1, sizeof(envvar_t));
90 
91  CRM_ASSERT(dst);
92  dst->name = strdup(src->name);
93  dst->value = src->value?strdup(src->value):NULL;
94  return (gpointer) dst;
95 }
96 
97 static GListPtr
98 add_dup_envvar(crm_alert_entry_t *entrys,
99  envvar_t *entry)
100 {
101  entrys->envvars = g_list_prepend(entrys->envvars, copy_envvar_entry(entry, NULL));
102  return entrys->envvars;
103 }
104 
105 GListPtr
107 {
108  int i;
109 
110  for (i = 0;
111  (entry->envvars) && ((count < 0) || (i < count));
112  i++) {
113  free_envvar_entry((envvar_t *) g_list_first(entry->envvars)->data);
114  entry->envvars = g_list_delete_link(entry->envvars,
115  g_list_first(entry->envvars));
116  }
117  return entry->envvars;
118 }
119 
120 static GListPtr
121 copy_envvar_list_remove_dupes(crm_alert_entry_t *entry)
122 {
123  GListPtr dst = NULL, ls, ld;
124 
125  /* we are adding to the front so variable dupes coming via
126  * recipient-section have got precedence over those in the
127  * global section - we don't expect that many variables here
128  * that it pays off to go for a hash-table to make dupe elimination
129  * more efficient - maybe later when we might decide to do more
130  * with the variables than cycling through them
131  */
132 
133  for (ls = g_list_first(entry->envvars); ls; ls = g_list_next(ls)) {
134  for (ld = g_list_first(dst); ld; ld = g_list_next(ld)) {
135  if (!strcmp(((envvar_t *)(ls->data))->name,
136  ((envvar_t *)(ld->data))->name)) {
137  break;
138  }
139  }
140  if (!ld) {
141  dst = g_list_prepend(dst,
142  copy_envvar_entry((envvar_t *)(ls->data), NULL));
143  }
144  }
145 
146  return dst;
147 }
148 
149 void
151 {
152  crm_alert_entry_t *new_entry =
153  (crm_alert_entry_t *) calloc(1, sizeof(crm_alert_entry_t));
154 
155  CRM_ASSERT(new_entry);
156  *new_entry = (crm_alert_entry_t) {
157  .id = strdup(entry->id),
158  .path = strdup(entry->path),
159  .timeout = entry->timeout,
160  .tstamp_format = entry->tstamp_format?strdup(entry->tstamp_format):NULL,
161  .recipient = entry->recipient?strdup(entry->recipient):NULL,
162  .envvars = entry->envvars?
163  copy_envvar_list_remove_dupes(entry)
164  :NULL
165  };
166  crm_alert_list = g_list_prepend(crm_alert_list, new_entry);
167 }
168 
169 GListPtr
170 crm_get_envvars_from_cib(xmlNode *basenode, crm_alert_entry_t *entry, int *count)
171 {
172  xmlNode *envvar;
173  xmlNode *pair;
174 
175  if ((!basenode) ||
176  (!(envvar = first_named_child(basenode, XML_TAG_ATTR_SETS)))) {
177  return entry->envvars;
178  }
179 
180  for (pair = first_named_child(envvar, XML_CIB_TAG_NVPAIR);
181  pair; pair = __xml_next(pair)) {
182 
183  envvar_t envvar_entry = (envvar_t) {
184  .name = (char *) crm_element_value(pair, XML_NVPAIR_ATTR_NAME),
185  .value = (char *) crm_element_value(pair, XML_NVPAIR_ATTR_VALUE)
186  };
187  crm_trace("Found environment variable %s = '%s'", envvar_entry.name,
188  envvar_entry.value?envvar_entry.value:"");
189  (*count)++;
190  add_dup_envvar(entry, &envvar_entry);
191  }
192 
193  return entry->envvars;
194 }
195 
196 void
197 crm_set_alert_key(enum crm_alert_keys_e name, const char *value)
198 {
199  const char **key;
200 
201  for (key = crm_alert_keys[name]; *key; key++) {
202  crm_trace("Setting alert key %s = '%s'", *key, value);
203  if (value) {
204  setenv(*key, value, 1);
205  } else {
206  unsetenv(*key);
207  }
208  }
209 }
210 
211 void
213 {
214  char *s = crm_itoa(value);
215 
216  crm_set_alert_key(name, s);
217  free(s);
218 }
219 
220 void
222 {
223  const char **key;
224  enum crm_alert_keys_e name;
225 
226  for(name = 0; name < DIMOF(crm_alert_keys); name++) {
227  for(key = crm_alert_keys[name]; *key; key++) {
228  crm_trace("Unsetting alert key %s", *key);
229  unsetenv(*key);
230  }
231  }
232 }
233 
234 void
236 {
237  GListPtr l;
238 
239  for (l = g_list_first(entry->envvars); l; l = g_list_next(l)) {
240  envvar_t *env = (envvar_t *)(l->data);
241 
242  crm_trace("Setting environment variable %s = '%s'", env->name,
243  env->value?env->value:"");
244  if (env->value) {
245  setenv(env->name, env->value, 1);
246  } else {
247  unsetenv(env->name);
248  }
249  }
250 }
251 
252 void
254 {
255  GListPtr l;
256 
257  for (l = g_list_first(entry->envvars); l; l = g_list_next(l)) {
258  envvar_t *env = (envvar_t *)(l->data);
259 
260  crm_trace("Unsetting environment variable %s", env->name);
261  unsetenv(env->name);
262  }
263 }
void crm_unset_envvar_list(crm_alert_entry_t *entry)
Definition: alerts.c:253
A dumping ground.
#define CRM_ALERT_DEFAULT_TIMEOUT_MS
char * recipient
#define XML_NVPAIR_ATTR_NAME
Definition: msg_xml.h:354
#define XML_CIB_TAG_NVPAIR
Definition: msg_xml.h:174
void crm_add_dup_alert_list_entry(crm_alert_entry_t *entry)
Definition: alerts.c:150
char * tstamp_format
#define XML_TAG_ATTR_SETS
Definition: msg_xml.h:177
char * id
void crm_unset_alert_keys()
Definition: alerts.c:221
void crm_set_alert_key(enum crm_alert_keys_e name, const char *value)
Definition: alerts.c:197
#define crm_trace(fmt, args...)
Definition: logging.h:254
int setenv(const char *name, const char *value, int why)
const char * crm_element_value(xmlNode *data, const char *name)
Definition: xml.c:5134
void crm_set_alert_key_int(enum crm_alert_keys_e name, int value)
Definition: alerts.c:212
const char * crm_alert_keys[14][3]
Definition: alerts.c:36
int timeout
#define DIMOF(a)
Definition: crm.h:39
#define XML_NVPAIR_ATTR_VALUE
Definition: msg_xml.h:355
crm_alert_keys_e
char * path
#define CRM_ASSERT(expr)
Definition: error.h:35
char data[0]
Definition: internal.h:58
xmlNode * first_named_child(xmlNode *parent, const char *name)
Definition: xml.c:5046
guint crm_alert_max_alert_timeout
Definition: alerts.c:30
GListPtr crm_alert_list
Definition: alerts.c:29
GListPtr crm_drop_envvars(crm_alert_entry_t *entry, int count)
Definition: alerts.c:106
char * crm_itoa(int an_int)
Definition: strings.c:60
void crm_set_envvar_list(crm_alert_entry_t *entry)
Definition: alerts.c:235
GList * GListPtr
Definition: crm.h:202
void crm_free_alert_list()
Definition: alerts.c:77
GListPtr crm_get_envvars_from_cib(xmlNode *basenode, crm_alert_entry_t *entry, int *count)
Definition: alerts.c:170
GListPtr envvars