From 477570e587b6b5a8f356a2727794155fa912d59f Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Sun, 9 Oct 2016 17:43:22 -0400 Subject: 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 --- vpp-api-test/vat/api_format.c | 7 +++++ vpp-api-test/vat/main.c | 70 ++++++++++++++++++++++++++++++++++++++++++- vpp-api-test/vat/vat.h | 2 ++ 3 files changed, 78 insertions(+), 1 deletion(-) (limited to 'vpp-api-test') diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c index d9325c4f..6874c7de 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 904540b6..8ba60e2b 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 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 041b3fb9..0bae23c0 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; -- cgit 1.2.3-korg