diff options
Diffstat (limited to 'nix')
-rw-r--r-- | nix/libstore/build.cc | 80 | ||||
-rw-r--r-- | nix/libstore/local-store.cc | 9 | ||||
-rw-r--r-- | nix/libstore/pathlocks.cc | 6 | ||||
-rw-r--r-- | nix/libutil/xml-writer.cc | 94 | ||||
-rw-r--r-- | nix/libutil/xml-writer.hh | 69 | ||||
-rw-r--r-- | nix/local.mk | 136 |
6 files changed, 145 insertions, 249 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index f9fd61adde..ae78e65199 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -1106,8 +1106,10 @@ void DerivationGoal::repairClosure() /* Get the output closure. */ PathSet outputClosure; - foreach (DerivationOutputs::iterator, i, drv.outputs) + foreach (DerivationOutputs::iterator, i, drv.outputs) { + if (!wantOutput(i->first, wantedOutputs)) continue; computeFSClosure(worker.store, i->second.path, outputClosure); + } /* Filter out our own outputs (which we have already checked). */ foreach (DerivationOutputs::iterator, i, drv.outputs) @@ -1289,7 +1291,6 @@ void DerivationGoal::tryToBuild() now hold the locks on the output paths, no other process can build this derivation, so no further checks are necessary. */ validPaths = checkPathValidity(true, buildMode == bmRepair); - assert(buildMode != bmCheck || validPaths.size() == drv.outputs.size()); if (buildMode != bmCheck && validPaths.size() == drv.outputs.size()) { debug(format("skipping build of derivation `%1%', someone beat us to it") % drvPath); outputLocks.setDeletion(true); @@ -1717,7 +1718,7 @@ void DerivationGoal::startBuilder() /* In a sandbox, for determinism, always use the same temporary directory. */ - tmpDirInSandbox = useChroot ? "/tmp/guix-build-" + drvName + "-0" : tmpDir; + tmpDirInSandbox = useChroot ? canonPath("/tmp", true) + "/guix-build-" + drvName + "-0" : tmpDir; /* For convenience, set an environment pointing to the top build directory. */ @@ -2319,6 +2320,8 @@ void DerivationGoal::registerOutputs() outputs to allow hard links between outputs. */ InodesSeen inodesSeen; + Path checkSuffix = "-check"; + /* Check whether the output paths were created, and grep each output path to determine what other paths it references. Also make all output paths read-only. */ @@ -2344,7 +2347,7 @@ void DerivationGoal::registerOutputs() && redirectedBadOutputs.find(path) != redirectedBadOutputs.end() && pathExists(redirected)) replaceValidPath(path, redirected); - if (buildMode == bmCheck) + if (buildMode == bmCheck && redirected != "") actualPath = redirected; } @@ -2428,9 +2431,20 @@ void DerivationGoal::registerOutputs() PathSet references = scanForReferences(actualPath, allPaths, hash); if (buildMode == bmCheck) { + if (!store->isValidPath(path)) continue; ValidPathInfo info = worker.store.queryPathInfo(path); - if (hash.first != info.hash) - throw Error(format("derivation `%1%' may not be deterministic: hash mismatch in output `%2%'") % drvPath % path); + if (hash.first != info.hash) { + if (settings.keepFailed) { + Path dst = path + checkSuffix; + if (pathExists(dst)) deletePath(dst); + if (rename(actualPath.c_str(), dst.c_str())) + throw SysError(format("renaming `%1%' to `%2%'") % actualPath % dst); + throw Error(format("derivation `%1%' may not be deterministic: output `%2%' differs from ‘%3%’") + % drvPath % path % dst); + } else + throw Error(format("derivation `%1%' may not be deterministic: output `%2%' differs") + % drvPath % path); + } continue; } @@ -2475,9 +2489,11 @@ void DerivationGoal::registerOutputs() checkRefs("disallowedReferences", false, false); checkRefs("disallowedRequisites", false, true); - worker.store.optimisePath(path); // FIXME: combine with scanForReferences() + if (curRound == nrRounds) { + worker.store.optimisePath(path); // FIXME: combine with scanForReferences() - worker.store.markContentsGood(path); + worker.store.markContentsGood(path); + } ValidPathInfo info; info.path = path; @@ -2490,10 +2506,37 @@ void DerivationGoal::registerOutputs() if (buildMode == bmCheck) return; - if (curRound > 1 && prevInfos != infos) - throw NotDeterministic( - format("result of ‘%1%’ differs from previous round; rejecting as non-deterministic") - % drvPath); + /* Compare the result with the previous round, and report which + path is different, if any.*/ + if (curRound > 1 && prevInfos != infos) { + assert(prevInfos.size() == infos.size()); + for (auto i = prevInfos.begin(), j = infos.begin(); i != prevInfos.end(); ++i, ++j) + if (!(*i == *j)) { + Path prev = i->path + checkSuffix; + if (pathExists(prev)) + throw NotDeterministic( + format("output ‘%1%’ of ‘%2%’ differs from ‘%3%’ from previous round") + % i->path % drvPath % prev); + else + throw NotDeterministic( + format("output ‘%1%’ of ‘%2%’ differs from previous round") + % i->path % drvPath); + } + assert(false); // shouldn't happen + } + + if (settings.keepFailed) { + for (auto & i : drv.outputs) { + Path prev = i.second.path + checkSuffix; + if (pathExists(prev)) deletePath(prev); + if (curRound < nrRounds) { + Path dst = i.second.path + checkSuffix; + if (rename(i.second.path.c_str(), dst.c_str())) + throw SysError(format("renaming ‘%1%’ to ‘%2%’") % i.second.path % dst); + } + } + + } if (curRound < nrRounds) { prevInfos = infos; @@ -3480,8 +3523,17 @@ void LocalStore::repairPath(const Path & path) worker.run(goals); - if (goal->getExitCode() != Goal::ecSuccess) - throw Error(format("cannot repair path `%1%'") % path, worker.exitStatus()); + if (goal->getExitCode() != Goal::ecSuccess) { + /* Since substituting the path didn't work, if we have a valid + deriver, then rebuild the deriver. */ + Path deriver = queryDeriver(path); + if (deriver != "" && isValidPath(deriver)) { + goals.clear(); + goals.insert(worker.makeDerivationGoal(deriver, StringSet(), bmRepair)); + worker.run(goals); + } else + throw Error(format("cannot repair path `%1%'") % path, worker.exitStatus()); + } } diff --git a/nix/libstore/local-store.cc b/nix/libstore/local-store.cc index 11f61ae030..347e8a703f 100644 --- a/nix/libstore/local-store.cc +++ b/nix/libstore/local-store.cc @@ -606,10 +606,10 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe users group); we check for this case below. */ if (st.st_uid != geteuid()) { #if HAVE_LCHOWN - if (lchown(path.c_str(), geteuid(), (gid_t) -1) == -1) + if (lchown(path.c_str(), geteuid(), getegid()) == -1) #else if (!S_ISLNK(st.st_mode) && - chown(path.c_str(), geteuid(), (gid_t) -1) == -1) + chown(path.c_str(), geteuid(), getegid()) == -1) #endif throw SysError(format("changing owner of `%1%' to %2%") % path % geteuid()); @@ -1213,6 +1213,9 @@ template<class T> T LocalStore::getIntLineFromSubstituter(RunningSubstituter & r PathSet LocalStore::querySubstitutablePaths(const PathSet & paths) { PathSet res; + + if (!settings.useSubstitutes) return res; + foreach (Paths::iterator, i, settings.substituters) { if (res.size() == paths.size()) break; RunningSubstituter & run(runningSubstituters[*i]); @@ -1239,6 +1242,8 @@ PathSet LocalStore::querySubstitutablePaths(const PathSet & paths) void LocalStore::querySubstitutablePathInfos(const Path & substituter, PathSet & paths, SubstitutablePathInfos & infos) { + if (!settings.useSubstitutes) return; + RunningSubstituter & run(runningSubstituters[substituter]); startSubstituter(substituter, run); if (run.disabled) return; diff --git a/nix/libstore/pathlocks.cc b/nix/libstore/pathlocks.cc index 830858ff8d..9797ddd7ab 100644 --- a/nix/libstore/pathlocks.cc +++ b/nix/libstore/pathlocks.cc @@ -162,7 +162,11 @@ bool PathLocks::lockPaths(const PathSet & _paths, PathLocks::~PathLocks() { - unlock(); + try { + unlock(); + } catch (...) { + ignoreException(); + } } diff --git a/nix/libutil/xml-writer.cc b/nix/libutil/xml-writer.cc deleted file mode 100644 index 01794001b2..0000000000 --- a/nix/libutil/xml-writer.cc +++ /dev/null @@ -1,94 +0,0 @@ -#include <assert.h> - -#include "xml-writer.hh" - - -namespace nix { - - -XMLWriter::XMLWriter(bool indent, std::ostream & output) - : output(output), indent(indent) -{ - output << "<?xml version='1.0' encoding='utf-8'?>" << std::endl; - closed = false; -} - - -XMLWriter::~XMLWriter() -{ - close(); -} - - -void XMLWriter::close() -{ - if (closed) return; - while (!pendingElems.empty()) closeElement(); - closed = true; -} - - -void XMLWriter::indent_(unsigned int depth) -{ - if (!indent) return; - output << string(depth * 2, ' '); -} - - -void XMLWriter::openElement(const string & name, - const XMLAttrs & attrs) -{ - assert(!closed); - indent_(pendingElems.size()); - output << "<" << name; - writeAttrs(attrs); - output << ">"; - if (indent) output << std::endl; - pendingElems.push_back(name); -} - - -void XMLWriter::closeElement() -{ - assert(!pendingElems.empty()); - indent_(pendingElems.size() - 1); - output << "</" << pendingElems.back() << ">"; - if (indent) output << std::endl; - pendingElems.pop_back(); - if (pendingElems.empty()) closed = true; -} - - -void XMLWriter::writeEmptyElement(const string & name, - const XMLAttrs & attrs) -{ - assert(!closed); - indent_(pendingElems.size()); - output << "<" << name; - writeAttrs(attrs); - output << " />"; - if (indent) output << std::endl; -} - - -void XMLWriter::writeAttrs(const XMLAttrs & attrs) -{ - for (XMLAttrs::const_iterator i = attrs.begin(); i != attrs.end(); ++i) { - output << " " << i->first << "=\""; - for (unsigned int j = 0; j < i->second.size(); ++j) { - char c = i->second[j]; - if (c == '"') output << """; - else if (c == '<') output << "<"; - else if (c == '>') output << ">"; - else if (c == '&') output << "&"; - /* Escape newlines to prevent attribute normalisation (see - XML spec, section 3.3.3. */ - else if (c == '\n') output << "
"; - else output << c; - } - output << "\""; - } -} - - -} diff --git a/nix/libutil/xml-writer.hh b/nix/libutil/xml-writer.hh deleted file mode 100644 index 3cefe3712c..0000000000 --- a/nix/libutil/xml-writer.hh +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include <iostream> -#include <string> -#include <list> -#include <map> - - -namespace nix { - -using std::string; -using std::map; -using std::list; - - -typedef map<string, string> XMLAttrs; - - -class XMLWriter -{ -private: - - std::ostream & output; - - bool indent; - bool closed; - - list<string> pendingElems; - -public: - - XMLWriter(bool indent, std::ostream & output); - ~XMLWriter(); - - void close(); - - void openElement(const string & name, - const XMLAttrs & attrs = XMLAttrs()); - void closeElement(); - - void writeEmptyElement(const string & name, - const XMLAttrs & attrs = XMLAttrs()); - -private: - void writeAttrs(const XMLAttrs & attrs); - - void indent_(unsigned int depth); -}; - - -class XMLOpenElement -{ -private: - XMLWriter & writer; -public: - XMLOpenElement(XMLWriter & writer, const string & name, - const XMLAttrs & attrs = XMLAttrs()) - : writer(writer) - { - writer.openElement(name, attrs); - } - ~XMLOpenElement() - { - writer.closeElement(); - } -}; - - -} diff --git a/nix/local.mk b/nix/local.mk index 3c15531f54..07a92f74ea 100644 --- a/nix/local.mk +++ b/nix/local.mk @@ -21,7 +21,7 @@ # Integration of the `guix-daemon' code taken from upstream Nix. # -BUILT_SOURCES += nix/libstore/schema.sql.hh +BUILT_SOURCES += %D%/libstore/schema.sql.hh CLEANFILES += $(BUILT_SOURCES) etc/guix-daemon.service etc/guix-daemon.conf noinst_LIBRARIES = libformat.a libutil.a libstore.a @@ -30,80 +30,78 @@ noinst_LIBRARIES = libformat.a libutil.a libstore.a AM_CXXFLAGS = -Wall -std=c++11 libformat_a_SOURCES = \ - nix/boost/format/free_funcs.cc \ - nix/boost/format/parsing.cc \ - nix/boost/format/format_implementation.cc + %D%/boost/format/free_funcs.cc \ + %D%/boost/format/parsing.cc \ + %D%/boost/format/format_implementation.cc libformat_headers = \ - nix/boost/throw_exception.hpp \ - nix/boost/format.hpp \ - nix/boost/assert.hpp \ - nix/boost/format/macros_default.hpp \ - nix/boost/format/format_fwd.hpp \ - nix/boost/format/format_class.hpp \ - nix/boost/format/exceptions.hpp \ - nix/boost/format/group.hpp \ - nix/boost/format/feed_args.hpp \ - nix/boost/format/internals_fwd.hpp \ - nix/boost/format/internals.hpp + %D%/boost/throw_exception.hpp \ + %D%/boost/format.hpp \ + %D%/boost/assert.hpp \ + %D%/boost/format/macros_default.hpp \ + %D%/boost/format/format_fwd.hpp \ + %D%/boost/format/format_class.hpp \ + %D%/boost/format/exceptions.hpp \ + %D%/boost/format/group.hpp \ + %D%/boost/format/feed_args.hpp \ + %D%/boost/format/internals_fwd.hpp \ + %D%/boost/format/internals.hpp libformat_a_CPPFLAGS = \ -I$(top_srcdir)/nix libutil_a_SOURCES = \ - nix/libutil/archive.cc \ - nix/libutil/affinity.cc \ - nix/libutil/serialise.cc \ - nix/libutil/util.cc \ - nix/libutil/xml-writer.cc \ - nix/libutil/hash.cc \ - nix/libutil/gcrypt-hash.cc + %D%/libutil/archive.cc \ + %D%/libutil/affinity.cc \ + %D%/libutil/serialise.cc \ + %D%/libutil/util.cc \ + %D%/libutil/hash.cc \ + %D%/libutil/gcrypt-hash.cc libutil_headers = \ - nix/libutil/affinity.hh \ - nix/libutil/hash.hh \ - nix/libutil/serialise.hh \ - nix/libutil/xml-writer.hh \ - nix/libutil/util.hh \ - nix/libutil/archive.hh \ - nix/libutil/types.hh \ - nix/libutil/gcrypt-hash.hh \ - nix/libutil/md5.h \ - nix/libutil/sha1.h \ - nix/libutil/sha256.h \ - nix/libutil/sha512.h + %D%/libutil/affinity.hh \ + %D%/libutil/hash.hh \ + %D%/libutil/serialise.hh \ + %D%/libutil/util.hh \ + %D%/libutil/archive.hh \ + %D%/libutil/types.hh \ + %D%/libutil/gcrypt-hash.hh \ + %D%/libutil/md5.h \ + %D%/libutil/sha1.h \ + %D%/libutil/sha256.h \ + %D%/libutil/sha512.h libutil_a_CPPFLAGS = \ -I$(top_builddir)/nix \ - -I$(top_srcdir)/nix/libutil \ + -I$(top_srcdir)/%D%/libutil \ $(libformat_a_CPPFLAGS) libstore_a_SOURCES = \ - nix/libstore/gc.cc \ - nix/libstore/globals.cc \ - nix/libstore/misc.cc \ - nix/libstore/references.cc \ - nix/libstore/store-api.cc \ - nix/libstore/optimise-store.cc \ - nix/libstore/local-store.cc \ - nix/libstore/build.cc \ - nix/libstore/pathlocks.cc \ - nix/libstore/derivations.cc + %D%/libstore/gc.cc \ + %D%/libstore/globals.cc \ + %D%/libstore/misc.cc \ + %D%/libstore/references.cc \ + %D%/libstore/store-api.cc \ + %D%/libstore/optimise-store.cc \ + %D%/libstore/local-store.cc \ + %D%/libstore/build.cc \ + %D%/libstore/pathlocks.cc \ + %D%/libstore/derivations.cc libstore_headers = \ - nix/libstore/references.hh \ - nix/libstore/pathlocks.hh \ - nix/libstore/globals.hh \ - nix/libstore/worker-protocol.hh \ - nix/libstore/derivations.hh \ - nix/libstore/misc.hh \ - nix/libstore/local-store.hh \ - nix/libstore/store-api.hh + %D%/libstore/references.hh \ + %D%/libstore/pathlocks.hh \ + %D%/libstore/globals.hh \ + %D%/libstore/worker-protocol.hh \ + %D%/libstore/derivations.hh \ + %D%/libstore/misc.hh \ + %D%/libstore/local-store.hh \ + %D%/libstore/store-api.hh libstore_a_CPPFLAGS = \ $(libutil_a_CPPFLAGS) \ - -I$(top_srcdir)/nix/libstore \ - -I$(top_builddir)/nix/libstore \ + -I$(top_srcdir)/%D%/libstore \ + -I$(top_builddir)/%D%/libstore \ -DNIX_STORE_DIR=\"$(storedir)\" \ -DNIX_DATA_DIR=\"$(datadir)\" \ -DNIX_STATE_DIR=\"$(localstatedir)/guix\" \ @@ -121,29 +119,29 @@ bin_PROGRAMS = guix-daemon sbin_PROGRAMS = guix-register guix_daemon_SOURCES = \ - nix/nix-daemon/nix-daemon.cc \ - nix/nix-daemon/guix-daemon.cc + %D%/nix-daemon/nix-daemon.cc \ + %D%/nix-daemon/guix-daemon.cc guix_daemon_CPPFLAGS = \ -DLOCALEDIR=\"$(localedir)\" \ $(libutil_a_CPPFLAGS) \ - -I$(top_srcdir)/nix/libstore + -I$(top_srcdir)/%D%/libstore guix_daemon_LDADD = \ libstore.a libutil.a libformat.a -lbz2 \ $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) guix_daemon_headers = \ - nix/nix-daemon/shared.hh + %D%/nix-daemon/shared.hh guix_register_SOURCES = \ - nix/guix-register/guix-register.cc + %D%/guix-register/guix-register.cc guix_register_CPPFLAGS = \ $(libutil_a_CPPFLAGS) \ $(libstore_a_CPPFLAGS) \ - -I$(top_srcdir)/nix/libstore + -I$(top_srcdir)/%D%/libstore # XXX: Should we start using shared libs? guix_register_LDADD = \ @@ -155,7 +153,7 @@ noinst_HEADERS = \ $(libformat_headers) $(libutil_headers) $(libstore_headers) \ $(guix_daemon_headers) -nix/libstore/schema.sql.hh: nix/libstore/schema.sql +%D%/libstore/schema.sql.hh: %D%/libstore/schema.sql $(AM_V_GEN)$(GUILE) --no-auto-compile -c \ "(use-modules (rnrs io ports)) \ (call-with-output-file \"$@\" \ @@ -165,20 +163,20 @@ nix/libstore/schema.sql.hh: nix/libstore/schema.sql (write (get-string-all in) out)))))" nodist_pkglibexec_SCRIPTS = \ - nix/scripts/list-runtime-roots \ - nix/scripts/substitute + %D%/scripts/list-runtime-roots \ + %D%/scripts/substitute if BUILD_DAEMON_OFFLOAD nodist_pkglibexec_SCRIPTS += \ - nix/scripts/offload + %D%/scripts/offload endif BUILD_DAEMON_OFFLOAD # XXX: It'd be better to hide it in $(pkglibexecdir). nodist_libexec_SCRIPTS = \ - nix/scripts/guix-authenticate + %D%/scripts/guix-authenticate # The '.service' file for systemd. systemdservicedir = $(libdir)/systemd/system @@ -203,9 +201,9 @@ etc/guix-daemon.conf: etc/guix-daemon.conf.in \ mv "$@.tmp" "$@" EXTRA_DIST += \ - nix/libstore/schema.sql \ - nix/AUTHORS \ - nix/COPYING \ + %D%/libstore/schema.sql \ + %D%/AUTHORS \ + %D%/COPYING \ etc/guix-daemon.service.in \ etc/guix-daemon.conf.in |