diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 172fa1ef0..1e6b396a9 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -363,7 +363,7 @@ LocalStore::LocalStore(const Params & params) if (!readOnly) { migrateCASchema(state->db, dbDir + "/ca-schema", globalLock); } else { - throw Error("need to migrate to CA schema, but this cannot be done in read-only mode"); + throw Error("need to migrate to content-addressed schema, but this cannot be done in read-only mode"); } } @@ -502,7 +502,7 @@ int LocalStore::getSchema() void LocalStore::openDB(State & state, bool create) { if (create && readOnly) { - throw Error("unable to create database while in read-only mode"); + throw Error("cannot create database while in read-only mode"); } if (access(dbDir.c_str(), R_OK | (readOnly ? 0 : W_OK))) diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index fcddffa82..a36ae162a 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -50,16 +50,16 @@ struct LocalStoreConfig : virtual LocalFSStoreConfig false, "read-only", R"( - Allow this store to be opened when its database is on a read-only filesystem. + Allow this store to be opened when its [database](@docroot@/glossary.md#gloss-nix-database) is on a read-only filesystem. - Normally Nix will attempt to open the store database in read-write mode, even - for querying (when write access is not needed). This causes it to fail if the - database is on a read-only filesystem. + Normally Nix will attempt to open the store database in read-write mode, even for querying (when write access is not needed). + This causes it to fail if the database is on a read-only filesystem. - Enable read-only mode to disable locking and open the SQLite database with the - **immutable** parameter set. Do not use this unless the filesystem is read-only. - Using it when the filesystem is writable can cause incorrect query results or - corruption errors if the database is changed by another process. + Enable read-only mode to disable locking and open the SQLite database with the [`immutable` parameter](https://www.sqlite.org/c3ref/open.html) set. + + **Warning** + Do not use this unless the filesystem is read-only. + Using it when the filesystem is writable can cause incorrect query results or corruption errors if the database is changed by another process. )"}; const std::string name() override { return "Local Store"; } @@ -292,6 +292,10 @@ public: private: + /** + * Retrieve the current version of the database schema. + * If the database does not exist yet, the version returned will be 0. + */ int getSchema(); void openDB(State & state, bool create); diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc index d30634b95..7c2b29a07 100644 --- a/src/libutil/experimental-features.cc +++ b/src/libutil/experimental-features.cc @@ -227,14 +227,13 @@ constexpr std::array xpFeatureDetails = {{ .description = R"( Allow the use of the `read-only` parameter in local store URIs. - Set this parameter to `true` to allow stores with databases on read-only - filesystems to be opened for querying; ordinarily Nix will refuse to do this. + Set this parameter to `true` to allow stores with databases on read-only filesystems to be opened for querying; ordinarily Nix will refuse to do this. - Enabling this setting disables the locking required for safe concurrent - access, so you should be certain that the database will not be changed. - While the filesystem the database resides on might be read-only to this - process, consider whether another user, process, or system, might have - write access to it. + This is because SQLite requires write access to the database file to perform the file locking operations necessary for safe concurrent access. + When `read-only` is set to `true`, the database will be opened in immutable mode. + + Under this mode, SQLite will not do any locking at all, so you should be certain that the database will not be changed. + While the filesystem the database resides on might be read-only to this process, consider whether another user, process, or system, might have write access to it. )", }, }}; diff --git a/tests/read-only-store.sh b/tests/read-only-store.sh index 2f89b849f..d63920c19 100644 --- a/tests/read-only-store.sh +++ b/tests/read-only-store.sh @@ -2,6 +2,8 @@ source common.sh enableFeatures "read-only-local-store" +needLocalStore "cannot open store read-only when daemon has already opened it writeable" + clearStore happy () {