summaryrefslogtreecommitdiff
path: root/nix
diff options
context:
space:
mode:
Diffstat (limited to 'nix')
-rw-r--r--nix/libstore/build.cc80
-rw-r--r--nix/libstore/local-store.cc9
-rw-r--r--nix/libstore/pathlocks.cc6
-rw-r--r--nix/libutil/xml-writer.cc94
-rw-r--r--nix/libutil/xml-writer.hh69
-rw-r--r--nix/local.mk136
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 << "&quot;";
- else if (c == '<') output << "&lt;";
- else if (c == '>') output << "&gt;";
- else if (c == '&') output << "&amp;";
- /* Escape newlines to prevent attribute normalisation (see
- XML spec, section 3.3.3. */
- else if (c == '\n') output << "&#xA;";
- 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