root/lib/cluster/corosync.c

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

DEFINITIONS

This source file includes following definitions.
  1. get_corosync_uuid
  2. corosync_node_name
  3. terminate_cs_connection
  4. pcmk_quorum_dispatch
  5. pcmk_quorum_notification
  6. cluster_connect_quorum
  7. init_cs_connection
  8. init_cs_connection_once
  9. check_message_sanity
  10. find_corosync_variant
  11. crm_is_corosync_peer_active
  12. corosync_initialize_nodelist
  13. corosync_cluster_name
  14. corosync_cmap_has_config

   1 /*
   2  * Copyright 2004-2019 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 Lesser General Public License
   7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <sys/socket.h>
  13 #include <netinet/in.h>
  14 #include <arpa/inet.h>
  15 #include <netdb.h>
  16 #include <inttypes.h>  /* U64T ~ PRIu64 */
  17 
  18 #include <bzlib.h>
  19 
  20 #include <crm/common/ipc.h>
  21 #include <crm/cluster/internal.h>
  22 #include <crm/common/mainloop.h>
  23 #include <sys/utsname.h>
  24 
  25 #include <qb/qbipcc.h>
  26 #include <qb/qbutil.h>
  27 
  28 #include <corosync/corodefs.h>
  29 #include <corosync/corotypes.h>
  30 #include <corosync/hdb.h>
  31 #include <corosync/cfg.h>
  32 #include <corosync/cmap.h>
  33 #include <corosync/quorum.h>
  34 
  35 #include <crm/msg_xml.h>
  36 
  37 #include <crm/common/ipc_internal.h>  /* PCMK__SPECIAL_PID* */
  38 
  39 quorum_handle_t pcmk_quorum_handle = 0;
  40 
  41 gboolean(*quorum_app_callback) (unsigned long long seq, gboolean quorate) = NULL;
  42 
  43 char *
  44 get_corosync_uuid(crm_node_t *node)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46     if (node && is_corosync_cluster()) {
  47         if (node->id > 0) {
  48             return crm_strdup_printf("%u", node->id);
  49         } else {
  50             crm_info("Node %s is not yet known by corosync", node->uname);
  51         }
  52     }
  53     return NULL;
  54 }
  55 
  56 /*
  57  * CFG functionality stolen from node_name() in corosync-quorumtool.c
  58  * This resolves the first address assigned to a node and returns the name or IP address.
  59  */
  60 char *
  61 corosync_node_name(uint64_t /*cmap_handle_t */ cmap_handle, uint32_t nodeid)
     /* [previous][next][first][last][top][bottom][index][help] */
  62 {
  63     int lpc = 0;
  64     cs_error_t rc = CS_OK;
  65     int retries = 0;
  66     char *name = NULL;
  67     cmap_handle_t local_handle = 0;
  68     int fd = -1;
  69     uid_t found_uid = 0;
  70     gid_t found_gid = 0;
  71     pid_t found_pid = 0;
  72     int rv;
  73 
  74     if (nodeid == 0) {
  75         nodeid = get_local_nodeid(0);
  76     }
  77 
  78     if (cmap_handle == 0 && local_handle == 0) {
  79         retries = 0;
  80         crm_trace("Initializing CMAP connection");
  81         do {
  82             rc = cmap_initialize(&local_handle);
  83             if (rc != CS_OK) {
  84                 retries++;
  85                 crm_debug("API connection setup failed: %s.  Retrying in %ds", cs_strerror(rc),
  86                           retries);
  87                 sleep(retries);
  88             }
  89 
  90         } while (retries < 5 && rc != CS_OK);
  91 
  92         if (rc != CS_OK) {
  93             crm_warn("Could not connect to Cluster Configuration Database API, error %s",
  94                      cs_strerror(rc));
  95             local_handle = 0;
  96         }
  97     }
  98 
  99     if (cmap_handle == 0) {
 100         cmap_handle = local_handle;
 101 
 102         rc = cmap_fd_get(cmap_handle, &fd);
 103         if (rc != CS_OK) {
 104             crm_err("Could not obtain the CMAP API connection: %s (%d)",
 105                     cs_strerror(rc), rc);
 106             goto bail;
 107         }
 108 
 109         /* CMAP provider run as root (in given user namespace, anyway)? */
 110         if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
 111                                                 &found_uid, &found_gid))) {
 112             crm_err("CMAP provider is not authentic:"
 113                     " process %lld (uid: %lld, gid: %lld)",
 114                     (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
 115                     (long long) found_uid, (long long) found_gid);
 116             goto bail;
 117         } else if (rv < 0) {
 118             crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
 119                     strerror(-rv), -rv);
 120             goto bail;
 121         }
 122     }
 123 
 124     while (name == NULL && cmap_handle != 0) {
 125         uint32_t id = 0;
 126         char *key = NULL;
 127 
 128         key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
 129         rc = cmap_get_uint32(cmap_handle, key, &id);
 130         crm_trace("Checking %u vs %u from %s", nodeid, id, key);
 131         free(key);
 132 
 133         if (rc != CS_OK) {
 134             break;
 135         }
 136 
 137         if (nodeid == id) {
 138             crm_trace("Searching for node name for %u in nodelist.node.%d %s", nodeid, lpc, name);
 139             if (name == NULL) {
 140                 key = crm_strdup_printf("nodelist.node.%d.name", lpc);
 141                 cmap_get_string(cmap_handle, key, &name);
 142                 crm_trace("%s = %s", key, name);
 143                 free(key);
 144             }
 145             if (name == NULL) {
 146                 key = crm_strdup_printf("nodelist.node.%d.ring0_addr", lpc);
 147                 cmap_get_string(cmap_handle, key, &name);
 148                 crm_trace("%s = %s", key, name);
 149 
 150                 if (node_name_is_valid(key, name) == FALSE) {
 151                     free(name);
 152                     name = NULL;
 153                 }
 154                 free(key);
 155             }
 156             break;
 157         }
 158 
 159         lpc++;
 160     }
 161 
 162 bail:
 163     if(local_handle) {
 164         cmap_finalize(local_handle);
 165     }
 166 
 167     if (name == NULL) {
 168         crm_info("Unable to get node name for nodeid %u", nodeid);
 169     }
 170     return name;
 171 }
 172 
 173 void
 174 terminate_cs_connection(crm_cluster_t *cluster)
     /* [previous][next][first][last][top][bottom][index][help] */
 175 {
 176     cluster_disconnect_cpg(cluster);
 177     if (pcmk_quorum_handle) {
 178         quorum_finalize(pcmk_quorum_handle);
 179         pcmk_quorum_handle = 0;
 180     }
 181     crm_notice("Disconnected from Corosync");
 182 }
 183 
 184 static int
 185 pcmk_quorum_dispatch(gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 186 {
 187     int rc = 0;
 188 
 189     rc = quorum_dispatch(pcmk_quorum_handle, CS_DISPATCH_ALL);
 190     if (rc < 0) {
 191         crm_err("Connection to the Quorum API failed: %d", rc);
 192         quorum_finalize(pcmk_quorum_handle);
 193         pcmk_quorum_handle = 0;
 194         return -1;
 195     }
 196     return 0;
 197 }
 198 
 199 static void
 200 pcmk_quorum_notification(quorum_handle_t handle,
     /* [previous][next][first][last][top][bottom][index][help] */
 201                          uint32_t quorate,
 202                          uint64_t ring_id, uint32_t view_list_entries, uint32_t * view_list)
 203 {
 204     int i;
 205     GHashTableIter iter;
 206     crm_node_t *node = NULL;
 207     static gboolean init_phase = TRUE;
 208 
 209     if (quorate != crm_have_quorum) {
 210         if (quorate) {
 211             crm_notice("Quorum acquired " CRM_XS " membership=%" U64T " members=%lu",
 212                        ring_id, (long unsigned int)view_list_entries);
 213         } else {
 214             crm_warn("Quorum lost " CRM_XS " membership=%" U64T " members=%lu",
 215                      ring_id, (long unsigned int)view_list_entries);
 216         }
 217         crm_have_quorum = quorate;
 218 
 219     } else {
 220         crm_info("Quorum %s " CRM_XS " membership=%" U64T " members=%lu",
 221                  (quorate? "retained" : "still lost"), ring_id,
 222                  (long unsigned int)view_list_entries);
 223     }
 224 
 225     if (view_list_entries == 0 && init_phase) {
 226         crm_info("Corosync membership is still forming, ignoring");
 227         return;
 228     }
 229 
 230     init_phase = FALSE;
 231 
 232     /* Reset last_seen for all cached nodes so we can tell which ones aren't
 233      * in the view list */
 234     g_hash_table_iter_init(&iter, crm_peer_cache);
 235     while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
 236         node->last_seen = 0;
 237     }
 238 
 239     /* Update the peer cache for each node in view list */
 240     for (i = 0; i < view_list_entries; i++) {
 241         uint32_t id = view_list[i];
 242 
 243         crm_debug("Member[%d] %u ", i, id);
 244 
 245         /* Get this node's peer cache entry (adding one if not already there) */
 246         node = crm_get_peer(id, NULL);
 247         if (node->uname == NULL) {
 248             char *name = corosync_node_name(0, id);
 249 
 250             crm_info("Obtaining name for new node %u", id);
 251             node = crm_get_peer(id, name);
 252             free(name);
 253         }
 254 
 255         /* Update the node state (including updating last_seen to ring_id) */
 256         crm_update_peer_state(__func__, node, CRM_NODE_MEMBER, ring_id);
 257     }
 258 
 259     /* Remove any peer cache entries we didn't update */
 260     crm_reap_unseen_nodes(ring_id);
 261 
 262     if (quorum_app_callback) {
 263         quorum_app_callback(ring_id, quorate);
 264     }
 265 }
 266 
 267 quorum_callbacks_t quorum_callbacks = {
 268     .quorum_notify_fn = pcmk_quorum_notification,
 269 };
 270 
 271 gboolean
 272 cluster_connect_quorum(gboolean(*dispatch) (unsigned long long, gboolean),
     /* [previous][next][first][last][top][bottom][index][help] */
 273                        void (*destroy) (gpointer))
 274 {
 275     cs_error_t rc;
 276     int fd = 0;
 277     int quorate = 0;
 278     uint32_t quorum_type = 0;
 279     struct mainloop_fd_callbacks quorum_fd_callbacks;
 280     uid_t found_uid = 0;
 281     gid_t found_gid = 0;
 282     pid_t found_pid = 0;
 283     int rv;
 284 
 285     quorum_fd_callbacks.dispatch = pcmk_quorum_dispatch;
 286     quorum_fd_callbacks.destroy = destroy;
 287 
 288     crm_debug("Configuring Pacemaker to obtain quorum from Corosync");
 289 
 290     rc = quorum_initialize(&pcmk_quorum_handle, &quorum_callbacks, &quorum_type);
 291     if (rc != CS_OK) {
 292         crm_err("Could not connect to the Quorum API: %s (%d)",
 293                 cs_strerror(rc), rc);
 294         goto bail;
 295 
 296     } else if (quorum_type != QUORUM_SET) {
 297         crm_err("Corosync quorum is not configured");
 298         goto bail;
 299     }
 300 
 301     rc = quorum_fd_get(pcmk_quorum_handle, &fd);
 302     if (rc != CS_OK) {
 303         crm_err("Could not obtain the Quorum API connection: %s (%d)",
 304                 strerror(rc), rc);
 305         goto bail;
 306     }
 307 
 308     /* Quorum provider run as root (in given user namespace, anyway)? */
 309     if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
 310                                             &found_uid, &found_gid))) {
 311         crm_err("Quorum provider is not authentic:"
 312                 " process %lld (uid: %lld, gid: %lld)",
 313                 (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
 314                 (long long) found_uid, (long long) found_gid);
 315         rc = CS_ERR_ACCESS;
 316         goto bail;
 317     } else if (rv < 0) {
 318         crm_err("Could not verify authenticity of Quorum provider: %s (%d)",
 319                 strerror(-rv), -rv);
 320         rc = CS_ERR_ACCESS;
 321         goto bail;
 322     }
 323 
 324     rc = quorum_getquorate(pcmk_quorum_handle, &quorate);
 325     if (rc != CS_OK) {
 326         crm_err("Could not obtain the current Quorum API state: %d", rc);
 327         goto bail;
 328     }
 329 
 330     if (quorate) {
 331         crm_notice("Quorum acquired");
 332     } else {
 333         crm_warn("Quorum lost");
 334     }
 335     quorum_app_callback = dispatch;
 336     crm_have_quorum = quorate;
 337 
 338     rc = quorum_trackstart(pcmk_quorum_handle, CS_TRACK_CHANGES | CS_TRACK_CURRENT);
 339     if (rc != CS_OK) {
 340         crm_err("Could not setup Quorum API notifications: %d", rc);
 341         goto bail;
 342     }
 343 
 344     mainloop_add_fd("quorum", G_PRIORITY_HIGH, fd, dispatch, &quorum_fd_callbacks);
 345 
 346     corosync_initialize_nodelist(NULL, FALSE, NULL);
 347 
 348   bail:
 349     if (rc != CS_OK) {
 350         quorum_finalize(pcmk_quorum_handle);
 351         return FALSE;
 352     }
 353     return TRUE;
 354 }
 355 
 356 gboolean
 357 init_cs_connection(crm_cluster_t * cluster)
     /* [previous][next][first][last][top][bottom][index][help] */
 358 {
 359     int retries = 0;
 360 
 361     while (retries < 5) {
 362         int rc = init_cs_connection_once(cluster);
 363 
 364         retries++;
 365 
 366         switch (rc) {
 367             case CS_OK:
 368                 return TRUE;
 369             case CS_ERR_TRY_AGAIN:
 370             case CS_ERR_QUEUE_FULL:
 371                 sleep(retries);
 372                 break;
 373             default:
 374                 return FALSE;
 375         }
 376     }
 377 
 378     crm_err("Could not connect to corosync after %d retries", retries);
 379     return FALSE;
 380 }
 381 
 382 gboolean
 383 init_cs_connection_once(crm_cluster_t * cluster)
     /* [previous][next][first][last][top][bottom][index][help] */
 384 {
 385     crm_node_t *peer = NULL;
 386     enum cluster_type_e stack = get_cluster_type();
 387 
 388     crm_peer_init();
 389 
 390     /* Here we just initialize comms */
 391     if (stack != pcmk_cluster_corosync) {
 392         crm_err("Invalid cluster type: %s (%d)", name_for_cluster_type(stack), stack);
 393         return FALSE;
 394     }
 395 
 396     if (cluster_connect_cpg(cluster) == FALSE) {
 397         return FALSE;
 398     }
 399     crm_info("Connection to '%s': established", name_for_cluster_type(stack));
 400 
 401     cluster->nodeid = get_local_nodeid(0);
 402     if(cluster->nodeid == 0) {
 403         crm_err("Could not establish local nodeid");
 404         return FALSE;
 405     }
 406 
 407     cluster->uname = get_node_name(0);
 408     if(cluster->uname == NULL) {
 409         crm_err("Could not establish local node name");
 410         return FALSE;
 411     }
 412 
 413     /* Ensure the local node always exists */
 414     peer = crm_get_peer(cluster->nodeid, cluster->uname);
 415     cluster->uuid = get_corosync_uuid(peer);
 416 
 417     return TRUE;
 418 }
 419 
 420 gboolean
 421 check_message_sanity(const AIS_Message * msg, const char *data)
     /* [previous][next][first][last][top][bottom][index][help] */
 422 {
 423     gboolean sane = TRUE;
 424     int dest = msg->host.type;
 425     int tmp_size = msg->header.size - sizeof(AIS_Message);
 426 
 427     if (sane && msg->header.size == 0) {
 428         crm_warn("Message with no size");
 429         sane = FALSE;
 430     }
 431 
 432     if (sane && msg->header.error != CS_OK) {
 433         crm_warn("Message header contains an error: %d", msg->header.error);
 434         sane = FALSE;
 435     }
 436 
 437     if (sane && ais_data_len(msg) != tmp_size) {
 438         crm_warn("Message payload size is incorrect: expected %d, got %d", ais_data_len(msg),
 439                  tmp_size);
 440         sane = TRUE;
 441     }
 442 
 443     if (sane && ais_data_len(msg) == 0) {
 444         crm_warn("Message with no payload");
 445         sane = FALSE;
 446     }
 447 
 448     if (sane && data && msg->is_compressed == FALSE) {
 449         int str_size = strlen(data) + 1;
 450 
 451         if (ais_data_len(msg) != str_size) {
 452             int lpc = 0;
 453 
 454             crm_warn("Message payload is corrupted: expected %d bytes, got %d",
 455                      ais_data_len(msg), str_size);
 456             sane = FALSE;
 457             for (lpc = (str_size - 10); lpc < msg->size; lpc++) {
 458                 if (lpc < 0) {
 459                     lpc = 0;
 460                 }
 461                 crm_debug("bad_data[%d]: %d / '%c'", lpc, data[lpc], data[lpc]);
 462             }
 463         }
 464     }
 465 
 466     if (sane == FALSE) {
 467         crm_err("Invalid message %d: (dest=%s:%s, from=%s:%s.%u, compressed=%d, size=%d, total=%d)",
 468                 msg->id, ais_dest(&(msg->host)), msg_type2text(dest),
 469                 ais_dest(&(msg->sender)), msg_type2text(msg->sender.type),
 470                 msg->sender.pid, msg->is_compressed, ais_data_len(msg), msg->header.size);
 471 
 472     } else {
 473         crm_trace
 474             ("Verified message %d: (dest=%s:%s, from=%s:%s.%u, compressed=%d, size=%d, total=%d)",
 475              msg->id, ais_dest(&(msg->host)), msg_type2text(dest), ais_dest(&(msg->sender)),
 476              msg_type2text(msg->sender.type), msg->sender.pid, msg->is_compressed,
 477              ais_data_len(msg), msg->header.size);
 478     }
 479 
 480     return sane;
 481 }
 482 
 483 enum cluster_type_e
 484 find_corosync_variant(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 485 {
 486     int rc = CS_OK;
 487     cmap_handle_t handle;
 488 
 489     rc = cmap_initialize(&handle);
 490 
 491     switch(rc) {
 492         case CS_OK:
 493             break;
 494         case CS_ERR_SECURITY:
 495             crm_debug("Failed to initialize the cmap API: Permission denied (%d)", rc);
 496             /* It's there, we just can't talk to it.
 497              * Good enough for us to identify as 'corosync'
 498              */
 499             return pcmk_cluster_corosync;
 500 
 501         default:
 502             crm_info("Failed to initialize the cmap API: %s (%d)",
 503                      ais_error2text(rc), rc);
 504             return pcmk_cluster_unknown;
 505     }
 506 
 507     cmap_finalize(handle);
 508     return pcmk_cluster_corosync;
 509 }
 510 
 511 gboolean
 512 crm_is_corosync_peer_active(const crm_node_t * node)
     /* [previous][next][first][last][top][bottom][index][help] */
 513 {
 514     if (node == NULL) {
 515         crm_trace("NULL");
 516         return FALSE;
 517 
 518     } else if (!pcmk__str_eq(node->state, CRM_NODE_MEMBER, pcmk__str_casei)) {
 519         crm_trace("%s: state=%s", node->uname, node->state);
 520         return FALSE;
 521 
 522     } else if ((node->processes & crm_proc_cpg) == 0) {
 523         crm_trace("%s: processes=%.16x", node->uname, node->processes);
 524         return FALSE;
 525     }
 526     return TRUE;
 527 }
 528 
 529 gboolean
 530 corosync_initialize_nodelist(void *cluster, gboolean force_member, xmlNode * xml_parent)
     /* [previous][next][first][last][top][bottom][index][help] */
 531 {
 532     int lpc = 0;
 533     cs_error_t rc = CS_OK;
 534     int retries = 0;
 535     gboolean any = FALSE;
 536     cmap_handle_t cmap_handle;
 537     int fd = -1;
 538     uid_t found_uid = 0;
 539     gid_t found_gid = 0;
 540     pid_t found_pid = 0;
 541     int rv;
 542 
 543     do {
 544         rc = cmap_initialize(&cmap_handle);
 545         if (rc != CS_OK) {
 546             retries++;
 547             crm_debug("API connection setup failed: %s.  Retrying in %ds", cs_strerror(rc),
 548                       retries);
 549             sleep(retries);
 550         }
 551 
 552     } while (retries < 5 && rc != CS_OK);
 553 
 554     if (rc != CS_OK) {
 555         crm_warn("Could not connect to Cluster Configuration Database API, error %d", rc);
 556         return FALSE;
 557     }
 558 
 559     rc = cmap_fd_get(cmap_handle, &fd);
 560     if (rc != CS_OK) {
 561         crm_err("Could not obtain the CMAP API connection: %s (%d)",
 562                 cs_strerror(rc), rc);
 563         goto bail;
 564     }
 565 
 566     /* CMAP provider run as root (in given user namespace, anyway)? */
 567     if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
 568                                             &found_uid, &found_gid))) {
 569         crm_err("CMAP provider is not authentic:"
 570                 " process %lld (uid: %lld, gid: %lld)",
 571                 (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
 572                 (long long) found_uid, (long long) found_gid);
 573         goto bail;
 574     } else if (rv < 0) {
 575         crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
 576                 strerror(-rv), -rv);
 577         goto bail;
 578     }
 579 
 580     crm_peer_init();
 581     crm_trace("Initializing corosync nodelist");
 582     for (lpc = 0; TRUE; lpc++) {
 583         uint32_t nodeid = 0;
 584         char *name = NULL;
 585         char *key = NULL;
 586 
 587         key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
 588         rc = cmap_get_uint32(cmap_handle, key, &nodeid);
 589         free(key);
 590 
 591         if (rc != CS_OK) {
 592             break;
 593         }
 594 
 595         name = corosync_node_name(cmap_handle, nodeid);
 596         if (name != NULL) {
 597             GHashTableIter iter;
 598             crm_node_t *node = NULL;
 599 
 600             g_hash_table_iter_init(&iter, crm_peer_cache);
 601             while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
 602                 if(node && node->uname && strcasecmp(node->uname, name) == 0) {
 603                     if (node->id && node->id != nodeid) {
 604                         crm_crit("Nodes %u and %u share the same name '%s': shutting down", node->id,
 605                                  nodeid, name);
 606                         crm_exit(CRM_EX_FATAL);
 607                     }
 608                 }
 609             }
 610         }
 611 
 612         if (nodeid > 0 || name != NULL) {
 613             crm_trace("Initializing node[%d] %u = %s", lpc, nodeid, name);
 614             crm_get_peer(nodeid, name);
 615         }
 616 
 617         if (nodeid > 0 && name != NULL) {
 618             any = TRUE;
 619 
 620             if (xml_parent) {
 621                 xmlNode *node = create_xml_node(xml_parent, XML_CIB_TAG_NODE);
 622 
 623                 crm_xml_set_id(node, "%u", nodeid);
 624                 crm_xml_add(node, XML_ATTR_UNAME, name);
 625                 if (force_member) {
 626                     crm_xml_add(node, XML_ATTR_TYPE, CRM_NODE_MEMBER);
 627                 }
 628             }
 629         }
 630 
 631         free(name);
 632     }
 633 bail:
 634     cmap_finalize(cmap_handle);
 635     return any;
 636 }
 637 
 638 char *
 639 corosync_cluster_name(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 640 {
 641     cmap_handle_t handle;
 642     char *cluster_name = NULL;
 643     cs_error_t rc = CS_OK;
 644     int fd = -1;
 645     uid_t found_uid = 0;
 646     gid_t found_gid = 0;
 647     pid_t found_pid = 0;
 648     int rv;
 649 
 650     rc = cmap_initialize(&handle);
 651     if (rc != CS_OK) {
 652         crm_info("Failed to initialize the cmap API: %s (%d)",
 653                  cs_strerror(rc), rc);
 654         return NULL;
 655     }
 656 
 657     rc = cmap_fd_get(handle, &fd);
 658     if (rc != CS_OK) {
 659         crm_err("Could not obtain the CMAP API connection: %s (%d)",
 660                 cs_strerror(rc), rc);
 661         goto bail;
 662     }
 663 
 664     /* CMAP provider run as root (in given user namespace, anyway)? */
 665     if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
 666                                             &found_uid, &found_gid))) {
 667         crm_err("CMAP provider is not authentic:"
 668                 " process %lld (uid: %lld, gid: %lld)",
 669                 (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
 670                 (long long) found_uid, (long long) found_gid);
 671         goto bail;
 672     } else if (rv < 0) {
 673         crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
 674                 strerror(-rv), -rv);
 675         goto bail;
 676     }
 677 
 678     rc = cmap_get_string(handle, "totem.cluster_name", &cluster_name);
 679     if (rc != CS_OK) {
 680         crm_info("Cannot get totem.cluster_name: %s (%d)", cs_strerror(rc), rc);
 681 
 682     } else {
 683         crm_debug("cmap totem.cluster_name = '%s'", cluster_name);
 684     }
 685 
 686 bail:
 687     cmap_finalize(handle);
 688     return cluster_name;
 689 }
 690 
 691 /*!
 692  * \internal
 693  * \brief Check whether Corosync has any configuration keys with given prefix
 694  *
 695  * \param[in] prefix  Configuration key prefix
 696  *
 697  * \return -1 on error, 0 if no such key present, 1 if any such key present
 698  * \note This function always returns the result of the first time it was
 699  *       called, even if later called with a different section name (which
 700  *       obviously should never be done), and even if the corosync configuration
 701  *       has since been reloaded.
 702  */
 703 int
 704 corosync_cmap_has_config(const char *prefix)
     /* [previous][next][first][last][top][bottom][index][help] */
 705 {
 706     cs_error_t rc = CS_OK;
 707     int retries = 0;
 708     static int found = -1;
 709     cmap_handle_t cmap_handle;
 710     cmap_iter_handle_t iter_handle;
 711     char key_name[CMAP_KEYNAME_MAXLEN + 1];
 712     int fd = -1;
 713     uid_t found_uid = 0;
 714     gid_t found_gid = 0;
 715     pid_t found_pid = 0;
 716     int rv;
 717 
 718     if(found != -1) {
 719         return found;
 720     }
 721 
 722     do {
 723         rc = cmap_initialize(&cmap_handle);
 724         if (rc != CS_OK) {
 725             retries++;
 726             crm_debug("API connection setup failed: %s.  Retrying in %ds", cs_strerror(rc),
 727                       retries);
 728             sleep(retries);
 729         }
 730 
 731     } while (retries < 5 && rc != CS_OK);
 732 
 733     if (rc != CS_OK) {
 734         crm_warn("Could not connect to Cluster Configuration Database API: %s (rc=%d)",
 735                  cs_strerror(rc), rc);
 736         return -1;
 737     }
 738 
 739     rc = cmap_fd_get(cmap_handle, &fd);
 740     if (rc != CS_OK) {
 741         crm_err("Could not obtain the CMAP API connection: %s (%d)",
 742                 cs_strerror(rc), rc);
 743         goto bail;
 744     }
 745 
 746     /* CMAP provider run as root (in given user namespace, anyway)? */
 747     if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
 748                                             &found_uid, &found_gid))) {
 749         crm_err("CMAP provider is not authentic:"
 750                 " process %lld (uid: %lld, gid: %lld)",
 751                 (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
 752                 (long long) found_uid, (long long) found_gid);
 753         goto bail;
 754     } else if (rv < 0) {
 755         crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
 756                 strerror(-rv), -rv);
 757         goto bail;
 758     }
 759 
 760     rc = cmap_iter_init(cmap_handle, prefix, &iter_handle);
 761     if (rc != CS_OK) {
 762         crm_warn("Failed to initialize iteration for corosync cmap '%s': %s (rc=%d)",
 763                  prefix, cs_strerror(rc), rc);
 764         goto bail;
 765     }
 766 
 767     found = 0;
 768     if (cmap_iter_next(cmap_handle, iter_handle, key_name, NULL, NULL) == CS_OK) {
 769         crm_trace("'%s' is configured in corosync cmap: %s", prefix, key_name);
 770         found = 1;
 771     }
 772     cmap_iter_finalize(cmap_handle, iter_handle);
 773 
 774 bail:
 775     cmap_finalize(cmap_handle);
 776 
 777     return found;
 778 }

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