summary refs log tree commit diff
path: root/nix/libstore/build.cc
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2018-01-05 17:15:41 +0100
committerLudovic Courtès <ludo@gnu.org>2018-01-07 23:47:22 +0100
commit29a686688674dc875775305312513405fa396a06 (patch)
tree9e5f286444b8e663f3f99503c8bdc526aeb67c14 /nix/libstore/build.cc
parent896fec476f728183b331cbb6e2afb891207b4205 (diff)
downloadguix-29a686688674dc875775305312513405fa396a06.tar.gz
daemon: Add gzip log compression.
* nix/nix-daemon/guix-daemon.cc (GUIX_OPT_LOG_COMPRESSION): New macro.
(options): Mark "disable-log-compression" as hidden and add
"log-compression".
(parse_opt): Handle GUIX_OPT_LOG_COMPRESSION.
* nix/libstore/build.cc (DerivationGoal): Add 'gzLogFile'.
(openLogFile): Initialize it when 'logCompression' is COMPRESSION_GZIP.
(closeLogFile, handleChildOutput): Honor 'gzLogFile'.
* nix/libstore/globals.hh (Settings)[compressLog]: Remove.
[logCompression]: New field.
(CompressionType): New enum.
* nix/libstore/globals.cc (Settings::Settings): Initialize it.
(update): Remove '_get' call for 'compressLog'.
* nix/local.mk (guix_daemon_LDADD, guix_register_LDADD): Add -lz.
* guix/store.scm (log-file): Handle '.gz' log files.
* tests/guix-daemon.sh: Add test with '--log-compression=gzip'.
* doc/guix.texi (Invoking guix-daemon): Adjust accordingly.
* config-daemon.ac: Check for libz and zlib.h.
Diffstat (limited to 'nix/libstore/build.cc')
-rw-r--r--nix/libstore/build.cc45
1 files changed, 41 insertions, 4 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index d68e8b2bc0..5bf3e3aacb 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -31,6 +31,7 @@
 #include <pwd.h>
 #include <grp.h>
 
+#include <zlib.h>
 #include <bzlib.h>
 
 /* Includes required for chroot support. */
@@ -744,6 +745,7 @@ private:
 
     /* File descriptor for the log file. */
     FILE * fLogFile;
+    gzFile   gzLogFile;
     BZFILE * bzLogFile;
     AutoCloseFD fdLogFile;
 
@@ -892,6 +894,7 @@ DerivationGoal::DerivationGoal(const Path & drvPath, const StringSet & wantedOut
     , needRestart(false)
     , retrySubstitution(false)
     , fLogFile(0)
+    , gzLogFile(0)
     , bzLogFile(0)
     , useChroot(false)
     , buildMode(buildMode)
@@ -2599,8 +2602,25 @@ Path DerivationGoal::openLogFile()
     Path dir = (format("%1%/%2%/%3%/") % settings.nixLogDir % drvsLogDir % string(baseName, 0, 2)).str();
     createDirs(dir);
 
-    if (settings.compressLog) {
+    switch (settings.logCompression)
+      {
+      case COMPRESSION_GZIP: {
+        Path logFileName = (format("%1%/%2%.gz") % dir % string(baseName, 2)).str();
+        AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
+        if (fd == -1) throw SysError(format("creating log file `%1%'") % logFileName);
+        closeOnExec(fd);
+
+	/* Note: FD will be closed by 'gzclose'.  */
+        if (!(gzLogFile = gzdopen(fd.borrow(), "w")))
+            throw Error(format("cannot open compressed log file `%1%'") % logFileName);
+
+        gzbuffer(gzLogFile, 32768);
+        gzsetparams(gzLogFile, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY);
 
+        return logFileName;
+      }
+
+      case COMPRESSION_BZIP2: {
         Path logFileName = (format("%1%/%2%.bz2") % dir % string(baseName, 2)).str();
         AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
         if (fd == -1) throw SysError(format("creating log file `%1%'") % logFileName);
@@ -2614,20 +2634,30 @@ Path DerivationGoal::openLogFile()
             throw Error(format("cannot open compressed log file `%1%'") % logFileName);
 
         return logFileName;
+      }
 
-    } else {
+      case COMPRESSION_NONE: {
         Path logFileName = (format("%1%/%2%") % dir % string(baseName, 2)).str();
         fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
         if (fdLogFile == -1) throw SysError(format("creating log file `%1%'") % logFileName);
         closeOnExec(fdLogFile);
         return logFileName;
+      }
     }
+
+    abort();
 }
 
 
 void DerivationGoal::closeLogFile()
 {
-    if (bzLogFile) {
+    if (gzLogFile) {
+	int err;
+	err = gzclose(gzLogFile);
+	gzLogFile = NULL;
+	if (err != Z_OK) throw Error(format("cannot close compressed log file (gzip error = %1%)") % err);
+    }
+    else if (bzLogFile) {
         int err;
         BZ2_bzWriteClose(&err, bzLogFile, 0, 0, 0);
         bzLogFile = 0;
@@ -2695,7 +2725,14 @@ void DerivationGoal::handleChildOutput(int fd, const string & data)
         }
         if (verbosity >= settings.buildVerbosity)
             writeToStderr(data);
-        if (bzLogFile) {
+
+	if (gzLogFile) {
+	    if (data.size() > 0) {
+		int count, err;
+		count = gzwrite(gzLogFile, data.data(), data.size());
+		if (count == 0) throw Error(format("cannot write to compressed log file (gzip error = %1%)") % gzerror(gzLogFile, &err));
+	    }
+	} else if (bzLogFile) {
             int err;
             BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size());
             if (err != BZ_OK) throw Error(format("cannot write to compressed log file (BZip2 error = %1%)") % err);