Commit c871ee40 authored by JinYu's avatar JinYu Committed by Tomasz Zawadzki
Browse files

nvmf_example: add the signal handler



Add the same handler for SIGINT and SIGTERM so that
the working thread can exit.

Change-Id: If1ce617ddd778e92bed6f95089c48caf841e256f
Signed-off-by: default avatarJinYu <jin.yu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468661


Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarGangCao <gang.cao@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 9db5eca6
Loading
Loading
Loading
Loading
+72 −3
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ static struct spdk_thread *g_init_thread = NULL;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
static bool g_reactors_exit = false;
static enum nvmf_target_state g_target_state;
static bool g_intr_received = false;

static void nvmf_target_advance_state(void);

@@ -312,9 +313,6 @@ nvmf_subsystem_init_done(int rc, void *cb_arg)
	fprintf(stdout, "bdev subsystem init successfully\n");
	spdk_rpc_initialize(g_rpc_addr);
	spdk_rpc_set_state(SPDK_RPC_RUNTIME);

	g_target_state = NVMF_FINI_SUBSYSTEM;
	nvmf_target_advance_state();
}

static void
@@ -344,6 +342,73 @@ nvmf_target_app_start(void *arg)
	nvmf_target_advance_state();
}

static void
_nvmf_shutdown_cb(void *ctx)
{
	/* Still in initialization state, defer shutdown operation */
	if (g_target_state < NVMF_INIT_SUBSYSTEM) {
		spdk_thread_send_msg(spdk_get_thread(), _nvmf_shutdown_cb, NULL);
		return;
	} else if (g_target_state >= NVMF_FINI_SUBSYSTEM) {
		/* Already in Shutdown status, ignore the signal */
		return;
	}

	g_target_state = NVMF_FINI_SUBSYSTEM;
	nvmf_target_advance_state();
}

static void
nvmf_shutdown_cb(int signo)
{
	if (!g_intr_received) {
		g_intr_received = true;
		spdk_thread_send_msg(g_init_thread, _nvmf_shutdown_cb, NULL);
	}
}

static int
nvmf_setup_signal_handlers(void)
{
	struct sigaction	sigact;
	sigset_t		sigmask;
	int			signals[] = {SIGINT, SIGTERM};
	int			num_signals = sizeof(signals) / sizeof(int);
	int			rc, i;

	rc = sigemptyset(&sigmask);
	if (rc) {
		fprintf(stderr, "errno:%d--failed to empty signal set\n", errno);
		return rc;
	}
	memset(&sigact, 0, sizeof(sigact));
	rc = sigemptyset(&sigact.sa_mask);
	if (rc) {
		fprintf(stderr, "errno:%d--failed to empty signal set\n", errno);
		return rc;
	}

	/* Install the same handler for SIGINT and SIGTERM */
	sigact.sa_handler = nvmf_shutdown_cb;

	for (i = 0; i < num_signals; i++) {
		rc = sigaction(signals[i], &sigact, NULL);
		if (rc < 0) {
			fprintf(stderr, "errno:%d--sigaction() failed\n", errno);
			return rc;
		}
		rc = sigaddset(&sigmask, signals[i]);
		if (rc) {
			fprintf(stderr, "errno:%d--failed to add set\n", errno);
			return rc;
		}
	}

	pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL);

	return 0;
}

int main(int argc, char **argv)
{
	int rc;
@@ -374,6 +439,10 @@ int main(int argc, char **argv)
	lw_thread = TAILQ_FIRST(&g_master_reactor->threads);
	g_init_thread = spdk_thread_get_from_ctx(lw_thread);
	assert(g_init_thread != NULL);

	rc = nvmf_setup_signal_handlers();
	assert(rc == 0);

	spdk_thread_send_msg(g_init_thread, nvmf_target_app_start, NULL);

	nvmf_reactor_run(g_master_reactor);
+4 −1
Original line number Diff line number Diff line
@@ -21,8 +21,10 @@ NVMF_EXAMPLE="$(build_nvmf_example_args)"
function nvmfexamplestart()
{
        timing_enter start_nvmf_example
        $NVMF_EXAMPLE $1
        $NVMF_EXAMPLE $1 &
        nvmfpid=$!
	trap 'process_shm --id $NVMF_APP_SHM_ID; nvmftestfini; exit 1' SIGINT SIGTERM EXIT
	waitforfile /var/tmp/spdk.sock
        timing_exit start_nvmf_example
}

@@ -30,5 +32,6 @@ timing_enter nvmf_example_test
nvmftestinit
nvmfexamplestart "-m 0xF"

trap - SIGINT SIGTERM EXIT
nvmftestfini
timing_exit nvmf_example_test