root/daemons/fenced/fenced_cib.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. node_has_attr
  2. add_topology_level
  3. topology_remove_helper
  4. remove_topology_level
  5. register_fencing_topology
  6. fencing_topology_init
  7. update_stonith_watchdog_timeout_ms
  8. cib_devices_update
  9. update_cib_stonith_devices
  10. watchdog_device_update
  11. fenced_query_cib
  12. update_fencing_topology
  13. update_cib_cache_cb
  14. init_cib_cache_cb
  15. cib_connection_destroy
  16. fenced_cib_cleanup
  17. setup_cib

   1 /*
   2  * Copyright 2009-2024 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU General Public License version 2
   7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   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  * \internal
  33  * \brief Check whether a node has a specific attribute name/value
  34  *
  35  * \param[in] node    Name of node to check
  36  * \param[in] name    Name of an attribute to look for
  37  * \param[in] value   The value the named attribute needs to be set to in order to be considered a match
  38  *
  39  * \return TRUE if the locally cached CIB has the specified node attribute
  40  */
  41 gboolean
  42 node_has_attr(const char *node, const char *name, const char *value)
     /* [previous][next][first][last][top][bottom][index][help] */
  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     /* Search for the node's attributes in the CIB. While the schema allows
  51      * multiple sets of instance attributes, and allows instance attributes to
  52      * use id-ref to reference values elsewhere, that is intended for resources,
  53      * so we ignore that here.
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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     pcmk__xml_free(data);
  99     free(desc);
 100 }
 101 
 102 static void
 103 remove_topology_level(xmlNode *match)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 /* Fencing
 130 <diff crm_feature_set="3.0.6">
 131   <diff-removed>
 132     <fencing-topology>
 133       <fencing-level id="f-p1.1" target="pcmk-1" index="1" devices="poison-pill" __crm_diff_marker__="removed:top"/>
 134       <fencing-level id="f-p1.2" target="pcmk-1" index="2" devices="power" __crm_diff_marker__="removed:top"/>
 135       <fencing-level devices="disk,network" id="f-p2.1"/>
 136     </fencing-topology>
 137   </diff-removed>
 138   <diff-added>
 139     <fencing-topology>
 140       <fencing-level id="f-p.1" target="pcmk-1" index="1" devices="poison-pill" __crm_diff_marker__="added:top"/>
 141       <fencing-level id="f-p2.1" target="pcmk-2" index="1" devices="disk,something"/>
 142       <fencing-level id="f-p3.1" target="pcmk-2" index="2" devices="power" __crm_diff_marker__="added:top"/>
 143     </fencing-topology>
 144   </diff-added>
 145 </diff>
 146 */
 147 
 148 void
 149 fencing_topology_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 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     /* Grab everything */
 159     xpathObj = xpath_search(local_cib, xpath);
 160     register_fencing_topology(xpathObj);
 161 
 162     freeXpathObject(xpathObj);
 163 }
 164 
 165 #define XPATH_WATCHDOG_TIMEOUT "//" PCMK_XE_NVPAIR      \
 166                                "[@" PCMK_XA_NAME "='"   \
 167                                     PCMK_OPT_STONITH_WATCHDOG_TIMEOUT "']"
 168 
 169 static void
 170 update_stonith_watchdog_timeout_ms(xmlNode *cib)
     /* [previous][next][first][last][top][bottom][index][help] */
 171 {
 172     long long timeout_ms = 0;
 173     xmlNode *stonith_watchdog_xml = NULL;
 174     const char *value = NULL;
 175 
 176     stonith_watchdog_xml = get_xpath_object(XPATH_WATCHDOG_TIMEOUT, cib,
 177                                             LOG_NEVER);
 178     if (stonith_watchdog_xml) {
 179         value = crm_element_value(stonith_watchdog_xml, PCMK_XA_VALUE);
 180     }
 181     if (value) {
 182         timeout_ms = crm_get_msec(value);
 183     }
 184 
 185     if (timeout_ms < 0) {
 186         timeout_ms = pcmk__auto_stonith_watchdog_timeout();
 187     }
 188 
 189     stonith_watchdog_timeout_ms = timeout_ms;
 190 }
 191 
 192 /*!
 193  * \internal
 194  * \brief Update all STONITH device definitions based on current CIB
 195  */
 196 static void
 197 cib_devices_update(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199     GHashTableIter iter;
 200     stonith_device_t *device = NULL;
 201 
 202     crm_info("Updating devices to version %s.%s.%s",
 203              crm_element_value(local_cib, PCMK_XA_ADMIN_EPOCH),
 204              crm_element_value(local_cib, PCMK_XA_EPOCH),
 205              crm_element_value(local_cib, PCMK_XA_NUM_UPDATES));
 206 
 207     g_hash_table_iter_init(&iter, device_list);
 208     while (g_hash_table_iter_next(&iter, NULL, (void **)&device)) {
 209         if (device->cib_registered) {
 210             device->dirty = TRUE;
 211         }
 212     }
 213 
 214     /* have list repopulated if cib has a watchdog-fencing-resource
 215        TODO: keep a cached list for queries happening while we are refreshing
 216      */
 217     g_list_free_full(stonith_watchdog_targets, free);
 218     stonith_watchdog_targets = NULL;
 219 
 220     fenced_scheduler_run(local_cib);
 221 
 222     g_hash_table_iter_init(&iter, device_list);
 223     while (g_hash_table_iter_next(&iter, NULL, (void **)&device)) {
 224         if (device->dirty) {
 225             g_hash_table_iter_remove(&iter);
 226         }
 227     }
 228 }
 229 
 230 static void
 231 update_cib_stonith_devices(const char *event, xmlNode * msg)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233     int format = 1;
 234     xmlNode *wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT,
 235                                             NULL, NULL);
 236     xmlNode *patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
 237     char *reason = NULL;
 238 
 239     CRM_CHECK(patchset != NULL, return);
 240     crm_element_value_int(patchset, PCMK_XA_FORMAT, &format);
 241 
 242     if (format != 2) {
 243         crm_warn("Unknown patch format: %d", format);
 244         return;
 245     }
 246 
 247     for (xmlNode *change = pcmk__xe_first_child(patchset, NULL, NULL, NULL);
 248          change != NULL; change = pcmk__xe_next(change, NULL)) {
 249 
 250         const char *op = crm_element_value(change, PCMK_XA_OPERATION);
 251         const char *xpath = crm_element_value(change, PCMK_XA_PATH);
 252         const char *shortpath = NULL;
 253 
 254         if (pcmk__str_eq(op, PCMK_VALUE_MOVE, pcmk__str_null_matches)
 255             || (strstr(xpath, "/" PCMK_XE_STATUS) != NULL)) {
 256             continue;
 257         }
 258 
 259         if (pcmk__str_eq(op, PCMK_VALUE_DELETE, pcmk__str_none)
 260             && (strstr(xpath, "/" PCMK_XE_PRIMITIVE) != NULL)) {
 261             const char *rsc_id = NULL;
 262             char *search = NULL;
 263             char *mutable = NULL;
 264 
 265             if ((strstr(xpath, PCMK_XE_INSTANCE_ATTRIBUTES) != NULL)
 266                 || (strstr(xpath, PCMK_XE_META_ATTRIBUTES) != NULL)) {
 267 
 268                 reason = pcmk__str_copy("(meta) attribute deleted from "
 269                                         "resource");
 270                 break;
 271             }
 272             mutable = pcmk__str_copy(xpath);
 273             rsc_id = strstr(mutable, PCMK_XE_PRIMITIVE "[@" PCMK_XA_ID "=\'");
 274             if (rsc_id != NULL) {
 275                 rsc_id += strlen(PCMK_XE_PRIMITIVE "[@" PCMK_XA_ID "=\'");
 276                 search = strchr(rsc_id, '\'');
 277             }
 278             if (search != NULL) {
 279                 *search = 0;
 280                 stonith_device_remove(rsc_id, true);
 281                 /* watchdog_device_update called afterwards
 282                    to fall back to implicit definition if needed */
 283             } else {
 284                 crm_warn("Ignoring malformed CIB update (resource deletion)");
 285             }
 286             free(mutable);
 287 
 288         } else if (strstr(xpath, "/" PCMK_XE_RESOURCES)
 289                    || strstr(xpath, "/" PCMK_XE_CONSTRAINTS)
 290                    || strstr(xpath, "/" PCMK_XE_RSC_DEFAULTS)) {
 291             shortpath = strrchr(xpath, '/');
 292             pcmk__assert(shortpath != NULL);
 293             reason = crm_strdup_printf("%s %s", op, shortpath+1);
 294             break;
 295         }
 296     }
 297 
 298     if (reason != NULL) {
 299         crm_info("Updating device list from CIB: %s", reason);
 300         cib_devices_update();
 301         free(reason);
 302     } else {
 303         crm_trace("No updates for device list found in CIB");
 304     }
 305 }
 306 
 307 static void
 308 watchdog_device_update(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 309 {
 310     if (stonith_watchdog_timeout_ms > 0) {
 311         if (!g_hash_table_lookup(device_list, STONITH_WATCHDOG_ID) &&
 312             !stonith_watchdog_targets) {
 313             /* getting here watchdog-fencing enabled, no device there yet
 314                and reason isn't stonith_watchdog_targets preventing that
 315              */
 316             int rc;
 317             xmlNode *xml;
 318 
 319             xml = create_device_registration_xml(
 320                     STONITH_WATCHDOG_ID,
 321                     st_namespace_internal,
 322                     STONITH_WATCHDOG_AGENT,
 323                     NULL, /* stonith_device_register will add our
 324                              own name as PCMK_STONITH_HOST_LIST param
 325                              so we can skip that here
 326                            */
 327                     NULL);
 328             rc = stonith_device_register(xml, TRUE);
 329             pcmk__xml_free(xml);
 330             if (rc != pcmk_ok) {
 331                 rc = pcmk_legacy2rc(rc);
 332                 exit_code = CRM_EX_FATAL;
 333                 crm_crit("Cannot register watchdog pseudo fence agent: %s",
 334                          pcmk_rc_str(rc));
 335                 stonith_shutdown(0);
 336             }
 337         }
 338 
 339     } else if (g_hash_table_lookup(device_list, STONITH_WATCHDOG_ID) != NULL) {
 340         /* be silent if no device - todo parameter to stonith_device_remove */
 341         stonith_device_remove(STONITH_WATCHDOG_ID, true);
 342     }
 343 }
 344 
 345 /*!
 346  * \internal
 347  * \brief Query the full CIB
 348  *
 349  * \return Standard Pacemaker return code
 350  */
 351 static int
 352 fenced_query_cib(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 353 {
 354     int rc = pcmk_ok;
 355 
 356     crm_trace("Re-requesting full CIB");
 357     rc = cib_api->cmds->query(cib_api, NULL, &local_cib, cib_sync_call);
 358     rc = pcmk_legacy2rc(rc);
 359     if (rc == pcmk_rc_ok) {
 360         pcmk__assert(local_cib != NULL);
 361     } else {
 362         crm_err("Couldn't retrieve the CIB: %s " QB_XS " rc=%d",
 363                 pcmk_rc_str(rc), rc);
 364     }
 365     return rc;
 366 }
 367 
 368 static void
 369 update_fencing_topology(const char *event, xmlNode *msg)
     /* [previous][next][first][last][top][bottom][index][help] */
 370 {
 371     xmlNode *wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT,
 372                                             NULL, NULL);
 373     xmlNode *patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
 374 
 375     int format = 1;
 376 
 377     int add[] = { 0, 0, 0 };
 378     int del[] = { 0, 0, 0 };
 379 
 380     CRM_CHECK(patchset != NULL, return);
 381 
 382     crm_element_value_int(patchset, PCMK_XA_FORMAT, &format);
 383     if (format != 2) {
 384         crm_warn("Unknown patch format: %d", format);
 385         return;
 386     }
 387 
 388     xml_patch_versions(patchset, add, del);
 389 
 390     for (xmlNode *change = pcmk__xe_first_child(patchset, NULL, NULL, NULL);
 391          change != NULL; change = pcmk__xe_next(change, NULL)) {
 392 
 393         const char *op = crm_element_value(change, PCMK_XA_OPERATION);
 394         const char *xpath = crm_element_value(change, PCMK_XA_PATH);
 395 
 396         if (op == NULL) {
 397             continue;
 398         }
 399 
 400         if (strstr(xpath, "/" PCMK_XE_FENCING_LEVEL) != NULL) {
 401             // Change to a specific entry
 402             crm_trace("Handling %s operation %d.%d.%d for %s",
 403                       op, add[0], add[1], add[2], xpath);
 404 
 405             if (strcmp(op, PCMK_VALUE_DELETE) == 0) {
 406                 /* We have only path and ID, which is not enough info to remove
 407                  * a specific entry. Re-initialize the whole topology.
 408                  */
 409                 crm_info("Re-initializing fencing topology after %s operation "
 410                          "%d.%d.%d for %s",
 411                          op, add[0], add[1], add[2], xpath);
 412                 fencing_topology_init();
 413                 return;
 414             }
 415 
 416             if (strcmp(op, PCMK_VALUE_CREATE) == 0) {
 417                 add_topology_level(change->children);
 418 
 419             } else if (strcmp(op, PCMK_VALUE_MODIFY) == 0) {
 420                 xmlNode *match = pcmk__xe_first_child(change,
 421                                                       PCMK_XE_CHANGE_RESULT,
 422                                                       NULL, NULL);
 423 
 424                 if (match != NULL) {
 425                     remove_topology_level(match->children);
 426                     add_topology_level(match->children);
 427                 }
 428             }
 429             continue;
 430         }
 431 
 432         if (strstr(xpath, "/" PCMK_XE_FENCING_TOPOLOGY) != NULL) {
 433             // Change to the topology in general
 434             crm_info("Re-initializing fencing topology after top-level "
 435                      "%s operation %d.%d.%d for %s",
 436                      op, add[0], add[1], add[2], xpath);
 437             fencing_topology_init();
 438             return;
 439         }
 440 
 441         if ((strstr(xpath, "/" PCMK_XE_CONFIGURATION) != NULL)
 442             && (pcmk__xe_first_child(change, PCMK_XE_FENCING_TOPOLOGY, NULL,
 443                                      NULL) != NULL)
 444             && pcmk__str_any_of(op, PCMK_VALUE_CREATE, PCMK_VALUE_DELETE,
 445                                 NULL)) {
 446 
 447             // Topology was created or entire configuration section was deleted
 448             crm_info("Re-initializing fencing topology after top-level "
 449                      "%s operation %d.%d.%d for %s",
 450                      op, add[0], add[1], add[2], xpath);
 451             fencing_topology_init();
 452             return;
 453         }
 454 
 455         crm_trace("Nothing for us in %s operation %d.%d.%d for %s",
 456                   op, add[0], add[1], add[2], xpath);
 457     }
 458 }
 459 
 460 static void
 461 update_cib_cache_cb(const char *event, xmlNode * msg)
     /* [previous][next][first][last][top][bottom][index][help] */
 462 {
 463     long long timeout_ms_saved = stonith_watchdog_timeout_ms;
 464     bool need_full_refresh = false;
 465 
 466     if(!have_cib_devices) {
 467         crm_trace("Skipping updates until we get a full dump");
 468         return;
 469 
 470     } else if(msg == NULL) {
 471         crm_trace("Missing %s update", event);
 472         return;
 473     }
 474 
 475     /* Maintain a local copy of the CIB so that we have full access
 476      * to device definitions, location constraints, and node attributes
 477      */
 478     if (local_cib != NULL) {
 479         int rc = pcmk_ok;
 480         xmlNode *wrapper = NULL;
 481         xmlNode *patchset = NULL;
 482 
 483         crm_element_value_int(msg, PCMK__XA_CIB_RC, &rc);
 484         if (rc != pcmk_ok) {
 485             return;
 486         }
 487 
 488         wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT, NULL,
 489                                        NULL);
 490         patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
 491 
 492         rc = xml_apply_patchset(local_cib, patchset, TRUE);
 493         switch (rc) {
 494             case pcmk_ok:
 495             case -pcmk_err_old_data:
 496                 break;
 497             case -pcmk_err_diff_resync:
 498             case -pcmk_err_diff_failed:
 499                 crm_notice("[%s] Patch aborted: %s (%d)", event, pcmk_strerror(rc), rc);
 500                 pcmk__xml_free(local_cib);
 501                 local_cib = NULL;
 502                 break;
 503             default:
 504                 crm_warn("[%s] ABORTED: %s (%d)", event, pcmk_strerror(rc), rc);
 505                 pcmk__xml_free(local_cib);
 506                 local_cib = NULL;
 507         }
 508     }
 509 
 510     if (local_cib == NULL) {
 511         if (fenced_query_cib() != pcmk_rc_ok) {
 512             return;
 513         }
 514         need_full_refresh = true;
 515     }
 516 
 517     pcmk__refresh_node_caches_from_cib(local_cib);
 518     update_stonith_watchdog_timeout_ms(local_cib);
 519 
 520     if (timeout_ms_saved != stonith_watchdog_timeout_ms) {
 521         need_full_refresh = true;
 522     }
 523 
 524     if (need_full_refresh) {
 525         fencing_topology_init();
 526         cib_devices_update();
 527     } else {
 528         // Partial refresh
 529         update_fencing_topology(event, msg);
 530         update_cib_stonith_devices(event, msg);
 531     }
 532 
 533     watchdog_device_update();
 534 }
 535 
 536 static void
 537 init_cib_cache_cb(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 538 {
 539     crm_info("Updating device list from CIB");
 540     have_cib_devices = TRUE;
 541     local_cib = pcmk__xml_copy(NULL, output);
 542 
 543     pcmk__refresh_node_caches_from_cib(local_cib);
 544     update_stonith_watchdog_timeout_ms(local_cib);
 545 
 546     fencing_topology_init();
 547     cib_devices_update();
 548     watchdog_device_update();
 549 }
 550 
 551 static void
 552 cib_connection_destroy(gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 553 {
 554     if (stonith_shutdown_flag) {
 555         crm_info("Connection to the CIB manager closed");
 556         return;
 557     } else {
 558         crm_crit("Lost connection to the CIB manager, shutting down");
 559     }
 560     if (cib_api) {
 561         cib_api->cmds->signoff(cib_api);
 562     }
 563     stonith_shutdown(0);
 564 }
 565 
 566 /*!
 567  * \internal
 568  * \brief Disconnect from CIB manager
 569  */
 570 void
 571 fenced_cib_cleanup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 572 {
 573     if (cib_api != NULL) {
 574         cib_api->cmds->del_notify_callback(cib_api, PCMK__VALUE_CIB_DIFF_NOTIFY,
 575                                            update_cib_cache_cb);
 576         cib__clean_up_connection(&cib_api);
 577     }
 578     pcmk__xml_free(local_cib);
 579     local_cib = NULL;
 580 }
 581 
 582 void
 583 setup_cib(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 584 {
 585     int rc, retries = 0;
 586 
 587     cib_api = cib_new();
 588     if (cib_api == NULL) {
 589         crm_err("No connection to the CIB manager");
 590         return;
 591     }
 592 
 593     do {
 594         sleep(retries);
 595         rc = cib_api->cmds->signon(cib_api, crm_system_name, cib_command);
 596     } while (rc == -ENOTCONN && ++retries < 5);
 597 
 598     if (rc != pcmk_ok) {
 599         crm_err("Could not connect to the CIB manager: %s (%d)", pcmk_strerror(rc), rc);
 600         return;
 601     }
 602 
 603     rc = cib_api->cmds->add_notify_callback(cib_api,
 604                                             PCMK__VALUE_CIB_DIFF_NOTIFY,
 605                                             update_cib_cache_cb);
 606     if (rc != pcmk_ok) {
 607         crm_err("Could not set CIB notification callback");
 608         return;
 609     }
 610 
 611     rc = cib_api->cmds->query(cib_api, NULL, NULL, cib_none);
 612     cib_api->cmds->register_callback(cib_api, rc, 120, FALSE, NULL,
 613                                      "init_cib_cache_cb", init_cib_cache_cb);
 614     cib_api->cmds->set_connection_dnotify(cib_api, cib_connection_destroy);
 615     crm_info("Watching for fencing topology changes");
 616 }

/* [previous][next][first][last][top][bottom][index][help] */