#
# Bacula Tools Makefile
#
-# Version $Id$
-#
@MCOMMON@
PYTHON_INC = @PYTHON_INCDIR@
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
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 \
--- /dev/null
+.\" 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 .
--- /dev/null
+/*-
+ * 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);
+}
#!/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
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
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
#!/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
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
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
#!/bin/sh
#
-# Run all tape tests
+# ./run all tape tests
#
. ./config
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
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
#!/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
--- /dev/null
+#!/bin/sh
+bin/bacula start
+bin/bconsole -c bin/bconsole.conf
esac
}
+
# Save current directory
cwd=`pwd`
if test "x${REGRESS_DEBUG}" = "x1"; then
AUTOCHANGER_SCRIPT=${AUTOCHANGER_SCRIPT:-mtx-changer}
LD_LIBRARY_PATH=$bin:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
+
+trap "{ estat=999; end_test; }" TERM