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