aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-07-06 16:40:10 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-07-06 16:40:10 +0200
commit54712aaf8a4d9d6a42232fe9b360fc72f35ed02d (patch)
tree02f1ad7cb8628ed5877ed411a7ed67b3c0917da9 /src/libstore
parent6ff9aa8df7ce8266147f74c65e2cc529a1e72ce0 (diff)
parent14227aeb327798a1446ddde59fc561c3d2e6b7a8 (diff)
Merge remote-tracking branch 'origin/master' into flakes
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc11
-rw-r--r--src/libstore/builtins/fetchurl.cc9
-rw-r--r--src/libstore/daemon.cc13
-rw-r--r--src/libstore/globals.cc2
-rw-r--r--src/libstore/globals.hh4
-rw-r--r--src/libstore/local-store.cc11
-rw-r--r--src/libstore/local-store.hh2
-rw-r--r--src/libstore/path.hh1
-rw-r--r--src/libstore/remote-store.cc38
-rw-r--r--src/libstore/remote-store.hh1
-rw-r--r--src/libstore/store-api.cc10
-rw-r--r--src/libstore/store-api.hh7
-rw-r--r--src/libstore/worker-protocol.hh6
13 files changed, 91 insertions, 24 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 0c25897f8..347fe1b99 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -1950,8 +1950,11 @@ void linkOrCopy(const Path & from, const Path & to)
/* Hard-linking fails if we exceed the maximum link count on a
file (e.g. 32000 of ext3), which is quite possible after a
'nix-store --optimise'. FIXME: actually, why don't we just
- bind-mount in this case? */
- if (errno != EMLINK)
+ bind-mount in this case?
+
+ It can also fail with EPERM in BeegFS v7 and earlier versions
+ which don't allow hard-links to other directories */
+ if (errno != EMLINK && errno != EPERM)
throw SysError("linking '%s' to '%s'", to, from);
copyPath(from, to);
}
@@ -2750,8 +2753,8 @@ struct RestrictedStore : public LocalFSStore
void queryReferrers(const StorePath & path, StorePathSet & referrers) override
{ }
- StorePathSet queryDerivationOutputs(const StorePath & path) override
- { throw Error("queryDerivationOutputs"); }
+ OutputPathMap queryDerivationOutputMap(const StorePath & path) override
+ { throw Error("queryDerivationOutputMap"); }
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override
{ throw Error("queryPathFromHashPart"); }
diff --git a/src/libstore/builtins/fetchurl.cc b/src/libstore/builtins/fetchurl.cc
index 1cfe4a46a..e630cf6f1 100644
--- a/src/libstore/builtins/fetchurl.cc
+++ b/src/libstore/builtins/fetchurl.cc
@@ -58,13 +58,16 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
}
};
+ /* We always have one output, and if it's a fixed-output derivation (as
+ checked below) it must be the only output */
+ auto & output = drv.outputs.begin()->second;
+
/* Try the hashed mirrors first. */
- if (getAttr("outputHashMode") == "flat")
+ if (output.hash && output.hash->method == FileIngestionMethod::Flat)
for (auto hashedMirror : settings.hashedMirrors.get())
try {
if (!hasSuffix(hashedMirror, "/")) hashedMirror += '/';
- auto ht = parseHashTypeOpt(getAttr("outputHashAlgo"));
- auto h = Hash(getAttr("outputHash"), ht);
+ auto & h = output.hash->hash;
fetch(hashedMirror + printHashType(*h.type) + "/" + h.to_string(Base16, false));
return;
} catch (Error & e) {
diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc
index 842aef20c..a8fb62e0a 100644
--- a/src/libstore/daemon.cc
+++ b/src/libstore/daemon.cc
@@ -78,10 +78,10 @@ struct TunnelLogger : public Logger
if (ei.level > verbosity) return;
std::stringstream oss;
- oss << ei;
+ showErrorInfo(oss, ei, false);
StringSink buf;
- buf << STDERR_NEXT << oss.str() << "\n"; // (fs.s + "\n");
+ buf << STDERR_NEXT << oss.str() << "\n";
enqueueMsg(*buf.s);
}
@@ -347,6 +347,15 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
break;
}
+ case wopQueryDerivationOutputMap: {
+ auto path = store->parseStorePath(readString(from));
+ logger->startWork();
+ OutputPathMap outputs = store->queryDerivationOutputMap(path);
+ logger->stopWork();
+ writeOutputPathMap(*store, to, outputs);
+ break;
+ }
+
case wopQueryDeriver: {
auto path = store->parseStorePath(readString(from));
logger->startWork();
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index bee94cbd8..683fa5196 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -35,7 +35,7 @@ Settings::Settings()
, nixLibexecDir(canonPath(getEnv("NIX_LIBEXEC_DIR").value_or(NIX_LIBEXEC_DIR)))
, nixBinDir(canonPath(getEnv("NIX_BIN_DIR").value_or(NIX_BIN_DIR)))
, nixManDir(canonPath(NIX_MAN_DIR))
- , nixDaemonSocketFile(canonPath(nixStateDir + DEFAULT_SOCKET_PATH))
+ , nixDaemonSocketFile(canonPath(getEnv("NIX_DAEMON_SOCKET_PATH").value_or(nixStateDir + DEFAULT_SOCKET_PATH)))
{
buildUsersGroup = getuid() == 0 ? "nixbld" : "";
lockCPU = getEnv("NIX_AFFINITY_HACK") == "1";
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 699abf353..101633869 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -196,10 +196,6 @@ public:
/* Whether to lock the Nix client and worker to the same CPU. */
bool lockCPU;
- /* Whether to show a stack trace if Nix evaluation fails. */
- Setting<bool> showTrace{this, false, "show-trace",
- "Whether to show a stack trace on evaluation errors."};
-
Setting<SandboxMode> sandboxMode{this,
#if __linux__
smEnabled
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 5b462c5b3..12a6a03c3 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -774,17 +774,20 @@ StorePathSet LocalStore::queryValidDerivers(const StorePath & path)
}
-StorePathSet LocalStore::queryDerivationOutputs(const StorePath & path)
+OutputPathMap LocalStore::queryDerivationOutputMap(const StorePath & path)
{
- return retrySQLite<StorePathSet>([&]() {
+ return retrySQLite<OutputPathMap>([&]() {
auto state(_state.lock());
auto useQueryDerivationOutputs(state->stmtQueryDerivationOutputs.use()
(queryValidPathId(*state, path)));
- StorePathSet outputs;
+ OutputPathMap outputs;
while (useQueryDerivationOutputs.next())
- outputs.insert(parseStorePath(useQueryDerivationOutputs.getStr(1)));
+ outputs.emplace(
+ useQueryDerivationOutputs.getStr(0),
+ parseStorePath(useQueryDerivationOutputs.getStr(1))
+ );
return outputs;
});
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index e17cc45ae..ff36cb00e 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -133,7 +133,7 @@ public:
StorePathSet queryValidDerivers(const StorePath & path) override;
- StorePathSet queryDerivationOutputs(const StorePath & path) override;
+ OutputPathMap queryDerivationOutputMap(const StorePath & path) override;
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override;
diff --git a/src/libstore/path.hh b/src/libstore/path.hh
index 4f79843fe..e43a8b50c 100644
--- a/src/libstore/path.hh
+++ b/src/libstore/path.hh
@@ -62,6 +62,7 @@ public:
typedef std::set<StorePath> StorePathSet;
typedef std::vector<StorePath> StorePaths;
+typedef std::map<string, StorePath> OutputPathMap;
/* Extension of derivations in the Nix store. */
const std::string drvExtension = ".drv";
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index b7cc7a5fc..118aadf7e 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -8,6 +8,7 @@
#include "derivations.hh"
#include "pool.hh"
#include "finally.hh"
+#include "logging.hh"
#include <sys/types.h>
#include <sys/stat.h>
@@ -38,6 +39,29 @@ void writeStorePaths(const Store & store, Sink & out, const StorePathSet & paths
out << store.printStorePath(i);
}
+std::map<string, StorePath> readOutputPathMap(const Store & store, Source & from)
+{
+ std::map<string, StorePath> pathMap;
+ auto rawInput = readStrings<Strings>(from);
+ if (rawInput.size() % 2)
+ throw Error("got an odd number of elements from the daemon when trying to read a output path map");
+ auto curInput = rawInput.begin();
+ while (curInput != rawInput.end()) {
+ auto thisKey = *curInput++;
+ auto thisValue = *curInput++;
+ pathMap.emplace(thisKey, store.parseStorePath(thisValue));
+ }
+ return pathMap;
+}
+
+void writeOutputPathMap(const Store & store, Sink & out, const std::map<string, StorePath> & pathMap)
+{
+ out << 2*pathMap.size();
+ for (auto & i : pathMap) {
+ out << i.first;
+ out << store.printStorePath(i.second);
+ }
+}
/* TODO: Separate these store impls into different files, give them better names */
RemoteStore::RemoteStore(const Params & params)
@@ -197,7 +221,7 @@ void RemoteStore::setOptions(Connection & conn)
overrides.erase(settings.maxSilentTime.name);
overrides.erase(settings.buildCores.name);
overrides.erase(settings.useSubstitutes.name);
- overrides.erase(settings.showTrace.name);
+ overrides.erase(loggerSettings.showTrace.name);
conn.to << overrides.size();
for (auto & i : overrides)
conn.to << i.first << i.second.value;
@@ -412,12 +436,24 @@ StorePathSet RemoteStore::queryValidDerivers(const StorePath & path)
StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path)
{
auto conn(getConnection());
+ if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 0x16) {
+ return Store::queryDerivationOutputs(path);
+ }
conn->to << wopQueryDerivationOutputs << printStorePath(path);
conn.processStderr();
return readStorePaths<StorePathSet>(*this, conn->from);
}
+OutputPathMap RemoteStore::queryDerivationOutputMap(const StorePath & path)
+{
+ auto conn(getConnection());
+ conn->to << wopQueryDerivationOutputMap << printStorePath(path);
+ conn.processStderr();
+ return readOutputPathMap(*this, conn->from);
+
+}
+
std::optional<StorePath> RemoteStore::queryPathFromHashPart(const std::string & hashPart)
{
auto conn(getConnection());
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index 80c8e9f11..fb2052752 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -51,6 +51,7 @@ public:
StorePathSet queryDerivationOutputs(const StorePath & path) override;
+ OutputPathMap queryDerivationOutputMap(const StorePath & path) override;
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override;
StorePathSet querySubstitutablePaths(const StorePathSet & paths) override;
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index e4a4ae11e..c0a8bc9f6 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -242,6 +242,16 @@ bool Store::PathInfoCacheValue::isKnownNow()
return std::chrono::steady_clock::now() < time_point + ttl;
}
+StorePathSet Store::queryDerivationOutputs(const StorePath & path)
+{
+ auto outputMap = this->queryDerivationOutputMap(path);
+ StorePathSet outputPaths;
+ for (auto & i: outputMap) {
+ outputPaths.emplace(std::move(i.second));
+ }
+ return outputPaths;
+}
+
bool Store::isValidPath(const StorePath & storePath)
{
std::string hashPart(storePath.hashPart());
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 25d78c297..b122e05d6 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -418,8 +418,11 @@ public:
virtual StorePathSet queryValidDerivers(const StorePath & path) { return {}; };
/* Query the outputs of the derivation denoted by `path'. */
- virtual StorePathSet queryDerivationOutputs(const StorePath & path)
- { unsupported("queryDerivationOutputs"); }
+ virtual StorePathSet queryDerivationOutputs(const StorePath & path);
+
+ /* Query the mapping outputName=>outputPath for the given derivation */
+ virtual OutputPathMap queryDerivationOutputMap(const StorePath & path)
+ { unsupported("queryDerivationOutputMap"); }
/* Query the full store path given the hash part of a valid store
path, or empty if the path doesn't exist. */
diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh
index ac42457fc..8b538f6da 100644
--- a/src/libstore/worker-protocol.hh
+++ b/src/libstore/worker-protocol.hh
@@ -6,7 +6,7 @@ namespace nix {
#define WORKER_MAGIC_1 0x6e697863
#define WORKER_MAGIC_2 0x6478696f
-#define PROTOCOL_VERSION 0x115
+#define PROTOCOL_VERSION 0x116
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
@@ -30,7 +30,7 @@ typedef enum {
wopSetOptions = 19,
wopCollectGarbage = 20,
wopQuerySubstitutablePathInfo = 21,
- wopQueryDerivationOutputs = 22,
+ wopQueryDerivationOutputs = 22, // obsolete
wopQueryAllValidPaths = 23,
wopQueryFailedPaths = 24,
wopClearFailedPaths = 25,
@@ -49,6 +49,7 @@ typedef enum {
wopNarFromPath = 38,
wopAddToStoreNar = 39,
wopQueryMissing = 40,
+ wopQueryDerivationOutputMap = 41,
} WorkerOp;
@@ -69,5 +70,6 @@ template<class T> T readStorePaths(const Store & store, Source & from);
void writeStorePaths(const Store & store, Sink & out, const StorePathSet & paths);
+void writeOutputPathMap(const Store & store, Sink & out, const OutputPathMap & paths);
}