]> git.sur5r.net Git - bacula/bacula/commitdiff
Implement a timeout on regression tests of 15 minutes
authorKern Sibbald <kern@sibbald.com>
Fri, 2 Nov 2012 09:43:25 +0000 (10:43 +0100)
committerKern Sibbald <kern@sibbald.com>
Sat, 20 Apr 2013 12:51:06 +0000 (14:51 +0200)
Conflicts:

bacula/src/tools/Makefile.in
regress/all-changer-tests
regress/all-dev-tests
regress/all-disk-tests

12 files changed:
bacula/src/tools/Makefile.in
bacula/src/tools/timelimit.1 [new file with mode: 0644]
bacula/src/tools/timelimit.c [new file with mode: 0644]
regress/all-changer-tests
regress/all-dev-tests
regress/all-disk-tests
regress/all-root-tests
regress/all-tape-tests
regress/do_all_tests
regress/run
regress/run_bconsole [new file with mode: 0755]
regress/scripts/functions

index 2463957f0a79a28a7beb3f410275e0bbf949a5a1..6de011bc83680dc6e30be01112ce054828a6f480 100644 (file)
@@ -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 (file)
index 0000000..1d3a7c9
--- /dev/null
@@ -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 (file)
index 0000000..c337a18
--- /dev/null
@@ -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 <sys/types.h>
+#include <sys/signal.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <errno.h>
+
+#ifdef HAVE_ERR
+#include <err.h>
+#endif /* HAVE_ERR */
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#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);
+}
index 65dc26e4dbb3a845f47bb4722e362481434396ca..a2a8ce86f20871de44f08e01bec38b3cd76d55dd 100755 (executable)
@@ -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
index 85c8ac98b3ffe7580b674450630fdef9c1e54a51..a7db3434b1d8058013d05570d2c4f1cc767f0dce 100755 (executable)
@@ -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
index 2af26a50d46b1a5224d397ca84533bd0b4a13e39..6bbdb6274373c307c2b7fc0beb5bd66c276d8c78 100755 (executable)
 #!/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
index 284f4e47038333cc008af6aebc6d4051d2518818..2ce6ed2f855a9379a41b066597df72980b786c03 100755 (executable)
@@ -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
index a99ad9234859f0fae52e62e41645be119d390992..19c4a7249288751f9da5c7de7b58c7e163663a77 100755 (executable)
@@ -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
index 3603bdbcc126be3195e66f8c592d799d1466ad5f..44be9b0f946f53e06f882c0a72d2c4614ff2676d 100755 (executable)
@@ -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
index d48e2623c619ac9a9ade9d870f5495c35df1064f..f7f7d4d7a72419600dd9ee0979e34dfd05a3e415 100755 (executable)
@@ -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 (executable)
index 0000000..d48e262
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+bin/bacula start
+bin/bconsole -c bin/bconsole.conf
index 7395361cd503be1368fffabb39aedf8b0f8b7a6f..28f9912bcdf870de97a7fa5088196377be04f372 100644 (file)
@@ -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