From 7e8a6115684970658568323e36f460d5ea85a06b Mon Sep 17 00:00:00 2001 From: Ziye Yang Date: Fri, 8 Dec 2017 18:57:43 +0800 Subject: [PATCH] nvmf/tgt: Fix issues for ctrlr+ c handling. When receving ctrlr+c event, NVMe-oF target could in any state. So we cannot guarantee g_acceptor_poller is initialized or not. If we do not handle such case, ctrlr+c will trigger unexpected coredump issue. To solve this issue, following methods are used. Currently, our code in event module (lib/event/app.c) can only receive ctrlr + c command once, so when we receive the ctrlr+c, we should complete the shutdown process. The idea is to use spdk_event_call, we will only enter shutdown process if tgt is in NVMF_TGT_RUNNING status. After several patch tries, I think that this solution is much simple. Though we would like to kill after entering the running state, it may wait some time if users kill the application in early state, but those operations will not be quite often in real case. Change-Id: Id89a96b5d39f8a528e72dea8c0eb6524bdaf7ee4 Signed-off-by: Ziye Yang Reviewed-on: https://review.gerrithub.io/389433 Tested-by: SPDK Automated Test System Reviewed-by: Ben Walker Reviewed-by: Daniel Verkamp --- app/nvmf_tgt/nvmf_tgt.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/app/nvmf_tgt/nvmf_tgt.c b/app/nvmf_tgt/nvmf_tgt.c index c95b08ece..8546d67b5 100644 --- a/app/nvmf_tgt/nvmf_tgt.c +++ b/app/nvmf_tgt/nvmf_tgt.c @@ -57,16 +57,38 @@ static struct spdk_poller *g_acceptor_poller = NULL; static void nvmf_tgt_advance_state(void *arg1, void *arg2); static void -spdk_nvmf_shutdown_cb(void) +_spdk_nvmf_shutdown_cb(void *arg1, void *arg2) { - fprintf(stdout, "\n=========================\n"); - fprintf(stdout, " NVMF shutdown signal\n"); - fprintf(stdout, "=========================\n"); + /* Still in initialization state, defer shutdown operation */ + if (g_tgt.state < NVMF_TGT_RUNNING) { + spdk_event_call(spdk_event_allocate(spdk_env_get_current_core(), + _spdk_nvmf_shutdown_cb, NULL, NULL)); + return; + } else if (g_tgt.state > NVMF_TGT_RUNNING) { + /* Already in Shutdown status, ignore the signal */ + return; + } g_tgt.state = NVMF_TGT_FINI_STOP_ACCEPTOR; nvmf_tgt_advance_state(NULL, NULL); } +static void +spdk_nvmf_shutdown_cb(void) +{ + printf("\n=========================\n"); + printf(" NVMF shutdown signal\n"); + printf("=========================\n"); + + /* Always let the first core to handle the case */ + if (spdk_env_get_current_core() != spdk_env_get_first_core()) { + spdk_event_call(spdk_event_allocate(spdk_env_get_first_core(), + _spdk_nvmf_shutdown_cb, NULL, NULL)); + } else { + _spdk_nvmf_shutdown_cb(NULL, NULL); + } +} + struct spdk_nvmf_subsystem * nvmf_tgt_create_subsystem(const char *name, enum spdk_nvmf_subtype subtype, uint32_t num_ns) {