forked from lix-project/lix
Merge "libstore: Create platform LocalStore subclasses" into main
This commit is contained in:
commit
8175e47ce5
|
@ -7,7 +7,14 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Garbage-collector roots, referring to a store path
|
||||||
|
*/
|
||||||
typedef std::unordered_map<StorePath, std::unordered_set<std::string>> Roots;
|
typedef std::unordered_map<StorePath, std::unordered_set<std::string>> Roots;
|
||||||
|
/**
|
||||||
|
* Possible garbage collector roots, referring to any path
|
||||||
|
*/
|
||||||
|
typedef std::unordered_map<Path, std::unordered_set<std::string>> UncheckedRoots;
|
||||||
|
|
||||||
|
|
||||||
struct GCOptions
|
struct GCOptions
|
||||||
|
|
|
@ -321,105 +321,8 @@ Roots LocalStore::findRoots(bool censor)
|
||||||
return roots;
|
return roots;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::unordered_map<Path, std::unordered_set<std::string>> UncheckedRoots;
|
void LocalStore::findPlatformRoots(UncheckedRoots & unchecked)
|
||||||
|
|
||||||
static void readProcLink(const std::string & file, UncheckedRoots & roots)
|
|
||||||
{
|
{
|
||||||
constexpr auto bufsiz = PATH_MAX;
|
|
||||||
char buf[bufsiz];
|
|
||||||
auto res = readlink(file.c_str(), buf, bufsiz);
|
|
||||||
if (res == -1) {
|
|
||||||
if (errno == ENOENT || errno == EACCES || errno == ESRCH)
|
|
||||||
return;
|
|
||||||
throw SysError("reading symlink");
|
|
||||||
}
|
|
||||||
if (res == bufsiz) {
|
|
||||||
throw Error("overly long symlink starting with '%1%'", std::string_view(buf, bufsiz));
|
|
||||||
}
|
|
||||||
if (res > 0 && buf[0] == '/')
|
|
||||||
roots[std::string(static_cast<char *>(buf), res)]
|
|
||||||
.emplace(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string quoteRegexChars(const std::string & raw)
|
|
||||||
{
|
|
||||||
static auto specialRegex = std::regex(R"([.^$\\*+?()\[\]{}|])");
|
|
||||||
return std::regex_replace(raw, specialRegex, R"(\$&)");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if __linux__
|
|
||||||
static void readFileRoots(const char * path, UncheckedRoots & roots)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
roots[readFile(path)].emplace(path);
|
|
||||||
} catch (SysError & e) {
|
|
||||||
if (e.errNo != ENOENT && e.errNo != EACCES)
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
|
|
||||||
{
|
|
||||||
UncheckedRoots unchecked;
|
|
||||||
|
|
||||||
auto procDir = AutoCloseDir{opendir("/proc")};
|
|
||||||
if (procDir) {
|
|
||||||
struct dirent * ent;
|
|
||||||
auto digitsRegex = std::regex(R"(^\d+$)");
|
|
||||||
auto mapRegex = std::regex(R"(^\s*\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(/\S+)\s*$)");
|
|
||||||
auto storePathRegex = std::regex(quoteRegexChars(storeDir) + R"(/[0-9a-z]+[0-9a-zA-Z\+\-\._\?=]*)");
|
|
||||||
while (errno = 0, ent = readdir(procDir.get())) {
|
|
||||||
checkInterrupt();
|
|
||||||
if (std::regex_match(ent->d_name, digitsRegex)) {
|
|
||||||
try {
|
|
||||||
readProcLink(fmt("/proc/%s/exe" ,ent->d_name), unchecked);
|
|
||||||
readProcLink(fmt("/proc/%s/cwd", ent->d_name), unchecked);
|
|
||||||
|
|
||||||
auto fdStr = fmt("/proc/%s/fd", ent->d_name);
|
|
||||||
auto fdDir = AutoCloseDir(opendir(fdStr.c_str()));
|
|
||||||
if (!fdDir) {
|
|
||||||
if (errno == ENOENT || errno == EACCES)
|
|
||||||
continue;
|
|
||||||
throw SysError("opening %1%", fdStr);
|
|
||||||
}
|
|
||||||
struct dirent * fd_ent;
|
|
||||||
while (errno = 0, fd_ent = readdir(fdDir.get())) {
|
|
||||||
if (fd_ent->d_name[0] != '.')
|
|
||||||
readProcLink(fmt("%s/%s", fdStr, fd_ent->d_name), unchecked);
|
|
||||||
}
|
|
||||||
if (errno) {
|
|
||||||
if (errno == ESRCH)
|
|
||||||
continue;
|
|
||||||
throw SysError("iterating /proc/%1%/fd", ent->d_name);
|
|
||||||
}
|
|
||||||
fdDir.reset();
|
|
||||||
|
|
||||||
auto mapFile = fmt("/proc/%s/maps", ent->d_name);
|
|
||||||
auto mapLines = tokenizeString<std::vector<std::string>>(readFile(mapFile), "\n");
|
|
||||||
for (const auto & line : mapLines) {
|
|
||||||
auto match = std::smatch{};
|
|
||||||
if (std::regex_match(line, match, mapRegex))
|
|
||||||
unchecked[match[1]].emplace(mapFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto envFile = fmt("/proc/%s/environ", ent->d_name);
|
|
||||||
auto envString = readFile(envFile);
|
|
||||||
auto env_end = std::sregex_iterator{};
|
|
||||||
for (auto i = std::sregex_iterator{envString.begin(), envString.end(), storePathRegex}; i != env_end; ++i)
|
|
||||||
unchecked[i->str()].emplace(envFile);
|
|
||||||
} catch (SysError & e) {
|
|
||||||
if (errno == ENOENT || errno == EACCES || errno == ESRCH)
|
|
||||||
continue;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (errno)
|
|
||||||
throw SysError("iterating /proc");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(__linux__)
|
|
||||||
// lsof is really slow on OS X. This actually causes the gc-concurrent.sh test to fail.
|
// lsof is really slow on OS X. This actually causes the gc-concurrent.sh test to fail.
|
||||||
// See: https://github.com/NixOS/nix/issues/3011
|
// See: https://github.com/NixOS/nix/issues/3011
|
||||||
// Because of this we disable lsof when running the tests.
|
// Because of this we disable lsof when running the tests.
|
||||||
|
@ -437,13 +340,13 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
|
||||||
/* lsof not installed, lsof failed */
|
/* lsof not installed, lsof failed */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
#if __linux__
|
void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
|
||||||
readFileRoots("/proc/sys/kernel/modprobe", unchecked);
|
{
|
||||||
readFileRoots("/proc/sys/kernel/fbsplash", unchecked);
|
UncheckedRoots unchecked;
|
||||||
readFileRoots("/proc/sys/kernel/poweroff_cmd", unchecked);
|
|
||||||
#endif
|
findPlatformRoots(unchecked);
|
||||||
|
|
||||||
for (auto & [target, links] : unchecked) {
|
for (auto & [target, links] : unchecked) {
|
||||||
if (!isInStore(target)) continue;
|
if (!isInStore(target)) continue;
|
||||||
|
|
|
@ -1940,6 +1940,4 @@ std::optional<std::string> LocalStore::getVersion()
|
||||||
return nixVersion;
|
return nixVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterStoreImplementation<LocalStore, LocalStoreConfig> regLocalStore;
|
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|
|
@ -127,6 +127,17 @@ private:
|
||||||
|
|
||||||
const PublicKeys & getPublicKeys();
|
const PublicKeys & getPublicKeys();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the local store, upgrading the schema if
|
||||||
|
* necessary.
|
||||||
|
* Protected so that users don't accidentally create a LocalStore
|
||||||
|
* instead of a platform's subclass.
|
||||||
|
*/
|
||||||
|
LocalStore(const Params & params);
|
||||||
|
LocalStore(std::string scheme, std::string path, const Params & params);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,18 +145,16 @@ public:
|
||||||
*/
|
*/
|
||||||
PathSet locksHeld;
|
PathSet locksHeld;
|
||||||
|
|
||||||
/**
|
virtual ~LocalStore();
|
||||||
* Initialise the local store, upgrading the schema if
|
|
||||||
* necessary.
|
|
||||||
*/
|
|
||||||
LocalStore(const Params & params);
|
|
||||||
LocalStore(std::string scheme, std::string path, const Params & params);
|
|
||||||
|
|
||||||
~LocalStore();
|
|
||||||
|
|
||||||
static std::set<std::string> uriSchemes()
|
static std::set<std::string> uriSchemes()
|
||||||
{ return {}; }
|
{ return {}; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a LocalStore, possibly a platform-specific subclass
|
||||||
|
*/
|
||||||
|
static std::shared_ptr<LocalStore> makeLocalStore(const Params & params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementations of abstract store API methods.
|
* Implementations of abstract store API methods.
|
||||||
*/
|
*/
|
||||||
|
@ -330,6 +339,12 @@ private:
|
||||||
|
|
||||||
void findRootsNoTemp(Roots & roots, bool censor);
|
void findRootsNoTemp(Roots & roots, bool censor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find possible garbage collector roots in a platform-specific manner,
|
||||||
|
* e.g. by looking in `/proc` or using `lsof`
|
||||||
|
*/
|
||||||
|
virtual void findPlatformRoots(UncheckedRoots & unchecked);
|
||||||
|
|
||||||
void findRuntimeRoots(Roots & roots, bool censor);
|
void findRuntimeRoots(Roots & roots, bool censor);
|
||||||
|
|
||||||
std::pair<Path, AutoCloseFD> createTempDirInStore();
|
std::pair<Path, AutoCloseFD> createTempDirInStore();
|
||||||
|
|
|
@ -5,6 +5,11 @@ libstore_NAME = libnixstore
|
||||||
libstore_DIR := $(d)
|
libstore_DIR := $(d)
|
||||||
|
|
||||||
libstore_SOURCES := $(wildcard $(d)/*.cc $(d)/builtins/*.cc $(d)/build/*.cc)
|
libstore_SOURCES := $(wildcard $(d)/*.cc $(d)/builtins/*.cc $(d)/build/*.cc)
|
||||||
|
ifdef HOST_LINUX
|
||||||
|
libstore_SOURCES += $(d)/platform/linux.cc
|
||||||
|
else
|
||||||
|
libstore_SOURCES += $(d)/platform/fallback.cc
|
||||||
|
endif
|
||||||
|
|
||||||
libstore_LIBS = libutil
|
libstore_LIBS = libutil
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ libstore_sources = files(
|
||||||
'path-with-outputs.cc',
|
'path-with-outputs.cc',
|
||||||
'path.cc',
|
'path.cc',
|
||||||
'pathlocks.cc',
|
'pathlocks.cc',
|
||||||
|
'platform.cc',
|
||||||
'profiles.cc',
|
'profiles.cc',
|
||||||
'realisation.cc',
|
'realisation.cc',
|
||||||
'remote-fs-accessor.cc',
|
'remote-fs-accessor.cc',
|
||||||
|
@ -158,6 +159,14 @@ libstore_headers = files(
|
||||||
'worker-protocol.hh',
|
'worker-protocol.hh',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if host_machine.system() == 'linux'
|
||||||
|
libstore_sources += files('platform/linux.cc')
|
||||||
|
libstore_headers += files('platform/linux.hh')
|
||||||
|
else
|
||||||
|
libstore_sources += files('platform/fallback.cc')
|
||||||
|
libstore_headers += files('platform/fallback.hh')
|
||||||
|
endif
|
||||||
|
|
||||||
# These variables (aside from LSOF) are created pseudo-dynamically, near the beginning of
|
# These variables (aside from LSOF) are created pseudo-dynamically, near the beginning of
|
||||||
# the top-level meson.build. Aside from prefix itself, each of these was
|
# the top-level meson.build. Aside from prefix itself, each of these was
|
||||||
# made into an absolute path by joining it with prefix, unless it was already
|
# made into an absolute path by joining it with prefix, unless it was already
|
||||||
|
|
18
src/libstore/platform.cc
Normal file
18
src/libstore/platform.cc
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include "local-store.hh"
|
||||||
|
|
||||||
|
#if __linux__
|
||||||
|
#include "platform/linux.hh"
|
||||||
|
#else
|
||||||
|
#include "platform/fallback.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
std::shared_ptr<LocalStore> LocalStore::makeLocalStore(const Params & params)
|
||||||
|
{
|
||||||
|
#if __linux__
|
||||||
|
return std::shared_ptr<LocalStore>(new LinuxLocalStore(params));
|
||||||
|
#else
|
||||||
|
return std::shared_ptr<LocalStore>(new FallbackLocalStore(params));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
5
src/libstore/platform/fallback.cc
Normal file
5
src/libstore/platform/fallback.cc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include "platform/fallback.hh"
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
static RegisterStoreImplementation<FallbackLocalStore, LocalStoreConfig> regLocalStore;
|
||||||
|
}
|
31
src/libstore/platform/fallback.hh
Normal file
31
src/libstore/platform/fallback.hh
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
///@file
|
||||||
|
|
||||||
|
#include "local-store.hh"
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback platform implementation of LocalStore
|
||||||
|
* Exists so we can make LocalStore constructor protected
|
||||||
|
*/
|
||||||
|
class FallbackLocalStore : public LocalStore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FallbackLocalStore(const Params & params)
|
||||||
|
: StoreConfig(params)
|
||||||
|
, LocalFSStoreConfig(params)
|
||||||
|
, LocalStoreConfig(params)
|
||||||
|
, Store(params)
|
||||||
|
, LocalFSStore(params)
|
||||||
|
, LocalStore(params)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
FallbackLocalStore(const std::string scheme, std::string path, const Params & params)
|
||||||
|
: FallbackLocalStore(params)
|
||||||
|
{
|
||||||
|
throw UnimplementedError("FallbackLocalStore");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
123
src/libstore/platform/linux.cc
Normal file
123
src/libstore/platform/linux.cc
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
#include "gc-store.hh"
|
||||||
|
#include "signals.hh"
|
||||||
|
#include "platform/linux.hh"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
static RegisterStoreImplementation<LinuxLocalStore, LocalStoreConfig> regLocalStore;
|
||||||
|
|
||||||
|
static void readProcLink(const std::string & file, UncheckedRoots & roots)
|
||||||
|
{
|
||||||
|
constexpr auto bufsiz = PATH_MAX;
|
||||||
|
char buf[bufsiz];
|
||||||
|
auto res = readlink(file.c_str(), buf, bufsiz);
|
||||||
|
if (res == -1) {
|
||||||
|
if (errno == ENOENT || errno == EACCES || errno == ESRCH) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw SysError("reading symlink");
|
||||||
|
}
|
||||||
|
if (res == bufsiz) {
|
||||||
|
throw Error("overly long symlink starting with '%1%'", std::string_view(buf, bufsiz));
|
||||||
|
}
|
||||||
|
if (res > 0 && buf[0] == '/') {
|
||||||
|
roots[std::string(static_cast<char *>(buf), res)].emplace(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string quoteRegexChars(const std::string & raw)
|
||||||
|
{
|
||||||
|
static auto specialRegex = std::regex(R"([.^$\\*+?()\[\]{}|])");
|
||||||
|
return std::regex_replace(raw, specialRegex, R"(\$&)");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void readFileRoots(const char * path, UncheckedRoots & roots)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
roots[readFile(path)].emplace(path);
|
||||||
|
} catch (SysError & e) {
|
||||||
|
if (e.errNo != ENOENT && e.errNo != EACCES) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxLocalStore::findPlatformRoots(UncheckedRoots & unchecked)
|
||||||
|
{
|
||||||
|
auto procDir = AutoCloseDir{opendir("/proc")};
|
||||||
|
if (procDir) {
|
||||||
|
struct dirent * ent;
|
||||||
|
auto digitsRegex = std::regex(R"(^\d+$)");
|
||||||
|
auto mapRegex = std::regex(R"(^\s*\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(/\S+)\s*$)");
|
||||||
|
auto storePathRegex =
|
||||||
|
std::regex(quoteRegexChars(storeDir) + R"(/[0-9a-z]+[0-9a-zA-Z\+\-\._\?=]*)");
|
||||||
|
while (errno = 0, ent = readdir(procDir.get())) {
|
||||||
|
checkInterrupt();
|
||||||
|
if (std::regex_match(ent->d_name, digitsRegex)) {
|
||||||
|
try {
|
||||||
|
readProcLink(fmt("/proc/%s/exe", ent->d_name), unchecked);
|
||||||
|
readProcLink(fmt("/proc/%s/cwd", ent->d_name), unchecked);
|
||||||
|
|
||||||
|
auto fdStr = fmt("/proc/%s/fd", ent->d_name);
|
||||||
|
auto fdDir = AutoCloseDir(opendir(fdStr.c_str()));
|
||||||
|
if (!fdDir) {
|
||||||
|
if (errno == ENOENT || errno == EACCES) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw SysError("opening %1%", fdStr);
|
||||||
|
}
|
||||||
|
struct dirent * fd_ent;
|
||||||
|
while (errno = 0, fd_ent = readdir(fdDir.get())) {
|
||||||
|
if (fd_ent->d_name[0] != '.') {
|
||||||
|
readProcLink(fmt("%s/%s", fdStr, fd_ent->d_name), unchecked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errno) {
|
||||||
|
if (errno == ESRCH) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw SysError("iterating /proc/%1%/fd", ent->d_name);
|
||||||
|
}
|
||||||
|
fdDir.reset();
|
||||||
|
|
||||||
|
auto mapFile = fmt("/proc/%s/maps", ent->d_name);
|
||||||
|
auto mapLines =
|
||||||
|
tokenizeString<std::vector<std::string>>(readFile(mapFile), "\n");
|
||||||
|
for (const auto & line : mapLines) {
|
||||||
|
auto match = std::smatch{};
|
||||||
|
if (std::regex_match(line, match, mapRegex)) {
|
||||||
|
unchecked[match[1]].emplace(mapFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto envFile = fmt("/proc/%s/environ", ent->d_name);
|
||||||
|
auto envString = readFile(envFile);
|
||||||
|
auto env_end = std::sregex_iterator{};
|
||||||
|
for (auto i =
|
||||||
|
std::sregex_iterator{
|
||||||
|
envString.begin(), envString.end(), storePathRegex
|
||||||
|
};
|
||||||
|
i != env_end;
|
||||||
|
++i)
|
||||||
|
{
|
||||||
|
unchecked[i->str()].emplace(envFile);
|
||||||
|
}
|
||||||
|
} catch (SysError & e) {
|
||||||
|
if (errno == ENOENT || errno == EACCES || errno == ESRCH) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errno) {
|
||||||
|
throw SysError("iterating /proc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readFileRoots("/proc/sys/kernel/modprobe", unchecked);
|
||||||
|
readFileRoots("/proc/sys/kernel/fbsplash", unchecked);
|
||||||
|
readFileRoots("/proc/sys/kernel/poweroff_cmd", unchecked);
|
||||||
|
}
|
||||||
|
}
|
35
src/libstore/platform/linux.hh
Normal file
35
src/libstore/platform/linux.hh
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
///@file
|
||||||
|
|
||||||
|
#include "gc-store.hh"
|
||||||
|
#include "local-store.hh"
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linux-specific implementation of LocalStore
|
||||||
|
*/
|
||||||
|
class LinuxLocalStore : public LocalStore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LinuxLocalStore(const Params & params)
|
||||||
|
: StoreConfig(params)
|
||||||
|
, LocalFSStoreConfig(params)
|
||||||
|
, LocalStoreConfig(params)
|
||||||
|
, Store(params)
|
||||||
|
, LocalFSStore(params)
|
||||||
|
, LocalStore(params)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
LinuxLocalStore(const std::string scheme, std::string path, const Params & params)
|
||||||
|
: LinuxLocalStore(params)
|
||||||
|
{
|
||||||
|
throw UnimplementedError("LinuxLocalStore");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void findPlatformRoots(UncheckedRoots & unchecked) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1426,7 +1426,7 @@ std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Para
|
||||||
if (uri == "" || uri == "auto") {
|
if (uri == "" || uri == "auto") {
|
||||||
auto stateDir = getOr(params, "state", settings.nixStateDir);
|
auto stateDir = getOr(params, "state", settings.nixStateDir);
|
||||||
if (access(stateDir.c_str(), R_OK | W_OK) == 0)
|
if (access(stateDir.c_str(), R_OK | W_OK) == 0)
|
||||||
return std::make_shared<LocalStore>(params);
|
return LocalStore::makeLocalStore(params);
|
||||||
else if (pathExists(settings.nixDaemonSocketFile))
|
else if (pathExists(settings.nixDaemonSocketFile))
|
||||||
return std::make_shared<UDSRemoteStore>(params);
|
return std::make_shared<UDSRemoteStore>(params);
|
||||||
#if __linux__
|
#if __linux__
|
||||||
|
@ -1444,26 +1444,26 @@ std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Para
|
||||||
try {
|
try {
|
||||||
createDirs(chrootStore);
|
createDirs(chrootStore);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
return std::make_shared<LocalStore>(params);
|
return LocalStore::makeLocalStore(params);
|
||||||
}
|
}
|
||||||
warn("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
|
warn("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
|
||||||
} else
|
} else
|
||||||
debug("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
|
debug("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
|
||||||
Store::Params params2;
|
Store::Params params2;
|
||||||
params2["root"] = chrootStore;
|
params2["root"] = chrootStore;
|
||||||
return std::make_shared<LocalStore>(params2);
|
return LocalStore::makeLocalStore(params);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
return std::make_shared<LocalStore>(params);
|
return LocalStore::makeLocalStore(params);
|
||||||
} else if (uri == "daemon") {
|
} else if (uri == "daemon") {
|
||||||
return std::make_shared<UDSRemoteStore>(params);
|
return std::make_shared<UDSRemoteStore>(params);
|
||||||
} else if (uri == "local") {
|
} else if (uri == "local") {
|
||||||
return std::make_shared<LocalStore>(params);
|
return LocalStore::makeLocalStore(params);
|
||||||
} else if (isNonUriPath(uri)) {
|
} else if (isNonUriPath(uri)) {
|
||||||
Store::Params params2 = params;
|
Store::Params params2 = params;
|
||||||
params2["root"] = absPath(uri);
|
params2["root"] = absPath(uri);
|
||||||
return std::make_shared<LocalStore>(params2);
|
return LocalStore::makeLocalStore(params2);
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue