This source file includes following definitions.
- node_has_attr
- add_topology_level
- topology_remove_helper
- remove_topology_level
- register_fencing_topology
- fencing_topology_init
- remove_cib_device
- update_stonith_watchdog_timeout_ms
- cib_devices_update
- update_cib_stonith_devices_v1
- update_cib_stonith_devices_v2
- update_cib_stonith_devices
- watchdog_device_update
- fenced_query_cib
- remove_fencing_topology
- update_fencing_topology
- update_cib_cache_cb
- init_cib_cache_cb
- cib_connection_destroy
- fenced_cib_cleanup
- setup_cib
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdbool.h>
13 #include <stdio.h>
14 #include <libxml/tree.h>
15 #include <libxml/xpath.h>
16
17 #include <crm/crm.h>
18 #include <crm/common/xml.h>
19
20 #include <crm/cluster/internal.h>
21
22 #include <crm/cib.h>
23 #include <crm/cib/internal.h>
24
25 #include <pacemaker-fenced.h>
26
27 static xmlNode *local_cib = NULL;
28 static cib_t *cib_api = NULL;
29 static bool have_cib_devices = FALSE;
30
31
32
33
34
35
36
37
38
39
40
41 gboolean
42 node_has_attr(const char *node, const char *name, const char *value)
43 {
44 GString *xpath = NULL;
45 xmlNode *match;
46
47 CRM_CHECK((local_cib != NULL) && (node != NULL) && (name != NULL)
48 && (value != NULL), return FALSE);
49
50
51
52
53
54
55 xpath = g_string_sized_new(256);
56 pcmk__g_strcat(xpath,
57 "//" PCMK_XE_NODES "/" PCMK_XE_NODE
58 "[@" PCMK_XA_UNAME "='", node, "']"
59 "/" PCMK_XE_INSTANCE_ATTRIBUTES
60 "/" PCMK_XE_NVPAIR
61 "[@" PCMK_XA_NAME "='", name, "' "
62 "and @" PCMK_XA_VALUE "='", value, "']", NULL);
63
64 match = get_xpath_object((const char *) xpath->str, local_cib, LOG_NEVER);
65
66 g_string_free(xpath, TRUE);
67 return (match != NULL);
68 }
69
70 static void
71 add_topology_level(xmlNode *match)
72 {
73 char *desc = NULL;
74 pcmk__action_result_t result = PCMK__UNKNOWN_RESULT;
75
76 CRM_CHECK(match != NULL, return);
77
78 fenced_register_level(match, &desc, &result);
79 fenced_send_config_notification(STONITH_OP_LEVEL_ADD, &result, desc);
80 pcmk__reset_result(&result);
81 free(desc);
82 }
83
84 static void
85 topology_remove_helper(const char *node, int level)
86 {
87 char *desc = NULL;
88 pcmk__action_result_t result = PCMK__UNKNOWN_RESULT;
89 xmlNode *data = pcmk__xe_create(NULL, PCMK_XE_FENCING_LEVEL);
90
91 crm_xml_add(data, PCMK__XA_ST_ORIGIN, __func__);
92 crm_xml_add_int(data, PCMK_XA_INDEX, level);
93 crm_xml_add(data, PCMK_XA_TARGET, node);
94
95 fenced_unregister_level(data, &desc, &result);
96 fenced_send_config_notification(STONITH_OP_LEVEL_DEL, &result, desc);
97 pcmk__reset_result(&result);
98 free_xml(data);
99 free(desc);
100 }
101
102 static void
103 remove_topology_level(xmlNode *match)
104 {
105 int index = 0;
106 char *key = NULL;
107
108 CRM_CHECK(match != NULL, return);
109
110 key = stonith_level_key(match, fenced_target_by_unknown);
111 crm_element_value_int(match, PCMK_XA_INDEX, &index);
112 topology_remove_helper(key, index);
113 free(key);
114 }
115
116 static void
117 register_fencing_topology(xmlXPathObjectPtr xpathObj)
118 {
119 int max = numXpathResults(xpathObj), lpc = 0;
120
121 for (lpc = 0; lpc < max; lpc++) {
122 xmlNode *match = getXpathResult(xpathObj, lpc);
123
124 remove_topology_level(match);
125 add_topology_level(match);
126 }
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 void
149 fencing_topology_init(void)
150 {
151 xmlXPathObjectPtr xpathObj = NULL;
152 const char *xpath = "//" PCMK_XE_FENCING_LEVEL;
153
154 crm_trace("Full topology refresh");
155 free_topology_list();
156 init_topology_list();
157
158
159 xpathObj = xpath_search(local_cib, xpath);
160 register_fencing_topology(xpathObj);
161
162 freeXpathObject(xpathObj);
163 }
164
165 static void
166 remove_cib_device(xmlXPathObjectPtr xpathObj)
167 {
168 int max = numXpathResults(xpathObj), lpc = 0;
169
170 for (lpc = 0; lpc < max; lpc++) {
171 const char *rsc_id = NULL;
172 const char *standard = NULL;
173 xmlNode *match = getXpathResult(xpathObj, lpc);
174
175 CRM_LOG_ASSERT(match != NULL);
176 if(match != NULL) {
177 standard = crm_element_value(match, PCMK_XA_CLASS);
178 }
179
180 if (!pcmk__str_eq(standard, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) {
181 continue;
182 }
183
184 rsc_id = crm_element_value(match, PCMK_XA_ID);
185
186 stonith_device_remove(rsc_id, true);
187 }
188 }
189
190 #define XPATH_WATCHDOG_TIMEOUT "//" PCMK_XE_NVPAIR \
191 "[@" PCMK_XA_NAME "='" \
192 PCMK_OPT_STONITH_WATCHDOG_TIMEOUT "']"
193
194 static void
195 update_stonith_watchdog_timeout_ms(xmlNode *cib)
196 {
197 long long timeout_ms = 0;
198 xmlNode *stonith_watchdog_xml = NULL;
199 const char *value = NULL;
200
201 stonith_watchdog_xml = get_xpath_object(XPATH_WATCHDOG_TIMEOUT, cib,
202 LOG_NEVER);
203 if (stonith_watchdog_xml) {
204 value = crm_element_value(stonith_watchdog_xml, PCMK_XA_VALUE);
205 }
206 if (value) {
207 timeout_ms = crm_get_msec(value);
208 }
209
210 if (timeout_ms < 0) {
211 timeout_ms = pcmk__auto_stonith_watchdog_timeout();
212 }
213
214 stonith_watchdog_timeout_ms = timeout_ms;
215 }
216
217
218
219
220
221 static void
222 cib_devices_update(void)
223 {
224 GHashTableIter iter;
225 stonith_device_t *device = NULL;
226
227 crm_info("Updating devices to version %s.%s.%s",
228 crm_element_value(local_cib, PCMK_XA_ADMIN_EPOCH),
229 crm_element_value(local_cib, PCMK_XA_EPOCH),
230 crm_element_value(local_cib, PCMK_XA_NUM_UPDATES));
231
232 g_hash_table_iter_init(&iter, device_list);
233 while (g_hash_table_iter_next(&iter, NULL, (void **)&device)) {
234 if (device->cib_registered) {
235 device->dirty = TRUE;
236 }
237 }
238
239
240
241
242 g_list_free_full(stonith_watchdog_targets, free);
243 stonith_watchdog_targets = NULL;
244
245 fenced_scheduler_run(local_cib);
246
247 g_hash_table_iter_init(&iter, device_list);
248 while (g_hash_table_iter_next(&iter, NULL, (void **)&device)) {
249 if (device->dirty) {
250 g_hash_table_iter_remove(&iter);
251 }
252 }
253 }
254
255 static void
256 update_cib_stonith_devices_v1(const char *event, xmlNode * msg)
257 {
258 const char *reason = "none";
259 gboolean needs_update = FALSE;
260 xmlXPathObjectPtr xpath_obj = NULL;
261
262
263 xpath_obj = xpath_search(msg,
264 "//" PCMK__XE_CIB_UPDATE_RESULT
265 "//" PCMK_XE_RSC_LOCATION);
266 if (numXpathResults(xpath_obj) > 0) {
267 int max = numXpathResults(xpath_obj), lpc = 0;
268
269
270 needs_update = TRUE;
271 reason = "new location constraint";
272
273 for (lpc = 0; lpc < max; lpc++) {
274 xmlNode *match = getXpathResult(xpath_obj, lpc);
275
276 crm_log_xml_trace(match, "new constraint");
277 }
278 }
279 freeXpathObject(xpath_obj);
280
281
282 xpath_obj = xpath_search(msg,
283 "//" PCMK__XE_CIB_UPDATE_RESULT
284 "//" PCMK__XE_DIFF_REMOVED
285 "//" PCMK_XE_PRIMITIVE);
286 if (numXpathResults(xpath_obj) > 0) {
287 remove_cib_device(xpath_obj);
288 }
289 freeXpathObject(xpath_obj);
290
291
292 xpath_obj = xpath_search(msg,
293 "//" PCMK__XE_CIB_UPDATE_RESULT
294 "//" PCMK__XE_DIFF_ADDED
295 "//" PCMK_XE_PRIMITIVE);
296 if (numXpathResults(xpath_obj) > 0) {
297 int max = numXpathResults(xpath_obj), lpc = 0;
298
299 for (lpc = 0; lpc < max; lpc++) {
300 const char *rsc_id = NULL;
301 const char *standard = NULL;
302 xmlNode *match = getXpathResult(xpath_obj, lpc);
303
304 rsc_id = crm_element_value(match, PCMK_XA_ID);
305 standard = crm_element_value(match, PCMK_XA_CLASS);
306
307 if (!pcmk__str_eq(standard, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) {
308 continue;
309 }
310
311 crm_trace("Fencing resource %s was added or modified", rsc_id);
312 reason = "new resource";
313 needs_update = TRUE;
314 }
315 }
316 freeXpathObject(xpath_obj);
317
318 if(needs_update) {
319 crm_info("Updating device list from CIB: %s", reason);
320 cib_devices_update();
321 }
322 }
323
324 static void
325 update_cib_stonith_devices_v2(const char *event, xmlNode * msg)
326 {
327 xmlNode *change = NULL;
328 char *reason = NULL;
329 xmlNode *wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT,
330 NULL, NULL);
331 xmlNode *patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
332
333 for (change = pcmk__xe_first_child(patchset, NULL, NULL, NULL);
334 change != NULL; change = pcmk__xe_next(change)) {
335
336 const char *op = crm_element_value(change, PCMK_XA_OPERATION);
337 const char *xpath = crm_element_value(change, PCMK_XA_PATH);
338 const char *shortpath = NULL;
339
340 if (pcmk__str_eq(op, PCMK_VALUE_MOVE, pcmk__str_null_matches)
341 || (strstr(xpath, "/" PCMK_XE_STATUS) != NULL)) {
342 continue;
343 }
344
345 if (pcmk__str_eq(op, PCMK_VALUE_DELETE, pcmk__str_none)
346 && (strstr(xpath, "/" PCMK_XE_PRIMITIVE) != NULL)) {
347 const char *rsc_id = NULL;
348 char *search = NULL;
349 char *mutable = NULL;
350
351 if ((strstr(xpath, PCMK_XE_INSTANCE_ATTRIBUTES) != NULL)
352 || (strstr(xpath, PCMK_XE_META_ATTRIBUTES) != NULL)) {
353
354 reason = pcmk__str_copy("(meta) attribute deleted from "
355 "resource");
356 break;
357 }
358 mutable = pcmk__str_copy(xpath);
359 rsc_id = strstr(mutable, PCMK_XE_PRIMITIVE "[@" PCMK_XA_ID "=\'");
360 if (rsc_id != NULL) {
361 rsc_id += strlen(PCMK_XE_PRIMITIVE "[@" PCMK_XA_ID "=\'");
362 search = strchr(rsc_id, '\'');
363 }
364 if (search != NULL) {
365 *search = 0;
366 stonith_device_remove(rsc_id, true);
367
368
369 } else {
370 crm_warn("Ignoring malformed CIB update (resource deletion)");
371 }
372 free(mutable);
373
374 } else if (strstr(xpath, "/" PCMK_XE_RESOURCES)
375 || strstr(xpath, "/" PCMK_XE_CONSTRAINTS)
376 || strstr(xpath, "/" PCMK_XE_RSC_DEFAULTS)) {
377 shortpath = strrchr(xpath, '/');
378 pcmk__assert(shortpath != NULL);
379 reason = crm_strdup_printf("%s %s", op, shortpath+1);
380 break;
381 }
382 }
383
384 if (reason != NULL) {
385 crm_info("Updating device list from CIB: %s", reason);
386 cib_devices_update();
387 free(reason);
388 } else {
389 crm_trace("No updates for device list found in CIB");
390 }
391 }
392
393 static void
394 update_cib_stonith_devices(const char *event, xmlNode * msg)
395 {
396 int format = 1;
397 xmlNode *wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT,
398 NULL, NULL);
399 xmlNode *patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
400
401 pcmk__assert(patchset != NULL);
402 crm_element_value_int(patchset, PCMK_XA_FORMAT, &format);
403 switch(format) {
404 case 1:
405 update_cib_stonith_devices_v1(event, msg);
406 break;
407 case 2:
408 update_cib_stonith_devices_v2(event, msg);
409 break;
410 default:
411 crm_warn("Unknown patch format: %d", format);
412 }
413 }
414
415 static void
416 watchdog_device_update(void)
417 {
418 if (stonith_watchdog_timeout_ms > 0) {
419 if (!g_hash_table_lookup(device_list, STONITH_WATCHDOG_ID) &&
420 !stonith_watchdog_targets) {
421
422
423
424 int rc;
425 xmlNode *xml;
426
427 xml = create_device_registration_xml(
428 STONITH_WATCHDOG_ID,
429 st_namespace_internal,
430 STONITH_WATCHDOG_AGENT,
431 NULL,
432
433
434
435 NULL);
436 rc = stonith_device_register(xml, TRUE);
437 free_xml(xml);
438 if (rc != pcmk_ok) {
439 rc = pcmk_legacy2rc(rc);
440 exit_code = CRM_EX_FATAL;
441 crm_crit("Cannot register watchdog pseudo fence agent: %s",
442 pcmk_rc_str(rc));
443 stonith_shutdown(0);
444 }
445 }
446
447 } else if (g_hash_table_lookup(device_list, STONITH_WATCHDOG_ID) != NULL) {
448
449 stonith_device_remove(STONITH_WATCHDOG_ID, true);
450 }
451 }
452
453
454
455
456
457
458
459 static int
460 fenced_query_cib(void)
461 {
462 int rc = pcmk_ok;
463
464 crm_trace("Re-requesting full CIB");
465 rc = cib_api->cmds->query(cib_api, NULL, &local_cib,
466 cib_scope_local|cib_sync_call);
467 rc = pcmk_legacy2rc(rc);
468 if (rc == pcmk_rc_ok) {
469 pcmk__assert(local_cib != NULL);
470 } else {
471 crm_err("Couldn't retrieve the CIB: %s " CRM_XS " rc=%d",
472 pcmk_rc_str(rc), rc);
473 }
474 return rc;
475 }
476
477 static void
478 remove_fencing_topology(xmlXPathObjectPtr xpathObj)
479 {
480 int max = numXpathResults(xpathObj), lpc = 0;
481
482 for (lpc = 0; lpc < max; lpc++) {
483 xmlNode *match = getXpathResult(xpathObj, lpc);
484
485 CRM_LOG_ASSERT(match != NULL);
486 if (match && crm_element_value(match, PCMK__XA_CRM_DIFF_MARKER)) {
487
488 int index = 0;
489 char *target = stonith_level_key(match, fenced_target_by_unknown);
490
491 crm_element_value_int(match, PCMK_XA_INDEX, &index);
492 if (target == NULL) {
493 crm_err("Invalid fencing target in element %s",
494 pcmk__xe_id(match));
495
496 } else if (index <= 0) {
497 crm_err("Invalid level for %s in element %s",
498 target, pcmk__xe_id(match));
499
500 } else {
501 topology_remove_helper(target, index);
502 }
503
504 }
505 }
506 }
507
508 static void
509 update_fencing_topology(const char *event, xmlNode * msg)
510 {
511 int format = 1;
512 const char *xpath;
513 xmlXPathObjectPtr xpathObj = NULL;
514 xmlNode *wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT,
515 NULL, NULL);
516 xmlNode *patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
517
518 pcmk__assert(patchset != NULL);
519 crm_element_value_int(patchset, PCMK_XA_FORMAT, &format);
520
521 if(format == 1) {
522
523 xpath = "//" PCMK__XE_CIB_UPDATE_RESULT
524 "//" PCMK__XE_DIFF_REMOVED
525 "//" PCMK_XE_FENCING_LEVEL;
526 xpathObj = xpath_search(msg, xpath);
527
528 remove_fencing_topology(xpathObj);
529 freeXpathObject(xpathObj);
530
531
532 xpath = "//" PCMK__XE_CIB_UPDATE_RESULT
533 "//" PCMK__XE_DIFF_ADDED
534 "//" PCMK_XE_FENCING_LEVEL;
535 xpathObj = xpath_search(msg, xpath);
536
537 register_fencing_topology(xpathObj);
538 freeXpathObject(xpathObj);
539
540 } else if(format == 2) {
541 xmlNode *change = NULL;
542 int add[] = { 0, 0, 0 };
543 int del[] = { 0, 0, 0 };
544
545 xml_patch_versions(patchset, add, del);
546
547 for (change = pcmk__xe_first_child(patchset, NULL, NULL, NULL);
548 change != NULL; change = pcmk__xe_next(change)) {
549
550 const char *op = crm_element_value(change, PCMK_XA_OPERATION);
551 const char *xpath = crm_element_value(change, PCMK_XA_PATH);
552
553 if(op == NULL) {
554 continue;
555
556 } else if(strstr(xpath, "/" PCMK_XE_FENCING_LEVEL) != NULL) {
557
558
559 crm_trace("Handling %s operation %d.%d.%d for %s", op, add[0], add[1], add[2], xpath);
560 if (strcmp(op, PCMK_VALUE_MOVE) == 0) {
561 continue;
562
563 } else if (strcmp(op, PCMK_VALUE_CREATE) == 0) {
564 add_topology_level(change->children);
565
566 } else if (strcmp(op, PCMK_VALUE_MODIFY) == 0) {
567 xmlNode *match = pcmk__xe_first_child(change,
568 PCMK_XE_CHANGE_RESULT,
569 NULL, NULL);
570
571 if(match) {
572 remove_topology_level(match->children);
573 add_topology_level(match->children);
574 }
575
576 } else if (strcmp(op, PCMK_VALUE_DELETE) == 0) {
577
578 crm_info("Re-initializing fencing topology after %s operation %d.%d.%d for %s",
579 op, add[0], add[1], add[2], xpath);
580 fencing_topology_init();
581 return;
582 }
583
584 } else if (strstr(xpath, "/" PCMK_XE_FENCING_TOPOLOGY) != NULL) {
585
586 crm_info("Re-initializing fencing topology after top-level %s operation %d.%d.%d for %s",
587 op, add[0], add[1], add[2], xpath);
588 fencing_topology_init();
589 return;
590
591 } else if (strstr(xpath, "/" PCMK_XE_CONFIGURATION)) {
592
593 if (pcmk__xe_first_child(change, PCMK_XE_FENCING_TOPOLOGY, NULL,
594 NULL) == NULL) {
595 crm_trace("Nothing for us in %s operation %d.%d.%d for %s.",
596 op, add[0], add[1], add[2], xpath);
597
598 } else if (pcmk__str_any_of(op,
599 PCMK_VALUE_DELETE,
600 PCMK_VALUE_CREATE, NULL)) {
601 crm_info("Re-initializing fencing topology after top-level %s operation %d.%d.%d for %s.",
602 op, add[0], add[1], add[2], xpath);
603 fencing_topology_init();
604 return;
605 }
606
607 } else {
608 crm_trace("Nothing for us in %s operation %d.%d.%d for %s",
609 op, add[0], add[1], add[2], xpath);
610 }
611 }
612
613 } else {
614 crm_warn("Unknown patch format: %d", format);
615 }
616 }
617
618 static void
619 update_cib_cache_cb(const char *event, xmlNode * msg)
620 {
621 long long timeout_ms_saved = stonith_watchdog_timeout_ms;
622 bool need_full_refresh = false;
623
624 if(!have_cib_devices) {
625 crm_trace("Skipping updates until we get a full dump");
626 return;
627
628 } else if(msg == NULL) {
629 crm_trace("Missing %s update", event);
630 return;
631 }
632
633
634
635
636 if (local_cib != NULL) {
637 int rc = pcmk_ok;
638 xmlNode *wrapper = NULL;
639 xmlNode *patchset = NULL;
640
641 crm_element_value_int(msg, PCMK__XA_CIB_RC, &rc);
642 if (rc != pcmk_ok) {
643 return;
644 }
645
646 wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT, NULL,
647 NULL);
648 patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
649
650 rc = xml_apply_patchset(local_cib, patchset, TRUE);
651 switch (rc) {
652 case pcmk_ok:
653 case -pcmk_err_old_data:
654 break;
655 case -pcmk_err_diff_resync:
656 case -pcmk_err_diff_failed:
657 crm_notice("[%s] Patch aborted: %s (%d)", event, pcmk_strerror(rc), rc);
658 free_xml(local_cib);
659 local_cib = NULL;
660 break;
661 default:
662 crm_warn("[%s] ABORTED: %s (%d)", event, pcmk_strerror(rc), rc);
663 free_xml(local_cib);
664 local_cib = NULL;
665 }
666 }
667
668 if (local_cib == NULL) {
669 if (fenced_query_cib() != pcmk_rc_ok) {
670 return;
671 }
672 need_full_refresh = true;
673 }
674
675 pcmk__refresh_node_caches_from_cib(local_cib);
676 update_stonith_watchdog_timeout_ms(local_cib);
677
678 if (timeout_ms_saved != stonith_watchdog_timeout_ms) {
679 need_full_refresh = true;
680 }
681
682 if (need_full_refresh) {
683 fencing_topology_init();
684 cib_devices_update();
685 } else {
686
687 update_fencing_topology(event, msg);
688 update_cib_stonith_devices(event, msg);
689 }
690
691 watchdog_device_update();
692 }
693
694 static void
695 init_cib_cache_cb(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
696 {
697 crm_info("Updating device list from CIB");
698 have_cib_devices = TRUE;
699 local_cib = pcmk__xml_copy(NULL, output);
700
701 pcmk__refresh_node_caches_from_cib(local_cib);
702 update_stonith_watchdog_timeout_ms(local_cib);
703
704 fencing_topology_init();
705 cib_devices_update();
706 watchdog_device_update();
707 }
708
709 static void
710 cib_connection_destroy(gpointer user_data)
711 {
712 if (stonith_shutdown_flag) {
713 crm_info("Connection to the CIB manager closed");
714 return;
715 } else {
716 crm_crit("Lost connection to the CIB manager, shutting down");
717 }
718 if (cib_api) {
719 cib_api->cmds->signoff(cib_api);
720 }
721 stonith_shutdown(0);
722 }
723
724
725
726
727
728 void
729 fenced_cib_cleanup(void)
730 {
731 if (cib_api != NULL) {
732 cib_api->cmds->del_notify_callback(cib_api, PCMK__VALUE_CIB_DIFF_NOTIFY,
733 update_cib_cache_cb);
734 cib__clean_up_connection(&cib_api);
735 }
736 free_xml(local_cib);
737 local_cib = NULL;
738 }
739
740 void
741 setup_cib(void)
742 {
743 int rc, retries = 0;
744
745 cib_api = cib_new();
746 if (cib_api == NULL) {
747 crm_err("No connection to the CIB manager");
748 return;
749 }
750
751 do {
752 sleep(retries);
753 rc = cib_api->cmds->signon(cib_api, CRM_SYSTEM_STONITHD, cib_command);
754 } while (rc == -ENOTCONN && ++retries < 5);
755
756 if (rc != pcmk_ok) {
757 crm_err("Could not connect to the CIB manager: %s (%d)", pcmk_strerror(rc), rc);
758 return;
759 }
760
761 rc = cib_api->cmds->add_notify_callback(cib_api,
762 PCMK__VALUE_CIB_DIFF_NOTIFY,
763 update_cib_cache_cb);
764 if (rc != pcmk_ok) {
765 crm_err("Could not set CIB notification callback");
766 return;
767 }
768
769 rc = cib_api->cmds->query(cib_api, NULL, NULL, cib_scope_local);
770 cib_api->cmds->register_callback(cib_api, rc, 120, FALSE, NULL,
771 "init_cib_cache_cb", init_cib_cache_cb);
772 cib_api->cmds->set_connection_dnotify(cib_api, cib_connection_destroy);
773 crm_info("Watching for fencing topology changes");
774 }