On 11/12/2022 5:28 PM, Stephen Hemminger wrote: > Do a clean shutdown of testpmd when a signal is received; > instead of having testpmd kill itself. > This fixes the problem where a signal could be received > in the middle of a PMD and then the signal handler would call > PMD's close routine leading to locking problems. > > An added benefit is it gets rid of some Windows specific code. > > Fixes: d9a191a00e81 ("app/testpmd: fix quitting in container") > Signed-off-by: Stephen Hemminger <step...@networkplumber.org> > --- > v8 - fix build on Windows (again) > Windows doesn't have FILENO_STDIN > > app/test-pmd/testpmd.c | 67 +++++++++++++++++++----------------------- > 1 file changed, 31 insertions(+), 36 deletions(-) > > diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c > index aa7ea29f15ba..b4fb6a2bcbcf 100644 > --- a/app/test-pmd/testpmd.c > +++ b/app/test-pmd/testpmd.c > @@ -11,6 +11,7 @@ > #include <fcntl.h> > #ifndef RTE_EXEC_ENV_WINDOWS > #include <sys/mman.h> > +#include <sys/select.h> > #endif > #include <sys/types.h> > #include <errno.h> > @@ -4224,13 +4225,6 @@ init_port(void) > memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS); > } > > -static void > -force_quit(void) > -{ > - pmd_test_exit(); > - prompt_exit(); > -} > - > static void > print_stats(void) > { > @@ -4249,28 +4243,9 @@ print_stats(void) > } > > static void > -signal_handler(int signum) > +signal_handler(int signum __rte_unused) > { > - if (signum == SIGINT || signum == SIGTERM) { > - fprintf(stderr, "\nSignal %d received, preparing to exit...\n", > - signum); > -#ifdef RTE_LIB_PDUMP > - /* uninitialize packet capture framework */ > - rte_pdump_uninit(); > -#endif > -#ifdef RTE_LIB_LATENCYSTATS > - if (latencystats_enabled != 0) > - rte_latencystats_uninit(); > -#endif > - force_quit(); > - /* Set flag to indicate the force termination. */ > - f_quit = 1; > - /* exit with the expected status */ > -#ifndef RTE_EXEC_ENV_WINDOWS > - signal(signum, SIG_DFL); > - kill(getpid(), signum); > -#endif > - } > + f_quit = 1; > }
Signal handler used for interactive mode too, that is why 'force_quit();' is still needed in signal handler. Perhaps different signal handlers can be set for interactive and non-interactive modes. > > int > @@ -4449,9 +4424,6 @@ main(int argc, char** argv) > } else > #endif > { > - char c; > - int rc; > - > f_quit = 0; > > printf("No commandline core given, start packet forwarding\n"); > @@ -4476,15 +4448,38 @@ main(int argc, char** argv) > prev_time = cur_time; > rte_delay_us_sleep(US_PER_S); > } > - } > + } else { > + char c; > + fd_set fds; > + > + printf("Press enter to exit\n"); > + > + FD_ZERO(&fds); > + FD_SET(0, &fds); > > - printf("Press enter to exit\n"); > - rc = read(0, &c, 1); > + ret = select(1, &fds, NULL, NULL, NULL); > + if (ret < 0 && errno != EINTR) > + rte_exit(EXIT_FAILURE, > + "Select failed: %s\n", > + strerror(errno)); > + > + if (ret == 1 && read(0, &c, 1) < 0) > + rte_exit(EXIT_FAILURE, > + "Read failed: %s\n", > + strerror(errno)); > + } > pmd_test_exit(); > - if (rc < 0) > - return 1; > } > > +#ifdef RTE_LIB_PDUMP > + /* uninitialize packet capture framework */ > + rte_pdump_uninit(); > +#endif > +#ifdef RTE_LIB_LATENCYSTATS > + if (latencystats_enabled != 0) > + rte_latencystats_uninit(); > +#endif +1 to move these functions here, but signal handler for the interactive mode also needs these functions. > + > ret = rte_eal_cleanup(); > if (ret != 0) > rte_exit(EXIT_FAILURE,