summaryrefslogtreecommitdiff
path: root/nix
diff options
context:
space:
mode:
authorRutherther <rutherther@ditigal.xyz>2025-12-21 13:25:59 +0100
committerRutherther <rutherther@ditigal.xyz>2025-12-22 11:00:17 +0100
commit2a0ac4cba5e3816e203b412934ee66345667c5ca (patch)
tree4c687744f286d99186663b52f828f0fd6e9d48bd /nix
parent09eda1627e41bfdf966539c80a260bce6307e57c (diff)
daemon: Ensure store is writable even as non-root.
If the store is read only, return an error early. This is bit of a compromise. Not all operations of the daemon need the store as writable. For example, if hello package is built already `guix build hello` could previously succeed even if store is RO. * nix/libstore/local-store.cc (makeStoreWritable): Rename to ensureStoreWritable. (ensureStoreWritable): As non-root, check that the store is writable and if not, throw an error. (LocalStore::LocalStore): Use it. * nix/libstore/local-store.hh: Rename makeStoreWritable to ensureStoreWritable. Change-Id: I94783ba7e32d57bfa77e37e84b6ac316f95e31e2 Signed-off-by: Rutherther <rutherther@ditigal.xyz>
Diffstat (limited to 'nix')
-rw-r--r--nix/libstore/local-store.cc18
-rw-r--r--nix/libstore/local-store.hh2
2 files changed, 14 insertions, 6 deletions
diff --git a/nix/libstore/local-store.cc b/nix/libstore/local-store.cc
index 161c8d81bda..43f3c1770a8 100644
--- a/nix/libstore/local-store.cc
+++ b/nix/libstore/local-store.cc
@@ -67,7 +67,7 @@ LocalStore::LocalStore(bool reserveSpace)
/* Create missing state directories if they don't already exist. */
createDirs(settings.nixStore);
- makeStoreWritable();
+ ensureStoreWritable();
createDirs(linksDir = settings.nixStore + "/.links");
Path profilesDir = settings.nixStateDir + "/profiles";
createDirs(profilesDir);
@@ -300,18 +300,26 @@ void LocalStore::openDB(bool create)
}
-/* To improve purity, users may want to make the store a read-only
- bind mount. So make the store writable for this process. */
-void LocalStore::makeStoreWritable()
+/* To improve purity, users may want to make the store a read-only bind mount.
+ So make the store writable for this process. In case the store is read-only
+ and cannot be made writable, throw an error. */
+void LocalStore::ensureStoreWritable()
{
#if HAVE_UNSHARE && HAVE_STATVFS && HAVE_SYS_MOUNT_H && defined(MS_BIND) && defined(MS_REMOUNT)
- if (getuid() != 0) return;
/* Check if /nix/store is on a read-only mount. */
struct statvfs stat;
if (statvfs(settings.nixStore.c_str(), &stat) != 0)
throw SysError("getting info about the store mount point");
if (stat.f_flag & ST_RDONLY) {
+ if (getuid() != 0) {
+ throw Error(
+ std::format(
+ "'{}' is read-only; make sure to mount it read-write "
+ "for proper guix-daemon operation",
+ settings.nixStore));
+ }
+
if (unshare(CLONE_NEWNS) == -1)
throw SysError("setting up a private mount namespace");
diff --git a/nix/libstore/local-store.hh b/nix/libstore/local-store.hh
index 4d529b37a44..23af8c3f029 100644
--- a/nix/libstore/local-store.hh
+++ b/nix/libstore/local-store.hh
@@ -212,7 +212,7 @@ private:
void openDB(bool create);
- void makeStoreWritable();
+ void ensureStoreWritable();
uint64_t queryValidPathId(const Path & path);