1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-25 19:51:00 +01:00

* Lock the Nix store during upgrades.

This commit is contained in:
Eelco Dolstra 2008-03-08 23:47:05 +00:00
parent 4df6dc28c3
commit 341b2de643
5 changed files with 53 additions and 26 deletions

View file

@ -2,7 +2,6 @@
#include "misc.hh" #include "misc.hh"
#include "pathlocks.hh" #include "pathlocks.hh"
#include "local-store.hh" #include "local-store.hh"
#include "util.hh"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>

View file

@ -1,6 +1,5 @@
#include "config.h" #include "config.h"
#include "local-store.hh" #include "local-store.hh"
#include "util.hh"
#include "globals.hh" #include "globals.hh"
#include "archive.hh" #include "archive.hh"
#include "pathlocks.hh" #include "pathlocks.hh"
@ -43,40 +42,37 @@ LocalStore::LocalStore()
{ {
substitutablePathsLoaded = false; substitutablePathsLoaded = false;
schemaPath = nixDBPath + "/schema";
if (readOnlyMode) return; if (readOnlyMode) return;
checkStoreNotSymlink(); checkStoreNotSymlink();
try { Path globalLockPath = nixDBPath + "/big-lock";
createDirs(nixDBPath + "/info"); globalLock = open(globalLockPath.c_str(), O_RDWR | O_CREAT, 0666);
createDirs(nixDBPath + "/referrer"); if (globalLock == -1) throw SysError(format("opening file `%1%'") % globalLockPath);
} catch (Error & e) {
// !!! fix access check
printMsg(lvlTalkative, "cannot access Nix database; continuing anyway");
readOnlyMode = true;
return;
}
int curSchema = 0; if (!lockFile(globalLock, ltRead, false)) {
Path schemaFN = nixDBPath + "/schema"; printMsg(lvlError, "waiting for the big Nix store lock...");
if (pathExists(schemaFN)) { lockFile(globalLock, ltRead, true);
string s = readFile(schemaFN);
if (!string2Int(s, curSchema))
throw Error(format("`%1%' is corrupt") % schemaFN);
} }
createDirs(nixDBPath + "/info");
createDirs(nixDBPath + "/referrer");
//printMsg(lvlTalkative, "cannot access Nix database; continuing anyway");
//readOnlyMode = true;
int curSchema = getSchema();
if (curSchema > nixSchemaVersion) if (curSchema > nixSchemaVersion)
throw Error(format("current Nix store schema is version %1%, but I only support %2%") throw Error(format("current Nix store schema is version %1%, but I only support %2%")
% curSchema % nixSchemaVersion); % curSchema % nixSchemaVersion);
if (curSchema == 0) { /* new store */
if (curSchema < nixSchemaVersion) { curSchema = nixSchemaVersion;
if (curSchema == 0) /* new store */ writeFile(schemaPath, (format("%1%") % nixSchemaVersion).str());
curSchema = nixSchemaVersion;
if (curSchema <= 1)
throw Error("your Nix store is no longer supported");
if (curSchema <= 4) upgradeStore12();
writeFile(schemaFN, (format("%1%") % nixSchemaVersion).str());
} }
if (curSchema == 1) throw Error("your Nix store is no longer supported");
if (curSchema < nixSchemaVersion) upgradeStore12();
} }
@ -90,6 +86,18 @@ LocalStore::~LocalStore()
} }
int LocalStore::getSchema()
{
int curSchema = 0;
if (pathExists(schemaPath)) {
string s = readFile(schemaPath);
if (!string2Int(s, curSchema))
throw Error(format("`%1%' is corrupt") % schemaPath);
}
return curSchema;
}
void copyPath(const Path & src, const Path & dst, PathFilter & filter) void copyPath(const Path & src, const Path & dst, PathFilter & filter)
{ {
debug(format("copying `%1%' to `%2%'") % src % dst); debug(format("copying `%1%' to `%2%'") % src % dst);

View file

@ -4,6 +4,7 @@
#include <string> #include <string>
#include "store-api.hh" #include "store-api.hh"
#include "util.hh"
namespace nix { namespace nix {
@ -114,6 +115,11 @@ public:
private: private:
Path schemaPath;
/* Lock file used for upgrading. */
AutoCloseFD globalLock;
/* !!! The cache can grow very big. Maybe it should be pruned /* !!! The cache can grow very big. Maybe it should be pruned
every once in a while. */ every once in a while. */
std::map<Path, ValidPathInfo> pathInfoCache; std::map<Path, ValidPathInfo> pathInfoCache;
@ -121,6 +127,8 @@ private:
/* Store paths for which the referrers file must be purged. */ /* Store paths for which the referrers file must be purged. */
PathSet delayedUpdates; PathSet delayedUpdates;
int getSchema();
void registerValidPath(const ValidPathInfo & info, bool ignoreValidity = false); void registerValidPath(const ValidPathInfo & info, bool ignoreValidity = false);
ValidPathInfo queryPathInfo(const Path & path); ValidPathInfo queryPathInfo(const Path & path);

View file

@ -1,5 +1,5 @@
#include "local-store.hh"
#include "util.hh" #include "util.hh"
#include "local-store.hh"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>

View file

@ -3,6 +3,7 @@
#include "util.hh" #include "util.hh"
#include "local-store.hh" #include "local-store.hh"
#include "globals.hh" #include "globals.hh"
#include "pathlocks.hh"
#include <iostream> #include <iostream>
@ -18,8 +19,15 @@ Hash parseHashField(const Path & path, const string & s);
meta-information in files. */ meta-information in files. */
void LocalStore::upgradeStore12() void LocalStore::upgradeStore12()
{ {
if (!lockFile(globalLock, ltWrite, false)) {
printMsg(lvlError, "waiting for exclusive access to the Nix store...");
lockFile(globalLock, ltWrite, true);
}
printMsg(lvlError, "upgrading Nix store to new schema (this may take a while)..."); printMsg(lvlError, "upgrading Nix store to new schema (this may take a while)...");
if (getSchema() >= nixSchemaVersion) return; /* somebody else beat us to it */
/* Open the old Nix database and tables. */ /* Open the old Nix database and tables. */
Database nixDB; Database nixDB;
nixDB.open(nixDBPath); nixDB.open(nixDBPath);
@ -76,6 +84,10 @@ void LocalStore::upgradeStore12()
} }
std::cerr << std::endl; std::cerr << std::endl;
writeFile(schemaPath, (format("%1%") % nixSchemaVersion).str());
lockFile(globalLock, ltRead, true);
} }