diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2013-09-02 11:58:18 +0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2013-09-02 11:58:18 +0200 |
commit | efe428946431c6c670151c949884fa8c1fa31794 (patch) | |
tree | 3d9d05c8397aef96010f10261912e458c44814ef /src | |
parent | afc6c1bad63e27d68adf49e673f8aafd36495a8a (diff) |
Add an option to limit the log output of builders
This is mostly useful for Hydra to deal with builders that get stuck
in an infinite loop writing data to stdout/stderr.
Diffstat (limited to 'src')
-rw-r--r-- | src/libstore/build.cc | 13 | ||||
-rw-r--r-- | src/libstore/globals.cc | 2 | ||||
-rw-r--r-- | src/libstore/globals.hh | 4 |
3 files changed, 19 insertions, 0 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index b5d064e8c..25bf848ca 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -813,6 +813,9 @@ private: BZFILE * bzLogFile; AutoCloseFD fdLogFile; + /* Number of bytes received from the builder's stdout/stderr. */ + unsigned long logSize; + /* Pipe for the builder's standard output/error. */ Pipe builderOut; @@ -2403,6 +2406,8 @@ string drvsLogDir = "drvs"; Path DerivationGoal::openLogFile() { + logSize = 0; + if (!settings.keepLog) return ""; string baseName = baseNameOf(drvPath); @@ -2478,6 +2483,14 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) if ((hook && fd == hook->builderOut.readSide) || (!hook && fd == builderOut.readSide)) { + logSize += data.size(); + if (settings.maxLogSize && logSize > settings.maxLogSize) { + printMsg(lvlError, + format("%1% killed after writing more than %2% bytes of log output") + % getName() % settings.maxLogSize); + cancel(true); // not really a timeout, but close enough + return; + } if (verbosity >= settings.buildVerbosity) writeToStderr(data); if (bzLogFile) { diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index d17bd947d..aeb52e1a8 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -46,6 +46,7 @@ Settings::Settings() impersonateLinux26 = false; keepLog = true; compressLog = true; + maxLogSize = 0; cacheFailure = false; pollInterval = 5; checkRootReachability = false; @@ -140,6 +141,7 @@ void Settings::update() get(impersonateLinux26, "build-impersonate-linux-26"); get(keepLog, "build-keep-log"); get(compressLog, "build-compress-log"); + get(maxLogSize, "build-max-log-size"); get(cacheFailure, "build-cache-failure"); get(pollInterval, "build-poll-interval"); get(checkRootReachability, "gc-check-reachability"); diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index f129d9a11..50b61725c 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -153,6 +153,10 @@ struct Settings { /* Whether to compress logs. */ bool compressLog; + /* Maximum number of bytes a builder can write to stdout/stderr + before being killed (0 means no limit). */ + unsigned long maxLogSize; + /* Whether to cache build failures. */ bool cacheFailure; |