From bd11e87d594790509bc739f200462decde0c9a07 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Sat, 29 Oct 2011 04:48:12 +0400 Subject: [PATCH] xfstests: fsstress should kill children tasks before exit It is very hard to predict runtime for fsstress. In many cases it is useful to give test to run a reasonable time, and then kill it. But currently there is no reliable way to kill test without leaving running children. This patch add sanity cleanup logic which looks follow: - On sigterm received by parent, it resend signal to it's children - Wait for each child to terminates - EXTRA_SANITY: Even if parent was killed by other signal, children will be terminated with SIGKILL to preven staled children. So now one can simply run fsstress like this: ./fsstress -p 1000 -n999999999 -d $TEST_DIR & PID=$! sleep 300 kill $PID wait $PID Signed-off-by: Dmitry Monakhov Signed-off-by: Christoph Hellwig --- aclocal.m4 | 5 +++++ configure.in | 1 + ltp/fsstress.c | 37 ++++++++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/aclocal.m4 b/aclocal.m4 index 168eb59e..55326063 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -16,6 +16,11 @@ AC_DEFUN([AC_PACKAGE_WANT_LINUX_FIEMAP_H], AC_SUBST(have_fiemap) ]) +AC_DEFUN([AC_PACKAGE_WANT_LINUX_PRCTL_H], + [ AC_CHECK_HEADERS([sys/prctl.h], [ have_prctl=true ], [ have_prctl=false ]) + AC_SUBST(have_prctl) + ]) + AC_DEFUN([AC_PACKAGE_WANT_FALLOCATE], [ AC_MSG_CHECKING([for fallocate]) AC_TRY_LINK([ diff --git a/configure.in b/configure.in index c697b4f6..76d23e40 100644 --- a/configure.in +++ b/configure.in @@ -67,6 +67,7 @@ in AC_PACKAGE_WANT_DMAPI AC_PACKAGE_WANT_LINUX_FIEMAP_H AC_PACKAGE_WANT_FALLOCATE + AC_PACKAGE_WANT_LINUX_PRCTL_H ;; esac diff --git a/ltp/fsstress.c b/ltp/fsstress.c index c7001f3c..133a247a 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -28,7 +28,9 @@ #ifndef HAVE_ATTR_LIST #define attr_list(path, buf, size, flags, cursor) (errno = -ENOSYS, -1) #endif - +#ifdef HAVE_SYS_PRCTL_H +#include +#endif #include #define XFS_ERRTAG_MAX 17 #define XFS_IDMODULO_MAX 31 /* user/group IDs (1 << x) */ @@ -209,6 +211,7 @@ int rtpct; unsigned long seed = 0; ino_t top_ino; int verbose = 0; +sig_atomic_t should_stop = 0; void add_to_flist(int, int, int); void append_pathname(pathname_t *, char *); @@ -253,6 +256,11 @@ void usage(void); void write_freq(void); void zero_freq(void); +void sg_handler(int signum) +{ + should_stop = 1; +} + int main(int argc, char **argv) { char buf[10]; @@ -269,6 +277,7 @@ int main(int argc, char **argv) ptrdiff_t srval; int nousage = 0; xfs_error_injection_t err_inj; + struct sigaction action; errrange = errtag = 0; umask(0); @@ -429,8 +438,27 @@ int main(int argc, char **argv) } } else close(fd); + + setpgid(0, 0); + action.sa_handler = sg_handler; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + if (sigaction(SIGTERM, &action, 0)) { + perror("sigaction failed"); + exit(1); + } + for (i = 0; i < nproc; i++) { if (fork() == 0) { + action.sa_handler = SIG_DFL; + sigemptyset(&action.sa_mask); + if (sigaction(SIGTERM, &action, 0)) + return 1; +#ifdef HAVE_SYS_PRCTL_H + prctl(PR_SET_PDEATHSIG, SIGKILL); + if (getppid() == 1) /* parent died already? */ + return 0; +#endif if (logname) { char path[PATH_MAX]; snprintf(path, sizeof(path), "%s/%s.%d", @@ -445,8 +473,15 @@ int main(int argc, char **argv) return 0; } } + while (wait(&stat) > 0 && !should_stop) { + continue; + } + action.sa_flags = SA_RESTART; + sigaction(SIGTERM, &action, 0); + kill(-getpid(), SIGTERM); while (wait(&stat) > 0) continue; + if (errtag != 0) { err_inj.errtag = 0; err_inj.fd = fd; -- 2.30.2