summaryrefslogtreecommitdiffstats
path: root/vpp-api-test/vat
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2016-10-09 17:43:22 -0400
committerDamjan Marion <dmarion.lists@gmail.com>2016-10-10 20:49:29 +0000
commit477570e587b6b5a8f356a2727794155fa912d59f (patch)
tree486062f11e6675d83ad19788f2e855080be195b0 /vpp-api-test/vat
parentb21b6768ffcf02554529ac94792e4f8f23a1f15d (diff)
Add signal handling
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 <dave@barachs.net>
Diffstat (limited to 'vpp-api-test/vat')
-rw-r--r--vpp-api-test/vat/api_format.c7
-rw-r--r--vpp-api-test/vat/main.c70
-rw-r--r--vpp-api-test/vat/vat.h2
3 files changed, 78 insertions, 1 deletions
diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c
index d9325c4ffa2..6874c7de573 100644
--- a/vpp-api-test/vat/api_format.c
+++ b/vpp-api-test/vat/api_format.c
@@ -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));
}
diff --git a/vpp-api-test/vat/main.c b/vpp-api-test/vat/main.c
index 904540b679e..8ba60e2b36d 100644
--- a/vpp-api-test/vat/main.c
+++ b/vpp-api-test/vat/main.c
@@ -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 ();
diff --git a/vpp-api-test/vat/vat.h b/vpp-api-test/vat/vat.h
index 041b3fb9a2c..0bae23c017d 100644
--- a/vpp-api-test/vat/vat.h
+++ b/vpp-api-test/vat/vat.h
@@ -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;