From 903651caf320dfdaabd20a0e6f3cd0ffc843e02f Mon Sep 17 00:00:00 2001
From: Dave Barach <dave@barachs.net>
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 <dave@barachs.net>
---
 src/vlib/main.h      | 5 +++++
 src/vlib/unix/main.c | 7 +++----
 2 files changed, 8 insertions(+), 4 deletions(-)

(limited to 'src')

diff --git a/src/vlib/main.h b/src/vlib/main.h
index fb67334e4e2..4288d6f0388 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 ed0631ec871..f286c870b80 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