Check that overlay store directory is mounted correctly.

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.
This commit is contained in:
Ben Radford 2023-05-15 10:20:16 +01:00 committed by Ben Radford
parent 4173743a3c
commit b5591ece4c
2 changed files with 30 additions and 0 deletions

View file

@ -1,5 +1,6 @@
#include "local-overlay-store.hh" #include "local-overlay-store.hh"
#include "callback.hh" #include "callback.hh"
#include <regex>
namespace nix { namespace nix {
@ -17,6 +18,32 @@ LocalOverlayStore::LocalOverlayStore(const Params & params)
, LocalStore(params) , LocalStore(params)
, lowerStore(openStore(lowerStoreUri).dynamic_pointer_cast<LocalFSStore>()) , lowerStore(openStore(lowerStoreUri).dynamic_pointer_cast<LocalFSStore>())
{ {
if (checkMount.get()) {
std::smatch match;
std::string mountInfo;
auto mounts = readFile("/proc/self/mounts");
auto regex = std::regex(R"((^|\n)overlay )" + realStoreDir.get() + R"( .*(\n|$))");
// Mount points can be stacked, so there might be multiple matching entries.
// Loop until the last match, which will be the current state of the mount point.
while (std::regex_search(mounts, match, regex)) {
mountInfo = match.str();
mounts = match.suffix();
}
auto checkOption = [&](std::string option, std::string value) {
return std::regex_search(mountInfo, std::regex("\\b" + option + "=" + value + "( |,)"));
};
auto expectedLowerDir = lowerStore->realStoreDir.get();
if (!checkOption("lowerdir", expectedLowerDir) || !checkOption("upperdir", upperLayer)) {
debug("expected lowerdir: %s", expectedLowerDir);
debug("expected upperdir: %s", upperLayer);
debug("actual mount: %s", mountInfo);
throw Error("overlay filesystem '%s' mounted incorrectly",
realStoreDir.get());
}
}
} }

View file

@ -30,6 +30,9 @@ struct LocalOverlayStoreConfig : virtual LocalStoreConfig
Must be used as OverlayFS upper layer for this store's store dir. Must be used as OverlayFS upper layer for this store's store dir.
)"}; )"};
Setting<bool> checkMount{(StoreConfig*) this, true, "check-mount",
"Check that the overlay filesystem is correctly mounted."};
const std::string name() override { return "Experimental Local Overlay Store"; } const std::string name() override { return "Experimental Local Overlay Store"; }
std::string doc() override std::string doc() override