2023-05-08 17:20:06 +03:00
|
|
|
#include "local-store.hh"
|
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configuration for `LocalOverlayStore`.
|
|
|
|
*/
|
|
|
|
struct LocalOverlayStoreConfig : virtual LocalStoreConfig
|
|
|
|
{
|
|
|
|
// FIXME why doesn't this work?
|
|
|
|
// using LocalStoreConfig::LocalStoreConfig;
|
|
|
|
|
|
|
|
LocalOverlayStoreConfig(const StringMap & params)
|
|
|
|
: StoreConfig(params)
|
|
|
|
, LocalFSStoreConfig(params)
|
|
|
|
, LocalStoreConfig(params)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
const Setting<std::string> lowerStoreUri{(StoreConfig*) this, "", "lower-store",
|
|
|
|
R"(
|
|
|
|
[Store URL](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format)
|
|
|
|
for the lower store. The default is `auto` (i.e. use the Nix daemon or `/nix/store` directly).
|
|
|
|
|
|
|
|
Must be a store with a store dir on the file system.
|
2023-05-09 01:50:16 +03:00
|
|
|
Must be used as OverlayFS lower layer for this store's store dir.
|
|
|
|
)"};
|
|
|
|
|
2023-07-10 04:53:06 +03:00
|
|
|
const PathSetting upperLayer{(StoreConfig*) this, "", "upper-layer",
|
2023-05-09 01:50:16 +03:00
|
|
|
R"(
|
|
|
|
Must be used as OverlayFS upper layer for this store's store dir.
|
2023-05-08 17:20:06 +03:00
|
|
|
)"};
|
|
|
|
|
2023-05-15 12:20:16 +03:00
|
|
|
Setting<bool> checkMount{(StoreConfig*) this, true, "check-mount",
|
2023-05-16 15:10:25 +03:00
|
|
|
R"(
|
|
|
|
Check that the overlay filesystem is correctly mounted.
|
|
|
|
|
|
|
|
Nix does not manage the overlayfs mount point itself, but the correct
|
|
|
|
functioning of the overlay store does depend on this mount point being set up
|
|
|
|
correctly. Rather than just assume this is the case, check that the lowerdir
|
|
|
|
and upperdir options are what we expect them to be. This check is on by
|
|
|
|
default, but can be disabled if needed.
|
|
|
|
)"};
|
2023-05-15 12:20:16 +03:00
|
|
|
|
2023-07-26 13:31:26 +03:00
|
|
|
const PathSetting remountHook{(StoreConfig*) this, "", "remount-hook",
|
|
|
|
R"(
|
|
|
|
Script or program to run when overlay filesystem needs remounting.
|
|
|
|
|
|
|
|
TODO: Document this in more detail.
|
|
|
|
)"};
|
|
|
|
|
2023-05-08 17:20:06 +03:00
|
|
|
const std::string name() override { return "Experimental Local Overlay Store"; }
|
|
|
|
|
|
|
|
std::string doc() override
|
|
|
|
{
|
|
|
|
return
|
|
|
|
""
|
|
|
|
// FIXME write docs
|
|
|
|
//#include "local-overlay-store.md"
|
|
|
|
;
|
|
|
|
}
|
2023-05-09 01:50:16 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a store path, get its location (if it is exists) in the
|
|
|
|
* upper layer of the overlayfs.
|
|
|
|
*/
|
|
|
|
Path toUpperPath(const StorePath & path);
|
2023-05-08 17:20:06 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Variation of local store using overlayfs for the store dir.
|
|
|
|
*/
|
|
|
|
class LocalOverlayStore : public virtual LocalOverlayStoreConfig, public virtual LocalStore
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* The store beneath us.
|
|
|
|
*
|
|
|
|
* Our store dir should be an overlay fs where the lower layer
|
|
|
|
* is that store's store dir, and the upper layer is some
|
|
|
|
* scratch storage just for us.
|
|
|
|
*/
|
|
|
|
ref<LocalFSStore> lowerStore;
|
|
|
|
|
|
|
|
public:
|
|
|
|
LocalOverlayStore(const Params & params);
|
|
|
|
|
|
|
|
LocalOverlayStore(std::string scheme, std::string path, const Params & params)
|
|
|
|
: LocalOverlayStore(params)
|
|
|
|
{
|
|
|
|
throw UnimplementedError("LocalOverlayStore");
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::set<std::string> uriSchemes()
|
|
|
|
{ return {}; }
|
|
|
|
|
|
|
|
std::string getUri() override
|
|
|
|
{
|
|
|
|
return "local-overlay";
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Overridden methods…
|
2023-05-08 23:48:55 +03:00
|
|
|
|
|
|
|
void registerDrvOutput(const Realisation & info) override;
|
2023-05-09 00:30:17 +03:00
|
|
|
|
|
|
|
void queryPathInfoUncached(const StorePath & path,
|
|
|
|
Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept override;
|
2023-05-09 01:50:16 +03:00
|
|
|
|
|
|
|
bool isValidPathUncached(const StorePath & path) override;
|
|
|
|
|
2023-05-10 00:20:58 +03:00
|
|
|
void queryReferrers(const StorePath & path, StorePathSet & referrers) override;
|
|
|
|
|
|
|
|
StorePathSet queryValidDerivers(const StorePath & path) override;
|
|
|
|
|
2023-05-09 17:40:10 +03:00
|
|
|
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override;
|
|
|
|
|
2023-05-09 17:22:38 +03:00
|
|
|
void registerValidPaths(const ValidPathInfos & infos) override;
|
|
|
|
|
2023-05-09 01:50:16 +03:00
|
|
|
void queryRealisationUncached(const DrvOutput&,
|
|
|
|
Callback<std::shared_ptr<const Realisation>> callback) noexcept override;
|
2023-05-24 13:26:33 +03:00
|
|
|
|
2023-07-26 16:05:54 +03:00
|
|
|
void collectGarbage(const GCOptions & options, GCResults & results) override;
|
|
|
|
|
2023-07-26 15:29:31 +03:00
|
|
|
void deleteStorePath(const Path & path, uint64_t & bytesFreed) override;
|
2023-07-18 15:49:13 +03:00
|
|
|
|
2023-07-18 15:59:22 +03:00
|
|
|
void optimiseStore() override;
|
2023-07-25 17:28:11 +03:00
|
|
|
|
2023-07-28 12:59:16 +03:00
|
|
|
bool verifyAllValidPaths(RepairFlag repair, StorePathSet & validPaths) override;
|
|
|
|
|
2023-07-26 00:09:23 +03:00
|
|
|
/**
|
|
|
|
* For lower-store paths, we used the lower store location. This avoids the
|
|
|
|
* wasteful "copying up" that would otherwise happen.
|
|
|
|
*/
|
2023-07-25 17:28:11 +03:00
|
|
|
Path toRealPathForHardLink(const StorePath & storePath) override;
|
2023-07-26 00:09:23 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Deletion only effects the upper layer, so we ignore lower-layer referrers.
|
|
|
|
*/
|
|
|
|
void queryGCReferrers(const StorePath & path, StorePathSet & referrers) override;
|
2023-07-26 19:01:08 +03:00
|
|
|
|
2023-07-26 16:05:54 +03:00
|
|
|
void remountIfNecessary();
|
|
|
|
|
2023-07-26 16:44:14 +03:00
|
|
|
std::atomic_bool _remountRequired = false;
|
2023-05-08 17:20:06 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|