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:

committed by
Damjan Marion

parent
b21b6768ff
commit
477570e587
@ -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));
|
||||
}
|
||||
|
@ -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 ();
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user