* Lock the Nix store during upgrades.
This commit is contained in:
parent
4df6dc28c3
commit
341b2de643
|
@ -2,7 +2,6 @@
|
|||
#include "misc.hh"
|
||||
#include "pathlocks.hh"
|
||||
#include "local-store.hh"
|
||||
#include "util.hh"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "local-store.hh"
|
||||
#include "util.hh"
|
||||
#include "local-store.hh"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue