This source file includes following definitions.
- attrd_set_requesting_shutdown
- attrd_clear_requesting_shutdown
- attrd_shutting_down
- attrd_shutdown
- attrd_init_mainloop
- attrd_run_mainloop
- 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
64
65
66
67
68
69
70
71 bool
72 attrd_shutting_down(bool if_requested)
73 {
74 return shutting_down || (if_requested && requesting_shutdown);
75 }
76
77
78
79
80
81
82
83 void
84 attrd_shutdown(int nsig)
85 {
86
87 shutting_down = true;
88
89
90 mainloop_destroy_signal(SIGTERM);
91 mainloop_destroy_signal(SIGCHLD);
92 mainloop_destroy_signal(SIGPIPE);
93 mainloop_destroy_signal(SIGUSR1);
94 mainloop_destroy_signal(SIGUSR2);
95 mainloop_destroy_signal(SIGTRAP);
96
97 attrd_free_waitlist();
98 attrd_free_confirmations();
99
100 if (peer_protocol_vers != NULL) {
101 g_hash_table_destroy(peer_protocol_vers);
102 peer_protocol_vers = NULL;
103 }
104
105 if ((mloop == NULL) || !g_main_loop_is_running(mloop)) {
106
107
108
109 crm_exit(CRM_EX_OK);
110 } else {
111 g_main_loop_quit(mloop);
112 g_main_loop_unref(mloop);
113 }
114 }
115
116
117
118
119
120 void
121 attrd_init_mainloop(void)
122 {
123 mloop = g_main_loop_new(NULL, FALSE);
124 }
125
126
127
128
129
130 void
131 attrd_run_mainloop(void)
132 {
133 g_main_loop_run(mloop);
134 }
135
136
137 #define plus_plus_len (5)
138
139
140
141
142
143
144
145
146
147 bool
148 attrd_value_needs_expansion(const char *value)
149 {
150 return ((strlen(value) >= (plus_plus_len + 2))
151 && (value[plus_plus_len] == '+')
152 && ((value[plus_plus_len + 1] == '+')
153 || (value[plus_plus_len + 1] == '=')));
154 }
155
156
157
158
159
160
161
162
163
164
165 int
166 attrd_expand_value(const char *value, const char *old_value)
167 {
168 int offset = 1;
169 int int_value = char2score(old_value);
170
171 if (value[plus_plus_len + 1] != '+') {
172 const char *offset_s = value + (plus_plus_len + 2);
173
174 offset = char2score(offset_s);
175 }
176 int_value += offset;
177
178 if (int_value > INFINITY) {
179 int_value = INFINITY;
180 }
181 return int_value;
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197 int
198 attrd_failure_regex(regex_t *regex, const char *rsc, const char *op,
199 guint interval_ms)
200 {
201 char *pattern = NULL;
202 int rc;
203
204
205
206 if (rsc == NULL) {
207 pattern = strdup(ATTRD_RE_CLEAR_ALL);
208 } else if (op == NULL) {
209 pattern = crm_strdup_printf(ATTRD_RE_CLEAR_ONE, rsc);
210 } else {
211 pattern = crm_strdup_printf(ATTRD_RE_CLEAR_OP, rsc, op, interval_ms);
212 }
213
214
215 crm_trace("Clearing attributes matching %s", pattern);
216 rc = regcomp(regex, pattern, REG_EXTENDED|REG_NOSUB);
217 free(pattern);
218
219 return (rc == 0)? pcmk_ok : -EINVAL;
220 }
221
222 void
223 attrd_free_attribute_value(gpointer data)
224 {
225 attribute_value_t *v = data;
226
227 free(v->nodename);
228 free(v->current);
229 free(v->requested);
230 free(v);
231 }
232
233 void
234 attrd_free_attribute(gpointer data)
235 {
236 attribute_t *a = data;
237 if(a) {
238 free(a->id);
239 free(a->set_id);
240 free(a->set_type);
241 free(a->uuid);
242 free(a->user);
243
244 mainloop_timer_del(a->timer);
245 g_hash_table_destroy(a->values);
246
247 free(a);
248 }
249 }
250
251
252
253
254
255
256
257 void
258 attrd_remove_peer_protocol_ver(const char *host)
259 {
260 if (peer_protocol_vers != NULL) {
261 g_hash_table_remove(peer_protocol_vers, host);
262 }
263 }
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279 void
280 attrd_update_minimum_protocol_ver(const char *host, const char *value)
281 {
282 int ver;
283
284 if (peer_protocol_vers == NULL) {
285 peer_protocol_vers = pcmk__strkey_table(free, NULL);
286 }
287
288 pcmk__scan_min_int(value, &ver, 0);
289
290 if (ver > 0) {
291 char *host_name = strdup(host);
292
293
294 CRM_ASSERT(host_name != NULL);
295 g_hash_table_insert(peer_protocol_vers, host_name, GINT_TO_POINTER(ver));
296
297
298 if (minimum_protocol_version == -1 || ver < minimum_protocol_version) {
299 minimum_protocol_version = ver;
300 crm_trace("Set minimum attrd protocol version to %d",
301 minimum_protocol_version);
302 }
303 }
304 }
305
306 void
307 attrd_copy_xml_attributes(xmlNode *src, xmlNode *dest)
308 {
309
310
311
312
313
314
315
316 for (xmlAttrPtr a = pcmk__xe_first_attr(src); a != NULL; a = a->next) {
317 const char *p_name = (const char *) a->name;
318 const char *p_value = ((a == NULL) || (a->children == NULL)) ? NULL :
319 (const char *) a->children->content;
320
321 if (crm_element_value(dest, p_name) == NULL) {
322 crm_xml_add(dest, p_name, p_value);
323 }
324 }
325 }