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