diff options
author | Dave Barach <dave@barachs.net> | 2016-10-09 17:43:22 -0400 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2016-10-10 20:49:29 +0000 |
commit | 477570e587b6b5a8f356a2727794155fa912d59f (patch) | |
tree | 486062f11e6675d83ad19788f2e855080be195b0 /vpp-api-test | |
parent | b21b6768ffcf02554529ac94792e4f8f23a1f15d (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')
-rw-r--r-- | vpp-api-test/vat/api_format.c | 7 | ||||
-rw-r--r-- | vpp-api-test/vat/main.c | 70 | ||||
-rw-r--r-- | vpp-api-test/vat/vat.h | 2 |
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 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 <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 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; |