From 53bcd50bb5d83c12047432716fce75d382def25f Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 2 Nov 2012 10:43:25 +0100 Subject: [PATCH] Implement a timeout on regression tests of 15 minutes Conflicts: bacula/src/tools/Makefile.in regress/all-changer-tests regress/all-dev-tests regress/all-disk-tests --- bacula/src/tools/Makefile.in | 8 +- bacula/src/tools/timelimit.1 | 217 ++++++++++++++ bacula/src/tools/timelimit.c | 537 +++++++++++++++++++++++++++++++++++ regress/all-changer-tests | 10 +- regress/all-dev-tests | 100 +++---- regress/all-disk-tests | 209 +++++++------- regress/all-root-tests | 12 +- regress/all-tape-tests | 28 +- regress/do_all_tests | 6 +- regress/run | 15 +- regress/run_bconsole | 3 + regress/scripts/functions | 3 + 12 files changed, 967 insertions(+), 181 deletions(-) create mode 100644 bacula/src/tools/timelimit.1 create mode 100644 bacula/src/tools/timelimit.c create mode 100755 regress/run_bconsole diff --git a/bacula/src/tools/Makefile.in b/bacula/src/tools/Makefile.in index 2463957f0a..6de011bc83 100644 --- a/bacula/src/tools/Makefile.in +++ b/bacula/src/tools/Makefile.in @@ -1,8 +1,6 @@ # # Bacula Tools Makefile # -# Version $Id$ -# @MCOMMON@ PYTHON_INC = @PYTHON_INCDIR@ @@ -37,7 +35,7 @@ EXTRAOBJS = @OBJLIST@ DIRCONFOBJS = ../dird/dird_conf.o ../dird/ua_acl.o ../dird/run_conf.o ../dird/inc_conf.o NODIRTOOLS = bsmtp -DIRTOOLS = bsmtp dbcheck drivetype fstype testfind testls bregex bwild bbatch bregtest bvfs_test ing_test bpluginfo +DIRTOOLS = bsmtp dbcheck drivetype fstype testfind testls bregex bwild bbatch bregtest bvfs_test ing_test bpluginfo timelimit TOOLS = $(@DIR_TOOLS@) INSNODIRTOOLS = bsmtp @@ -88,6 +86,10 @@ run_conf.o: ../dird/run_conf.c inc_conf.o: ../dird/inc_conf.c $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< +timelimit: timelimit.o + ${CC} ${DEFS} ${DEBUG} -pipe -DHAVE_ERR -DHAVE_SYSEXITS_H -DHAVE_ERRNO_H -DHAVE_SETITIMER -DHAVE_SIGACTION -c timelimit.c + ${CC} -o timelimit timelimit.o + testfind: Makefile ../lib/libbac$(DEFAULT_ARCHIVE_TYPE) ../lib/libbaccfg$(DEFAULT_ARCHIVE_TYPE) \ ../findlib/libbacfind$(DEFAULT_ARCHIVE_TYPE) $(FINDOBJS) $(LIBTOOL_LINK) $(CXX) -g $(LDFLAGS) -o $@ $(FINDOBJS) -L. -L../lib -L../findlib \ diff --git a/bacula/src/tools/timelimit.1 b/bacula/src/tools/timelimit.1 new file mode 100644 index 0000000000..1d3a7c93de --- /dev/null +++ b/bacula/src/tools/timelimit.1 @@ -0,0 +1,217 @@ +.\" Copyright (c) 2001, 2007 - 2010 Peter Pentchev +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Ringlet$ +.\" +.Dd September 29, 2010 +.Dt TIMELIMIT 1 +.Os +.Sh NAME +.Nm timelimit +.Nd effectively limit the absolute execution time of a process +.Sh SYNOPSIS +.Nm +.Op Fl pq +.Op Fl S Ar killsig +.Op Fl s Ar warnsig +.Op Fl T Ar killtime +.Op Fl t Ar warntime +.Ar command +.Op Ar arguments ... +.Sh DESCRIPTION +The +.Nm +utility executes a given +.Ar command +with the supplied +.Ar arguments +and terminates the spawned process after a given time with a given signal. +If the process exits before the time limit has elapsed, +.Nm +will silently exit, too. +.Pp +Options: +.Bl -tag -width indent +.It Fl p +If the child process is terminated by a signal, +.Nm +propagates this condition, i.e. sends the same signal to itself. +This allows the program executing +.Nm +to determine whether the child process was terminated by a signal or +actually exited with an exit code larger than 128. +.It Fl q +Quiet operation - +.Nm +does not output diagnostic messages about signals sent to the child process. +.It Fl S Ar killsig +Specify the number of the signal to be sent to the process +.Ar killtime +seconds after +.Ar warntime +has expired. +Defaults to 9 (SIGKILL). +.It Fl s Ar warnsig +Specify the number of the signal to be sent to the process +.Ar warntime +seconds after it has been started. +Defaults to 15 (SIGTERM). +.It Fl T Ar killtime +Specify the maximum execution time of the process before sending +.Ar killsig +after +.Ar warnsig +has been sent. +Defaults to 120 seconds. +.It Fl t Ar warntime +Specify the maximum execution time of the process in seconds before sending +.Ar warnsig . +Defaults to 3600 seconds. +.El +.Pp +On systems that support the +.Xr setitimer 2 +system call, the +.Ar warntime +and +.Ar killtime +values may be specified in fractional seconds with microsecond precision. +.Sh ENVIRONMENT +.Bl -tag -width indent +.It Ev KILLSIG +The +.Ar killsig +to use if the +.Fl S +option was not specified. +.It Ev KILLTIME +The +.Ar killtime +to use if the +.Fl T +option was not specified. +.It Ev WARNSIG +The +.Ar warnsig +to use if the +.Fl s +option was not specified. +.It Ev WARNTIME +The +.Ar warntime +to use if the +.Fl t +option was not specified. +.El +.Sh EXIT STATUS +If the child process exits normally, the +.Nm +utility will pass its exit code on up. +If the child process is terminated by a signal and the +.Fl p +flag was not specified, the +.Nm +utility's exit status is 128 plus the signal number, similar to +.Xr sh 1 . +If the +.Fl p +flag was specified, the +.Nm +utility will raise the signal itself so that its own parent process +may in turn reliably distinguish between a signal and a larger than 128 +exit code. +.Pp +In rare cases, the +.Nm +utility may encounter a system or user error; then, its exit status is one +of the standard +.Xr sysexits 3 +values: +.Bl -tag -width indent +.It Dv EX_USAGE +The command-line parameters and options were incorrectly specified. +.It Dv EX_SOFTWARE +The +.Nm +utility itself received an unexpected signal while waiting for the child +process to terminate. +.It Dv EX_OSERR +The +.Nm +utility was unable to execute the child process, wait for it to terminate, +or examine its exit status. +.El +.Sh EXAMPLES +.Pp +The following examples are shown as given to the shell: +.Pp +.Dl timelimit -p /usr/local/bin/rsync rsync://some.host/dir /opt/mirror +.Pp +Run the rsync program to mirror a WWW or FTP site and kill it if it +runs longer than 1 hour (that is 3600 seconds) with SIGTERM. +If the rsync process does not exit after receiving the SIGTERM, +.Nm +issues a SIGKILL 120 seconds after the SIGTERM. +If the rsync process is terminated by a signal, +.Nm +will itself raise this signal. +.Pp +.Dl tcpserver 0 8888 timelimit -t600 -T300 /opt/services/chat/stats +.Pp +Start a +.Xr tcpserver n +process listening on tcp port 8888; each client connection shall invoke +an instance of an IRC statistics tool under +.Pa /opt/services/chat +and kill it after 600 seconds have elapsed. +If the stats process is still running after the SIGTERM, it will be +killed by a SIGKILL sent 300 seconds later. +.Pp +.Dl env WARNTIME=4.99 WARNSIG=1 KILLTIME=1.000001 timelimit sh stats.sh +.Pp +Start a shell script and kill it with a SIGHUP in a little under 5 seconds. +If the shell gets stuck and does not respond to the SIGHUP, kill it +with the default SIGKILL just a bit over a second afterwards. +.Sh SEE ALSO +.Xr kill 1 , +.Xr rsync 1 , +.Xr signal 3 , +.Xr tcpserver n +.Sh STANDARDS +No standards documentation was harmed in the process of creating +.Nm . +.Sh BUGS +Please report any bugs in +.Nm +to the author. +.Sh AUTHOR +The +.Nm +utility was conceived and written by +.An Peter Pentchev Aq roam@ringlet.net +with contributions and suggestions by +.An Karsten W Rohrbach Aq karsten@rohrbach.de , +.An Teddy Hogeborn Aq teddy@fukt.bsnet.se , +and +.An Tomasz Nowak Aq nowak2000@poczta.onet.pl . diff --git a/bacula/src/tools/timelimit.c b/bacula/src/tools/timelimit.c new file mode 100644 index 0000000000..c337a18251 --- /dev/null +++ b/bacula/src/tools/timelimit.c @@ -0,0 +1,537 @@ +/*- + * Copyright (c) 2001, 2007 - 2010 Peter Pentchev + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +/* we hope all OS's have those..*/ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_ERR +#include +#endif /* HAVE_ERR */ + +#ifdef HAVE_SYSEXITS_H +#include +#else +#define EX_OK 0 /* successful termination */ +#define EX__BASE 64 /* base value for error messages */ +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ +#define EX__MAX 78 /* maximum listed value */ +#endif /* HAVE_SYSEXITS_H */ + +#ifndef __unused +#ifdef __GNUC__ +#define __unused __attribute__((unused)) +#else /* __GNUC__ */ +#define __unused +#endif /* __GNUC__ */ +#endif /* __unused */ + +#ifndef __dead2 +#ifdef __GNUC__ +#define __dead2 __attribute__((noreturn)) +#else /* __GNUC__ */ +#define __dead2 +#endif /* __GNUC__ */ +#endif /* __dead2 */ + +#define PARSE_CMDLINE + +unsigned long warntime, warnmsec, killtime, killmsec; +unsigned long warnsig, killsig; +volatile int fdone, falarm, fsig, sigcaught; +int propagate, quiet; + +static struct { + const char *name, opt, issig; + unsigned long *sec, *msec; +} envopts[] = { + {"KILLSIG", 'S', 1, &killsig, NULL}, + {"KILLTIME", 'T', 0, &killtime, &killmsec}, + {"WARNSIG", 's', 1, &warnsig, NULL}, + {"WARNTIME", 't', 0, &warntime, &warnmsec}, + {NULL, 0, 0, NULL, NULL} +}; + +static struct { + const char *name; + int num; +} signals[] = { + /* We kind of assume that the POSIX-mandated signals are present */ + {"ABRT", SIGABRT}, + {"ALRM", SIGALRM}, + {"BUS", SIGBUS}, + {"CHLD", SIGCHLD}, + {"CONT", SIGCONT}, + {"FPE", SIGFPE}, + {"HUP", SIGHUP}, + {"ILL", SIGILL}, + {"INT", SIGINT}, + {"KILL", SIGKILL}, + {"PIPE", SIGPIPE}, + {"QUIT", SIGQUIT}, + {"SEGV", SIGSEGV}, + {"STOP", SIGSTOP}, + {"TERM", SIGTERM}, + {"TSTP", SIGTSTP}, + {"TTIN", SIGTTIN}, + {"TTOU", SIGTTOU}, + {"USR1", SIGUSR1}, + {"USR2", SIGUSR2}, + {"PROF", SIGPROF}, + {"SYS", SIGSYS}, + {"TRAP", SIGTRAP}, + {"URG", SIGURG}, + {"VTALRM", SIGVTALRM}, + {"XCPU", SIGXCPU}, + {"XFSZ", SIGXFSZ}, + + /* Some more signals found on a Linux 2.6 system */ +#ifdef SIGIO + {"IO", SIGIO}, +#endif +#ifdef SIGIOT + {"IOT", SIGIOT}, +#endif +#ifdef SIGLOST + {"LOST", SIGLOST}, +#endif +#ifdef SIGPOLL + {"POLL", SIGPOLL}, +#endif +#ifdef SIGPWR + {"PWR", SIGPWR}, +#endif +#ifdef SIGSTKFLT + {"STKFLT", SIGSTKFLT}, +#endif +#ifdef SIGWINCH + {"WINCH", SIGWINCH}, +#endif + + /* Some more signals found on a FreeBSD 8.x system */ +#ifdef SIGEMT + {"EMT", SIGEMT}, +#endif +#ifdef SIGINFO + {"INFO", SIGINFO}, +#endif +#ifdef SIGLWP + {"LWP", SIGLWP}, +#endif +#ifdef SIGTHR + {"THR", SIGTHR}, +#endif +}; +#define SIGNALS (sizeof(signals) / sizeof(signals[0])) + +#ifndef HAVE_ERR +static void err(int, const char *, ...); +static void errx(int, const char *, ...); +#endif /* !HAVE_ERR */ + +static void usage(void); + +static void init(int, char *[]); +static pid_t doit(char *[]); +static void child(char *[]); +static void raisesignal(int) __dead2; +static void setsig_fatal(int, void (*)(int)); +static void setsig_fatal_gen(int, void (*)(int), int, const char *); +static void terminated(const char *); + +#ifndef HAVE_ERR +static void +err(int code, const char *fmt, ...) { + va_list v; + + va_start(v, fmt); + vfprintf(stderr, fmt, v); + va_end(v); + + fprintf(stderr, ": %s\n", strerror(errno)); + exit(code); +} + +static void +errx(int code, const char *fmt, ...) { + va_list v; + + va_start(v, fmt); + vfprintf(stderr, fmt, v); + va_end(v); + + fprintf(stderr, "\n"); + exit(code); +} + +static void +warnx(const char *fmt, ...) { + va_list v; + + va_start(v, fmt); + vfprintf(stderr, fmt, v); + va_end(v); + + fprintf(stderr, "\n"); +} +#endif /* !HAVE_ERR */ + +static void +usage(void) { + errx(EX_USAGE, "usage: timelimit [-pq] [-S ksig] [-s wsig] " + "[-T ktime] [-t wtime] command"); +} + +static void +atou_fatal(const char *s, unsigned long *sec, unsigned long *msec, int issig) { + unsigned long v, vm, mul; + const char *p; + size_t i; + + if (s[0] < '0' || s[0] > '9') { + if (s[0] == '\0' || !issig) + usage(); + for (i = 0; i < SIGNALS; i++) + if (!strcmp(signals[i].name, s)) + break; + if (i == SIGNALS) + usage(); + *sec = (unsigned long)signals[i].num; + if (msec != NULL) + *msec = 0; + return; + } + + v = 0; + for (p = s; (*p >= '0') && (*p <= '9'); p++) + v = v * 10 + *p - '0'; + if (*p == '\0') { + *sec = v; + if (msec != NULL) + *msec = 0; + return; + } else if (*p != '.' || msec == NULL) { + usage(); + } + p++; + + vm = 0; + mul = 1000000; + for (; (*p >= '0') && (*p <= '9'); p++) { + vm = vm * 10 + *p - '0'; + mul = mul / 10; + } + if (*p != '\0') + usage(); + else if (mul < 1) + errx(EX_USAGE, "no more than microsecond precision"); +#ifndef HAVE_SETITIMER + if (msec != 0) + errx(EX_UNAVAILABLE, + "subsecond precision not supported on this platform"); +#endif + *sec = v; + *msec = vm * mul; +} + +static void +init(int argc, char *argv[]) { +#ifdef PARSE_CMDLINE + int ch, listsigs; +#endif + int optset; + unsigned i; + char *s; + + /* defaults */ + quiet = 0; + warnsig = SIGTERM; + killsig = SIGKILL; + warntime = 900; + warnmsec = 0; + killtime = 5; + killmsec = 0; + + optset = 0; + + /* process environment variables first */ + for (i = 0; envopts[i].name != NULL; i++) + if ((s = getenv(envopts[i].name)) != NULL) { + atou_fatal(s, envopts[i].sec, envopts[i].msec, + envopts[i].issig); + optset = 1; + } + +#ifdef PARSE_CMDLINE + listsigs = 0; + while ((ch = getopt(argc, argv, "+lqpS:s:T:t:")) != -1) { + switch (ch) { + case 'l': + listsigs = 1; + break; + case 'p': + propagate = 1; + break; + case 'q': + quiet = 1; + break; + default: + /* check if it's a recognized option */ + for (i = 0; envopts[i].name != NULL; i++) + if (ch == envopts[i].opt) { + atou_fatal(optarg, + envopts[i].sec, + envopts[i].msec, + envopts[i].issig); + optset = 1; + break; + } + if (envopts[i].name == NULL) + usage(); + } + } + + if (listsigs) { + for (i = 0; i < SIGNALS; i++) + printf("%s%c", signals[i].name, + i + 1 < SIGNALS? ' ': '\n'); + exit(EX_OK); + } +#else + optind = 1; +#endif + + if (!optset) /* && !quiet? */ + warnx("using defaults: warntime=%lu, warnsig=%lu, " + "killtime=%lu, killsig=%lu", + warntime, warnsig, killtime, killsig); + + argc -= optind; + argv += optind; + if (argc == 0) + usage(); + + /* sanity checks */ + if ((warntime == 0 && warnmsec == 0) || (killtime == 0 && killmsec == 0)) + usage(); +} + +static void +sigchld(int sig __unused) { + + fdone = 1; +} + +static void +sigalrm(int sig __unused) { + + falarm = 1; +} + +static void +sighandler(int sig) { + + sigcaught = sig; + fsig = 1; +} + +static void +setsig_fatal(int sig, void (*handler)(int)) { + + setsig_fatal_gen(sig, handler, 1, "setting"); +} + +static void +setsig_fatal_gen(int sig, void (*handler)(int), int nocld, const char *what) { +#ifdef HAVE_SIGACTION + struct sigaction act; + + memset(&act, 0, sizeof(act)); + act.sa_handler = handler; + act.sa_flags = 0; +#ifdef SA_NOCLDSTOP + if (nocld) + act.sa_flags |= SA_NOCLDSTOP; +#endif /* SA_NOCLDSTOP */ + if (sigaction(sig, &act, NULL) < 0) + err(EX_OSERR, "%s signal handler for %d", what, sig); +#else /* HAVE_SIGACTION */ + if (signal(sig, handler) == SIG_ERR) + err(EX_OSERR, "%s signal handler for %d", what, sig); +#endif /* HAVE_SIGACTION */ +} + +static void +settimer(const char *name, unsigned long sec, unsigned long msec) +{ +#ifdef HAVE_SETITIMER + struct itimerval tval; + + tval.it_interval.tv_sec = tval.it_interval.tv_usec = 0; + tval.it_value.tv_sec = sec; + tval.it_value.tv_usec = msec; + if (setitimer(ITIMER_REAL, &tval, NULL) == -1) + err(EX_OSERR, "could not set the %s timer", name); +#else + alarm(sec); +#endif +} + +static pid_t +doit(char *argv[]) { + pid_t pid; + + /* install signal handlers */ + fdone = falarm = fsig = sigcaught = 0; + setsig_fatal(SIGALRM, sigalrm); + setsig_fatal(SIGCHLD, sigchld); + setsig_fatal(SIGTERM, sighandler); + setsig_fatal(SIGHUP, sighandler); + setsig_fatal(SIGINT, sighandler); + setsig_fatal(SIGQUIT, sighandler); + + /* fork off the child process */ + if ((pid = fork()) < 0) + err(EX_OSERR, "fork"); + if (pid == 0) + child(argv); + + /* sleep for the allowed time */ + settimer("warning", warntime, warnmsec); + while (!(fdone || falarm || fsig)) + pause(); + alarm(0); + + /* send the warning signal */ + if (fdone) + return (pid); + if (fsig) + terminated("run"); + falarm = 0; + if (!quiet) + warnx("sending warning signal %lu", warnsig); + kill(pid, (int) warnsig); + +#ifndef HAVE_SIGACTION + /* reset our signal handlers, just in case */ + setsig_fatal(SIGALRM, sigalrm); + setsig_fatal(SIGCHLD, sigchld); + setsig_fatal(SIGTERM, sighandler); + setsig_fatal(SIGHUP, sighandler); + setsig_fatal(SIGINT, sighandler); + setsig_fatal(SIGQUIT, sighandler); +#endif /* HAVE_SIGACTION */ + + /* sleep for the grace time */ + settimer("kill", killtime, killmsec); + while (!(fdone || falarm || fsig)) + pause(); + alarm(0); + + /* send the kill signal */ + if (fdone) + return (pid); + if (fsig) + terminated("grace"); + if (!quiet) + warnx("sending kill signal %lu", killsig); + kill(pid, (int) killsig); + setsig_fatal_gen(SIGCHLD, SIG_DFL, 0, "restoring"); + return (pid); +} + +static void +terminated(const char *period) { + + errx(EX_SOFTWARE, "terminated by signal %d during the %s period", + sigcaught, period); +} + +static void +child(char *argv[]) { + + execvp(argv[0], argv); + err(EX_OSERR, "executing %s", argv[0]); +} + +static __dead2 void +raisesignal (int sig) { + + setsig_fatal_gen(sig, SIG_DFL, 0, "restoring"); + raise(sig); + while (1) + pause(); + /* NOTREACHED */ +} + +int +main(int argc, char *argv[]) { + pid_t pid; + int status; + + init(argc, argv); + argc -= optind; + argv += optind; + pid = doit(argv); + + if (waitpid(pid, &status, 0) == -1) + err(EX_OSERR, "could not get the exit status for process %ld", + (long)pid); + if (WIFEXITED(status)) + return (WEXITSTATUS(status)); + else if (!WIFSIGNALED(status)) + return (EX_OSERR); + if (propagate) + raisesignal(WTERMSIG(status)); + else + return (WTERMSIG(status) + 128); +} diff --git a/regress/all-changer-tests b/regress/all-changer-tests index 65dc26e4db..a2a8ce86f2 100755 --- a/regress/all-changer-tests +++ b/regress/all-changer-tests @@ -1,15 +1,15 @@ #!/bin/sh # -# Run all tape tests +# ./run all tape tests # echo "Start autochanger tests" echo "Start autochanger tests" >>test.out rm -f dumps/* -nice tests/incremental-changer -nice tests/two-pool-changer -nice tests/two-volume-changer -nice tests/vol-duration-changer +./run tests/incremental-changer +./run tests/two-pool-changer +./run tests/two-volume-changer +./run tests/vol-duration-changer echo "End autochanger tests" echo "End autochanger tests" >>test.out diff --git a/regress/all-dev-tests b/regress/all-dev-tests index 85c8ac98b3..a7db3434b1 100755 --- a/regress/all-dev-tests +++ b/regress/all-dev-tests @@ -8,49 +8,49 @@ echo " " >>test.out echo "Start sample non-root disk tests" echo "Start sample non-root disk tests" >>test.out rm -f dumps/* -nice tests/acl-xattr-test -nice tests/action-on-purge-test -nice tests/allowcompress-test -nice tests/auto-label-test -nice tests/backup-bacula-test -nice tests/base-job-test -nice tests/bextract-test -nice tests/bconsole-test -nice tests/comment-test -nice tests/compressed-test -nice tests/compress-encrypt-test -nice tests/concurrent-jobs-test -nice tests/copy-job-test -nice tests/encrypt-bug-test -nice tests/estimate-test -nice tests/lockmgr-test -nice tests/exclude-dir-test -nice tests/fifo-test -nice tests/fileregexp-test -nice tests/backup-to-null -nice tests/regexwhere-test -nice tests/differential-test -nice tests/four-jobs-test -nice tests/incremental-test -nice tests/query-test -nice tests/recycle-test -nice tests/restore2-by-file-test -nice tests/restore-by-file-test -nice tests/restore-disk-seek-test -nice tests/next-vol-test -nice tests/strip-test -nice tests/two-vol-test -nice tests/verify-vol-test -nice tests/weird-files2-test -nice tests/weird-files-test -nice tests/migration-job-test -nice tests/messages-test -nice tests/multi-storage-test -# prune-test does not work for now -#nice tests/prune-test -nice tests/hardlink-test -nice tests/tls-test -nice tests/virtual-backup-test +./run tests/acl-xattr-test +./run tests/action-on-purge-test +./run tests/allowcompress-test +./run tests/auto-label-test +./run tests/backup-bacula-test +./run tests/base-job-test +./run tests/bextract-test +./run tests/bconsole-test +./run tests/comment-test +./run tests/compressed-test +./run tests/compress-encrypt-test +./run tests/concurrent-jobs-test +./run tests/copy-job-test +./run tests/encrypt-bug-test +./run tests/estimate-test +./run tests/lockmgr-test +./run tests/exclude-dir-test +./run tests/fifo-test +./run tests/fileregexp-test +./run tests/backup-to-null +./run tests/regexwhere-test +./run tests/differential-test +./run tests/four-jobs-test +./run tests/incremental-test +./run tests/query-test +./run tests/recycle-test +./run tests/restore2-by-file-test +./run tests/restore-by-file-test +./run tests/restore-disk-seek-test +./run tests/next-vol-test +./run tests/strip-test +./run tests/sqlite-test +./run tests/two-vol-test +./run tests/verify-vol-test +./run tests/weird-files2-test +./run tests/weird-files-test +./run tests/migration-job-test +./run tests/messages-test +./run tests/multi-storage-test +./run tests/prune-test +./run tests/hardlink-test +./run tests/tls-test +./run tests/virtual-backup-test echo "End sample non-root disk tests" echo "End sample non-root disk tests" >>test.out @@ -60,12 +60,12 @@ echo " " echo " " >>test.out echo "Start sample non-root disk autochanger tests" echo "Start sample non-root disk autochanger tests" >>test.out -#nice tests/three-pool-recycle-test -nice tests/fast-two-pool-test -nice tests/two-volume-test -nice tests/2drive-concurrent-test -nice tests/incremental-2media -nice tests/2drive-3pool-test -nice tests/2drive-swap-test +#./run tests/three-pool-recycle-test +./run tests/fast-two-pool-test +./run tests/two-volume-test +./run tests/2drive-concurrent-test +./run tests/incremental-2media +./run tests/2drive-3pool-test +./run tests/2drive-swap-test echo "End sample non-root disk autochanger tests" echo "End sample non-root disk autochanger tests" >>test.out diff --git a/regress/all-disk-tests b/regress/all-disk-tests index 2af26a50d4..6bbdb62743 100755 --- a/regress/all-disk-tests +++ b/regress/all-disk-tests @@ -1,98 +1,111 @@ #!/bin/sh # -# Run all tests +# ./run all tests # echo " " echo " " >>test.out echo "Start non-root disk tests" echo "Start non-root disk tests" >>test.out rm -f dumps/* -nice tests/acl-xattr-test -nice tests/action-on-purge-test -nice tests/allowcompress-test -nice tests/accurate-test -nice tests/auto-label-test -nice tests/backup-bacula-test -nice tests/bextract-test -nice tests/bconsole-test -nice tests/base-job-test -nice tests/big-vol-test -nice tests/bscan-test -nice tests/bsr-opt-test -nice tests/comment-test -nice tests/compressed-test -nice tests/lzo-test -nice tests/compress-encrypt-test -nice tests/lzo-encrypt-test -nice tests/concurrent-jobs-test -nice tests/copy-job-test -nice tests/copy-jobspan-test -nice tests/copy-uncopied-test -nice tests/copy-upgrade-test -nice tests/copy-volume-test -nice tests/data-encrypt-test -nice tests/delete-test -nice tests/encrypt-bug-test -nice tests/estimate-test -nice tests/exclude-dir-test -nice tests/fifo-test -nice tests/fileregexp-test -nice tests/backup-to-null -nice tests/regexwhere-test +<<<<<<< HEAD +./run tests/acl-xattr-test +./run tests/action-on-purge-test +./run tests/allowcompress-test +./run tests/accurate-test +./run tests/auto-label-test +./run tests/backup-bacula-test +./run tests/bextract-test +./run tests/bconsole-test +./run tests/base-job-test +./run tests/big-vol-test +./run tests/bscan-test +./run tests/bsr-opt-test +./run tests/comment-test +./run tests/compressed-test +./run tests/lzo-test +./run tests/compress-encrypt-test +./run tests/lzo-encrypt-test +./run tests/concurrent-jobs-test +./run tests/copy-job-test +./run tests/copy-jobspan-test +./run tests/copy-uncopied-test +./run tests/copy-upgrade-test +./run tests/copy-volume-test +./run tests/data-encrypt-test +./run tests/delete-test +./run tests/encrypt-bug-test +./run tests/estimate-test +./run tests/exclude-dir-test +./run tests/fifo-test +./run tests/fileregexp-test +./run tests/backup-to-null +./run tests/regexwhere-test # The following two can uses *lots* of disk space # so they are normally turned off, but if you have -# at least two GB free, you can run them -#nice tests/sparse-encrypt-test -#nice tests/gigaslam-sparse-test -nice tests/differential-test -nice tests/four-concurrent-jobs-test -nice tests/four-jobs-test -nice tests/incremental-test -nice tests/query-test -nice tests/recycle-test -nice tests/restore2-by-file-test -nice tests/restore-by-file-test -nice tests/restore-disk-seek-test -nice tests/runscript-test -nice tests/source-addr-test -nice tests/stats-test -nice tests/six-vol-test -nice tests/span-vol-test -nice tests/maxbytes-test -nice tests/maxtime-test -nice tests/maxuseduration-test -nice tests/maxvol-test -nice tests/maxvol2-test -nice tests/messages-test -nice tests/next-vol-test -nice tests/sparse-compressed-test -nice tests/sparse-lzo-test -nice tests/sparse-test -nice tests/strip-test -nice tests/two-jobs-test -nice tests/two-vol-test -nice tests/verify-cat-test -nice tests/verify-vol-test -nice tests/verify-voltocat-test -nice tests/weird-files2-test -nice tests/weird-files-test -nice tests/migration-job-test -nice tests/migration-job-purge-test -nice tests/migration-jobspan-test -nice tests/migration-volume-test -nice tests/migration-time-test -nice tests/multi-storage-test +# at least two GB free, you can ./run them +#./run tests/sparse-encrypt-test +#./run tests/gigaslam-sparse-test +#./run tests/delta-big-test +#./run tests/delta3-test +./run tests/differential-test +./run tests/four-concurrent-jobs-test +./run tests/four-jobs-test +./run tests/incremental-test +./run tests/opt-plugin-test +./run tests/delta2-test +./run tests/delta-options-test +./run tests/query-test +./run tests/recycle-test +./run tests/restart-job-test +./run tests/restart2-job-test +./run tests/restart2-base-job-test +./run tests/restart-accurate-job-test +./run tests/restore2-by-file-test +./run tests/restore-by-file-test +./run tests/restore-disk-seek-test +./run tests/./runscript-test +./run tests/source-addr-test +./run tests/stats-test +./run tests/six-vol-test +./run tests/span-vol-test +./run tests/maxbytes-test +./run tests/maxbw-test +./run tests/maxtime-test +./run tests/maxuseduration-test +./run tests/maxvol-test +./run tests/maxvol2-test +./run tests/messages-test +./run tests/next-vol-test +./run tests/sparse-compressed-test +./run tests/sparse-lzo-test +./run tests/sparse-test +./run tests/strip-test +./run tests/sqlite-test +./run tests/two-jobs-test +./run tests/two-vol-test +./run tests/verify-cat-test +./run tests/verify-vol-test +./run tests/verify-voltocat-test +./run tests/weird-files2-test +./run tests/weird-files-test +./run tests/migration-job-test +./run tests/migration-job-purge-test +./run tests/migration-jobspan-test +./run tests/migration-volume-test +./run tests/migration-time-test +./run tests/multi-storage-test # prune-test does not work for now -#nice tests/prune-test -nice tests/prune-config-test -nice tests/prune-migration-test -nice tests/prune-copy-test -nice tests/prune-base-job-test -nice tests/hardlink-test -nice tests/tls-duplicate-job-test -nice tests/tls-test -nice tests/virtual-changer-test -nice tests/virtual-backup-test +#./run tests/prune-test +./run tests/prune-pool-test +./run tests/prune-config-test +./run tests/prune-migration-test +./run tests/prune-copy-test +./run tests/prune-base-job-test +./run tests/hardlink-test +./run tests/tls-duplicate-job-test +./run tests/tls-test +./run tests/virtual-changer-test +./run tests/virtual-backup-test echo "End non-root disk tests" echo "End non-root disk tests" >>test.out @@ -102,20 +115,20 @@ echo " " echo " " >>test.out echo "Start non-root virtual disk autochanger tests" echo "Start non-root virtual disk autochanger tests" >>test.out -#nice tests/three-pool-recycle-test -nice tests/two-pool-test -nice tests/fast-two-pool-test -nice tests/two-volume-test -nice tests/incremental-2disk -nice tests/2drive-incremental-2disk -nice tests/scratch-pool-test -nice tests/scratchpool-pool-test -nice tests/2drive-concurrent-test -nice tests/incremental-2media -nice tests/three-pool-test -nice tests/2drive-3pool-test -nice tests/2drive-swap-test +#./run tests/three-pool-recycle-test +./run tests/two-pool-test +./run tests/fast-two-pool-test +./run tests/two-volume-test +./run tests/incremental-2disk +./run tests/2drive-incremental-2disk +./run tests/scratch-pool-test +./run tests/scratchpool-pool-test +./run tests/2drive-concurrent-test +./run tests/incremental-2media +./run tests/three-pool-test +./run tests/2drive-3pool-test +./run tests/2drive-swap-test # Turn back on after next_vol.c bug is fixed -# nice tests/next-vol-test +# ./run tests/next-vol-test echo "End non-root virtual disk autochanger tests" echo "End non-root virtual disk autochanger tests" >>test.out diff --git a/regress/all-root-tests b/regress/all-root-tests index 284f4e4703..2ce6ed2f85 100755 --- a/regress/all-root-tests +++ b/regress/all-root-tests @@ -7,9 +7,9 @@ echo " " >>test.out echo "Start root tests" echo "Start root tests" >>test.out rm -f dumps/* -tests/dev-test-root -tests/etc-test-root -tests/lib-test-root -tests/usr-tape-root -echo "End root tests" -echo "End root tests" >>test.out +./run tests/dev-test-root +./run tests/etc-test-root +./run tests/lib-test-root +./run tests/usr-tape-root +echo "End root ./run tests" +echo "End root ./run tests" >>test.out diff --git a/regress/all-tape-tests b/regress/all-tape-tests index a99ad92348..19c4a72492 100755 --- a/regress/all-tape-tests +++ b/regress/all-tape-tests @@ -1,6 +1,6 @@ #!/bin/sh # -# Run all tape tests +# ./run all tape tests # . ./config @@ -17,18 +17,18 @@ echo " " >>test.out echo "Start all non-root tape tests" echo "Start all non-root tape tests" >>test.out rm -f dumps/* -nice tests/ansi-label-tape -nice tests/backup-bacula-tape -nice tests/bscan-tape -nice tests/fixed-block-size-tape -nice tests/four-concurrent-jobs-tape -nice tests/four-jobs-tape -nice tests/incremental-tape -nice tests/relabel-tape -nice tests/restore-by-file-tape -nice tests/small-file-size-tape -nice tests/truncate-bug-tape -nice tests/verify-vol-tape -# nice tests/manual-two-vol-tape +./run tests/ansi-label-tape +./run tests/backup-bacula-tape +./run tests/bscan-tape +./run tests/fixed-block-size-tape +./run tests/four-concurrent-jobs-tape +./run tests/four-jobs-tape +./run tests/incremental-tape +./run tests/relabel-tape +./run tests/restore-by-file-tape +./run tests/small-file-size-tape +./run tests/t./runcate-bug-tape +./run tests/verify-vol-tape +# ./run tests/manual-two-vol-tape echo "End all non-root tape tests" echo "End all non-root tape tests" >>test.out diff --git a/regress/do_all_tests b/regress/do_all_tests index 3603bdbcc1..44be9b0f94 100755 --- a/regress/do_all_tests +++ b/regress/do_all_tests @@ -9,9 +9,9 @@ echo " " >>test.out echo "Test results" >>test.out echo " " >>test.out ./starttime -nice ./all-disk-tests -nice ./all-tape-tests -nice ./all-changer-tests +./all-disk-tests +./all-tape-tests +./all-changer-tests echo " " echo "End do_all tests" echo "End do_all tests" >>test.out diff --git a/regress/run b/regress/run index d48e2623c6..f7f7d4d7a7 100755 --- a/regress/run +++ b/regress/run @@ -1,3 +1,14 @@ #!/bin/sh -bin/bacula start -bin/bconsole -c bin/bconsole.conf +# +# Script to run a regression test with a time limit (in seconds) +# this allows the script to be killed if say the SD crashes +# due to an ASSERT. Otherwise the script will hang for +# a very long time, perhaps forever. +# Of course, this implies that all tests must terminate normally +# within the timeout period (900 seconds). +# +if [ -f bin/timelimit ] ; then + WARNTIME=900 KILLTIME=5 bin/timelimit $* +else + nice $* +fi diff --git a/regress/run_bconsole b/regress/run_bconsole new file mode 100755 index 0000000000..d48e2623c6 --- /dev/null +++ b/regress/run_bconsole @@ -0,0 +1,3 @@ +#!/bin/sh +bin/bacula start +bin/bconsole -c bin/bconsole.conf diff --git a/regress/scripts/functions b/regress/scripts/functions index 7395361cd5..28f9912bcd 100644 --- a/regress/scripts/functions +++ b/regress/scripts/functions @@ -500,6 +500,7 @@ case $1 in esac } + # Save current directory cwd=`pwd` if test "x${REGRESS_DEBUG}" = "x1"; then @@ -575,3 +576,5 @@ fi AUTOCHANGER_SCRIPT=${AUTOCHANGER_SCRIPT:-mtx-changer} LD_LIBRARY_PATH=$bin:$LD_LIBRARY_PATH export LD_LIBRARY_PATH + +trap "{ estat=999; end_test; }" TERM -- 2.39.5