00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "asterisk.h"
00036
00037 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 369001 $");
00038
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include <string.h>
00042 #include <unistd.h>
00043 #include <errno.h>
00044
00045 #include "ais.h"
00046
00047 #include "asterisk/module.h"
00048 #include "asterisk/utils.h"
00049 #include "asterisk/cli.h"
00050 #include "asterisk/logger.h"
00051
00052 SaClmHandleT clm_handle;
00053 static SaAisErrorT clm_init_res;
00054
00055 static void clm_node_get_cb(SaInvocationT invocation,
00056 const SaClmClusterNodeT *cluster_node, SaAisErrorT error);
00057 static void clm_track_cb(const SaClmClusterNotificationBufferT *notif_buffer,
00058 SaUint32T num_members, SaAisErrorT error);
00059
00060 static const SaClmCallbacksT clm_callbacks = {
00061 .saClmClusterNodeGetCallback = clm_node_get_cb,
00062 .saClmClusterTrackCallback = clm_track_cb,
00063 };
00064
00065 static void clm_node_get_cb(SaInvocationT invocation,
00066 const SaClmClusterNodeT *cluster_node, SaAisErrorT error)
00067 {
00068
00069 }
00070
00071 static void clm_track_cb(const SaClmClusterNotificationBufferT *notif_buffer,
00072 SaUint32T num_members, SaAisErrorT error)
00073 {
00074 unsigned int i;
00075 unsigned int node_joined = 0;
00076
00077 ast_debug(1, "Cluster membership changed. Number of members: %u\n", num_members);
00078
00079 for (i = 0; i < notif_buffer->numberOfItems; i++) {
00080 SaClmClusterNotificationT *notif = notif_buffer->notification + i;
00081
00082 if (notif->clusterChange == SA_CLM_NODE_JOINED) {
00083 node_joined = 1;
00084 break;
00085 }
00086 }
00087
00088 if (node_joined) {
00089 ast_debug(1, "A node has joined the cluster, dumping event cache.\n");
00090 ast_ais_cmd(AST_AIS_CMD_MEMBERSHIP_CHANGED);
00091 }
00092 }
00093
00094 static char *ais_clm_show_members(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00095 {
00096 int i;
00097 SaClmClusterNotificationBufferT buf;
00098 SaClmClusterNotificationT notif[64];
00099 SaAisErrorT ais_res;
00100
00101 switch (cmd) {
00102 case CLI_INIT:
00103 e->command = "ais clm show members";
00104 e->usage =
00105 "Usage: ais clm show members\n"
00106 " List members of the cluster using the CLM (Cluster Membership) service.\n";
00107 return NULL;
00108
00109 case CLI_GENERATE:
00110 return NULL;
00111 }
00112
00113 if (a->argc != e->args)
00114 return CLI_SHOWUSAGE;
00115
00116 buf.notification = notif;
00117 buf.numberOfItems = ARRAY_LEN(notif);
00118
00119 ais_res = saClmClusterTrack(clm_handle, SA_TRACK_CURRENT, &buf);
00120 if (ais_res != SA_AIS_OK) {
00121 ast_cli(a->fd, "Error retrieving current cluster members.\n");
00122 return CLI_FAILURE;
00123 }
00124
00125 ast_cli(a->fd, "\n"
00126 "=============================================================\n"
00127 "=== Cluster Members =========================================\n"
00128 "=============================================================\n"
00129 "===\n");
00130
00131 for (i = 0; i < buf.numberOfItems; i++) {
00132 SaClmClusterNodeT *node = &buf.notification[i].clusterNode;
00133
00134 ast_cli(a->fd, "=== ---------------------------------------------------------\n"
00135 "=== Node Name: %s\n"
00136 "=== ==> ID: 0x%x\n"
00137 "=== ==> Address: %s\n"
00138 "=== ==> Member: %s\n",
00139 (char *) node->nodeName.value, (int) node->nodeId,
00140 (char *) node->nodeAddress.value,
00141 node->member ? "Yes" : "No");
00142
00143 ast_cli(a->fd, "=== ---------------------------------------------------------\n"
00144 "===\n");
00145 }
00146
00147 ast_cli(a->fd, "=============================================================\n"
00148 "\n");
00149
00150 return CLI_SUCCESS;
00151 }
00152
00153 static struct ast_cli_entry ais_cli[] = {
00154 AST_CLI_DEFINE(ais_clm_show_members, "List current members of the cluster"),
00155 };
00156
00157 int ast_ais_clm_load_module(void)
00158 {
00159 SaAisErrorT ais_res;
00160
00161 clm_init_res = saClmInitialize(&clm_handle, &clm_callbacks, &ais_version);
00162 if (clm_init_res != SA_AIS_OK) {
00163 ast_log(LOG_ERROR, "Could not initialize cluster membership service: %s\n",
00164 ais_err2str(clm_init_res));
00165 return -1;
00166 }
00167
00168 ais_res = saClmClusterTrack(clm_handle, SA_TRACK_CHANGES, NULL);
00169 if (ais_res != SA_AIS_OK) {
00170 ast_log(LOG_ERROR, "Error starting tracking of cluster membership changes.\n");
00171 }
00172
00173 ast_cli_register_multiple(ais_cli, ARRAY_LEN(ais_cli));
00174
00175 return 0;
00176 }
00177
00178 int ast_ais_clm_unload_module(void)
00179 {
00180 SaAisErrorT ais_res;
00181
00182 if (clm_init_res != SA_AIS_OK) {
00183 return 0;
00184 }
00185
00186 ast_cli_unregister_multiple(ais_cli, ARRAY_LEN(ais_cli));
00187
00188 ais_res = saClmFinalize(clm_handle);
00189 if (ais_res != SA_AIS_OK) {
00190 ast_log(LOG_ERROR, "Problem stopping cluster membership service: %s\n",
00191 ais_err2str(ais_res));
00192 return -1;
00193 }
00194
00195 return 0;
00196 }