lib/event: Fix SEGV causing by spdk_app_stop executing twice.

Bdevperf shutdown_cb calls spdk_app_stop(0) directly.
 But since json configuration also failed, spdk_rpc_initialize()
 that calls spdk_app_stop, with -EINVAL. So subsystems are shutdown twice.

 Adding a flag stopped in spdk_app to record the spdk_app status.
 This confirms spdk app one start and one stop.

 Meanwhile this fixes some SEGVS.

 Fixes issue: #1731.

Signed-off-by: yidong0635 <dongx.yi@intel.com>
Change-Id: Ic3e36a458813a2d6bcf806de67ab691446b8d6fe
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5802
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Community-CI: Mellanox Build Bot
This commit is contained in:
yidong0635 2021-01-12 07:42:33 -05:00 committed by Tomasz Zawadzki
parent 2212610cd1
commit ad583422ce

View File

@ -59,6 +59,7 @@
struct spdk_app {
const char *json_config_file;
bool json_config_ignore_errors;
bool stopped;
const char *rpc_addr;
int shm_id;
spdk_app_shutdown_cb shutdown_cb;
@ -522,6 +523,7 @@ spdk_app_start(struct spdk_app_opts *opts_user, spdk_msg_fn start_fn,
g_spdk_app.shm_id = opts->shm_id;
g_spdk_app.shutdown_cb = opts->shutdown_cb;
g_spdk_app.rc = 0;
g_spdk_app.stopped = false;
spdk_log_set_level(SPDK_APP_DEFAULT_LOG_LEVEL);
@ -594,8 +596,18 @@ spdk_app_fini(void)
static void
app_stop(void *arg1)
{
if (g_spdk_app.rc == 0) {
g_spdk_app.rc = (int)(intptr_t)arg1;
}
if (g_spdk_app.stopped) {
SPDK_NOTICELOG("spdk_app_stop called twice\n");
return;
}
spdk_rpc_finish();
spdk_subsystem_fini(spdk_reactors_stop, NULL);
g_spdk_app.stopped = true;
}
void
@ -604,12 +616,12 @@ spdk_app_stop(int rc)
if (rc) {
SPDK_WARNLOG("spdk_app_stop'd on non-zero\n");
}
g_spdk_app.rc = rc;
/*
* We want to run spdk_subsystem_fini() from the same thread where spdk_subsystem_init()
* was called.
*/
spdk_thread_send_msg(g_app_thread, app_stop, NULL);
spdk_thread_send_msg(g_app_thread, app_stop, (void *)(intptr_t)rc);
}
static void