* 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 "pathlocks.hh"
#include "local-store.hh"
#include "util.hh"
#include <boost/shared_ptr.hpp>

View file

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

View file

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

View file

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

View file

@ -3,6 +3,7 @@
#include "util.hh"
#include "local-store.hh"
#include "globals.hh"
#include "pathlocks.hh"
#include <iostream>
@ -18,8 +19,15 @@ Hash parseHashField(const Path & path, const string & s);
meta-information in files. */
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)...");
if (getSchema() >= nixSchemaVersion) return; /* somebody else beat us to it */
/* Open the old Nix database and tables. */
Database nixDB;
nixDB.open(nixDBPath);
@ -76,6 +84,10 @@ void LocalStore::upgradeStore12()
}
std::cerr << std::endl;
writeFile(schemaPath, (format("%1%") % nixSchemaVersion).str());
lockFile(globalLock, ltRead, true);
}