Author: ludo
Date: Thu Jun 30 15:19:13 2011
New Revision: 27564
URL: https://svn.nixos.org/websvn/nix/?rev=27564&sc=1
Log:
Add support for the `build-timeout' and `--timeout' options.
Added:
nix/trunk/tests/timeout.builder.sh
nix/trunk/tests/timeout.nix
nix/trunk/tests/timeout.sh
Modified:
nix/trunk/doc/manual/conf-file.xml
nix/trunk/doc/manual/opt-common-syn.xml
nix/trunk/doc/manual/opt-common.xml
nix/trunk/doc/manual/release-notes.xml
nix/trunk/src/libmain/shared.cc
nix/trunk/src/libstore/build.cc
nix/trunk/src/libstore/globals.cc
nix/trunk/src/libstore/globals.hh
nix/trunk/tests/Makefile.am
Modified: nix/trunk/doc/manual/conf-file.xml
==============================================================================
--- nix/trunk/doc/manual/conf-file.xml Thu Jun 30 15:12:26 2011 (r27563)
+++ nix/trunk/doc/manual/conf-file.xml Thu Jun 30 15:19:13 2011 (r27564)
@@ -134,6 +134,23 @@
</listitem>
+ <varlistentry
xml:id="conf-build-timeout"><term><literal>build-timeout</literal></term>
+
+ <listitem>
+
+ <para>This option defines the maximum number of seconds that a
+ builder can run. This is useful (for instance in a automated
+ build system) to catch builds that are stuck in an infinite loop
+ but keep writing to their standard output or standard error. It
+ can be overriden using the <option
+ linkend="opt-timeout">--timeout</option> command line
+ switch.</para>
+
+ <para>The value <literal>0</literal> means that there is no
+ timeout. This is also the default.</para>
+
+ </listitem>
+
</varlistentry>
Modified: nix/trunk/doc/manual/opt-common-syn.xml
==============================================================================
--- nix/trunk/doc/manual/opt-common-syn.xml Thu Jun 30 15:12:26 2011
(r27563)
+++ nix/trunk/doc/manual/opt-common-syn.xml Thu Jun 30 15:19:13 2011
(r27564)
@@ -21,6 +21,10 @@
<arg><option>--max-silent-time</option></arg>
<replaceable>number</replaceable>
</arg>
+<arg>
+ <arg><option>--timeout</option></arg>
+ <replaceable>number</replaceable>
+</arg>
<arg><option>--keep-going</option></arg>
<arg><option>-k</option></arg>
<arg><option>--keep-failed</option></arg>
Modified: nix/trunk/doc/manual/opt-common.xml
==============================================================================
--- nix/trunk/doc/manual/opt-common.xml Thu Jun 30 15:12:26 2011 (r27563)
+++ nix/trunk/doc/manual/opt-common.xml Thu Jun 30 15:19:13 2011 (r27564)
@@ -132,6 +132,16 @@
</varlistentry>
+<varlistentry xml:id="opt-timeout"><term><option>--timeout</option></term>
+
+ <listitem><para>Sets the maximum number of seconds that a builder
+ can run. The default is specified by the <link
+ linkend='conf-build-timeout'><literal>build-timeout</literal></link>
+ configuration setting. <literal>0</literal> means no
+ timeout.</para></listitem>
+
+</varlistentry>
+
<varlistentry><term><option>--keep-going</option></term>
<term><option>-k</option></term>
Modified: nix/trunk/doc/manual/release-notes.xml
==============================================================================
--- nix/trunk/doc/manual/release-notes.xml Thu Jun 30 15:12:26 2011
(r27563)
+++ nix/trunk/doc/manual/release-notes.xml Thu Jun 30 15:19:13 2011
(r27564)
@@ -22,6 +22,16 @@
option.</para>
</listitem>
+ <listitem>
+ <para>The option <option>--timeout</option> (corresponding to the
+ configuration setting <literal>build-timeout</literal>) allows you
+ to set an absolute timeout on builds — if a build runs for more than
+ the given number of seconds, it is terminated. This is useful for
+ recovering automatically from builds that are stuck in an infinite
+ loop but keep producing output, and for which
+ <literal>--max-silent-time</literal> is ineffective.</para>
+ </listitem>
+
</itemizedlist>
</section>
Modified: nix/trunk/src/libmain/shared.cc
==============================================================================
--- nix/trunk/src/libmain/shared.cc Thu Jun 30 15:12:26 2011 (r27563)
+++ nix/trunk/src/libmain/shared.cc Thu Jun 30 15:19:13 2011 (r27564)
@@ -142,6 +142,7 @@
maxBuildJobs = queryIntSetting("build-max-jobs", 1);
buildCores = queryIntSetting("build-cores", 1);
maxSilentTime = queryIntSetting("build-max-silent-time", 0);
+ buildTimeout = queryIntSetting("build-timeout", 0);
/* Catch SIGINT. */
struct sigaction act;
@@ -237,6 +238,8 @@
readOnlyMode = true;
else if (arg == "--max-silent-time")
maxSilentTime = getIntArg<unsigned int>(arg, i, args.end());
+ else if (arg == "--timeout")
+ buildTimeout = getIntArg<unsigned int>(arg, i, args.end());
else if (arg == "--no-build-hook")
useBuildHook = false;
else if (arg == "--show-trace")
Modified: nix/trunk/src/libstore/build.cc
==============================================================================
--- nix/trunk/src/libstore/build.cc Thu Jun 30 15:12:26 2011 (r27563)
+++ nix/trunk/src/libstore/build.cc Thu Jun 30 15:19:13 2011 (r27564)
@@ -209,7 +209,10 @@
/* Last time the goals in `waitingForAWhile' where woken up. */
time_t lastWokenUp;
-
+
+ /* Last time `waitForInput' was last called. */
+ time_t lastWait;
+
public:
bool cacheFailure;
@@ -681,7 +684,8 @@
builderOut.readSide.close();
if (dup2(builderOut.writeSide, 4) == -1)
throw SysError("dupping builder's stdout/stderr");
-
+
+ /* XXX: Pass `buildTimeout' to the hook? */
execl(buildHook.c_str(), buildHook.c_str(), thisSystem.c_str(),
(format("%1%") % maxSilentTime).str().c_str(),
(format("%1%") % printBuildTrace).str().c_str(),
@@ -2666,7 +2670,14 @@
struct timeval timeout;
timeout.tv_usec = 0;
time_t before = time(0);
-
+
+ /* If a global timeout has been set, sleep until it's done. */
+ if (buildTimeout != 0) {
+ useTimeout = true;
+ if (lastWait == 0 || lastWait > before) lastWait = before;
+ timeout.tv_sec = std::max((time_t) 0, lastWait + buildTimeout - before);
+ }
+
/* If we're monitoring for silence on stdout/stderr, sleep until
the first deadline for any child. */
if (maxSilentTime != 0) {
@@ -2678,8 +2689,11 @@
}
}
if (oldest) {
+ time_t silenceTimeout = std::max((time_t) 0, oldest + maxSilentTime
- before);
+ timeout.tv_sec = useTimeout
+ ? std::min(silenceTimeout, timeout.tv_sec)
+ : silenceTimeout;
useTimeout = true;
- timeout.tv_sec = std::max((time_t) 0, oldest + maxSilentTime -
before);
printMsg(lvlVomit, format("sleeping %1% seconds") %
timeout.tv_sec);
}
}
@@ -2717,6 +2731,9 @@
time_t after = time(0);
+ /* Keep track of when we were last called. */
+ lastWait = after;
+
/* Process all available file descriptors. */
/* Since goals may be canceled from inside the loop below (causing
@@ -2765,6 +2782,15 @@
% goal->getName() % maxSilentTime);
goal->cancel();
}
+
+ if (buildTimeout != 0 &&
+ after - before >= (time_t) buildTimeout)
+ {
+ printMsg(lvlError,
+ format("%1% timed out after %2% seconds of activity")
+ % goal->getName() % buildTimeout);
+ goal->cancel();
+ }
}
if (!waitingForAWhile.empty() && lastWokenUp + wakeUpInterval <= after) {
Modified: nix/trunk/src/libstore/globals.cc
==============================================================================
--- nix/trunk/src/libstore/globals.cc Thu Jun 30 15:12:26 2011 (r27563)
+++ nix/trunk/src/libstore/globals.cc Thu Jun 30 15:19:13 2011 (r27564)
@@ -26,6 +26,7 @@
bool readOnlyMode = false;
string thisSystem = "unset";
time_t maxSilentTime = 0;
+time_t buildTimeout = 0;
Paths substituters;
bool useBuildHook = true;
bool printBuildTrace = false;
Modified: nix/trunk/src/libstore/globals.hh
==============================================================================
--- nix/trunk/src/libstore/globals.hh Thu Jun 30 15:12:26 2011 (r27563)
+++ nix/trunk/src/libstore/globals.hh Thu Jun 30 15:19:13 2011 (r27564)
@@ -72,6 +72,10 @@
infinity. */
extern time_t maxSilentTime;
+/* The maximum duration in seconds that a builder can run. 0 means
+ infinity. */
+extern time_t buildTimeout;
+
/* The substituters. There are programs that can somehow realise a
store path without building, e.g., by downloading it or copying it
from a CD. */
Modified: nix/trunk/tests/Makefile.am
==============================================================================
--- nix/trunk/tests/Makefile.am Thu Jun 30 15:12:26 2011 (r27563)
+++ nix/trunk/tests/Makefile.am Thu Jun 30 15:19:13 2011 (r27564)
@@ -8,7 +8,7 @@
referrers.sh user-envs.sh logging.sh nix-build.sh misc.sh fixed.sh \
gc-runtime.sh install-package.sh check-refs.sh filter-source.sh \
remote-store.sh export.sh export-graph.sh negative-caching.sh \
- binary-patching.sh
+ binary-patching.sh timeout.sh
XFAIL_TESTS =
@@ -33,5 +33,6 @@
export-graph.nix \
negative-caching.nix \
binary-patching.nix \
+ timeout.nix timeout.builder.sh \
$(wildcard lang/*.nix) $(wildcard lang/*.exp) $(wildcard lang/*.exp.xml)
$(wildcard lang/*.flags) \
common.sh.in
Added: nix/trunk/tests/timeout.builder.sh
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ nix/trunk/tests/timeout.builder.sh Thu Jun 30 15:19:13 2011 (r27564)
@@ -0,0 +1,2 @@
+echo "\`timeout' builder entering an infinite loop"
+while true ; do : ; done
Added: nix/trunk/tests/timeout.nix
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ nix/trunk/tests/timeout.nix Thu Jun 30 15:19:13 2011 (r27564)
@@ -0,0 +1,8 @@
+with import ./config.nix;
+
+mkDerivation {
+ name = "timeout";
+ builder = ./timeout.builder.sh;
+ PATH = "";
+ goodPath = path;
+}
Added: nix/trunk/tests/timeout.sh
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ nix/trunk/tests/timeout.sh Thu Jun 30 15:19:13 2011 (r27564)
@@ -0,0 +1,24 @@
+# Test the `--timeout' option.
+
+source common.sh
+
+drvPath=$($nixinstantiate timeout.nix)
+
+test "$($nixstore -q --binding system "$drvPath")" = "$system"
+
+echo "derivation is $drvPath"
+
+failed=0
+messages="`$nixstore -r --timeout 2 $drvPath 2>&1 || failed=1`"
+if test $failed -ne 0; then
+ echo "error: \`nix-store' succeeded; should have timed out" >&2
+ exit 1
+fi
+
+if ! echo "$messages" | grep "timed out"; then
+ echo "error: \`nix-store' may have failed for reasons other than timeout"
>&2
+ echo >&2
+ echo "output of \`nix-store' follows:" >&2
+ echo "$messages" >&2
+ exit 1
+fi
_______________________________________________
nix-commits mailing list
[email protected]
http://mail.cs.uu.nl/mailman/listinfo/nix-commits