aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/local-store.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/local-store.cc')
-rw-r--r--src/libstore/local-store.cc71
1 files changed, 51 insertions, 20 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 485fdd691..49061f27d 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -5,6 +5,7 @@
#include "worker-protocol.hh"
#include "derivations.hh"
#include "nar-info.hh"
+#include "references.hh"
#include <iostream>
#include <algorithm>
@@ -70,15 +71,17 @@ LocalStore::LocalStore(const Params & params)
createSymlink(profilesDir, gcRootsDir + "/profiles");
}
+ for (auto & perUserDir : {profilesDir + "/per-user", gcRootsDir + "/per-user"}) {
+ createDirs(perUserDir);
+ if (chmod(perUserDir.c_str(), 0755) == -1)
+ throw SysError("could not set permissions on '%s' to 755", perUserDir);
+ }
+
+ createUser(getUserName(), getuid());
+
/* Optionally, create directories and set permissions for a
multi-user install. */
if (getuid() == 0 && settings.buildUsersGroup != "") {
-
- Path perUserDir = profilesDir + "/per-user";
- createDirs(perUserDir);
- if (chmod(perUserDir.c_str(), 01777) == -1)
- throw SysError(format("could not set permissions on '%1%' to 1777") % perUserDir);
-
mode_t perm = 01775;
struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
@@ -629,7 +632,7 @@ uint64_t LocalStore::addValidPath(State & state,
void LocalStore::queryPathInfoUncached(const Path & path,
- Callback<std::shared_ptr<ValidPathInfo>> callback)
+ Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept
{
try {
auto info = std::make_shared<ValidPathInfo>();
@@ -879,8 +882,8 @@ void LocalStore::querySubstitutablePathInfos(const PathSet & paths,
info->references,
narInfo ? narInfo->fileSize : 0,
info->narSize};
- } catch (InvalidPath) {
- } catch (SubstituterDisabled) {
+ } catch (InvalidPath &) {
+ } catch (SubstituterDisabled &) {
} catch (Error & e) {
if (settings.tryFallback)
printError(e.what());
@@ -1007,17 +1010,24 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source,
/* While restoring the path from the NAR, compute the hash
of the NAR. */
- HashSink hashSink(htSHA256);
+ std::unique_ptr<AbstractHashSink> hashSink;
+ if (info.ca == "")
+ hashSink = std::make_unique<HashSink>(htSHA256);
+ else {
+ if (!info.references.empty())
+ settings.requireExperimentalFeature("ca-references");
+ hashSink = std::make_unique<HashModuloSink>(htSHA256, storePathToHash(info.path));
+ }
LambdaSource wrapperSource([&](unsigned char * data, size_t len) -> size_t {
size_t n = source.read(data, len);
- hashSink(data, n);
+ (*hashSink)(data, n);
return n;
});
restorePath(realPath, wrapperSource);
- auto hashResult = hashSink.finish();
+ auto hashResult = hashSink->finish();
if (hashResult.first != info.narHash)
throw Error("hash mismatch importing path '%s';\n wanted: %s\n got: %s",
@@ -1210,7 +1220,8 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
bool errors = false;
- /* Acquire the global GC lock to prevent a garbage collection. */
+ /* Acquire the global GC lock to get a consistent snapshot of
+ existing and valid paths. */
AutoCloseFD fdGCLock = openGCLock(ltWrite);
PathSet store;
@@ -1221,13 +1232,11 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
PathSet validPaths2 = queryAllValidPaths(), validPaths, done;
+ fdGCLock = -1;
+
for (auto & i : validPaths2)
verifyPath(i, store, done, validPaths, repair, errors);
- /* Release the GC lock so that checking content hashes (which can
- take ages) doesn't block the GC or builds. */
- fdGCLock = -1;
-
/* Optionally, check the content hashes (slow). */
if (checkContents) {
printInfo("checking hashes...");
@@ -1240,7 +1249,15 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
/* Check the content hash (optionally - slow). */
printMsg(lvlTalkative, format("checking contents of '%1%'") % i);
- HashResult current = hashPath(info->narHash.type, toRealPath(i));
+
+ std::unique_ptr<AbstractHashSink> hashSink;
+ if (info->ca == "")
+ hashSink = std::make_unique<HashSink>(info->narHash.type);
+ else
+ hashSink = std::make_unique<HashModuloSink>(info->narHash.type, storePathToHash(info->path));
+
+ dumpPath(toRealPath(i), *hashSink);
+ auto current = hashSink->finish();
if (info->narHash != nullHash && info->narHash != current.first) {
printError(format("path '%1%' was modified! "
@@ -1293,8 +1310,7 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
{
checkInterrupt();
- if (done.find(path) != done.end()) return;
- done.insert(path);
+ if (!done.insert(path).second) return;
if (!isStorePath(path)) {
printError(format("path '%1%' is not in the Nix store") % path);
@@ -1434,4 +1450,19 @@ void LocalStore::signPathInfo(ValidPathInfo & info)
}
+void LocalStore::createUser(const std::string & userName, uid_t userId)
+{
+ for (auto & dir : {
+ fmt("%s/profiles/per-user/%s", stateDir, userName),
+ fmt("%s/gcroots/per-user/%s", stateDir, userName)
+ }) {
+ createDirs(dir);
+ if (chmod(dir.c_str(), 0755) == -1)
+ throw SysError("changing permissions of directory '%s'", dir);
+ if (chown(dir.c_str(), userId, getgid()) == -1)
+ throw SysError("changing owner of directory '%s'", dir);
+ }
+}
+
+
}