This source file includes following definitions.
- attrd_set_requesting_shutdown
- attrd_clear_requesting_shutdown
- attrd_requesting_shutdown
- attrd_shutting_down
- attrd_shutdown
- attrd_init_mainloop
- attrd_run_mainloop
- attrd_cib_disconnect
- attrd_cib_replaced_cb
- attrd_value_needs_expansion
- attrd_expand_value
- attrd_failure_regex
- attrd_free_attribute_value
- attrd_free_attribute
- attrd_remove_peer_protocol_ver
- attrd_update_minimum_protocol_ver
- attrd_copy_xml_attributes
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdio.h>
13 #include <stdbool.h>
14 #include <errno.h>
15 #include <glib.h>
16 #include <regex.h>
17 #include <sys/types.h>
18
19 #include <crm/crm.h>
20 #include <crm/common/ipc_internal.h>
21 #include <crm/common/mainloop.h>
22 #include <crm/msg_xml.h>
23
24 #include "pacemaker-attrd.h"
25
26 cib_t *the_cib = NULL;
27
28 static bool requesting_shutdown = false;
29 static bool shutting_down = false;
30 static GMainLoop *mloop = NULL;
31
32
33
34
35 GHashTable *peer_protocol_vers = NULL;
36
37
38
39
40
41 void
42 attrd_set_requesting_shutdown(void)
43 {
44 requesting_shutdown = true;
45 }
46
47
48
49
50
51 void
52 attrd_clear_requesting_shutdown(void)
53 {
54 requesting_shutdown = false;
55 }
56
57
58
59
60
61
62
63 bool
64 attrd_requesting_shutdown(void)
65 {
66 return requesting_shutdown;
67 }
68
69
70
71
72
73
74
75 bool
76 attrd_shutting_down(void)
77 {
78 return shutting_down;
79 }
80
81
82
83
84
85
86
87 void
88 attrd_shutdown(int nsig)
89 {
90
91 shutting_down = true;
92
93
94 mainloop_destroy_signal(SIGTERM);
95 mainloop_destroy_signal(SIGCHLD);
96 mainloop_destroy_signal(SIGPIPE);
97 mainloop_destroy_signal(SIGUSR1);
98 mainloop_destroy_signal(SIGUSR2);
99 mainloop_destroy_signal(SIGTRAP);
100
101 attrd_free_waitlist();
102 attrd_free_confirmations();
103
104 if (peer_protocol_vers != NULL) {
105 g_hash_table_destroy(peer_protocol_vers);
106 peer_protocol_vers = NULL;
107 }
108
109 if ((mloop == NULL) || !g_main_loop_is_running(mloop)) {
110
111
112
113 crm_exit(CRM_EX_OK);
114 } else {
115 g_main_loop_quit(mloop);
116 g_main_loop_unref(mloop);
117 }
118 }
119
120
121
122
123
124 void
125 attrd_init_mainloop(void)
126 {
127 mloop = g_main_loop_new(NULL, FALSE);
128 }
129
130
131
132
133
134 void
135 attrd_run_mainloop(void)
136 {
137 g_main_loop_run(mloop);
138 }
139
140 void
141 attrd_cib_disconnect(void)
142 {
143 CRM_CHECK(the_cib != NULL, return);
144 the_cib->cmds->del_notify_callback(the_cib, T_CIB_REPLACE_NOTIFY, attrd_cib_replaced_cb);
145 the_cib->cmds->del_notify_callback(the_cib, T_CIB_DIFF_NOTIFY, attrd_cib_updated_cb);
146 cib__clean_up_connection(&the_cib);
147 }
148
149 void
150 attrd_cib_replaced_cb(const char *event, xmlNode * msg)
151 {
152 int change_section = cib_change_section_nodes | cib_change_section_status | cib_change_section_alerts;
153
154 if (attrd_requesting_shutdown() || attrd_shutting_down()) {
155 return;
156 }
157
158 crm_element_value_int(msg, F_CIB_CHANGE_SECTION, &change_section);
159
160 if (attrd_election_won()) {
161 if (change_section & (cib_change_section_nodes | cib_change_section_status)) {
162 crm_notice("Updating all attributes after %s event", event);
163 attrd_write_attributes(true, false);
164 }
165 }
166
167 if (change_section & cib_change_section_alerts) {
168
169 mainloop_set_trigger(attrd_config_read);
170 }
171 }
172
173
174 #define plus_plus_len (5)
175
176
177
178
179
180
181
182
183
184 bool
185 attrd_value_needs_expansion(const char *value)
186 {
187 return ((strlen(value) >= (plus_plus_len + 2))
188 && (value[plus_plus_len] == '+')
189 && ((value[plus_plus_len + 1] == '+')
190 || (value[plus_plus_len + 1] == '=')));
191 }
192
193
194
195
196
197
198
199
200
201
202 int
203 attrd_expand_value(const char *value, const char *old_value)
204 {
205 int offset = 1;
206 int int_value = char2score(old_value);
207
208 if (value[plus_plus_len + 1] != '+') {
209 const char *offset_s = value + (plus_plus_len + 2);
210
211 offset = char2score(offset_s);
212 }
213 int_value += offset;
214
215 if (int_value > INFINITY) {
216 int_value = INFINITY;
217 }
218 return int_value;
219 }
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234 int
235 attrd_failure_regex(regex_t *regex, const char *rsc, const char *op,
236 guint interval_ms)
237 {
238 char *pattern = NULL;
239 int rc;
240
241
242
243 if (rsc == NULL) {
244 pattern = strdup(ATTRD_RE_CLEAR_ALL);
245 } else if (op == NULL) {
246 pattern = crm_strdup_printf(ATTRD_RE_CLEAR_ONE, rsc);
247 } else {
248 pattern = crm_strdup_printf(ATTRD_RE_CLEAR_OP, rsc, op, interval_ms);
249 }
250
251
252 crm_trace("Clearing attributes matching %s", pattern);
253 rc = regcomp(regex, pattern, REG_EXTENDED|REG_NOSUB);
254 free(pattern);
255
256 return (rc == 0)? pcmk_ok : -EINVAL;
257 }
258
259 void
260 attrd_free_attribute_value(gpointer data)
261 {
262 attribute_value_t *v = data;
263
264 free(v->nodename);
265 free(v->current);
266 free(v->requested);
267 free(v);
268 }
269
270 void
271 attrd_free_attribute(gpointer data)
272 {
273 attribute_t *a = data;
274 if(a) {
275 free(a->id);
276 free(a->set_id);
277 free(a->set_type);
278 free(a->uuid);
279 free(a->user);
280
281 mainloop_timer_del(a->timer);
282 g_hash_table_destroy(a->values);
283
284 free(a);
285 }
286 }
287
288
289
290
291
292
293
294 void
295 attrd_remove_peer_protocol_ver(const char *host)
296 {
297 if (peer_protocol_vers != NULL) {
298 g_hash_table_remove(peer_protocol_vers, host);
299 }
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316 void
317 attrd_update_minimum_protocol_ver(const char *host, const char *value)
318 {
319 int ver;
320
321 if (peer_protocol_vers == NULL) {
322 peer_protocol_vers = pcmk__strkey_table(free, NULL);
323 }
324
325 pcmk__scan_min_int(value, &ver, 0);
326
327 if (ver > 0) {
328 char *host_name = strdup(host);
329
330
331 CRM_ASSERT(host_name != NULL);
332 g_hash_table_insert(peer_protocol_vers, host_name, GINT_TO_POINTER(ver));
333
334
335 if (minimum_protocol_version == -1 || ver < minimum_protocol_version) {
336 minimum_protocol_version = ver;
337 crm_trace("Set minimum attrd protocol version to %d",
338 minimum_protocol_version);
339 }
340 }
341 }
342
343 void
344 attrd_copy_xml_attributes(xmlNode *src, xmlNode *dest)
345 {
346
347
348
349
350
351
352
353 for (xmlAttrPtr a = pcmk__xe_first_attr(src); a != NULL; a = a->next) {
354 const char *p_name = (const char *) a->name;
355 const char *p_value = ((a == NULL) || (a->children == NULL)) ? NULL :
356 (const char *) a->children->content;
357
358 if (crm_element_value(dest, p_name) == NULL) {
359 crm_xml_add(dest, p_name, p_value);
360 }
361 }
362 }