From 84db40e02e74efabe094e0d46ed2fafd348d126d Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Fri, 13 Oct 2017 19:16:56 -0400 Subject: VPP-1029: Don't call clib_longjmp(...) directly from the SIGTERM handler It's way too easy to imagine leaving a mutex or a spin-lock held in the /vpe-api shared-memory segment, or elsewhere. Set a volatile variable and check it in a safe place... Change-Id: I9d91c38cffeb921143c272162d055c9c24a6c312 Signed-off-by: Dave Barach (cherry picked from commit 903651caf320dfdaabd20a0e6f3cd0ffc843e02f) --- src/vlib/main.h | 5 +++++ src/vlib/unix/main.c | 7 +++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vlib/main.h b/src/vlib/main.h index fb67334e..4288d6f0 100644 --- a/src/vlib/main.h +++ b/src/vlib/main.h @@ -85,6 +85,8 @@ typedef struct vlib_main_t /* Jump target to exit main loop with given code. */ u32 main_loop_exit_set; + /* Set e.g. in the SIGTERM signal handler, checked in a safe place... */ + volatile u32 main_loop_exit_now; clib_longjmp_t main_loop_exit; #define VLIB_MAIN_LOOP_EXIT_NONE 0 #define VLIB_MAIN_LOOP_EXIT_PANIC 1 @@ -340,6 +342,9 @@ vlib_increment_main_loop_counter (vlib_main_t * vm) vm->main_loop_nodes_processed = 0; vm->vector_counts_per_main_loop[i] = v; vm->node_counts_per_main_loop[i] = n; + + if (PREDICT_FALSE (vm->main_loop_exit_now)) + clib_longjmp (&vm->main_loop_exit, VLIB_MAIN_LOOP_EXIT_CLI); } always_inline void vlib_set_queue_signal_callback diff --git a/src/vlib/unix/main.c b/src/vlib/unix/main.c index ed0631ec..f286c870 100644 --- a/src/vlib/unix/main.c +++ b/src/vlib/unix/main.c @@ -75,7 +75,7 @@ VLIB_INIT_FUNCTION (unix_main_init); static void unix_signal_handler (int signum, siginfo_t * si, ucontext_t * uc) { - uword fatal; + uword fatal = 0; u8 *msg = 0; msg = format (msg, "received signal %U, PC %U", @@ -91,10 +91,9 @@ unix_signal_handler (int signum, siginfo_t * si, ucontext_t * uc) if (unix_main.vlib_main->main_loop_exit_set) { syslog (LOG_ERR | LOG_DAEMON, "received SIGTERM, exiting..."); - - clib_longjmp (&unix_main.vlib_main->main_loop_exit, - VLIB_MAIN_LOOP_EXIT_CLI); + unix_main.vlib_main->main_loop_exit_now = 1; } + break; /* fall through */ case SIGQUIT: case SIGINT: -- cgit 1.2.3-korg