Change in osmo-bts[master]: Introduce bts_shutdown FSM

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Tue Jun 23 12:49:11 UTC 2020


pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bts/+/18903 )

Change subject: Introduce bts_shutdown FSM
......................................................................

Introduce bts_shutdown FSM

Using an FSM here will allow for more complex ordered shutdown
procedures, like power ramp down, waiting for TRX deact asyncrhonously,
etc.

Current commit leaves everything in place already prepared to implement
ramp down, which will be implemented in next commit in the series.

Related: SYS#4920
Change-Id: I8f48f17e61c3b9b86342eaf5b8a2b1ac9758bde5
---
M include/osmo-bts/Makefile.am
A include/osmo-bts/bts_shutdown_fsm.h
M include/osmo-bts/gsm_data.h
M src/common/Makefile.am
M src/common/bts.c
A src/common/bts_shutdown_fsm.c
M src/common/gsm_data.c
7 files changed, 204 insertions(+), 34 deletions(-)

Approvals:
  fixeria: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/include/osmo-bts/Makefile.am b/include/osmo-bts/Makefile.am
index 4999ab4..310fce2 100644
--- a/include/osmo-bts/Makefile.am
+++ b/include/osmo-bts/Makefile.am
@@ -2,6 +2,7 @@
 	abis.h \
 	bts.h \
 	bts_model.h \
+	bts_shutdown_fsm.h \
 	gsm_data.h \
 	logging.h \
 	measurement.h \
diff --git a/include/osmo-bts/bts_shutdown_fsm.h b/include/osmo-bts/bts_shutdown_fsm.h
new file mode 100644
index 0000000..1268b2b
--- /dev/null
+++ b/include/osmo-bts/bts_shutdown_fsm.h
@@ -0,0 +1,38 @@
+/* BTS shutdown FSM */
+
+/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info at sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin at sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include <osmocom/core/fsm.h>
+
+/* 3GPP TS 24.008 § 4.1.3.3 GMM mobility management states on the network side */
+enum bts_shutdown_fsm_states {
+	BTS_SHUTDOWN_ST_NONE,
+	BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL,
+	BTS_SHUTDOWN_ST_EXIT,
+};
+
+enum bts_shutdown_fsm_events {
+	BTS_SHUTDOWN_EV_START,
+};
+
+extern struct osmo_fsm bts_shutdown_fsm;
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h
index 9032aeb..416864f 100644
--- a/include/osmo-bts/gsm_data.h
+++ b/include/osmo-bts/gsm_data.h
@@ -733,6 +733,9 @@
 		char *sock_path;
 	} pcu;
 
+	struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */
+	struct osmo_tdef *T_defs; /* Timer defines */
+
 	void *model_priv; /* Allocated by bts_model, contains model specific data pointer */
 };
 
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 85b7038..2fa5514 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -27,6 +27,7 @@
 	tx_power.c \
 	bts_ctrl_commands.c \
 	bts_ctrl_lookup.c \
+	bts_shutdown_fsm.c \
 	l1sap.c \
 	cbch.c \
 	power_control.c \
diff --git a/src/common/bts.c b/src/common/bts.c
index d2bca2f..dccb098 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -269,39 +269,6 @@
 	return 0;
 }
 
-static void shutdown_timer_cb(void *data)
-{
-	fprintf(stderr, "Shutdown timer expired\n");
-	exit(42);
-}
-
-static struct osmo_timer_list shutdown_timer = {
-	.cb = &shutdown_timer_cb,
-};
-
-void bts_shutdown(struct gsm_bts *bts, const char *reason)
-{
-	struct gsm_bts_trx *trx;
-
-	if (osmo_timer_pending(&shutdown_timer)) {
-		LOGP(DOML, LOGL_NOTICE,
-			"BTS is already being shutdown.\n");
-		return;
-	}
-
-	LOGP(DOML, LOGL_NOTICE, "Shutting down BTS %u, Reason %s\n",
-		bts->nr, reason);
-
-	llist_for_each_entry_reverse(trx, &bts->trx_list, list) {
-		bts_model_trx_deact_rf(trx);
-		bts_model_trx_close(trx);
-	}
-
-	/* schedule a timer to make sure select loop logic can run again
-	 * to dispatch any pending primitives */
-	osmo_timer_schedule(&shutdown_timer, 3, 0);
-}
-
 /* main link is established, send status report */
 int bts_link_estab(struct gsm_bts *bts)
 {
diff --git a/src/common/bts_shutdown_fsm.c b/src/common/bts_shutdown_fsm.c
new file mode 100644
index 0000000..50ef652
--- /dev/null
+++ b/src/common/bts_shutdown_fsm.c
@@ -0,0 +1,144 @@
+/* BTS shutdown FSM */
+
+/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info at sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin at sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/tdef.h>
+
+#include <osmo-bts/bts_shutdown_fsm.h>
+#include <osmo-bts/logging.h>
+#include <osmo-bts/gsm_data.h>
+#include <osmo-bts/bts_model.h>
+
+#define X(s) (1 << (s))
+
+static const struct osmo_tdef_state_timeout bts_shutdown_fsm_timeouts[32] = {
+	[BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL] = { .T = -1 },
+	[BTS_SHUTDOWN_ST_EXIT] = { .T = -2 },
+};
+
+#define bts_shutdown_fsm_state_chg(fi, NEXT_STATE) \
+	osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, bts_shutdown_fsm_timeouts, ((struct gsm_bts *)fi->priv)->T_defs, -1)
+
+static void st_none(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch(event) {
+	case BTS_SHUTDOWN_EV_START:
+		bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL);
+		break;
+	}
+}
+
+static void st_wait_ramp_down_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+	/* TODO: here power ramp down will be started on all TRX, prior to changing state */
+}
+
+static void st_wait_ramp_down_compl(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	/* TODO: In here once we have ramp down implemented we'll transit to
+	   regular exit. For now we simply wait for state timeout
+	   bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_EXIT);
+	*/
+}
+
+static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+	struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
+	struct gsm_bts_trx *trx;
+	llist_for_each_entry_reverse(trx, &bts->trx_list, list) {
+		bts_model_trx_deact_rf(trx);
+		bts_model_trx_close(trx);
+	}
+	/* There's yet no way to get confirmation from lower layers regarding
+	   state. Allow a few seconds of select() loop and timeout timer will
+	   exit later */
+}
+
+static struct osmo_fsm_state bts_shutdown_fsm_states[] = {
+	[BTS_SHUTDOWN_ST_NONE] = {
+		.in_event_mask =
+			X(BTS_SHUTDOWN_EV_START),
+		.out_state_mask = X(BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL),
+		.name = "NONE",
+		.action = st_none,
+	},
+	[BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL] = {
+		.in_event_mask = 0,
+		.out_state_mask =
+			X(BTS_SHUTDOWN_ST_EXIT),
+		.name = "WAIT_RAMP_DOWN_COMPL",
+		.onenter = st_wait_ramp_down_compl_on_enter,
+		.action = st_wait_ramp_down_compl,
+	},
+	[BTS_SHUTDOWN_ST_EXIT] = {
+		.name = "EXIT",
+		.onenter = st_exit_on_enter,
+	}
+};
+
+const struct value_string bts_shutdown_fsm_event_names[] = {
+	OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_START),
+	{ 0, NULL }
+};
+
+int bts_shutdown_fsm_timer_cb(struct osmo_fsm_inst *fi)
+{
+	switch (fi->state) {
+	case BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL:
+		LOGPFSML(fi, LOGL_ERROR, "Timer expired waiting for ramp down complete\n");
+		bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_EXIT);
+		break;
+	case BTS_SHUTDOWN_ST_EXIT:
+		LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfuly, exiting process\n");
+		exit(0);
+		break;
+	default:
+		OSMO_ASSERT(false);
+	}
+	return 0;
+}
+
+struct osmo_fsm bts_shutdown_fsm = {
+	.name = "BTS_SHUTDOWN",
+	.states = bts_shutdown_fsm_states,
+	.num_states = ARRAY_SIZE(bts_shutdown_fsm_states),
+	.event_names = bts_shutdown_fsm_event_names,
+	.log_subsys = DOML,
+	.timer_cb = bts_shutdown_fsm_timer_cb,
+};
+
+static __attribute__((constructor)) void bts_shutdown_fsm_init(void)
+{
+	OSMO_ASSERT(osmo_fsm_register(&bts_shutdown_fsm) == 0);
+}
+
+void bts_shutdown(struct gsm_bts *bts, const char *reason)
+{
+	struct osmo_fsm_inst *fi = bts->shutdown_fi;
+	if (fi->state != BTS_SHUTDOWN_ST_NONE) {
+		LOGPFSML(fi, LOGL_NOTICE, "BTS is already being shutdown.\n");
+		return;
+	}
+
+	LOGPFSML(fi, LOGL_NOTICE, "Shutting down BTS, reason: %s\n", reason);
+	osmo_fsm_inst_dispatch(fi, BTS_SHUTDOWN_EV_START, NULL);
+}
diff --git a/src/common/gsm_data.c b/src/common/gsm_data.c
index c680001..18d5b66 100644
--- a/src/common/gsm_data.c
+++ b/src/common/gsm_data.c
@@ -28,12 +28,22 @@
 
 #include <osmocom/core/linuxlist.h>
 #include <osmocom/core/talloc.h>
+#include <osmocom/core/statistics.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/tdef.h>
+
 #include <osmocom/gsm/gsm_utils.h>
 #include <osmocom/gsm/abis_nm.h>
-#include <osmocom/core/statistics.h>
 #include <osmocom/codec/ecu.h>
 
 #include <osmo-bts/gsm_data.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
+
+static struct osmo_tdef bts_T_defs[] = {
+	{ .T=-1, .default_val=1, .desc="Time after which osmo-bts exits if regular ramp down during shut down process does not finish (s)" },
+	{ .T=-2, .default_val=3, .desc="Time after which osmo-bts exits if requesting transceivers to stop during shut down process does not finish (s)" },
+	{}
+};
 
 void gsm_abis_mo_reset(struct gsm_abis_mo *mo)
 {
@@ -277,6 +287,12 @@
 	INIT_LLIST_HEAD(&bts->trx_list);
 	bts->ms_max_power = 15;	/* dBm */
 
+	bts->T_defs = bts_T_defs;
+	osmo_tdefs_reset(bts->T_defs);
+	bts->shutdown_fi = osmo_fsm_inst_alloc(&bts_shutdown_fsm, bts, bts,
+					       LOGL_INFO, NULL);
+	osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr);
+
 	gsm_mo_init(&bts->mo, bts, NM_OC_BTS,
 			bts->nr, 0xff, 0xff);
 	gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/18903
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I8f48f17e61c3b9b86342eaf5b8a2b1ac9758bde5
Gerrit-Change-Number: 18903
Gerrit-PatchSet: 5
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-CC: neels <nhofmeyr at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200623/3995b8e9/attachment.htm>


More information about the gerrit-log mailing list