This source file includes following definitions.
- do_cib_updated
- do_cib_replaced
- controld_disconnect_cib_manager
- do_cib_control
- crmd_cib_smart_opt
- controld_action_is_recordable
- cib_delete_callback
- controld_delete_node_state
- controld_delete_resource_history
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <unistd.h>
13
14 #include <crm/common/alerts_internal.h>
15 #include <crm/common/xml.h>
16 #include <crm/crm.h>
17 #include <crm/msg_xml.h>
18
19 #include <pacemaker-controld.h>
20
21 int cib_retries = 0;
22
23 void
24 do_cib_updated(const char *event, xmlNode * msg)
25 {
26 if (pcmk__alert_in_patchset(msg, TRUE)) {
27 mainloop_set_trigger(config_read);
28 }
29 }
30
31 void
32 do_cib_replaced(const char *event, xmlNode * msg)
33 {
34 int change_section = cib_change_section_nodes | cib_change_section_status;
35
36 crm_debug("Updating the CIB after a replace: DC=%s", pcmk__btoa(AM_I_DC));
37 if (AM_I_DC == FALSE) {
38 return;
39
40 } else if ((fsa_state == S_FINALIZE_JOIN)
41 && pcmk_is_set(fsa_input_register, R_CIB_ASKED)) {
42
43 return;
44 }
45
46 crm_element_value_int(msg, F_CIB_CHANGE_SECTION, &change_section);
47 if (change_section & (cib_change_section_nodes | cib_change_section_status)) {
48
49 populate_cib_nodes(node_update_quick|node_update_all, __func__);
50
51 register_fsa_input(C_FSA_INTERNAL, I_ELECTION, NULL);
52 }
53 }
54
55 void
56 controld_disconnect_cib_manager(void)
57 {
58 CRM_ASSERT(fsa_cib_conn != NULL);
59
60 crm_info("Disconnecting from the CIB manager");
61
62 controld_clear_fsa_input_flags(R_CIB_CONNECTED);
63
64 fsa_cib_conn->cmds->del_notify_callback(fsa_cib_conn, T_CIB_REPLACE_NOTIFY, do_cib_replaced);
65 fsa_cib_conn->cmds->del_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY, do_cib_updated);
66 cib_free_callbacks(fsa_cib_conn);
67 if (fsa_cib_conn->state != cib_disconnected) {
68
69 fsa_cib_conn->cmds->set_slave(fsa_cib_conn, cib_scope_local | cib_discard_reply);
70 fsa_cib_conn->cmds->signoff(fsa_cib_conn);
71 }
72
73 crm_notice("Disconnected from the CIB manager");
74 }
75
76
77 void
78 do_cib_control(long long action,
79 enum crmd_fsa_cause cause,
80 enum crmd_fsa_state cur_state,
81 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
82 {
83 CRM_ASSERT(fsa_cib_conn != NULL);
84
85 if (action & A_CIB_STOP) {
86
87 if (fsa_cib_conn->state != cib_disconnected && last_resource_update != 0) {
88 crm_info("Waiting for resource update %d to complete", last_resource_update);
89 crmd_fsa_stall(FALSE);
90 return;
91 }
92
93 controld_disconnect_cib_manager();
94
95 }
96
97 if (action & A_CIB_START) {
98 int rc = pcmk_ok;
99
100 if (cur_state == S_STOPPING) {
101 crm_err("Ignoring request to connect to the CIB manager after shutdown");
102 return;
103 }
104
105 rc = fsa_cib_conn->cmds->signon(fsa_cib_conn, CRM_SYSTEM_CRMD, cib_command_nonblocking);
106
107 if (rc != pcmk_ok) {
108
109 sleep(1);
110 rc = fsa_cib_conn->cmds->signon(fsa_cib_conn, CRM_SYSTEM_CRMD, cib_command_nonblocking);
111 }
112
113 if (rc != pcmk_ok) {
114 crm_info("Could not connect to the CIB manager: %s", pcmk_strerror(rc));
115
116 } else if (pcmk_ok !=
117 fsa_cib_conn->cmds->set_connection_dnotify(fsa_cib_conn,
118 crmd_cib_connection_destroy)) {
119 crm_err("Could not set dnotify callback");
120
121 } else if (pcmk_ok !=
122 fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn, T_CIB_REPLACE_NOTIFY,
123 do_cib_replaced)) {
124 crm_err("Could not set CIB notification callback (replace)");
125
126 } else if (pcmk_ok !=
127 fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY,
128 do_cib_updated)) {
129 crm_err("Could not set CIB notification callback (update)");
130
131 } else {
132 controld_set_fsa_input_flags(R_CIB_CONNECTED);
133 cib_retries = 0;
134 }
135
136 if (!pcmk_is_set(fsa_input_register, R_CIB_CONNECTED)) {
137
138 cib_retries++;
139 crm_warn("Couldn't complete CIB registration %d"
140 " times... pause and retry", cib_retries);
141
142 if (cib_retries < 30) {
143 controld_start_timer(wait_timer);
144 crmd_fsa_stall(FALSE);
145
146 } else {
147 crm_err("Could not complete CIB"
148 " registration %d times..." " hard error", cib_retries);
149 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
150 }
151 }
152 }
153 }
154
155
156
157
158
159
160
161 int crmd_cib_smart_opt()
162 {
163 int call_opt = cib_quorum_override;
164
165 if (fsa_state == S_ELECTION || fsa_state == S_PENDING) {
166 crm_info("Sending update to local CIB in state: %s", fsa_state2string(fsa_state));
167 cib__set_call_options(call_opt, "update", cib_scope_local);
168 }
169 return call_opt;
170 }
171
172
173
174
175
176
177
178
179
180 bool
181 controld_action_is_recordable(const char *action)
182 {
183 return !pcmk__strcase_any_of(action, CRMD_ACTION_CANCEL, CRMD_ACTION_DELETE,
184 CRMD_ACTION_NOTIFY, CRMD_ACTION_METADATA, NULL);
185 }
186
187 static void
188 cib_delete_callback(xmlNode *msg, int call_id, int rc, xmlNode *output,
189 void *user_data)
190 {
191 char *desc = user_data;
192
193 if (rc == 0) {
194 crm_debug("Deletion of %s (via CIB call %d) succeeded", desc, call_id);
195 } else {
196 crm_warn("Deletion of %s (via CIB call %d) failed: %s " CRM_XS " rc=%d",
197 desc, call_id, pcmk_strerror(rc), rc);
198 }
199 }
200
201
202
203
204 #define XPATH_NODE_STATE "//" XML_CIB_TAG_STATE "[@" XML_ATTR_UNAME "='%s']"
205
206
207 #define XPATH_NODE_LRM XPATH_NODE_STATE "/" XML_CIB_TAG_LRM
208
209
210 #define XPATH_NODE_LRM_UNLOCKED XPATH_NODE_STATE "//" XML_LRM_TAG_RSC_OP \
211 "|" XPATH_NODE_STATE \
212 "//" XML_LRM_TAG_RESOURCE \
213 "[not(@" XML_CONFIG_ATTR_SHUTDOWN_LOCK ")]"
214
215
216 #define XPATH_NODE_ATTRS XPATH_NODE_STATE "/" XML_TAG_TRANSIENT_NODEATTRS
217
218
219 #define XPATH_NODE_ALL XPATH_NODE_STATE "/*"
220
221
222 #define XPATH_NODE_ALL_UNLOCKED XPATH_NODE_LRM_UNLOCKED "|" XPATH_NODE_ATTRS
223
224
225
226
227
228
229
230
231
232 void
233 controld_delete_node_state(const char *uname, enum controld_section_e section,
234 int options)
235 {
236 char *xpath = NULL;
237 char *desc = NULL;
238
239 CRM_CHECK(uname != NULL, return);
240 switch (section) {
241 case controld_section_lrm:
242 xpath = crm_strdup_printf(XPATH_NODE_LRM, uname);
243 desc = crm_strdup_printf("resource history for node %s", uname);
244 break;
245 case controld_section_lrm_unlocked:
246 xpath = crm_strdup_printf(XPATH_NODE_LRM_UNLOCKED, uname, uname);
247 desc = crm_strdup_printf("resource history (other than shutdown "
248 "locks) for node %s", uname);
249 break;
250 case controld_section_attrs:
251 xpath = crm_strdup_printf(XPATH_NODE_ATTRS, uname);
252 desc = crm_strdup_printf("transient attributes for node %s", uname);
253 break;
254 case controld_section_all:
255 xpath = crm_strdup_printf(XPATH_NODE_ALL, uname);
256 desc = crm_strdup_printf("all state for node %s", uname);
257 break;
258 case controld_section_all_unlocked:
259 xpath = crm_strdup_printf(XPATH_NODE_ALL_UNLOCKED,
260 uname, uname, uname);
261 desc = crm_strdup_printf("all state (other than shutdown locks) "
262 "for node %s", uname);
263 break;
264 }
265
266 if (fsa_cib_conn == NULL) {
267 crm_warn("Unable to delete %s: no CIB connection", desc);
268 free(desc);
269 } else {
270 int call_id;
271
272 cib__set_call_options(options, "node state deletion",
273 cib_quorum_override|cib_xpath|cib_multiple);
274 call_id = fsa_cib_conn->cmds->remove(fsa_cib_conn, xpath, NULL, options);
275 crm_info("Deleting %s (via CIB call %d) " CRM_XS " xpath=%s",
276 desc, call_id, xpath);
277 fsa_register_cib_callback(call_id, FALSE, desc, cib_delete_callback);
278
279 }
280 free(xpath);
281 }
282
283
284 #define XPATH_RESOURCE_HISTORY "//" XML_CIB_TAG_STATE \
285 "[@" XML_ATTR_UNAME "='%s']/" \
286 XML_CIB_TAG_LRM "/" XML_LRM_TAG_RESOURCES \
287 "/" XML_LRM_TAG_RESOURCE \
288 "[@" XML_ATTR_ID "='%s']"
289
290
291
292
293
294
295
296
297
298
299
300
301
302 int
303 controld_delete_resource_history(const char *rsc_id, const char *node,
304 const char *user_name, int call_options)
305 {
306 char *desc = NULL;
307 char *xpath = NULL;
308 int rc = pcmk_rc_ok;
309
310 CRM_CHECK((rsc_id != NULL) && (node != NULL), return EINVAL);
311
312 desc = crm_strdup_printf("resource history for %s on %s", rsc_id, node);
313 if (fsa_cib_conn == NULL) {
314 crm_err("Unable to clear %s: no CIB connection", desc);
315 free(desc);
316 return ENOTCONN;
317 }
318
319
320 xpath = crm_strdup_printf(XPATH_RESOURCE_HISTORY, node, rsc_id);
321 rc = cib_internal_op(fsa_cib_conn, CIB_OP_DELETE, NULL, xpath, NULL,
322 NULL, call_options|cib_xpath, user_name);
323
324 if (rc < 0) {
325 rc = pcmk_legacy2rc(rc);
326 crm_err("Could not delete resource status of %s on %s%s%s: %s "
327 CRM_XS " rc=%d", rsc_id, node,
328 (user_name? " for user " : ""), (user_name? user_name : ""),
329 pcmk_rc_str(rc), rc);
330 free(desc);
331 free(xpath);
332 return rc;
333 }
334
335 if (pcmk_is_set(call_options, cib_sync_call)) {
336 if (pcmk_is_set(call_options, cib_dryrun)) {
337 crm_debug("Deletion of %s would succeed", desc);
338 } else {
339 crm_debug("Deletion of %s succeeded", desc);
340 }
341 free(desc);
342
343 } else {
344 crm_info("Clearing %s (via CIB call %d) " CRM_XS " xpath=%s",
345 desc, rc, xpath);
346 fsa_register_cib_callback(rc, FALSE, desc, cib_delete_callback);
347
348 }
349
350 free(xpath);
351 return pcmk_rc_ok;
352 }