diff options
| author | Leo Famulari | 2018-01-11 14:22:50 -0800 |
|---|---|---|
| committer | Leo Famulari | 2018-01-11 14:22:50 -0800 |
| commit | 4adb40bffc0dda8871878283887a0e0cd88d9578 (patch) | |
| tree | 74d5fb686116002da72de4a1075d0ed8f307cec1 /nix/libstore | |
| parent | 4610ab7c9a5327df0d475262817bc081a5891aa8 (diff) | |
| parent | 138c08899ba73049de8afd2b74a8cf6845a1d9e1 (diff) | |
Merge branch 'master' into core-updates
Diffstat (limited to 'nix/libstore')
| -rw-r--r-- | nix/libstore/build.cc | 83 | ||||
| -rw-r--r-- | nix/libstore/globals.cc | 8 | ||||
| -rw-r--r-- | nix/libstore/globals.hh | 11 |
3 files changed, 85 insertions, 17 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index d68e8b2bc..34647e677 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -31,7 +31,11 @@ #include <pwd.h> #include <grp.h> -#include <bzlib.h> +#include <zlib.h> + +#if HAVE_BZLIB_H +# include <bzlib.h> +#endif /* Includes required for chroot support. */ #if HAVE_SYS_PARAM_H @@ -744,7 +748,10 @@ private: /* File descriptor for the log file. */ FILE * fLogFile; + gzFile gzLogFile; +#if HAVE_BZLIB_H BZFILE * bzLogFile; +#endif AutoCloseFD fdLogFile; /* Number of bytes received from the builder's stdout/stderr. */ @@ -892,7 +899,10 @@ DerivationGoal::DerivationGoal(const Path & drvPath, const StringSet & wantedOut , needRestart(false) , retrySubstitution(false) , fLogFile(0) + , gzLogFile(0) +#if HAVE_BZLIB_H , bzLogFile(0) +#endif , useChroot(false) , buildMode(buildMode) { @@ -1672,15 +1682,6 @@ void DerivationGoal::startBuilder() f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); startNest(nest, lvlInfo, f % showPaths(missingPaths) % curRound % nrRounds); - /* Right platform? */ - if (!canBuildLocally(drv.platform)) { - if (settings.printBuildTrace) - printMsg(lvlError, format("@ unsupported-platform %1% %2%") % drvPath % drv.platform); - throw Error( - format("a `%1%' is required to build `%3%', but I am a `%2%'") - % drv.platform % settings.thisSystem % drvPath); - } - /* Note: built-in builders are *not* running in a chroot environment so that we can easily implement them in Guile without having it as a derivation input (they are running under a separate build user, @@ -2301,6 +2302,20 @@ void DerivationGoal::runChild() execve(drv.builder.c_str(), stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data()); + int error = errno; + + /* Right platform? Check this after we've tried 'execve' to allow for + transparent emulation of different platforms with binfmt_misc + handlers that invoke QEMU. */ + if (error == ENOEXEC && !canBuildLocally(drv.platform)) { + if (settings.printBuildTrace) + printMsg(lvlError, format("@ unsupported-platform %1% %2%") % drvPath % drv.platform); + throw Error( + format("a `%1%' is required to build `%3%', but I am a `%2%'") + % drv.platform % settings.thisSystem % drvPath); + } + + errno = error; throw SysError(format("executing `%1%'") % drv.builder); } catch (std::exception & e) { @@ -2599,8 +2614,26 @@ 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; + } + +#if HAVE_BZLIB_H + 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,25 +2647,38 @@ Path DerivationGoal::openLogFile() throw Error(format("cannot open compressed log file `%1%'") % logFileName); return logFileName; + } +#endif - } 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); + } +#if HAVE_BZLIB_H + else if (bzLogFile) { int err; BZ2_bzWriteClose(&err, bzLogFile, 0, 0, 0); bzLogFile = 0; if (err != BZ_OK) throw Error(format("cannot close compressed log file (BZip2 error = %1%)") % err); } +#endif if (fLogFile) { fclose(fLogFile); @@ -2695,10 +2741,19 @@ 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)); + } +#if HAVE_BZLIB_H + } 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); +#endif } else if (fdLogFile != -1) writeFull(fdLogFile, data); } diff --git a/nix/libstore/globals.cc b/nix/libstore/globals.cc index 65dad24d9..4ab6c3a0f 100644 --- a/nix/libstore/globals.cc +++ b/nix/libstore/globals.cc @@ -45,7 +45,11 @@ Settings::Settings() useSshSubstituter = false; impersonateLinux26 = false; keepLog = true; - compressLog = true; +#if HAVE_BZLIB_H + logCompression = COMPRESSION_BZIP2; +#else + logCompression = COMPRESSION_GZIP; +#endif maxLogSize = 0; cacheFailure = false; pollInterval = 5; @@ -162,7 +166,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 7beb1a55c..243993695 100644 --- a/nix/libstore/globals.hh +++ b/nix/libstore/globals.hh @@ -1,5 +1,6 @@ #pragma once +#include "config.h" #include "types.hh" #include <map> @@ -8,6 +9,14 @@ namespace nix { +enum CompressionType +{ + COMPRESSION_NONE = 0, + COMPRESSION_GZIP = 1 +#if HAVE_BZLIB_H + , COMPRESSION_BZIP2 = 2 +#endif +}; struct Settings { @@ -169,7 +178,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). */ |