aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2012-01-27 14:20:24 +0100
committerHarald Welte <laforge@gnumonks.org>2012-01-27 18:12:03 +0100
commit1dde661dd6653f21ddb003f203f8a23f201d68c9 (patch)
tree268560908c700e5cd20ab6dc589b7dbbbea3c337
parent122b6331927dd65d716d71cdf8fcb728cc2475f9 (diff)
osmo-bsc: Add configurable option to spawn + respawn osmo-bsc_mgcplaforge/mgcp-rework
If it is configured in the config file or on the VTY, osmo-bsc will fork+exec osmo-bsc_mgcp. Furthermore, if osmo-bsc_mgcp dies, osmo-bsc will re-spawn it. This also means that we can now send a SIGHUP to osmo-bsc_mgcp in the event of a Msc (re)connect, causing it to send RSIP, which in turn is required by certain call agents that forget to send a AUEP on startup to determine the endpoint state of the media gateway[s].
-rw-r--r--openbsc/include/openbsc/osmo_msc_data.h7
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_main.c44
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_msc.c5
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_vty.c62
4 files changed, 115 insertions, 3 deletions
diff --git a/openbsc/include/openbsc/osmo_msc_data.h b/openbsc/include/openbsc/osmo_msc_data.h
index 59b75c303..cc997ff8c 100644
--- a/openbsc/include/openbsc/osmo_msc_data.h
+++ b/openbsc/include/openbsc/osmo_msc_data.h
@@ -69,6 +69,13 @@ struct osmo_msc_data {
/* ussd welcome text */
char *ussd_welcome_txt;
+
+ /* osmo-bsc_mgcp related */
+ struct {
+ char *path;
+ char *config_path;
+ pid_t pid;
+ } bsc_mgcp;
};
int osmo_bsc_msc_init(struct gsm_network *network);
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_main.c b/openbsc/src/osmo-bsc/osmo_bsc_main.c
index 9a799c0c6..6997f3b28 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_main.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_main.c
@@ -138,15 +138,44 @@ static struct vty_app_info vty_info = {
.is_config_node = bsc_vty_is_config_node,
};
+static int spawn_mgcp(void)
+{
+ pid_t pid;
+ struct osmo_msc_data *data = bsc_gsmnet->msc_data;
+
+ if (!data->bsc_mgcp.path) {
+ LOGP(DMGCP, LOGL_NOTICE,
+ "Config file instructs us to not start osmo-bsc_mgcp!\n");
+ return 0;
+ }
+
+ pid = fork();
+ if (pid == 0) {
+ execlp(data->bsc_mgcp.path, "osmo-bsc_mgcp", "-c",
+ data->bsc_mgcp.config_path, NULL);
+ /* only in case of error we ever end up here */
+ fprintf(stderr, "Unable to exec() mgcp `%s`: %s\n",
+ data->bsc_mgcp.path, strerror(errno));
+ exit(1);
+ } else {
+ data->bsc_mgcp.pid = pid;
+ return 0;
+ }
+}
+
extern int bsc_shutdown_net(struct gsm_network *net);
-static void signal_handler(int signal)
+static void signal_handler(int signum)
{
- fprintf(stdout, "signal %u received\n", signal);
+ fprintf(stdout, "signal %u received\n", signum);
- switch (signal) {
+ switch (signum) {
case SIGINT:
bsc_shutdown_net(bsc_gsmnet);
osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
+ if (bsc_gsmnet->msc_data && bsc_gsmnet->msc_data->bsc_mgcp.pid) {
+ signal(SIGCHLD, SIG_IGN);
+ kill(bsc_gsmnet->msc_data->bsc_mgcp.pid, SIGTERM);
+ }
sleep(3);
exit(0);
break;
@@ -166,6 +195,12 @@ static void signal_handler(int signal)
return;
bsc_msc_lost(bsc_gsmnet->msc_data->msc_con);
break;
+ case SIGCHLD:
+ /* bsc_mgcp seems to have died */
+ /* sleep for some time to avoid fork bomb */
+ sleep(1);
+ spawn_mgcp();
+ break;
default:
break;
}
@@ -459,8 +494,11 @@ int main(int argc, char **argv)
signal(SIGABRT, &signal_handler);
signal(SIGUSR1, &signal_handler);
signal(SIGUSR2, &signal_handler);
+ signal(SIGCHLD, &signal_handler);
osmo_init_ignore_signals();
+ spawn_mgcp();
+
if (daemonize) {
rc = osmo_daemonize();
if (rc < 0) {
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_msc.c b/openbsc/src/osmo-bsc/osmo_bsc_msc.c
index 04cfb997d..68c469946 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_msc.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_msc.c
@@ -37,6 +37,7 @@
#include <osmocom/abis/ipa.h>
#include <sys/socket.h>
+#include <sys/signal.h>
#include <netinet/tcp.h>
#include <unistd.h>
@@ -342,6 +343,10 @@ static void msc_connection_connected(struct bsc_msc_connection *con)
data = (struct osmo_msc_data *) con->write_queue.bfd.data;
msc_ping_timeout_cb(data);
+ /* notify bsc_mgcp to reset all end-points */
+ if (data->bsc_mgcp.pid)
+ kill(data->bsc_mgcp.pid, SIGHUP);
+
sig.data = data;
osmo_signal_dispatch(SS_MSC, S_MSC_CONNECTED, &sig);
}
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_vty.c b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
index 0b1698e41..912d44646 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_vty.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
@@ -18,6 +18,8 @@
*
*/
+#include <sys/signal.h>
+
#include <openbsc/gsm_data.h>
#include <openbsc/osmo_msc_data.h>
#include <openbsc/vty.h>
@@ -325,6 +327,61 @@ DEFUN(cfg_net_rf_socket,
return CMD_SUCCESS;
}
+#define MGCP_STR "Configuration of the osmo-bsc_mgcp\n"
+
+DEFUN(cfg_net_msc_mgcp, cfg_net_msc_mgcp_cmd,
+ "bsc-mgcp executable PATH", MGCP_STR
+ "Set the filename / path of the osmo-bsc_mgcp executable.\n"
+ "filename / path of the osmo-bsc_mgcp executable\n")
+{
+ struct osmo_msc_data *data = osmo_msc_data(vty);
+ int equal = 0;
+
+ if (data->bsc_mgcp.path && !strcmp(data->bsc_mgcp.path, argv[0]))
+ equal = 1;
+
+ bsc_replace_string(data, &data->bsc_mgcp.path, argv[0]);
+
+ if (equal)
+ return CMD_SUCCESS;
+
+ if (data->bsc_mgcp.pid) {
+ kill(data->bsc_mgcp.pid, SIGTERM);
+ data->bsc_mgcp.pid = 0;
+ /* we will get SIGCHLD and re-spawn new path */
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_msc_no_mgcp, cfg_net_msc_no_mgcp_cmd,
+ "no bsc-mgcp executable", NO_STR MGCP_STR
+ "Do not start osmo-bsc_mgcp from osmo-bsc\n")
+{
+ struct osmo_msc_data *data = osmo_msc_data(vty);
+
+ talloc_free(data->bsc_mgcp.path);
+ data->bsc_mgcp.path = NULL;
+
+ if (data->bsc_mgcp.pid) {
+ kill(data->bsc_mgcp.pid, SIGTERM);
+ data->bsc_mgcp.pid = 0;
+ /* SIGCHLD handler will not try to respawn, as path == NULL */
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_msc_cfg_mgcp, cfg_net_msc_mgcp_cfg_cmd,
+ "bsc-mgcp config-file PATH", MGCP_STR
+ "Set the filename / path of the osmo-bsc_mgcp config file\n"
+ "filename / path of the osmo-bsc_mgcp config file\n")
+{
+ struct osmo_msc_data *data = osmo_msc_data(vty);
+
+ bsc_replace_string(data, &data->bsc_mgcp.config_path, argv[0]);
+ return CMD_SUCCESS;
+}
+
DEFUN(show_statistics,
show_statistics_cmd,
"show statistics",
@@ -353,6 +410,11 @@ int bsc_vty_init_extra(void)
install_element(MSC_NODE, &cfg_net_msc_welcome_ussd_cmd);
install_element(MSC_NODE, &cfg_net_rf_socket_cmd);
+ /* FIXME: this should probably be a global MGCP node? */
+ install_element(MSC_NODE, &cfg_net_msc_mgcp_cmd);
+ install_element(MSC_NODE, &cfg_net_msc_no_mgcp_cmd);
+ install_element(MSC_NODE, &cfg_net_msc_mgcp_cfg_cmd);
+
install_element_ve(&show_statistics_cmd);
return 0;