Skip to content
This repository
Browse code

makeStoreWritable: Use statvfs instead of /proc/self/mountinfo to fin…

…d out if /nix/store is a read-only bind mount

/nix/store could be a read-only bind mount even if it is / in its own filesystem, so checking the 4th field in mountinfo is insufficient.

Signed-off-by: Shea Levy <shea@shealevy.com>
  • Loading branch information...
commit 2c9cf5074642459b37f19a2d4c6bc0233248d3a4 1 parent c3fc60d
Shea Levy shlevy authored edolstra committed

Showing 2 changed files with 13 additions and 21 deletions. Show diff stats Hide diff stats

  1. +1 0  configure.ac
  2. +12 21 src/libstore/local-store.cc
1  configure.ac
@@ -106,6 +106,7 @@ AC_LANG_POP(C++)
106 106 # Check for chroot support (requires chroot() and bind mounts).
107 107 AC_CHECK_FUNCS([chroot])
108 108 AC_CHECK_FUNCS([unshare])
  109 +AC_CHECK_FUNCS([statvfs])
109 110 AC_CHECK_HEADERS([sched.h])
110 111 AC_CHECK_HEADERS([sys/param.h])
111 112 AC_CHECK_HEADERS([sys/mount.h], [], [],
33 src/libstore/local-store.cc
@@ -19,8 +19,9 @@
19 19 #include <stdio.h>
20 20 #include <time.h>
21 21
22   -#if HAVE_UNSHARE
  22 +#if HAVE_UNSHARE && HAVE_STATVFS && HAVE_SYS_MOUNT_H
23 23 #include <sched.h>
  24 +#include <sys/statvfs.h>
24 25 #include <sys/mount.h>
25 26 #endif
26 27
@@ -434,30 +435,20 @@ void LocalStore::openDB(bool create)
434 435 bind mount. So make the Nix store writable for this process. */
435 436 void LocalStore::makeStoreWritable()
436 437 {
437   -#if HAVE_UNSHARE
  438 +#if HAVE_UNSHARE && HAVE_STATVFS && HAVE_SYS_MOUNT_H && defined(MS_BIND) && defined(MS_REMOUNT)
438 439 if (getuid() != 0) return;
439   -
440   - if (!pathExists("/proc/self/mountinfo")) return;
441   -
442 440 /* Check if /nix/store is a read-only bind mount. */
443   - bool found = false;
444   - Strings mounts = tokenizeString<Strings>(readFile("/proc/self/mountinfo", true), "\n");
445   - foreach (Strings::iterator, i, mounts) {
446   - vector<string> fields = tokenizeString<vector<string> >(*i, " ");
447   - if (fields.at(3) == "/" || fields.at(4) != settings.nixStore) continue;
448   - Strings options = tokenizeString<Strings>(fields.at(5), ",");
449   - if (std::find(options.begin(), options.end(), "ro") == options.end()) continue;
450   - found = true;
451   - break;
452   - }
  441 + struct statvfs stat;
  442 + if (statvfs(settings.nixStore.c_str(), &stat) !=0)
  443 + throw SysError("Getting info of nix store mountpoint");
453 444
454   - if (!found) return;
  445 + if (stat.f_flag & (ST_RDONLY | MS_BIND)) {
  446 + if (unshare(CLONE_NEWNS) == -1)
  447 + throw SysError("setting up a private mount namespace");
455 448
456   - if (unshare(CLONE_NEWNS) == -1)
457   - throw SysError("setting up a private mount namespace");
458   -
459   - if (mount(0, settings.nixStore.c_str(), 0, MS_REMOUNT | MS_BIND, 0) == -1)
460   - throw SysError(format("remounting %1% writable") % settings.nixStore);
  449 + if (mount(0, settings.nixStore.c_str(), 0, MS_REMOUNT | MS_BIND, 0) == -1)
  450 + throw SysError(format("remounting %1% writable") % settings.nixStore);
  451 + }
461 452 #endif
462 453 }
463 454

0 comments on commit 2c9cf50

Please sign in to comment.
Something went wrong with that request. Please try again.