Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4638961
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
25 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment