Add signal handling 30/3330/5
authorDave Barach <[email protected]>
Sun, 9 Oct 2016 21:43:22 +0000 (17:43 -0400)
committerDamjan Marion <[email protected]>
Mon, 10 Oct 2016 20:49:29 +0000 (20:49 +0000)
Please send SIGTERM to stop vpp_api_test, especially during
long-running operations such as a high-count asynchronous set of
ip_add_del_routes.

Otherwise, there's every chance that the data plane to vpp_api_test
message queue will fill and cause an easily-avoided deadlock.

Change-Id: I09309b445c354e1a692fed708dd5ea44d1ea9882
Signed-off-by: Dave Barach <[email protected]>
vpp-api-test/vat/api_format.c
vpp-api-test/vat/main.c
vpp-api-test/vat/vat.h

index d9325c4..6874c7d 100644 (file)
@@ -5829,6 +5829,9 @@ api_ip_add_del_route (vat_main_t * vam)
        }
       /* send it... */
       S;
+      /* If we receive SIGTERM, stop now... */
+      if (vam->do_exit)
+       break;
     }
 
   /* When testing multiple add/del ops, use a control-ping to sync */
@@ -5861,6 +5864,10 @@ api_ip_add_del_route (vat_main_t * vam)
       vam->async_errors = 0;
       after = vat_time_now (vam);
 
+      /* slim chance, but we might have eaten SIGTERM on the first iteration */
+      if (j > 0)
+       count = j;
+
       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
               count, after - before, count / (after - before));
     }
index 904540b..8ba60e2 100644 (file)
@@ -14,6 +14,7 @@
  */
 #include "vat.h"
 #include "plugin.h"
+#include <signal.h>
 
 vat_main_t vat_main;
 
@@ -72,6 +73,8 @@ do_one_file (vat_main_t * vam)
   if (setjmp (vam->jump_buf) != 0)
     return;
 
+  vam->jump_buf_set = 1;
+
   while (1)
     {
       if (vam->ifp == stdin)
@@ -84,7 +87,8 @@ do_one_file (vat_main_t * vam)
 
       _vec_len (vam->inbuf) = 4096;
 
-      if (fgets ((char *) vam->inbuf, vec_len (vam->inbuf), vam->ifp) == 0)
+      if (vam->do_exit ||
+         fgets ((char *) vam->inbuf, vec_len (vam->inbuf), vam->ifp) == 0)
        break;
 
       vam->input_line_number++;
@@ -195,6 +199,68 @@ eval_current_line (macro_main_t * mm, i32 complain)
   return ((i8 *) format (0, "%d%c", vam->input_line_number, 0));
 }
 
+static void
+signal_handler (int signum, siginfo_t * si, ucontext_t * uc)
+{
+  vat_main_t *vam = &vat_main;
+
+  switch (signum)
+    {
+      /* these (caught) signals cause the application to exit */
+    case SIGINT:
+    case SIGTERM:
+      if (vam->jump_buf_set)
+       {
+         vam->do_exit = 1;
+         return;
+       }
+
+      /* FALLTHROUGH on purpose */
+
+    default:
+      break;
+    }
+
+  _exit (1);
+}
+
+static void
+setup_signal_handlers (void)
+{
+  uword i;
+  struct sigaction sa;
+
+  for (i = 1; i < 32; i++)
+    {
+      memset (&sa, 0, sizeof (sa));
+      sa.sa_sigaction = (void *) signal_handler;
+      sa.sa_flags = SA_SIGINFO;
+
+      switch (i)
+       {
+         /* these signals take the default action */
+       case SIGABRT:
+       case SIGKILL:
+       case SIGSTOP:
+       case SIGUSR1:
+       case SIGUSR2:
+         continue;
+
+         /* ignore SIGPIPE, SIGCHLD */
+       case SIGPIPE:
+       case SIGCHLD:
+         sa.sa_sigaction = (void *) SIG_IGN;
+         break;
+
+         /* catch and handle all other signals */
+       default:
+         break;
+       }
+
+      if (sigaction (i, &sa, 0) < 0)
+       clib_unix_warning ("sigaction %U", format_signal, i);
+    }
+}
 
 int
 main (int argc, char **argv)
@@ -273,6 +339,8 @@ main (int argc, char **argv)
   vat_api_hookup (vam);
   vat_plugin_api_reference ();
 
+  setup_signal_handlers ();
+
   if (connect_to_vpe ("vpp_api_test") < 0)
     {
       svm_region_exit ();
index 041b3fb..0bae23c 100644 (file)
@@ -147,6 +147,8 @@ typedef struct
 
   /* Unwind (so we can quit) */
   jmp_buf jump_buf;
+  int jump_buf_set;
+  volatile int do_exit;
 
   /* temporary parse buffer */
   unformat_input_t *input;