diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2020-06-18 19:38:18 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2020-06-23 14:55:51 +0200 |
commit | a6386ea64d5be35aea8fe9331270a9ef146984e5 (patch) | |
tree | 56f7313ede40f9b13bd3995f85fc8bbfc3c7b111 | |
parent | 8090df2a813a3cf174afb8acb9aba92b65d275fb (diff) |
bts_shutdown: Wait until all TRX are closed
Setting the phy link of a trx to SHUTDOWN sets operative state to
DISABLED, so we use operative state as a condition to know whether all
TRX are already powered off properly and we can exit.
Change-Id: I2bcd211d7edcc8486461a555d6c470a94b166ed7
-rw-r--r-- | include/osmo-bts/bts_shutdown_fsm.h | 2 | ||||
-rw-r--r-- | src/common/bts_shutdown_fsm.c | 60 |
2 files changed, 51 insertions, 11 deletions
diff --git a/include/osmo-bts/bts_shutdown_fsm.h b/include/osmo-bts/bts_shutdown_fsm.h index 42f953a3..1e74ac6b 100644 --- a/include/osmo-bts/bts_shutdown_fsm.h +++ b/include/osmo-bts/bts_shutdown_fsm.h @@ -28,12 +28,14 @@ enum bts_shutdown_fsm_states { BTS_SHUTDOWN_ST_NONE, BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL, + BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED, BTS_SHUTDOWN_ST_EXIT, }; enum bts_shutdown_fsm_events { BTS_SHUTDOWN_EV_START, BTS_SHUTDOWN_EV_TRX_RAMP_COMPL, + BTS_SHUTDOWN_EV_TRX_CLOSED, }; extern struct osmo_fsm bts_shutdown_fsm; diff --git a/src/common/bts_shutdown_fsm.c b/src/common/bts_shutdown_fsm.c index 81cd3489..d8a8d112 100644 --- a/src/common/bts_shutdown_fsm.c +++ b/src/common/bts_shutdown_fsm.c @@ -32,7 +32,7 @@ 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 }, + [BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED] = { .T = -2 }, }; #define bts_shutdown_fsm_state_chg(fi, NEXT_STATE) \ @@ -79,12 +79,12 @@ static void st_wait_ramp_down_compl(struct osmo_fsm_inst *fi, uint32_t event, vo LOGPFSML(fi, LOGL_INFO, "%s Ramping down complete, %u TRX remaining\n", gsm_trx_name(src_trx), remaining); if (remaining == 0) - bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_EXIT); + bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED); break; } } -static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +static void st_wait_trx_closed_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; @@ -94,9 +94,36 @@ static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) llist_for_each_entry_reverse(trx, &bts->trx_list, list) { 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 */ + /* Now wait until all TRX are closed asynchronously, we'll get feedback through events... */ +} + +static void st_wait_trx_closed(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_bts *bts = (struct gsm_bts *)fi->priv; + struct gsm_bts_trx *src_trx, *trx; + unsigned int remaining = 0; + + switch(event) { + case BTS_SHUTDOWN_EV_TRX_CLOSED: + src_trx = (struct gsm_bts_trx *)data; + + llist_for_each_entry(trx, &bts->trx_list, list) { + if (trx->mo.nm_state.operational != NM_OPSTATE_DISABLED) + remaining++; + } + + LOGPFSML(fi, LOGL_INFO, "%s TRX closed, %u TRX remaining\n", + gsm_trx_name(src_trx), remaining); + if (remaining == 0) + bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_EXIT); + break; + } +} + +static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfuly, exiting process\n"); + exit(0); } static struct osmo_fsm_state bts_shutdown_fsm_states[] = { @@ -111,11 +138,20 @@ static struct osmo_fsm_state bts_shutdown_fsm_states[] = { .in_event_mask = X(BTS_SHUTDOWN_EV_TRX_RAMP_COMPL), .out_state_mask = - X(BTS_SHUTDOWN_ST_EXIT), + X(BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED), .name = "WAIT_RAMP_DOWN_COMPL", .onenter = st_wait_ramp_down_compl_on_enter, .action = st_wait_ramp_down_compl, }, + [BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED] = { + .in_event_mask = + X(BTS_SHUTDOWN_EV_TRX_CLOSED), + .out_state_mask = + X(BTS_SHUTDOWN_ST_EXIT), + .name = "WAIT_TRX_CLOSED", + .onenter = st_wait_trx_closed_on_enter, + .action = st_wait_trx_closed, + }, [BTS_SHUTDOWN_ST_EXIT] = { .name = "EXIT", .onenter = st_exit_on_enter, @@ -125,6 +161,7 @@ static struct osmo_fsm_state bts_shutdown_fsm_states[] = { const struct value_string bts_shutdown_fsm_event_names[] = { OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_START), OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_TRX_RAMP_COMPL), + OSMO_VALUE_STRING(BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED), { 0, NULL } }; @@ -133,11 +170,11 @@ 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); + bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED); break; - case BTS_SHUTDOWN_ST_EXIT: - LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfuly, exiting process\n"); - exit(0); + case BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED: + LOGPFSML(fi, LOGL_ERROR, "Timer expired waiting for TRX close\n"); + bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_EXIT); break; default: OSMO_ASSERT(false); @@ -175,4 +212,5 @@ void bts_model_trx_close_cb(struct gsm_bts_trx *trx, int rc) { struct osmo_fsm_inst *fi = trx->bts->shutdown_fi; LOGPFSML(fi, LOGL_DEBUG, "%s Received TRX close cb rc=%d\n", gsm_trx_name(trx), rc); + osmo_fsm_inst_dispatch(fi, BTS_SHUTDOWN_EV_TRX_CLOSED, trx); } |