Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/lib/common/cluster.c b/lib/common/cluster.c
index 6bde8e7603..17ac0a19f4 100644
--- a/lib/common/cluster.c
+++ b/lib/common/cluster.c
@@ -1,425 +1,417 @@
/*
* Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <crm_internal.h>
#include <sys/param.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/common/msg.h>
#include <crm/common/ipc.h>
#include <crm/common/cluster.h>
#include "stack.h"
CRM_TRACE_INIT_DATA(cluster);
xmlNode *create_common_message(
xmlNode *original_request, xmlNode *xml_response_data);
-/*
-enum cluster_type_e
-find_active_cluster_type(void)
-{
- enum cluster_type_e type = find_corosync_variant();
- if(type == pcmk_cluster_unknown) {
- }
-}
-*/
+
gboolean crm_cluster_connect(
char **our_uname, char **our_uuid, void *dispatch, void *destroy,
#if SUPPORT_HEARTBEAT
ll_cluster_t **hb_conn
#else
void **hb_conn
#endif
) {
enum cluster_type_e type = get_cluster_type();
crm_info("Connecting to cluster infrastructure: %s", name_for_cluster_type(type));
if(hb_conn != NULL) {
*hb_conn = NULL;
}
#if SUPPORT_COROSYNC
if(is_openais_cluster()) {
crm_peer_init();
return init_ais_connection(dispatch, destroy, our_uuid, our_uname, NULL);
}
#endif
#if SUPPORT_HEARTBEAT
if(is_heartbeat_cluster()) {
int rv;
CRM_ASSERT(hb_conn != NULL);
if(*hb_conn == NULL) {
/* No object passed in, create a new one. */
*hb_conn = ll_cluster_new("heartbeat");
} else {
/* Object passed in. Disconnect first, then reconnect below. */
ll_cluster_t *conn = *hb_conn;
conn->llc_ops->signoff(conn, FALSE);
}
/* make sure we are disconnected first with the old object, if any. */
if (heartbeat_cluster && heartbeat_cluster != *hb_conn) {
heartbeat_cluster->llc_ops->signoff(heartbeat_cluster, FALSE);
}
CRM_ASSERT(*hb_conn != NULL);
heartbeat_cluster = *hb_conn;
rv = register_heartbeat_conn(
heartbeat_cluster, our_uuid, our_uname, dispatch, destroy);
if (rv) {
/* we'll benefit from a bigger queue length on heartbeat side.
* Otherwise, if peers send messages faster than we can consume
* them right now, heartbeat messaging layer will kick us out once
* it's (small) default queue fills up :(
* If we fail to adjust the sendq length, that's not yet fatal, though.
*/
if (HA_OK != (*hb_conn)->llc_ops->set_sendq_len(*hb_conn, 1024)) {
crm_warn("Cannot set sendq length: %s",
(*hb_conn)->llc_ops->errmsg(*hb_conn));
}
}
return rv;
}
#endif
crm_info("Unsupported cluster stack: %s", getenv("HA_cluster_type"));
return FALSE;
}
gboolean send_cluster_message(
const char *node, enum crm_ais_msg_types service, xmlNode *data, gboolean ordered) {
#if SUPPORT_COROSYNC
if(is_openais_cluster()) {
return send_ais_message(data, FALSE, node, service);
}
#endif
#if SUPPORT_HEARTBEAT
if(is_heartbeat_cluster()) {
return send_ha_message(heartbeat_cluster, data, node, ordered);
}
#endif
return FALSE;
}
static GHashTable *crm_uuid_cache = NULL;
static GHashTable *crm_uname_cache = NULL;
void
empty_uuid_cache(void)
{
if(crm_uuid_cache != NULL) {
g_hash_table_destroy(crm_uuid_cache);
crm_uuid_cache = NULL;
}
}
void
unget_uuid(const char *uname)
{
if(crm_uuid_cache == NULL) {
return;
}
g_hash_table_remove(crm_uuid_cache, uname);
}
const char *
get_uuid(const char *uname)
{
char *uuid_calc = NULL;
CRM_CHECK(uname != NULL, return NULL);
if(crm_uuid_cache == NULL) {
crm_uuid_cache = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
}
CRM_CHECK(uname != NULL, return NULL);
/* avoid blocking calls where possible */
uuid_calc = g_hash_table_lookup(crm_uuid_cache, uname);
if(uuid_calc != NULL) {
return uuid_calc;
}
#if SUPPORT_COROSYNC
if(is_openais_cluster()) {
uuid_calc = crm_strdup(uname);
goto fallback;
}
#endif
#if SUPPORT_HEARTBEAT
if(is_heartbeat_cluster()) {
cl_uuid_t uuid_raw;
const char *unknown = "00000000-0000-0000-0000-000000000000";
if(heartbeat_cluster == NULL) {
crm_warn("No connection to heartbeat, using uuid=uname");
uuid_calc = crm_strdup(uname);
goto fallback;
}
if(heartbeat_cluster->llc_ops->get_uuid_by_name(
heartbeat_cluster, uname, &uuid_raw) == HA_FAIL) {
crm_err("get_uuid_by_name() call failed for host %s", uname);
crm_free(uuid_calc);
return NULL;
}
crm_malloc0(uuid_calc, 50);
cl_uuid_unparse(&uuid_raw, uuid_calc);
if(safe_str_eq(uuid_calc, unknown)) {
crm_warn("Could not calculate UUID for %s", uname);
crm_free(uuid_calc);
return NULL;
}
}
#endif
fallback:
g_hash_table_insert(crm_uuid_cache, crm_strdup(uname), uuid_calc);
uuid_calc = g_hash_table_lookup(crm_uuid_cache, uname);
return uuid_calc;
}
const char *
get_uname(const char *uuid)
{
char *uname = NULL;
if(crm_uname_cache == NULL) {
crm_uname_cache = g_hash_table_new_full(
g_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
}
CRM_CHECK(uuid != NULL, return NULL);
/* avoid blocking calls where possible */
uname = g_hash_table_lookup(crm_uname_cache, uuid);
if(uname != NULL) {
return uname;
}
#if SUPPORT_COROSYNC
if(is_openais_cluster()) {
g_hash_table_insert(crm_uname_cache, crm_strdup(uuid), crm_strdup(uuid));
}
#endif
#if SUPPORT_HEARTBEAT
if(is_heartbeat_cluster()) {
if(heartbeat_cluster != NULL && uuid != NULL) {
cl_uuid_t uuid_raw;
char *uuid_copy = crm_strdup(uuid);
cl_uuid_parse(uuid_copy, &uuid_raw);
crm_malloc(uname, MAX_NAME);
if(heartbeat_cluster->llc_ops->get_name_by_uuid(
heartbeat_cluster, &uuid_raw, uname, MAX_NAME) == HA_FAIL) {
crm_err("Could not calculate uname for %s", uuid);
crm_free(uuid_copy);
crm_free(uname);
} else {
g_hash_table_insert(crm_uname_cache, uuid_copy, uname);
}
}
}
#endif
return g_hash_table_lookup(crm_uname_cache, uuid);
}
void
set_uuid(xmlNode *node,const char *attr,const char *uname)
{
const char *uuid_calc = get_uuid(uname);
crm_xml_add(node, attr, uuid_calc);
return;
}
xmlNode*
createPingAnswerFragment(const char *from, const char *status)
{
xmlNode *ping = NULL;
ping = create_xml_node(NULL, XML_CRM_TAG_PING);
crm_xml_add(ping, XML_PING_ATTR_STATUS, status);
crm_xml_add(ping, XML_PING_ATTR_SYSFROM, from);
return ping;
}
const char *
name_for_cluster_type(enum cluster_type_e type)
{
switch(type) {
case pcmk_cluster_classic_ais:
return "classic openais (with plugin)";
case pcmk_cluster_cman:
return "cman";
case pcmk_cluster_corosync:
return "corosync";
case pcmk_cluster_heartbeat:
return "heartbeat";
case pcmk_cluster_unknown:
return "unknown";
case pcmk_cluster_invalid:
return "invalid";
}
crm_err("Invalid cluster type: %d", type);
return "invalid";
}
/* Do not expose these two */
int set_cluster_type(enum cluster_type_e type);
static enum cluster_type_e cluster_type = pcmk_cluster_unknown;
int set_cluster_type(enum cluster_type_e type)
{
if(cluster_type == pcmk_cluster_unknown) {
crm_info("Cluster type set to: %s", name_for_cluster_type(type));
cluster_type = type;
return 0;
} else if(cluster_type == type) {
return 0;
} else if(pcmk_cluster_unknown == type) {
cluster_type = type;
return 0;
}
crm_err("Cluster type already set to %s, ignoring %s",
name_for_cluster_type(cluster_type),
name_for_cluster_type(type));
return -1;
}
enum cluster_type_e
get_cluster_type(void)
{
if(cluster_type == pcmk_cluster_unknown) {
const char *cluster = getenv("HA_cluster_type");
cluster_type = pcmk_cluster_invalid;
if(cluster) {
crm_info("Cluster type is: '%s'", cluster);
} else {
#if SUPPORT_COROSYNC
cluster_type = find_corosync_variant();
if(cluster_type == pcmk_cluster_unknown) {
cluster = "heartbeat";
crm_info("Assuming a 'heartbeat' based cluster");
} else {
cluster = name_for_cluster_type(cluster_type);
crm_info("Detected an active '%s' cluster", cluster);
}
#else
cluster = "heartbeat";
#endif
}
if(safe_str_eq(cluster, "heartbeat")) {
#if SUPPORT_HEARTBEAT
cluster_type = pcmk_cluster_heartbeat;
#else
crm_crit("This installation of Pacemaker does not support the '%s' cluster infrastructure. Terminating.",
cluster);
exit(100);
#endif
} else if(safe_str_eq(cluster, "openais")) {
#if SUPPORT_COROSYNC
cluster_type = pcmk_cluster_classic_ais;
#else
crm_crit("This installation of Pacemaker does not support the '%s' cluster infrastructure. Terminating.",
cluster);
exit(100);
#endif
} else if(safe_str_eq(cluster, "corosync")) {
#if SUPPORT_COROSYNC
cluster_type = pcmk_cluster_corosync;
#else
crm_crit("This installation of Pacemaker does not support the '%s' cluster infrastructure. Terminating.",
cluster);
exit(100);
#endif
} else if(safe_str_eq(cluster, "cman")) {
#if SUPPORT_CMAN
cluster_type = pcmk_cluster_cman;
#else
crm_crit("This installation of Pacemaker does not support the '%s' cluster infrastructure. Terminating.",
cluster);
exit(100);
#endif
} else {
crm_crit("Unknown cluster type: '%s'. Terminating.", cluster);
exit(100);
}
}
return cluster_type;
}
gboolean is_cman_cluster(void)
{
return get_cluster_type() == pcmk_cluster_cman;
}
gboolean is_corosync_cluster(void)
{
return get_cluster_type() == pcmk_cluster_corosync;
}
gboolean is_classic_ais_cluster(void)
{
return get_cluster_type() == pcmk_cluster_classic_ais;
}
gboolean is_openais_cluster(void)
{
enum cluster_type_e type = get_cluster_type();
if(type == pcmk_cluster_classic_ais) {
return TRUE;
} else if(type == pcmk_cluster_corosync) {
return TRUE;
} else if(type == pcmk_cluster_cman) {
return TRUE;
}
return FALSE;
}
gboolean is_heartbeat_cluster(void)
{
return get_cluster_type() == pcmk_cluster_heartbeat;
}
diff --git a/tools/ccm_epoche.c b/tools/ccm_epoche.c
index 0da9721446..d1f3afdfa9 100644
--- a/tools/ccm_epoche.c
+++ b/tools/ccm_epoche.c
@@ -1,561 +1,564 @@
/*
* Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <crm_internal.h>
#include <sys/param.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h> /* for basename() */
#include <crm/crm.h>
#include <crm/ais.h>
#include <crm/common/cluster.h>
#include <crm/cib.h>
int command = 0;
int ccm_fd = 0;
gboolean do_quiet = FALSE;
char *target_uuid = NULL;
char *target_uname = NULL;
const char *standby_value = NULL;
const char *standby_scope = NULL;
#include <../lib/common/stack.h>
static struct crm_option long_options[] = {
/* Top-level Options */
{"help", 0, 0, '?', "\tThis text"},
{"version", 0, 0, '$', "\tVersion information" },
{"verbose", 0, 0, 'V', "\tIncrease debug output"},
{"quiet", 0, 0, 'Q', "\tEssential output only"},
{"-spacer-", 1, 0, '-', "\nStack:"},
#ifdef SUPPORT_CMAN
{"cman", 0, 0, 'c', "\tOnly try connecting to a cman-based cluster"},
#endif
#ifdef SUPPORT_COROSYNC
{"openais", 0, 0, 'A', "\tOnly try connecting to an OpenAIS-based cluster"},
#endif
#ifdef SUPPORT_HEARTBEAT
{"heartbeat", 0, 0, 'H', "Only try connecting to a Heartbeat-based cluster"},
#endif
{"-spacer-", 1, 0, '-', "\nCommands:"},
{"epoch", 0, 0, 'e', "\tDisplay the epoch during which this node joined the cluster"},
{"quorum", 0, 0, 'q', "\tDisplay a 1 if our partition has quorum, 0 if not"},
{"list", 0, 0, 'l', "\tDisplay all known members (past and present) of this cluster (Not available for heartbeat clusters)"},
{"partition", 0, 0, 'p', "Display the members of this partition"},
{"cluster-id", 0, 0, 'i', "Display this node's cluster id"},
{"remove", 1, 0, 'R', "(Advanced, AIS-Only) Remove the (stopped) node with the specified nodeid from the cluster"},
{"-spacer-", 1, 0, '-', "\nAdditional Options:"},
{"force", 0, 0, 'f'},
{0, 0, 0, 0}
};
int local_id = 0;
#if SUPPORT_HEARTBEAT
# include <ocf/oc_event.h>
# include <ocf/oc_membership.h>
# include <clplumbing/cl_uuid.h>
# define UUID_LEN 16
oc_ev_t *ccm_token = NULL;
void oc_ev_special(const oc_ev_t *, oc_ev_class_t , int );
static gboolean read_local_hb_uuid(void)
{
cl_uuid_t uuid;
char *buffer = NULL;
long start = 0, read_len = 0;
FILE *input = fopen(UUID_FILE, "r");
if(input == NULL) {
crm_info("Could not open UUID file %s\n", UUID_FILE);
return FALSE;
}
/* see how big the file is */
start = ftell(input);
fseek(input, 0L, SEEK_END);
if(UUID_LEN != ftell(input)) {
fprintf(stderr, "%s must contain exactly %d bytes\n", UUID_FILE, UUID_LEN);
abort();
}
fseek(input, 0L, start);
if(start != ftell(input)) {
fprintf(stderr, "fseek not behaving: %ld vs. %ld\n", start, ftell(input));
exit(2);
}
buffer = malloc(50);
read_len = fread(uuid.uuid, 1, UUID_LEN, input);
if(read_len != UUID_LEN) {
fprintf(stderr, "Expected and read bytes differ: %d vs. %ld\n",
UUID_LEN, read_len);
exit(3);
} else if(buffer != NULL) {
cl_uuid_unparse(&uuid, buffer);
fprintf(stdout, "%s\n", buffer);
return TRUE;
} else {
fprintf(stderr, "No buffer to unparse\n");
exit(4);
}
free(buffer);
fclose(input);
return FALSE;
}
static void
ccm_age_callback(oc_ed_t event, void *cookie, size_t size, const void *data)
{
int lpc;
int node_list_size;
const oc_ev_membership_t *oc = (const oc_ev_membership_t *)data;
node_list_size = oc->m_n_member;
if(command == 'q') {
crm_debug("Processing \"%s\" event.",
event==OC_EV_MS_NEW_MEMBERSHIP?"NEW MEMBERSHIP":
event==OC_EV_MS_NOT_PRIMARY?"NOT PRIMARY":
event==OC_EV_MS_PRIMARY_RESTORED?"PRIMARY RESTORED":
event==OC_EV_MS_EVICTED?"EVICTED":
"NO QUORUM MEMBERSHIP");
if(ccm_have_quorum(event)) {
fprintf(stdout, "1\n");
} else {
fprintf(stdout, "0\n");
}
} else if(command == 'e') {
crm_debug("Searching %d members for our birth", oc->m_n_member);
}
for(lpc=0; lpc<node_list_size; lpc++) {
if(command == 'p') {
fprintf(stdout, "%s ",
oc->m_array[oc->m_memb_idx+lpc].node_uname);
} else if(command == 'e') {
if(oc_ev_is_my_nodeid(ccm_token, &(oc->m_array[lpc]))){
crm_debug("MATCH: nodeid=%d, uname=%s, born=%d",
oc->m_array[oc->m_memb_idx+lpc].node_id,
oc->m_array[oc->m_memb_idx+lpc].node_uname,
oc->m_array[oc->m_memb_idx+lpc].node_born_on);
fprintf(stdout, "%d\n",
oc->m_array[oc->m_memb_idx+lpc].node_born_on);
}
}
}
oc_ev_callback_done(cookie);
if(command == 'p') {
fprintf(stdout, "\n");
}
fflush(stdout);
exit(0);
}
static gboolean
ccm_age_connect(int *ccm_fd)
{
gboolean did_fail = FALSE;
int ret = 0;
crm_debug("Registering with CCM");
ret = oc_ev_register(&ccm_token);
if (ret != 0) {
crm_info("CCM registration failed: %d", ret);
did_fail = TRUE;
}
if(did_fail == FALSE) {
crm_debug("Setting up CCM callbacks");
ret = oc_ev_set_callback(ccm_token, OC_EV_MEMB_CLASS,
ccm_age_callback, NULL);
if (ret != 0) {
crm_warn("CCM callback not set: %d", ret);
did_fail = TRUE;
}
}
if(did_fail == FALSE) {
oc_ev_special(ccm_token, OC_EV_MEMB_CLASS, 0/*don't care*/);
crm_debug("Activating CCM token");
ret = oc_ev_activate(ccm_token, ccm_fd);
if (ret != 0){
crm_warn("CCM Activation failed: %d", ret);
did_fail = TRUE;
}
}
return !did_fail;
}
static gboolean try_heartbeat(int command, enum cluster_type_e stack)
{
crm_debug("Attempting to process %c command", command);
if(command == 'i') {
if(read_local_hb_uuid()) {
exit(0);
}
} else if(ccm_age_connect(&ccm_fd)) {
int rc = 0;
fd_set rset;
while (1) {
sleep(1);
FD_ZERO(&rset);
FD_SET(ccm_fd, &rset);
errno = 0;
rc = select(ccm_fd + 1, &rset, NULL,NULL,NULL);
if(rc > 0 && oc_ev_handle_event(ccm_token) != 0) {
crm_err("oc_ev_handle_event failed");
return FALSE;
} else if(rc < 0 && errno != EINTR) {
crm_perror(LOG_ERR, "select failed: %d", rc);
return FALSE;
}
}
}
return FALSE;
}
#endif
#if SUPPORT_CMAN
# include <libcman.h>
# define MAX_NODES 256
static gboolean try_cman(int command, enum cluster_type_e stack)
{
int rc = -1, lpc = 0, node_count = 0;
cman_node_t node;
cman_cluster_t cluster;
cman_handle_t cman_handle = NULL;
cman_node_t cman_nodes[MAX_NODES];
memset(&cluster, 0, sizeof(cluster));
cman_handle = cman_init(NULL);
if(cman_handle == NULL || cman_is_active(cman_handle) == FALSE) {
crm_info("Couldn't connect to cman");
return FALSE;
}
switch(command) {
case 'R':
fprintf(stderr, "Node removal not supported for cman based clusters\n");
exit(cib_NOTSUPPORTED);
break;
case 'e':
/* Age makes no sense (yet?) in a cman cluster */
fprintf(stdout, "1\n");
break;
case 'q':
fprintf(stdout, "%d\n", cman_is_quorate(cman_handle));
break;
case 'l':
case 'p':
rc = cman_get_nodes(cman_handle, MAX_NODES, &node_count, cman_nodes);
if (rc != 0) {
fprintf(stderr, "Couldn't query cman node list: %d %d", rc, errno);
goto cman_bail;
}
for (lpc = 0; lpc < node_count; lpc++) {
if(command == 'l') {
printf("%s ", cman_nodes[lpc].cn_name);
} else if (cman_nodes[lpc].cn_nodeid != 0 && cman_nodes[lpc].cn_member) {
/* Never allow node ID 0 to be considered a member #315711 */
printf("%s ", cman_nodes[lpc].cn_name);
}
}
printf("\n");
break;
case 'i':
rc = cman_get_node(cman_handle, CMAN_NODEID_US, &node);
if ( rc != 0) {
fprintf(stderr, "Couldn't query cman node id: %d %d", rc, errno);
goto cman_bail;
}
fprintf(stdout, "%u\n", node.cn_nodeid);
break;
default:
fprintf(stderr, "Unknown option '%c'\n", command);
crm_help('?', LSB_EXIT_GENERIC);
}
cman_finish(cman_handle);
exit(0);
cman_bail:
cman_finish(cman_handle);
exit(LSB_EXIT_GENERIC);
}
#endif
#if SUPPORT_COROSYNC
static void
ais_membership_destroy(gpointer user_data)
{
crm_err("AIS connection terminated");
ais_fd_sync = -1;
exit(1);
}
static gint member_sort(gconstpointer a, gconstpointer b)
{
const crm_node_t *node_a = a;
const crm_node_t *node_b = b;
return strcmp(node_a->uname, node_b->uname);
}
static void crm_add_member(
gpointer key, gpointer value, gpointer user_data)
{
GList **list = user_data;
crm_node_t *node = value;
if(node->uname != NULL) {
*list = g_list_insert_sorted(*list, node, member_sort);
}
}
static gboolean
ais_membership_dispatch(AIS_Message *wrapper, char *data, int sender)
{
switch(wrapper->header.id) {
case crm_class_members:
case crm_class_notify:
case crm_class_quorum:
break;
default:
return TRUE;
break;
}
if(command == 'q') {
if(crm_have_quorum) {
fprintf(stdout, "1\n");
} else {
fprintf(stdout, "0\n");
}
} else if(command == 'l') {
GList *nodes = NULL;
GListPtr lpc = NULL;
g_hash_table_foreach(crm_peer_cache, crm_add_member, &nodes);
for(lpc = nodes; lpc != NULL; lpc = lpc->next) {
crm_node_t *node = (crm_node_t*)lpc->data;
fprintf(stdout, "%u %s %s\n", node->id, node->uname, node->state);
}
fprintf(stdout, "\n");
} else if(command == 'p') {
GList *nodes = NULL;
GListPtr lpc = NULL;
g_hash_table_foreach(crm_peer_cache, crm_add_member, &nodes);
for(lpc = nodes; lpc != NULL; lpc = lpc->next) {
crm_node_t *node = (crm_node_t*)lpc->data;
if(node->uname && crm_is_member_active(node)) {
fprintf(stdout, "%s ", node->uname);
}
}
fprintf(stdout, "\n");
}
exit(0);
return TRUE;
}
static gboolean try_corosync(int command, enum cluster_type_e stack)
{
if(init_ais_connection_once(
ais_membership_dispatch, ais_membership_destroy, NULL, NULL, &local_id)) {
GMainLoop* amainloop = NULL;
switch(command) {
case 'R':
send_ais_text(crm_class_rmpeer, target_uname, TRUE, NULL, crm_msg_ais);
exit(0);
case 'e':
/* Age makes no sense (yet) in an AIS cluster */
fprintf(stdout, "1\n");
exit(0);
case 'q':
send_ais_text(crm_class_quorum, NULL, TRUE, NULL, crm_msg_ais);
break;
case 'l':
case 'p':
crm_info("Requesting the list of configured nodes");
send_ais_text(crm_class_members, __FUNCTION__, TRUE, NULL, crm_msg_ais);
break;
case 'i':
printf("%d\n", local_id);
exit(0);
default:
fprintf(stderr, "Unknown option '%c'\n", command);
crm_help('?', LSB_EXIT_GENERIC);
}
amainloop = g_main_new(FALSE);
g_main_run(amainloop);
}
return FALSE;
}
#endif
int set_cluster_type(enum cluster_type_e type);
int
main(int argc, char ** argv)
{
int flag = 0;
int argerr = 0;
gboolean force_flag = FALSE;
gboolean dangerous_cmd = FALSE;
enum cluster_type_e try_stack = pcmk_cluster_unknown;
int option_index = 0;
crm_peer_init();
crm_log_init(NULL, LOG_INFO, FALSE, FALSE, argc, argv);
crm_set_options("?V$qepHAR:iflCc", "command [options]", long_options,
"Tool for displaying low-level node information");
while (flag >= 0) {
flag = crm_get_option(argc, argv, &option_index);
switch(flag) {
case -1:
break;
case 'V':
cl_log_enable_stderr(TRUE);
alter_debug(DEBUG_INC);
break;
case '$':
case '?':
crm_help(flag, LSB_EXIT_OK);
break;
case 'Q':
do_quiet = TRUE;
break;
case 'H':
set_cluster_type(pcmk_cluster_heartbeat);
break;
case 'A':
set_cluster_type(pcmk_cluster_classic_ais);
break;
case 'C':
set_cluster_type(pcmk_cluster_corosync);
break;
case 'c':
set_cluster_type(pcmk_cluster_cman);
break;
case 'f':
force_flag = TRUE;
break;
case 'R':
dangerous_cmd = TRUE;
command = flag;
target_uname = optarg;
break;
case 'p':
case 'e':
case 'q':
case 'i':
case 'l':
command = flag;
break;
default:
++argerr;
break;
}
}
if (optind > argc) {
++argerr;
}
if (argerr) {
crm_help('?', LSB_EXIT_GENERIC);
}
if(dangerous_cmd && force_flag == FALSE) {
fprintf(stderr, "The supplied command is considered dangerous."
" To prevent accidental destruction of the cluster,"
" the --force flag is required in order to proceed.\n");
fflush(stderr);
exit(LSB_EXIT_GENERIC);
}
try_stack = get_cluster_type();
crm_debug("Attempting to process -%c command for cluster type: %s", command, name_for_cluster_type(try_stack));
-#if SUPPORT_COROSYNC
+#if SUPPORT_CMAN
if(try_stack == pcmk_cluster_cman) {
- try_cman(command, try_stack);
-
- } else if(try_stack == pcmk_cluster_corosync
- || try_stack == pcmk_cluster_classic_ais) {
+ try_cman(command, try_stack);
+ }
+#endif
+
+#if SUPPORT_COROSYNC
+ if(try_stack == pcmk_cluster_corosync
+ || try_stack == pcmk_cluster_classic_ais) {
try_corosync(command, try_stack);
}
#endif
#if SUPPORT_HEARTBEAT
if(try_stack == pcmk_cluster_heartbeat) {
try_heartbeat(command, try_stack);
}
#endif
return(1);
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 10, 1:48 AM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2009582
Default Alt Text
(25 KB)

Event Timeline