summaryrefslogtreecommitdiff
path: root/nix
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
parent896fec476f728183b331cbb6e2afb891207b4205 (diff)
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')
-rw-r--r--nix/libstore/build.cc45
-rw-r--r--nix/libstore/globals.cc4
-rw-r--r--nix/libstore/globals.hh8
-rw-r--r--nix/local.mk6
-rw-r--r--nix/nix-daemon/guix-daemon.cc25
5 files changed, 75 insertions, 13 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);
diff --git a/nix/libstore/globals.cc b/nix/libstore/globals.cc
index 65dad24d91..82d528dc98 100644
--- a/nix/libstore/globals.cc
+++ b/nix/libstore/globals.cc
@@ -45,7 +45,7 @@ Settings::Settings()
useSshSubstituter = false;
impersonateLinux26 = false;
keepLog = true;
- compressLog = true;
+ logCompression = COMPRESSION_BZIP2;
maxLogSize = 0;
cacheFailure = false;
pollInterval = 5;
@@ -162,7 +162,7 @@ void Settings::update()
_get(useChroot, "build-use-chroot");
_get(impersonateLinux26, "build-impersonate-linux-26");
_get(keepLog, "build-keep-log");
- _get(compressLog, "build-compress-log");
+ // _get(logCompression, "build-log-compression");
_get(maxLogSize, "build-max-log-size");
_get(cacheFailure, "build-cache-failure");
_get(pollInterval, "build-poll-interval");
diff --git a/nix/libstore/globals.hh b/nix/libstore/globals.hh
index 7beb1a55ca..81cf2f52d4 100644
--- a/nix/libstore/globals.hh
+++ b/nix/libstore/globals.hh
@@ -8,6 +8,12 @@
namespace nix {
+enum CompressionType
+{
+ COMPRESSION_NONE = 0,
+ COMPRESSION_GZIP = 1,
+ COMPRESSION_BZIP2 = 2
+};
struct Settings {
@@ -169,7 +175,7 @@ struct Settings {
bool keepLog;
/* Whether to compress logs. */
- bool compressLog;
+ enum CompressionType logCompression;
/* Maximum number of bytes a builder can write to stdout/stderr
before being killed (0 means no limit). */
diff --git a/nix/local.mk b/nix/local.mk
index 9e0c457bec..d802da6170 100644
--- a/nix/local.mk
+++ b/nix/local.mk
@@ -1,5 +1,5 @@
# GNU Guix --- Functional package management for GNU
-# Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+# Copyright © 2012, 2013, 2014, 2015, 2016, 2018 Ludovic Courtès <ludo@gnu.org>
# Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
#
# This file is part of GNU Guix.
@@ -132,7 +132,7 @@ guix_daemon_CPPFLAGS = \
-I$(top_srcdir)/%D%/libstore
guix_daemon_LDADD = \
- libstore.a libutil.a libformat.a -lbz2 \
+ libstore.a libutil.a libformat.a -lz -lbz2 \
$(SQLITE3_LIBS) $(LIBGCRYPT_LIBS)
guix_daemon_headers = \
@@ -149,7 +149,7 @@ guix_register_CPPFLAGS = \
# XXX: Should we start using shared libs?
guix_register_LDADD = \
- libstore.a libutil.a libformat.a -lbz2 \
+ libstore.a libutil.a libformat.a -lz -lbz2 \
$(SQLITE3_LIBS) $(LIBGCRYPT_LIBS)
diff --git a/nix/nix-daemon/guix-daemon.cc b/nix/nix-daemon/guix-daemon.cc
index 7963358202..a1ef90dfdc 100644
--- a/nix/nix-daemon/guix-daemon.cc
+++ b/nix/nix-daemon/guix-daemon.cc
@@ -1,5 +1,5 @@
/* GNU Guix --- Functional package management for GNU
- Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
+ Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
Copyright (C) 2006, 2010, 2012, 2014 Eelco Dolstra <e.dolstra@tudelft.nl>
This file is part of GNU Guix.
@@ -88,6 +88,7 @@ builds derivations on behalf of its clients.");
#define GUIX_OPT_BUILD_ROUNDS 17
#define GUIX_OPT_TIMEOUT 18
#define GUIX_OPT_MAX_SILENT_TIME 19
+#define GUIX_OPT_LOG_COMPRESSION 20
static const struct argp_option options[] =
{
@@ -120,8 +121,11 @@ static const struct argp_option options[] =
n_("build each derivation N times in a row") },
{ "lose-logs", GUIX_OPT_LOSE_LOGS, 0, 0,
n_("do not keep build logs") },
- { "disable-log-compression", GUIX_OPT_DISABLE_LOG_COMPRESSION, 0, 0,
+ { "disable-log-compression", GUIX_OPT_DISABLE_LOG_COMPRESSION, 0,
+ OPTION_HIDDEN, // deprecated
n_("disable compression of the build logs") },
+ { "log-compression", GUIX_OPT_LOG_COMPRESSION, "TYPE", 0,
+ n_("use the specified compression type for build logs") },
/* '--disable-deduplication' was known as '--disable-store-optimization'
up to Guix 0.7 included, so keep the alias around. */
@@ -197,8 +201,21 @@ parse_opt (int key, char *arg, struct argp_state *state)
settings.set("build-extra-chroot-dirs", chroot_dirs);
break;
}
+ case GUIX_OPT_LOG_COMPRESSION:
+ if (strcmp (arg, "none") == 0)
+ settings.logCompression = COMPRESSION_NONE;
+ else if (strcmp (arg, "gzip") == 0)
+ settings.logCompression = COMPRESSION_GZIP;
+ else if (strcmp (arg, "bzip2") == 0)
+ settings.logCompression = COMPRESSION_BZIP2;
+ else
+ {
+ fprintf (stderr, _("error: %s: unknown compression type\n"), arg);
+ exit (EXIT_FAILURE);
+ }
+ break;
case GUIX_OPT_DISABLE_LOG_COMPRESSION:
- settings.compressLog = false;
+ settings.logCompression = COMPRESSION_NONE;
break;
case GUIX_OPT_BUILD_USERS_GROUP:
settings.buildUsersGroup = arg;
@@ -487,6 +504,8 @@ main (int argc, char *argv[])
/* Effect all the changes made via 'settings.set'. */
settings.update ();
+ printMsg(lvlDebug,
+ format ("build log compression: %1%") % settings.logCompression);
if (settings.useSubstitutes)
{