mirror of
https://git.proxmox.com/git/mirror_corosync
synced 2025-06-03 19:55:26 +00:00
defect 841
Rabbe reported that cluster track callback operations dont work properly. This patch fixes that problem. git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@809 fd59a12c-fef9-0310-b244-a6a79926bd2f
This commit is contained in:
parent
319f0813cb
commit
ca58a16b6b
49
exec/clm.c
49
exec/clm.c
@ -241,6 +241,19 @@ void library_notification_send (SaClmClusterNotificationT *cluster_notification_
|
||||
struct conn_info *conn_info;
|
||||
struct list_head *list;
|
||||
|
||||
if (notify_entries == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
res_lib_clm_clustertrack.header.size = sizeof (struct res_lib_clm_clustertrack);
|
||||
res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKCALLBACK;
|
||||
res_lib_clm_clustertrack.header.error = SA_OK;
|
||||
res_lib_clm_clustertrack.viewNumber = 0;
|
||||
res_lib_clm_clustertrack.numberOfItems = notify_entries;
|
||||
memcpy (&res_lib_clm_clustertrack.notification,
|
||||
cluster_notification_entries,
|
||||
sizeof (SaClmClusterNotificationT) * notify_entries);
|
||||
|
||||
for (list = library_notification_send_listhead.next;
|
||||
list != &library_notification_send_listhead;
|
||||
list = list->next) {
|
||||
@ -250,39 +263,29 @@ void library_notification_send (SaClmClusterNotificationT *cluster_notification_
|
||||
/*
|
||||
* Send notifications to all CLM listeners
|
||||
*/
|
||||
if (notify_entries) {
|
||||
res_lib_clm_clustertrack.header.size = sizeof (struct res_lib_clm_clustertrack) +
|
||||
(notify_entries * sizeof (SaClmClusterNotificationT));
|
||||
res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKCALLBACK;
|
||||
res_lib_clm_clustertrack.header.error = SA_OK;
|
||||
res_lib_clm_clustertrack.viewNumber = 0;
|
||||
res_lib_clm_clustertrack.numberOfItems = notify_entries;
|
||||
libais_send_response (conn_info, &res_lib_clm_clustertrack,
|
||||
sizeof (struct res_lib_clm_clustertrack));
|
||||
libais_send_response (conn_info, cluster_notification_entries,
|
||||
sizeof (SaClmClusterNotificationT) * notify_entries);
|
||||
}
|
||||
libais_send_response (conn_info, &res_lib_clm_clustertrack,
|
||||
sizeof (struct res_lib_clm_clustertrack));
|
||||
}
|
||||
}
|
||||
|
||||
static void libraryNotificationJoin (SaClmNodeIdT node)
|
||||
static void notification_join (SaClmNodeIdT node)
|
||||
{
|
||||
SaClmClusterNotificationT clusterNotification;
|
||||
SaClmClusterNotificationT notification;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Generate notification element
|
||||
*/
|
||||
clusterNotification.clusterChange = SA_CLM_NODE_JOINED;
|
||||
clusterNotification.clusterNode.member = 1;
|
||||
notification.clusterChange = SA_CLM_NODE_JOINED;
|
||||
notification.clusterNode.member = 1;
|
||||
for (i = 0; i < clusterNodeEntries; i++) {
|
||||
if (node == clusterNodes[i].nodeId) {
|
||||
memcpy (&clusterNotification.clusterNode, &clusterNodes[i],
|
||||
memcpy (¬ification.clusterNode, &clusterNodes[i],
|
||||
sizeof (SaClmClusterNodeT));
|
||||
}
|
||||
}
|
||||
|
||||
library_notification_send (&clusterNotification, 1);
|
||||
library_notification_send (¬ification, 1);
|
||||
}
|
||||
|
||||
static void libraryNotificationLeave (SaClmNodeIdT *nodes, int nodes_entries)
|
||||
@ -385,10 +388,12 @@ static int clm_confchg_fn (
|
||||
* transitioning to network interface up or down
|
||||
*/
|
||||
thisClusterNode.nodeId = this_ip->sin_addr.s_addr;
|
||||
memcpy (&thisClusterNode.nodeAddress.value, &this_ip->sin_addr,
|
||||
sizeof (struct in_addr));
|
||||
thisClusterNode.nodeAddress.length = sizeof (struct in_addr);
|
||||
strcpy ((char *)thisClusterNode.nodeName.value, (char *)inet_ntoa (this_ip->sin_addr));
|
||||
|
||||
sprintf (thisClusterNode.nodeAddress.value, "%s", inet_ntoa (this_ip->sin_addr));
|
||||
thisClusterNode.nodeAddress.length = strlen (thisClusterNode.nodeAddress.value);
|
||||
thisClusterNode.nodeAddress.family = SA_CLM_AF_INET;
|
||||
sprintf (thisClusterNode.nodeName.value, "%s", inet_ntoa (this_ip->sin_addr));
|
||||
thisClusterNode.nodeName.length = strlen ((char *)thisClusterNode.nodeName.value);
|
||||
|
||||
return (0);
|
||||
@ -479,7 +484,7 @@ static int message_handler_req_exec_clm_nodejoin (void *message, struct in_addr
|
||||
sizeof (SaClmClusterNodeT));
|
||||
|
||||
clusterNodeEntries += 1;
|
||||
libraryNotificationJoin (req_exec_clm_nodejoin->clusterNode.nodeId);
|
||||
notification_join (req_exec_clm_nodejoin->clusterNode.nodeId);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
@ -32,16 +32,16 @@ LIBRARIES= ../lib/libSaClm.a ../lib/libSaAmf.a ../lib/libSaCkpt.a ../lib/libSaEv
|
||||
LIBS = $(LIBRARIES) -lpthread
|
||||
|
||||
# Production mode flags
|
||||
CFLAGS = -c -O3 -Wall -I../include
|
||||
CFLAGS = -c -O3 -Wall -I../include
|
||||
LDFLAGS = -L../lib
|
||||
#CFLAGS = -c -O3 -Wall -I../include
|
||||
#CFLAGS = -c -O3 -Wall -I../include
|
||||
#LDFLAGS = -L../lib
|
||||
#LIBRARIES= ../lib/libais.a ../lib/libevs.a
|
||||
#LIBS = $(LIBRARIES) -lpthread
|
||||
|
||||
# Debug mode flags
|
||||
#CFLAGS = -c -g -Wall -DDEBUG -I../include
|
||||
#CPPFLAGS = -c -g -Wall -DDEBUG -I../include
|
||||
#LDFLAGS = -g -L../lib
|
||||
CFLAGS = -c -g -Wall -DDEBUG -I../include
|
||||
CPPFLAGS = -c -g -Wall -DDEBUG -I../include
|
||||
LDFLAGS = -g -L../lib
|
||||
|
||||
# Profile mode flags
|
||||
#CFLAGS = -c -O3 -pg -DDEBUG -I../include
|
||||
@ -53,12 +53,12 @@ TEST_SRC = testclm.c testamf.c testamf1.c testamf2.c testamf3.c \
|
||||
testckpt.c ckptstress.c ckptbench.c \
|
||||
ckptbenchth.c testevt.c testevs.c evsbench.c \
|
||||
subscription.c publish.c evtbench.c \
|
||||
sa_error.c unlink.c
|
||||
sa_error.c unlink.c testclm2.c
|
||||
|
||||
all: testclm testamf testamf1 testamf2 testamf3 testamf4 testamf5 \
|
||||
testamf6 testamfth testckpt ckptstress ckptbench \
|
||||
ckptbenchth ckpt-rd ckpt-wr testevt testevs \
|
||||
evsbench subscription publish evtbench unlink
|
||||
evsbench subscription publish evtbench unlink testclm2
|
||||
|
||||
testtimer: testtimer.o $(LIBRARIES)
|
||||
$(CC) $(LDFLAGS) -o testtimer testtimer.o ../exec/timer.o
|
||||
@ -135,6 +135,9 @@ ckpt-rd: ckpt-rd.o sa_error.o $(LIBRARIES)
|
||||
ckpt-wr: ckpt-wr.o sa_error.o $(LIBRARIES)
|
||||
$(CC) $(LDFLAGS) -o ckpt-wr ckpt-wr.o sa_error.o $(LIBS)
|
||||
|
||||
testclm2: testclm2.o $(LIBRARIES)
|
||||
$(CC) $(LDFLAGS) -o testclm2 testclm2.o $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f *.o testclm testamf testamf1 testamf2 testamf3 testamf4 \
|
||||
testamf5 testamf6 testamfth testckpt ckptstress testtimer \
|
||||
|
353
test/testclm2.c
Normal file
353
test/testclm2.c
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Copyright (c) 2005 Ericsson AB
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Rabbe Fogelholm (rabbe.fogelholm@ericsson.com)
|
||||
*
|
||||
* This software licensed under BSD license, the text of which follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the MontaVista Software, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* testclm2.c
|
||||
*
|
||||
* Simple program to test cluster membership on an SA Forum platform.
|
||||
* The program expects one command-line argument which is "query"
|
||||
* or "callback". "Query" means that a single saClmClusterTrack call
|
||||
* is to be made. "Callback" means that callbacks are wanted when
|
||||
* there are changes in cluster membership. At least a 2-node cluster
|
||||
* is required to test this program mode.
|
||||
*
|
||||
* Tested on platforms:
|
||||
* Gentoo Linux 2005-08 (build)
|
||||
* Fedora Core 4 (build and run)
|
||||
*
|
||||
* Change history:
|
||||
* 2005-08-28 Rabbe Fogelholm:
|
||||
* Initial version
|
||||
* 2005-08-30 Rabbe Fogelholm:
|
||||
* Added call to saClmClusterTrackStop()
|
||||
* Possible to test SA_TRACK_CHANGES_ONLY
|
||||
* Improved diagnostics
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <saClm.h>
|
||||
|
||||
|
||||
#define PGM_NAME "testclm2"
|
||||
|
||||
#define MODE_QUERY 1
|
||||
#define MODE_CALLBACK 2
|
||||
#define MODE_UNKNOWN -1
|
||||
|
||||
|
||||
SaClmHandleT handle;
|
||||
|
||||
int mode = MODE_UNKNOWN;
|
||||
|
||||
|
||||
void interruptAction();
|
||||
|
||||
void usage();
|
||||
|
||||
void clusterTrack(const SaClmClusterNotificationBufferT *, SaUint32T, SaAisErrorT);
|
||||
|
||||
int apiCall(char *, SaAisErrorT);
|
||||
|
||||
char *decodeStatus(int);
|
||||
|
||||
void printBoolean(SaBoolT);
|
||||
|
||||
void printName(SaNameT *);
|
||||
|
||||
void printAddress(SaClmNodeAddressT *);
|
||||
|
||||
void printCluster(const SaClmClusterNotificationBufferT *);
|
||||
|
||||
void printDate(SaTimeT);
|
||||
|
||||
char *decodeClusterChange(int);
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct sigaction act;
|
||||
act.sa_handler = interruptAction;
|
||||
int status;
|
||||
if ((status = sigaction(SIGINT, &act, NULL)) != 0)
|
||||
{
|
||||
printf("sigaction returned: %d\n", status);
|
||||
}
|
||||
|
||||
if (argc != 2 && argc != 3)
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
mode =
|
||||
strcmp(argv[1], "query") == 0 ? MODE_QUERY :
|
||||
strcmp(argv[1], "callback") == 0 ? MODE_CALLBACK :
|
||||
MODE_UNKNOWN;
|
||||
if (mode == MODE_UNKNOWN)
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mode == MODE_CALLBACK && argc != 3)
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
int trackingMode =
|
||||
mode == MODE_QUERY ? SA_TRACK_CURRENT :
|
||||
mode == MODE_CALLBACK && strcmp(argv[2], "full") == 0 ? SA_TRACK_CHANGES :
|
||||
mode == MODE_CALLBACK && strcmp(argv[2], "delta") == 0 ? SA_TRACK_CHANGES_ONLY :
|
||||
-1;
|
||||
if (trackingMode == -1)
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
SaClmCallbacksT callbacks;
|
||||
callbacks.saClmClusterNodeGetCallback = NULL;
|
||||
callbacks.saClmClusterTrackCallback = (SaClmClusterTrackCallbackT)clusterTrack;
|
||||
|
||||
SaVersionT version;
|
||||
version.releaseCode = 'B';
|
||||
version.majorVersion = 1;
|
||||
version.minorVersion = 0;
|
||||
|
||||
|
||||
if (! apiCall("Initialize", saClmInitialize(&handle ,&callbacks, &version)))
|
||||
return 1;
|
||||
|
||||
printf("AIS version supported: %c.%d.%d\n",
|
||||
version.releaseCode, version.majorVersion, version.minorVersion);
|
||||
|
||||
if (mode == MODE_QUERY)
|
||||
{
|
||||
SaClmClusterNotificationBufferT buffer = {123456789, 123456789, NULL};
|
||||
apiCall("ClusterTrack", saClmClusterTrack(handle, trackingMode, &buffer));
|
||||
printCluster(&buffer);
|
||||
free(buffer.notification);
|
||||
}
|
||||
|
||||
if (mode == MODE_CALLBACK)
|
||||
{
|
||||
printf("(type ctrl-C to finish)\n");
|
||||
apiCall("ClusterTrack", saClmClusterTrack(handle, trackingMode, NULL));
|
||||
while (1)
|
||||
{
|
||||
apiCall("Dispatch", saClmDispatch(handle, SA_DISPATCH_ONE));
|
||||
printf("sleep 1 sec\n");
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
apiCall("Finalize", saClmFinalize(handle));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void interruptAction()
|
||||
{
|
||||
fprintf(stderr, "SIGINT signal caught\n");
|
||||
if (mode == MODE_CALLBACK)
|
||||
{
|
||||
apiCall("ClusterTrackStop", handle);
|
||||
}
|
||||
apiCall("Finalize", saClmFinalize(handle));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void usage()
|
||||
{
|
||||
fprintf(stderr, "%s: usage is:\n", PGM_NAME);
|
||||
fprintf(stderr, " membership query Query for membership once\n");
|
||||
fprintf(stderr, " membership callback full Callback on membership change, full report\n");
|
||||
fprintf(stderr, " membership callback delta Callback on membership change, delta report\n");
|
||||
}
|
||||
|
||||
|
||||
void clusterTrack(
|
||||
const SaClmClusterNotificationBufferT *buffer,
|
||||
SaUint32T numberOfMembers,
|
||||
SaAisErrorT error)
|
||||
{
|
||||
apiCall("clusterTrack callback", error);
|
||||
printf("number of members: %d\n\n", numberOfMembers);
|
||||
printCluster(buffer);
|
||||
}
|
||||
|
||||
|
||||
int apiCall(char *call, SaAisErrorT code)
|
||||
{
|
||||
char *s = decodeStatus(code);
|
||||
printf("called: %s, status: %s", call, s);
|
||||
if (strcmp(s, "unknown error code") == 0)
|
||||
{
|
||||
printf(": %d\n\n", code);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n\n");
|
||||
}
|
||||
return code == SA_AIS_OK ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
char *decodeStatus(int code)
|
||||
{
|
||||
return
|
||||
code == SA_AIS_OK ? "successful" :
|
||||
code == SA_AIS_ERR_LIBRARY ? "error in library, cannot be used anymore" :
|
||||
code == SA_AIS_ERR_VERSION ? "version incompatibility" :
|
||||
code == SA_AIS_ERR_INIT ? "callback function has not been supplied" :
|
||||
code == SA_AIS_ERR_TIMEOUT ? "timeout occurred, call may or may not have succeeded" :
|
||||
code == SA_AIS_ERR_TRY_AGAIN ? "service cannot be provided now, try later" :
|
||||
code == SA_AIS_ERR_INVALID_PARAM ? "a parameter is not set correctly" :
|
||||
code == SA_AIS_ERR_NO_MEMORY ? "out of memory" :
|
||||
code == SA_AIS_ERR_BAD_HANDLE ? "handle is invalid" :
|
||||
code == SA_AIS_ERR_BUSY ? "resource already in use" :
|
||||
code == SA_AIS_ERR_ACCESS ? "access denied" :
|
||||
code == SA_AIS_ERR_NOT_EXIST ? "entity does not exist" :
|
||||
code == SA_AIS_ERR_NAME_TOO_LONG ? "name too long" :
|
||||
code == SA_AIS_ERR_EXIST ? "entity already exists" :
|
||||
code == SA_AIS_ERR_NO_SPACE ? "buffer space is not sufficient" :
|
||||
code == SA_AIS_ERR_INTERRUPT ? "request canceled by timeout or other interrupt" :
|
||||
code == SA_AIS_ERR_NAME_NOT_FOUND ? "name not found" :
|
||||
code == SA_AIS_ERR_NOT_SUPPORTED ? "requested function is not supported" :
|
||||
code == SA_AIS_ERR_BAD_OPERATION ? "requested operation is not allowed" :
|
||||
code == SA_AIS_ERR_FAILED_OPERATION ? "healthcheck unsuccessful, error callback done" :
|
||||
code == SA_AIS_ERR_NO_RESOURCES ? "insufficient resources other than memory" :
|
||||
code == SA_AIS_ERR_MESSAGE_ERROR ? "a communication error occurred" :
|
||||
code == SA_AIS_ERR_QUEUE_FULL ? "destination queue is full" :
|
||||
code == SA_AIS_ERR_QUEUE_NOT_AVAILABLE ? "destination queue not available" :
|
||||
code == SA_AIS_ERR_BAD_FLAGS ? "flags are invalid" :
|
||||
code == SA_AIS_ERR_TOO_BIG ? "value larger than maximum permitted" :
|
||||
code == SA_AIS_ERR_NO_SECTIONS ? "no sections matching spec in SectionIteratorInitialize call" :
|
||||
"unknown error code";
|
||||
}
|
||||
|
||||
|
||||
void printBoolean(SaBoolT b)
|
||||
{
|
||||
printf("%s\n", b ? "true" : "false");
|
||||
}
|
||||
|
||||
|
||||
void printName(SaNameT *name)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<name->length; i++) printf("%c", name->value[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
void printAddress(SaClmNodeAddressT *nodeAddress)
|
||||
{
|
||||
if (nodeAddress->family == SA_CLM_AF_INET6)
|
||||
{
|
||||
printf("sorry, cannot decode IPv6 yet\n");
|
||||
}
|
||||
else if (nodeAddress->length == 4)
|
||||
{
|
||||
// we may get here due to defect 833, see
|
||||
// http://www.osdl.org/developer_bugzilla/show_bug.cgi?id=833 for details
|
||||
printf("%d.%d.%d.%d\n",
|
||||
nodeAddress->value[0],
|
||||
nodeAddress->value[1],
|
||||
nodeAddress->value[2],
|
||||
nodeAddress->value[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
int k;
|
||||
for (k = 0; k < nodeAddress->length; k++)
|
||||
{
|
||||
printf("%c", nodeAddress->value[k]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printCluster(const SaClmClusterNotificationBufferT *buffer)
|
||||
{
|
||||
printf(" view number: %llu\n", buffer->viewNumber);
|
||||
printf(" number of items: %u\n\n", buffer->numberOfItems);
|
||||
int j; for (j=0; j<buffer->numberOfItems; j++)
|
||||
{
|
||||
printf(" node index within sequence: %d\n", j);
|
||||
printf(" cluster node: %u\n", buffer->notification[j].clusterNode.nodeId);
|
||||
printf(" address: "); printAddress(& buffer->notification[j].clusterNode.nodeAddress);
|
||||
printf(" name: "); printName(&(buffer->notification[j].clusterNode.nodeName));
|
||||
printf(" member: "); printBoolean(buffer->notification[j].clusterNode.member);
|
||||
printf(" booted: "); printDate(buffer->notification[j].clusterNode.bootTimestamp);
|
||||
printf(" initial view number: %llu\n", buffer->notification[j].clusterNode.initialViewNumber);
|
||||
printf(" cluster change: %s\n", decodeClusterChange(buffer->notification[j].clusterChange));
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printDate(SaTimeT nanoseconds)
|
||||
{
|
||||
time_t tt = nanoseconds/SA_TIME_ONE_SECOND;
|
||||
struct tm *decodedTime = localtime(&tt);
|
||||
|
||||
printf("%d-%02d-%02d %02d:%02d:%02d\n",
|
||||
decodedTime->tm_year + 1900,
|
||||
decodedTime->tm_mon + 1,
|
||||
decodedTime->tm_mday,
|
||||
decodedTime->tm_hour,
|
||||
decodedTime->tm_min,
|
||||
decodedTime->tm_sec);
|
||||
}
|
||||
|
||||
|
||||
char *decodeClusterChange(int code)
|
||||
{
|
||||
return
|
||||
code == SA_CLM_NODE_NO_CHANGE ? "node has not changed" :
|
||||
code == SA_CLM_NODE_JOINED ? "node has joined the cluster" :
|
||||
code == SA_CLM_NODE_LEFT ? "node has left the cluster" :
|
||||
code == SA_CLM_NODE_RECONFIGURED ? "node has been reconfigured" :
|
||||
"unknown type of node change";
|
||||
}
|
Loading…
Reference in New Issue
Block a user