This source file includes following definitions.
- pcmk__cluster_parse_msg_type
 
- pcmk__cluster_node_uuid
 
- pcmk_cluster_connect
 
- pcmk_cluster_disconnect
 
- pcmk_cluster_new
 
- pcmk_cluster_free
 
- pcmk_cluster_set_destroy_fn
 
- pcmk__cluster_send_message
 
- pcmk__cluster_node_name
 
- pcmk__cluster_local_node_name
 
- pcmk__node_name_from_uuid
 
- pcmk_cluster_layer_text
 
- pcmk_get_cluster_layer
 
- set_uuid
 
- crm_cluster_connect
 
- crm_cluster_disconnect
 
- name_for_cluster_type
 
- get_cluster_type
 
- is_corosync_cluster
 
- send_cluster_message
 
- crm_peer_uuid
 
- get_node_name
 
- get_local_node_name
 
- crm_peer_uname
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <crm_internal.h>
  11 #include <dlfcn.h>
  12 
  13 #include <inttypes.h>               
  14 #include <stdbool.h>
  15 #include <stdio.h>
  16 #include <unistd.h>
  17 #include <string.h>
  18 #include <stdlib.h>
  19 #include <time.h>
  20 #include <sys/param.h>
  21 #include <sys/types.h>
  22 #include <sys/utsname.h>            
  23 
  24 #include <glib.h>                   
  25 
  26 #include <crm/crm.h>
  27 
  28 #include <crm/common/ipc.h>
  29 #include <crm/common/xml.h>
  30 #include <crm/cluster/internal.h>
  31 #include "crmcluster_private.h"
  32 
  33 CRM_TRACE_INIT_DATA(cluster);
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 enum crm_ais_msg_types
  44 pcmk__cluster_parse_msg_type(const char *text)
     
  45 {
  46     CRM_CHECK(text != NULL, return crm_msg_none);
  47 
  48     text = pcmk__message_name(text);
  49 
  50     if (pcmk__str_eq(text, "ais", pcmk__str_none)) {
  51         return crm_msg_ais;
  52     }
  53     if (pcmk__str_eq(text, CRM_SYSTEM_CIB, pcmk__str_none)) {
  54         return crm_msg_cib;
  55     }
  56     if (pcmk__str_any_of(text, CRM_SYSTEM_CRMD, CRM_SYSTEM_DC, NULL)) {
  57         return crm_msg_crmd;
  58     }
  59     if (pcmk__str_eq(text, CRM_SYSTEM_TENGINE, pcmk__str_none)) {
  60         return crm_msg_te;
  61     }
  62     if (pcmk__str_eq(text, CRM_SYSTEM_PENGINE, pcmk__str_none)) {
  63         return crm_msg_pe;
  64     }
  65     if (pcmk__str_eq(text, CRM_SYSTEM_LRMD, pcmk__str_none)) {
  66         return crm_msg_lrmd;
  67     }
  68     if (pcmk__str_eq(text, CRM_SYSTEM_STONITHD, pcmk__str_none)) {
  69         return crm_msg_stonithd;
  70     }
  71     if (pcmk__str_eq(text, "stonith-ng", pcmk__str_none)) {
  72         return crm_msg_stonith_ng;
  73     }
  74     if (pcmk__str_eq(text, "attrd", pcmk__str_none)) {
  75         return crm_msg_attrd;
  76     }
  77     return crm_msg_none;
  78 }
  79 
  80 
  81 
  82 
  83 
  84 
  85 
  86 
  87 
  88 const char *
  89 pcmk__cluster_node_uuid(crm_node_t *node)
     
  90 {
  91     const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
  92 
  93     if (node == NULL) {
  94         return NULL;
  95     }
  96     if (node->uuid != NULL) {
  97         return node->uuid;
  98     }
  99 
 100     switch (cluster_layer) {
 101 #if SUPPORT_COROSYNC
 102         case pcmk_cluster_layer_corosync:
 103             node->uuid = pcmk__corosync_uuid(node);
 104             return node->uuid;
 105 #endif  
 106 
 107         default:
 108             crm_err("Unsupported cluster layer %s",
 109                     pcmk_cluster_layer_text(cluster_layer));
 110             return NULL;
 111     }
 112 }
 113 
 114 
 115 
 116 
 117 
 118 
 119 
 120 
 121 
 122 int
 123 pcmk_cluster_connect(pcmk_cluster_t *cluster)
     
 124 {
 125     const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
 126     const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
 127 
 128     
 129     crm_notice("Connecting to %s cluster layer", cluster_layer_s);
 130 
 131     switch (cluster_layer) {
 132 #if SUPPORT_COROSYNC
 133         case pcmk_cluster_layer_corosync:
 134             return pcmk__corosync_connect(cluster);
 135 #endif 
 136 
 137         default:
 138             break;
 139     }
 140 
 141     crm_err("Failed to connect to unsupported cluster layer %s",
 142             cluster_layer_s);
 143     return EPROTONOSUPPORT;
 144 }
 145 
 146 
 147 
 148 
 149 
 150 
 151 
 152 
 153 int
 154 pcmk_cluster_disconnect(pcmk_cluster_t *cluster)
     
 155 {
 156     const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
 157     const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
 158 
 159     crm_info("Disconnecting from %s cluster layer", cluster_layer_s);
 160 
 161     switch (cluster_layer) {
 162 #if SUPPORT_COROSYNC
 163         case pcmk_cluster_layer_corosync:
 164             pcmk__corosync_disconnect(cluster);
 165             pcmk__cluster_destroy_node_caches();
 166             return pcmk_rc_ok;
 167 #endif 
 168 
 169         default:
 170             break;
 171     }
 172 
 173     crm_err("Failed to disconnect from unsupported cluster layer %s",
 174             cluster_layer_s);
 175     return EPROTONOSUPPORT;
 176 }
 177 
 178 
 179 
 180 
 181 
 182 
 183 
 184 
 185 pcmk_cluster_t *
 186 pcmk_cluster_new(void)
     
 187 {
 188     return (pcmk_cluster_t *) pcmk__assert_alloc(1, sizeof(pcmk_cluster_t));
 189 }
 190 
 191 
 192 
 193 
 194 
 195 
 196 void
 197 pcmk_cluster_free(pcmk_cluster_t *cluster)
     
 198 {
 199     if (cluster == NULL) {
 200         return;
 201     }
 202     free(cluster->uuid);
 203     free(cluster->uname);
 204     free(cluster);
 205 }
 206 
 207 
 208 
 209 
 210 
 211 
 212 
 213 
 214 
 215 int
 216 pcmk_cluster_set_destroy_fn(pcmk_cluster_t *cluster, void (*fn)(gpointer))
     
 217 {
 218     if (cluster == NULL) {
 219         return EINVAL;
 220     }
 221     cluster->destroy = fn;
 222     return pcmk_rc_ok;
 223 }
 224 
 225 
 226 
 227 
 228 
 229 
 230 
 231 
 232 
 233 
 234 
 235 bool
 236 pcmk__cluster_send_message(const crm_node_t *node,
     
 237                            enum crm_ais_msg_types service, const xmlNode *data)
 238 {
 239     
 240     switch (pcmk_get_cluster_layer()) {
 241 #if SUPPORT_COROSYNC
 242         case pcmk_cluster_layer_corosync:
 243             return pcmk__cpg_send_xml(data, node, service);
 244 #endif  
 245 
 246         default:
 247             break;
 248     }
 249     return false;
 250 }
 251 
 252 
 253 
 254 
 255 
 256 
 257 
 258 
 259 
 260 
 261 
 262 
 263 
 264 
 265 
 266 
 267 
 268 char *
 269 pcmk__cluster_node_name(uint32_t nodeid)
     
 270 {
 271     char *name = NULL;
 272     const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
 273     const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
 274 
 275     switch (cluster_layer) {
 276 #if SUPPORT_COROSYNC
 277         case pcmk_cluster_layer_corosync:
 278             name = pcmk__corosync_name(0, nodeid);
 279             if (name != NULL) {
 280                 return name;
 281             }
 282             break;
 283 #endif 
 284 
 285         default:
 286             crm_err("Unsupported cluster layer: %s", cluster_layer_s);
 287             break;
 288     }
 289 
 290     if (nodeid == 0) {
 291         struct utsname hostinfo;
 292 
 293         crm_notice("Could not get local node name from %s cluster layer, "
 294                    "defaulting to local hostname",
 295                    cluster_layer_s);
 296 
 297         if (uname(&hostinfo) < 0) {
 298             
 299             crm_err("Failed to get the local hostname");
 300             crm_exit(CRM_EX_FATAL);
 301         }
 302         return pcmk__str_copy(hostinfo.nodename);
 303     }
 304 
 305     crm_notice("Could not obtain a node name for node with "
 306                PCMK_XA_ID "=" PRIu32,
 307                nodeid);
 308     return NULL;
 309 }
 310 
 311 
 312 
 313 
 314 
 315 
 316 
 317 
 318 
 319 
 320 
 321 
 322 
 323 
 324 const char *
 325 pcmk__cluster_local_node_name(void)
     
 326 {
 327     
 328     static char *name = NULL;
 329 
 330     if (name == NULL) {
 331         name = pcmk__cluster_node_name(0);
 332     }
 333     return name;
 334 }
 335 
 336 
 337 
 338 
 339 
 340 
 341 
 342 
 343 
 344 
 345 
 346 const char *
 347 pcmk__node_name_from_uuid(const char *uuid)
     
 348 {
 349     
 350 
 351 
 352 
 353 
 354 
 355 
 356 
 357 
 358 
 359 
 360 
 361     GHashTableIter iter;
 362     crm_node_t *node = NULL;
 363 
 364     CRM_CHECK(uuid != NULL, return NULL);
 365 
 366     
 367     if (g_hash_table_lookup(crm_remote_peer_cache, uuid)) {
 368         return uuid;
 369     }
 370 
 371     g_hash_table_iter_init(&iter, crm_peer_cache);
 372     while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
 373         if (pcmk__str_eq(node->uuid, uuid, pcmk__str_casei)) {
 374             return node->uname;
 375         }
 376     }
 377     return NULL;
 378 }
 379 
 380 
 381 
 382 
 383 
 384 
 385 
 386 
 387 const char *
 388 pcmk_cluster_layer_text(enum pcmk_cluster_layer layer)
     
 389 {
 390     switch (layer) {
 391         case pcmk_cluster_layer_corosync:
 392             return "corosync";
 393         case pcmk_cluster_layer_unknown:
 394             return "unknown";
 395         case pcmk_cluster_layer_invalid:
 396             return "invalid";
 397         default:
 398             crm_err("Invalid cluster layer: %d", layer);
 399             return "invalid";
 400     }
 401 }
 402 
 403 
 404 
 405 
 406 
 407 
 408 
 409 
 410 
 411 
 412 
 413 
 414 enum pcmk_cluster_layer
 415 pcmk_get_cluster_layer(void)
     
 416 {
 417     static enum pcmk_cluster_layer cluster_layer = pcmk_cluster_layer_unknown;
 418     const char *cluster = NULL;
 419 
 420     
 421     if (cluster_layer != pcmk_cluster_layer_unknown) {
 422         return cluster_layer;
 423     }
 424 
 425     cluster = pcmk__env_option(PCMK__ENV_CLUSTER_TYPE);
 426 
 427     if (cluster != NULL) {
 428         crm_info("Verifying configured cluster layer '%s'", cluster);
 429         cluster_layer = pcmk_cluster_layer_invalid;
 430 
 431 #if SUPPORT_COROSYNC
 432         if (pcmk__str_eq(cluster, PCMK_VALUE_COROSYNC, pcmk__str_casei)) {
 433             cluster_layer = pcmk_cluster_layer_corosync;
 434         }
 435 #endif  
 436 
 437         if (cluster_layer == pcmk_cluster_layer_invalid) {
 438             crm_notice("This installation does not support the '%s' cluster "
 439                        "infrastructure: terminating",
 440                        cluster);
 441             crm_exit(CRM_EX_FATAL);
 442         }
 443         crm_info("Assuming an active '%s' cluster", cluster);
 444 
 445     } else {
 446         
 447 #if SUPPORT_COROSYNC
 448         crm_debug("Testing with Corosync");
 449         if (pcmk__corosync_is_active()) {
 450             cluster_layer = pcmk_cluster_layer_corosync;
 451         }
 452 #endif  
 453 
 454         if (cluster_layer == pcmk_cluster_layer_unknown) {
 455             crm_notice("Could not determine the current cluster layer");
 456         } else {
 457             crm_info("Detected an active '%s' cluster",
 458                      pcmk_cluster_layer_text(cluster_layer));
 459         }
 460     }
 461 
 462     return cluster_layer;
 463 }
 464 
 465 
 466 
 467 
 468 #include <crm/cluster/compat.h>
 469 
 470 void
 471 set_uuid(xmlNode *xml, const char *attr, crm_node_t *node)
     
 472 {
 473     crm_xml_add(xml, attr, pcmk__cluster_node_uuid(node));
 474 }
 475 
 476 gboolean
 477 crm_cluster_connect(pcmk_cluster_t *cluster)
     
 478 {
 479     return pcmk_cluster_connect(cluster) == pcmk_rc_ok;
 480 }
 481 
 482 void
 483 crm_cluster_disconnect(pcmk_cluster_t *cluster)
     
 484 {
 485     pcmk_cluster_disconnect(cluster);
 486 }
 487 
 488 const char *
 489 name_for_cluster_type(enum cluster_type_e type)
     
 490 {
 491     switch (type) {
 492         case pcmk_cluster_corosync:
 493             return "corosync";
 494         case pcmk_cluster_unknown:
 495             return "unknown";
 496         case pcmk_cluster_invalid:
 497             return "invalid";
 498     }
 499     crm_err("Invalid cluster type: %d", type);
 500     return "invalid";
 501 }
 502 
 503 enum cluster_type_e
 504 get_cluster_type(void)
     
 505 {
 506     return (enum cluster_type_e) pcmk_get_cluster_layer();
 507 }
 508 
 509 gboolean
 510 is_corosync_cluster(void)
     
 511 {
 512     return pcmk_get_cluster_layer() == pcmk_cluster_layer_corosync;
 513 }
 514 
 515 gboolean
 516 send_cluster_message(const crm_node_t *node, enum crm_ais_msg_types service,
     
 517                      const xmlNode *data, gboolean ordered)
 518 {
 519     return pcmk__cluster_send_message(node, service, data);
 520 }
 521 
 522 const char *
 523 crm_peer_uuid(crm_node_t *peer)
     
 524 {
 525     return pcmk__cluster_node_uuid(peer);
 526 }
 527 
 528 char *
 529 get_node_name(uint32_t nodeid)
     
 530 {
 531     return pcmk__cluster_node_name(nodeid);
 532 }
 533 
 534 const char *
 535 get_local_node_name(void)
     
 536 {
 537     return pcmk__cluster_local_node_name();
 538 }
 539 
 540 const char *
 541 crm_peer_uname(const char *uuid)
     
 542 {
 543     return pcmk__node_name_from_uuid(uuid);
 544 }
 545 
 546 
 547