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_ipc_accept
- attrd_ipc_closed
- attrd_ipc_destroy
- attrd_init_ipc
- attrd_cib_disconnect
- attrd_cib_replaced_cb
- attrd_value_needs_expansion
- attrd_expand_value
- attrd_failure_regex
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
23 #include "pacemaker-attrd.h"
24
25 cib_t *the_cib = NULL;
26
27 static bool requesting_shutdown = FALSE;
28 static bool shutting_down = FALSE;
29 static GMainLoop *mloop = NULL;
30
31
32
33
34
35 void
36 attrd_set_requesting_shutdown()
37 {
38 requesting_shutdown = TRUE;
39 }
40
41
42
43
44
45 void
46 attrd_clear_requesting_shutdown()
47 {
48 requesting_shutdown = FALSE;
49 }
50
51
52
53
54
55
56
57 gboolean
58 attrd_requesting_shutdown()
59 {
60 return requesting_shutdown;
61 }
62
63
64
65
66
67
68
69 gboolean
70 attrd_shutting_down()
71 {
72 return shutting_down;
73 }
74
75
76
77
78
79
80
81 void
82 attrd_shutdown(int nsig)
83 {
84
85 shutting_down = TRUE;
86
87
88 mainloop_destroy_signal(SIGTERM);
89 mainloop_destroy_signal(SIGCHLD);
90 mainloop_destroy_signal(SIGPIPE);
91 mainloop_destroy_signal(SIGUSR1);
92 mainloop_destroy_signal(SIGUSR2);
93 mainloop_destroy_signal(SIGTRAP);
94
95 if ((mloop == NULL) || !g_main_loop_is_running(mloop)) {
96
97
98
99 crm_exit(CRM_EX_OK);
100 } else {
101 g_main_loop_quit(mloop);
102 g_main_loop_unref(mloop);
103 }
104 }
105
106
107
108
109
110 void
111 attrd_init_mainloop()
112 {
113 mloop = g_main_loop_new(NULL, FALSE);
114 }
115
116
117
118
119
120 void
121 attrd_run_mainloop()
122 {
123 g_main_loop_run(mloop);
124 }
125
126
127
128
129
130
131
132
133
134
135
136 static int32_t
137 attrd_ipc_accept(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
138 {
139 crm_trace("New client connection %p", c);
140 if (shutting_down) {
141 crm_info("Ignoring new connection from pid %d during shutdown",
142 pcmk__client_pid(c));
143 return -EPERM;
144 }
145
146 if (pcmk__new_client(c, uid, gid) == NULL) {
147 return -EIO;
148 }
149 return pcmk_ok;
150 }
151
152
153
154
155
156
157
158
159
160 static int32_t
161 attrd_ipc_closed(qb_ipcs_connection_t *c)
162 {
163 pcmk__client_t *client = pcmk__find_client(c);
164
165 if (client == NULL) {
166 crm_trace("Ignoring request to clean up unknown connection %p", c);
167 } else {
168 crm_trace("Cleaning up closed client connection %p", c);
169 pcmk__free_client(client);
170 }
171 return FALSE;
172 }
173
174
175
176
177
178
179
180
181
182
183 static void
184 attrd_ipc_destroy(qb_ipcs_connection_t *c)
185 {
186 crm_trace("Destroying client connection %p", c);
187 attrd_ipc_closed(c);
188 }
189
190
191
192
193
194
195
196
197 void
198 attrd_init_ipc(qb_ipcs_service_t **ipcs, qb_ipcs_msg_process_fn dispatch_fn)
199 {
200
201 static struct qb_ipcs_service_handlers ipc_callbacks = {
202 .connection_accept = attrd_ipc_accept,
203 .connection_created = NULL,
204 .msg_process = NULL,
205 .connection_closed = attrd_ipc_closed,
206 .connection_destroyed = attrd_ipc_destroy
207 };
208
209 ipc_callbacks.msg_process = dispatch_fn;
210 pcmk__serve_attrd_ipc(ipcs, &ipc_callbacks);
211 }
212
213 void
214 attrd_cib_disconnect()
215 {
216 CRM_CHECK(the_cib != NULL, return);
217 the_cib->cmds->del_notify_callback(the_cib, T_CIB_REPLACE_NOTIFY, attrd_cib_replaced_cb);
218 the_cib->cmds->del_notify_callback(the_cib, T_CIB_DIFF_NOTIFY, attrd_cib_updated_cb);
219 the_cib->cmds->signoff(the_cib);
220 cib_delete(the_cib);
221 the_cib = NULL;
222 }
223
224 void
225 attrd_cib_replaced_cb(const char *event, xmlNode * msg)
226 {
227 if (attrd_requesting_shutdown() || attrd_shutting_down()) {
228 return;
229 }
230
231 if (attrd_election_won()) {
232 crm_notice("Updating all attributes after %s event", event);
233 write_attributes(TRUE, FALSE);
234 }
235
236
237 mainloop_set_trigger(attrd_config_read);
238 }
239
240
241 #define plus_plus_len (5)
242
243
244
245
246
247
248
249
250
251 gboolean
252 attrd_value_needs_expansion(const char *value)
253 {
254 return ((strlen(value) >= (plus_plus_len + 2))
255 && (value[plus_plus_len] == '+')
256 && ((value[plus_plus_len + 1] == '+')
257 || (value[plus_plus_len + 1] == '=')));
258 }
259
260
261
262
263
264
265
266
267
268
269 int
270 attrd_expand_value(const char *value, const char *old_value)
271 {
272 int offset = 1;
273 int int_value = char2score(old_value);
274
275 if (value[plus_plus_len + 1] != '+') {
276 const char *offset_s = value + (plus_plus_len + 2);
277
278 offset = char2score(offset_s);
279 }
280 int_value += offset;
281
282 if (int_value > INFINITY) {
283 int_value = INFINITY;
284 }
285 return int_value;
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 int
302 attrd_failure_regex(regex_t *regex, const char *rsc, const char *op,
303 guint interval_ms)
304 {
305 char *pattern = NULL;
306 int rc;
307
308
309
310 if (rsc == NULL) {
311 pattern = strdup(ATTRD_RE_CLEAR_ALL);
312 } else if (op == NULL) {
313 pattern = crm_strdup_printf(ATTRD_RE_CLEAR_ONE, rsc);
314 } else {
315 pattern = crm_strdup_printf(ATTRD_RE_CLEAR_OP, rsc, op, interval_ms);
316 }
317
318
319 crm_trace("Clearing attributes matching %s", pattern);
320 rc = regcomp(regex, pattern, REG_EXTENDED|REG_NOSUB);
321 free(pattern);
322
323 return (rc == 0)? pcmk_ok : -EINVAL;
324 }