Wed Jan 8 2020 09:49:46

Asterisk developer's documentation


clm.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*!
20  * \file
21  * \author Russell Bryant <russell@digium.com>
22  *
23  * \brief Usage of the SAForum AIS (Application Interface Specification)
24  *
25  * \arg http://www.openais.org/
26  *
27  * This file contains the code specific to the use of the CLM
28  * (Cluster Membership) Service.
29  */
30 
31 /*** MODULEINFO
32  <support_level>extended</support_level>
33  ***/
34 
35 #include "asterisk.h"
36 
37 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 369001 $");
38 
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <errno.h>
44 
45 #include "ais.h"
46 
47 #include "asterisk/module.h"
48 #include "asterisk/utils.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/logger.h"
51 
52 SaClmHandleT clm_handle;
53 static SaAisErrorT clm_init_res;
54 
55 static void clm_node_get_cb(SaInvocationT invocation,
56  const SaClmClusterNodeT *cluster_node, SaAisErrorT error);
57 static void clm_track_cb(const SaClmClusterNotificationBufferT *notif_buffer,
58  SaUint32T num_members, SaAisErrorT error);
59 
60 static const SaClmCallbacksT clm_callbacks = {
61  .saClmClusterNodeGetCallback = clm_node_get_cb,
62  .saClmClusterTrackCallback = clm_track_cb,
63 };
64 
65 static void clm_node_get_cb(SaInvocationT invocation,
66  const SaClmClusterNodeT *cluster_node, SaAisErrorT error)
67 {
68 
69 }
70 
71 static void clm_track_cb(const SaClmClusterNotificationBufferT *notif_buffer,
72  SaUint32T num_members, SaAisErrorT error)
73 {
74  unsigned int i;
75  unsigned int node_joined = 0;
76 
77  ast_debug(1, "Cluster membership changed. Number of members: %u\n", num_members);
78 
79  for (i = 0; i < notif_buffer->numberOfItems; i++) {
80  SaClmClusterNotificationT *notif = notif_buffer->notification + i;
81 
82  if (notif->clusterChange == SA_CLM_NODE_JOINED) {
83  node_joined = 1;
84  break;
85  }
86  }
87 
88  if (node_joined) {
89  ast_debug(1, "A node has joined the cluster, dumping event cache.\n");
91  }
92 }
93 
94 static char *ais_clm_show_members(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
95 {
96  int i;
97  SaClmClusterNotificationBufferT buf;
98  SaClmClusterNotificationT notif[64];
99  SaAisErrorT ais_res;
100 
101  switch (cmd) {
102  case CLI_INIT:
103  e->command = "ais clm show members";
104  e->usage =
105  "Usage: ais clm show members\n"
106  " List members of the cluster using the CLM (Cluster Membership) service.\n";
107  return NULL;
108 
109  case CLI_GENERATE:
110  return NULL; /* no completion */
111  }
112 
113  if (a->argc != e->args)
114  return CLI_SHOWUSAGE;
115 
116  buf.notification = notif;
117  buf.numberOfItems = ARRAY_LEN(notif);
118 
119  ais_res = saClmClusterTrack(clm_handle, SA_TRACK_CURRENT, &buf);
120  if (ais_res != SA_AIS_OK) {
121  ast_cli(a->fd, "Error retrieving current cluster members.\n");
122  return CLI_FAILURE;
123  }
124 
125  ast_cli(a->fd, "\n"
126  "=============================================================\n"
127  "=== Cluster Members =========================================\n"
128  "=============================================================\n"
129  "===\n");
130 
131  for (i = 0; i < buf.numberOfItems; i++) {
132  SaClmClusterNodeT *node = &buf.notification[i].clusterNode;
133 
134  ast_cli(a->fd, "=== ---------------------------------------------------------\n"
135  "=== Node Name: %s\n"
136  "=== ==> ID: 0x%x\n"
137  "=== ==> Address: %s\n"
138  "=== ==> Member: %s\n",
139  (char *) node->nodeName.value, (int) node->nodeId,
140  (char *) node->nodeAddress.value,
141  node->member ? "Yes" : "No");
142 
143  ast_cli(a->fd, "=== ---------------------------------------------------------\n"
144  "===\n");
145  }
146 
147  ast_cli(a->fd, "=============================================================\n"
148  "\n");
149 
150  return CLI_SUCCESS;
151 }
152 
153 static struct ast_cli_entry ais_cli[] = {
154  AST_CLI_DEFINE(ais_clm_show_members, "List current members of the cluster"),
155 };
156 
158 {
159  SaAisErrorT ais_res;
160 
161  clm_init_res = saClmInitialize(&clm_handle, &clm_callbacks, &ais_version);
162  if (clm_init_res != SA_AIS_OK) {
163  ast_log(LOG_ERROR, "Could not initialize cluster membership service: %s\n",
165  return -1;
166  }
167 
168  ais_res = saClmClusterTrack(clm_handle, SA_TRACK_CHANGES, NULL);
169  if (ais_res != SA_AIS_OK) {
170  ast_log(LOG_ERROR, "Error starting tracking of cluster membership changes.\n");
171  }
172 
173  ast_cli_register_multiple(ais_cli, ARRAY_LEN(ais_cli));
174 
175  return 0;
176 }
177 
179 {
180  SaAisErrorT ais_res;
181 
182  if (clm_init_res != SA_AIS_OK) {
183  return 0;
184  }
185 
186  ast_cli_unregister_multiple(ais_cli, ARRAY_LEN(ais_cli));
187 
188  ais_res = saClmFinalize(clm_handle);
189  if (ais_res != SA_AIS_OK) {
190  ast_log(LOG_ERROR, "Problem stopping cluster membership service: %s\n",
191  ais_err2str(ais_res));
192  return -1;
193  }
194 
195  return 0;
196 }
static void clm_track_cb(const SaClmClusterNotificationBufferT *notif_buffer, SaUint32T num_members, SaAisErrorT error)
Definition: clm.c:71
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
descriptor for a cli entry.
Definition: cli.h:165
const int argc
Definition: cli.h:154
Definition: cli.h:146
static const SaClmCallbacksT clm_callbacks
Definition: clm.c:60
ast_ais_cmd
Definition: ais.h:50
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
SaVersionT ais_version
Definition: res_ais.c:70
Utility functions.
int args
This gets set in ast_cli_register()
Definition: cli.h:179
int ast_ais_clm_load_module(void)
Definition: clm.c:157
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static SaAisErrorT clm_init_res
Definition: clm.c:53
const int fd
Definition: cli.h:153
Usage of the SAForum AIS (Application Interface Specification)
#define LOG_ERROR
Definition: logger.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
SaClmHandleT clm_handle
Definition: clm.c:52
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void clm_node_get_cb(SaInvocationT invocation, const SaClmClusterNodeT *cluster_node, SaAisErrorT error)
Definition: clm.c:65
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
Support for logging to various files, console and syslog Configuration in file logger.conf.
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char * ais_clm_show_members(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: clm.c:94
Standard Command Line Interface.
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
const char * ais_err2str(SaAisErrorT error)
Definition: res_ais.c:105
int ast_ais_clm_unload_module(void)
Definition: clm.c:178
Asterisk module definitions.
static struct ast_cli_entry ais_cli[]
Definition: clm.c:153
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180