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>
This commit is contained in:
Dave Barach
2016-10-09 17:43:22 -04:00
committed by Damjan Marion
parent b21b6768ff
commit 477570e587
3 changed files with 78 additions and 1 deletions

View 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));
}

View 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 ();

View 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;