about summary refs log tree commit diff
path: root/src/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc13
-rw-r--r--src/libstore/globals.cc2
-rw-r--r--src/libstore/globals.hh4
3 files changed, 19 insertions, 0 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index b5d064e8c60d..25bf848ca697 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 d17bd947d3da..aeb52e1a8696 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 f129d9a11edc..50b61725c742 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;