Mon Oct 8 12:39:01 2012

Asterisk developer's documentation


clm.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2007, Digium, Inc.
00005  *
00006  * Russell Bryant <russell@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*!
00020  * \file
00021  * \author Russell Bryant <russell@digium.com>
00022  *
00023  * \brief Usage of the SAForum AIS (Application Interface Specification)
00024  *
00025  * \arg http://www.openais.org/
00026  *
00027  * This file contains the code specific to the use of the CLM
00028  * (Cluster Membership) Service.
00029  */
00030 
00031 /*** MODULEINFO
00032    <support_level>extended</support_level>
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;   /* no completion */
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 }

Generated on Mon Oct 8 12:39:01 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7