1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-26 04:00:59 +01:00

Fixed a lot of remote store issues. But there is still a bug with 32bit unsigned integers: 'implementation cannot deal with > 32-bit integers'

This commit is contained in:
Wouter den Breejen 2007-08-28 15:22:27 +00:00
parent 2e7539bd27
commit 627afcc1aa
16 changed files with 144 additions and 54 deletions

View file

@ -621,7 +621,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
if(enableState && !disableState){ if(enableState && !disableState){
if(runtimeStateArgs == ""){ if(runtimeStateArgs == ""){
string enableStateS = bool2string("true"); string enableStateS = bool2string("true");
drv.stateOutputs["state"] = DerivationStateOutput("", "", "", "", stateIdentifier, enableStateS, "", "", "", runtimeStateArgs, queryCallingUsername(), "", false); drv.stateOutputs["state"] = DerivationStateOutput("", "", "", "", stateIdentifier, enableStateS, "", "", "", runtimeStateArgs, queryCurrentUsername(), "", false);
} }
} }
@ -657,7 +657,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
string enableStateS = bool2string("true"); string enableStateS = bool2string("true");
string createDirsBeforeInstallS = bool2string(createDirsBeforeInstall); string createDirsBeforeInstallS = bool2string(createDirsBeforeInstall);
drv.stateOutputs["state"] = DerivationStateOutput(stateOutPath, printHash(componentHash), outputHashAlgo, outputHash, stateIdentifier, enableStateS, drv.stateOutputs["state"] = DerivationStateOutput(stateOutPath, printHash(componentHash), outputHashAlgo, outputHash, stateIdentifier, enableStateS,
shareType, syncState, createDirsBeforeInstallS, runtimeStateArgs, queryCallingUsername(), sharedState); shareType, syncState, createDirsBeforeInstallS, runtimeStateArgs, queryCurrentUsername(), sharedState);
for(vector<DerivationStateOutputDir>::iterator i = stateDirs.begin(); i != stateDirs.end(); ++i) for(vector<DerivationStateOutputDir>::iterator i = stateDirs.begin(); i != stateDirs.end(); ++i)
drv.stateOutputDirs[(*i).path] = *(i); drv.stateOutputDirs[(*i).path] = *(i);

View file

@ -71,7 +71,7 @@ Transaction::~Transaction()
void Transaction::begin(Database & db) void Transaction::begin(Database & db)
{ {
assert(txn == 0); assert(txn == 0);
db.requireEnv(); db.requireEnv("begin transaction");
try { try {
db.env->txn_begin(0, &txn, 0); db.env->txn_begin(0, &txn, 0);
} catch (DbException e) { rethrow(e); } } catch (DbException e) { rethrow(e); }
@ -110,11 +110,11 @@ void Transaction::moveTo(Transaction & t)
} }
void Database::requireEnv() void Database::requireEnv(string debug)
{ {
checkInterrupt(); checkInterrupt();
if (!env) throw Error("database environment is not open " if (!env) throw Error(format("database environment is not open while trying '%1%'"
"(maybe you don't have sufficient permission?)"); "(maybe you don't have sufficient permission?)") % debug);
} }
@ -300,7 +300,7 @@ void Database::close()
TableId Database::openTable(const string & tableName, bool sorted) TableId Database::openTable(const string & tableName, bool sorted)
{ {
requireEnv(); requireEnv(tableName);
TableId table = nextId++; TableId table = nextId++;
try { try {

View file

@ -54,7 +54,7 @@ private:
TableId nextId; TableId nextId;
std::map<TableId, Db *> tables; std::map<TableId, Db *> tables;
void requireEnv(); void requireEnv(string debug);
Db * getDb(TableId table); Db * getDb(TableId table);

View file

@ -28,8 +28,8 @@ bool readOnlyMode = false;
string thisSystem = "unset"; string thisSystem = "unset";
unsigned int maxSilentTime = 0; unsigned int maxSilentTime = 0;
static bool settingsRead = false; static bool settingsRead = false;
uid_t callingUID = 0; uid_t callingUID = 0; //A root user will not set this value, so the default uid is 0
bool debugWorker = true; bool debugWorker = false; //TODO still experimental
static std::map<string, Strings> settings; static std::map<string, Strings> settings;
@ -132,16 +132,23 @@ void setCallingUID(uid_t uid, bool reset)
callingUID = uid; callingUID = uid;
} }
string queryCallingUsername() string uidToUsername(uid_t uid)
{ {
uid_t uid = queryCallingUID();
passwd *pwd = getpwuid(uid); passwd *pwd = getpwuid(uid);
char *pw_name = pwd->pw_name; char *pw_name = pwd->pw_name;
return (string)pw_name; return (string)pw_name;
} }
string queryCallingUsername()
{
uid_t uid = queryCallingUID();
return uidToUsername(uid);
}
string queryCurrentUsername()
{
return uidToUsername(geteuid());
}
} }

View file

@ -86,9 +86,16 @@ extern uid_t callingUID;
/* get/set the UID of the user that calls the nix-worker daemon */ /* get/set the UID of the user that calls the nix-worker daemon */
uid_t queryCallingUID(); uid_t queryCallingUID();
void setCallingUID(uid_t uid, bool reset = false); void setCallingUID(uid_t uid, bool reset = false);
/* Convert a uid to a username: Watch it! this segfaults when given a wrong uid !! */
string uidToUsername(uid_t uid);
/* get the username based on the UID of the user that calls the nix-worker daemon */ /* get the username based on the UID of the user that calls the nix-worker daemon */
string queryCallingUsername(); string queryCallingUsername();
/* get the username based on the UID of the user currently runs the process */
string queryCurrentUsername();
extern bool debugWorker; extern bool debugWorker;
} }

View file

@ -9,16 +9,29 @@
namespace nix { namespace nix {
Derivation derivationFromPathTxn(const Transaction & txn, const Path & drvPath) Derivation derivationFromPathPrivate(const bool dotxn, const Transaction & txn, const Path & drvPath)
{ {
assertStorePath(drvPath); assertStorePath(drvPath);
if(dotxn)
ensurePathTxn(txn, drvPath); ensurePathTxn(txn, drvPath);
else
store->ensurePath(drvPath);
ATerm t = ATreadFromNamedFile(drvPath.c_str()); ATerm t = ATreadFromNamedFile(drvPath.c_str());
if (!t) if (!t)
throw Error(format("cannot read aterm from `%1%'") % drvPath); throw Error(format("cannot read aterm from `%1%'") % drvPath);
return parseDerivation(t); return parseDerivation(t);
} }
//Wrappers
Derivation derivationFromPath(const Path & drvPath)
{
return derivationFromPathPrivate(false, noTxn, drvPath);
}
Derivation derivationFromPathTxn(const Transaction & txn, const Path & drvPath)
{
return derivationFromPathPrivate(true, txn, drvPath);
}
void computeFSClosure(const Path & path, PathSet & paths, const bool & withComponents, const bool & withState, const int revision, bool flipDirection) void computeFSClosure(const Path & path, PathSet & paths, const bool & withComponents, const bool & withState, const int revision, bool flipDirection)
{ {
computeFSClosureTxn(noTxn, path, paths, withComponents, withState, revision, flipDirection); computeFSClosureTxn(noTxn, path, paths, withComponents, withState, revision, flipDirection);

View file

@ -12,6 +12,9 @@ namespace nix {
ensurePath(). */ ensurePath(). */
Derivation derivationFromPathTxn(const Transaction & txn, const Path & drvPath); Derivation derivationFromPathTxn(const Transaction & txn, const Path & drvPath);
/* Same as above, but wihouth a txn now. This function can be called from the user side */
Derivation derivationFromPath(const Path & drvPath);
/* Place in `paths' the set of all store paths in the file system /* Place in `paths' the set of all store paths in the file system
closure of `storePath'; that is, all paths than can be directly or closure of `storePath'; that is, all paths than can be directly or
indirectly reached from it. `paths' is not cleared. If indirectly reached from it. `paths' is not cleared. If

View file

@ -274,9 +274,7 @@ Path RemoteStore::addToStore(const Path & _srcPath, bool fixed,
writeString(hashAlgo, to); writeString(hashAlgo, to);
dumpPath(srcPath, to, filter); dumpPath(srcPath, to, filter);
processStderr(); processStderr();
printMsg(lvlInfo, format("REMOTESTORE: ADD TO STORE REMOTE 1"));
Path path = readStorePath(from); Path path = readStorePath(from);
printMsg(lvlInfo, format("REMOTESTORE: ADD TO STORE REMOTE 2"));
return path; return path;
} }
@ -396,6 +394,14 @@ void RemoteStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
bytesFreed = (((unsigned long long) hi) << 32) | lo; bytesFreed = (((unsigned long long) hi) << 32) | lo;
} }
Path RemoteStore::queryDeriver(const Path & path)
{
writeInt(wopQueryDeriver, to);
writeString(path, to);
processStderr();
return readStorePath(from);
}
PathSet RemoteStore::queryDerivers(const Path & storePath, const string & identifier, const string & user) PathSet RemoteStore::queryDerivers(const Path & storePath, const string & identifier, const string & user)
{ {
writeInt(wopQueryDerivers, to); writeInt(wopQueryDerivers, to);
@ -498,13 +504,6 @@ void RemoteStore::scanAndUpdateAllReferences(const Path & statePath, const bool
readInt(from); readInt(from);
} }
Path RemoteStore::queryDeriver(const Path & path)
{
writeInt(wopQueryDeriver, to);
writeString(path, to);
processStderr();
return readStorePath(from);
}
PathSet RemoteStore::toNonSharedPathSet(const PathSet & statePaths) PathSet RemoteStore::toNonSharedPathSet(const PathSet & statePaths)
{ {

View file

@ -24,7 +24,7 @@ typedef enum {
wopQueryStateReferrers, wopQueryStateReferrers,
wopAddToStore, wopAddToStore,
wopAddTextToStore, wopAddTextToStore,
wopBuildDerivations, wopBuildDerivations, //TODO HANGS SOMETIMES !!!!!
wopEnsurePath, wopEnsurePath,
wopAddTempRoot, wopAddTempRoot,
wopAddIndirectRoot, wopAddIndirectRoot,

View file

@ -117,7 +117,7 @@ unsigned int readInt(Source & source)
unsigned char buf[8]; unsigned char buf[8];
source(buf, sizeof(buf)); source(buf, sizeof(buf));
if (buf[4] || buf[5] || buf[6] || buf[7]) if (buf[4] || buf[5] || buf[6] || buf[7])
throw Error("implementation cannot deal with > 32-bit integers"); throw Error("implementation cannot deal with > 32-bit integers"); //TODO !!!!!!!!!!!!!!!!! unsigned Int reader
return return
buf[0] | buf[0] |
(buf[1] << 8) | (buf[1] << 8) |

View file

@ -370,9 +370,9 @@ void writeStringToFile(const Path & path, const string & s)
LogType logType = ltPretty; LogType logType = ltPretty;
//Verbosity verbosity = lvlInfo; Verbosity verbosity = lvlInfo;
//Verbosity verbosity = lvlDebug; //Verbosity verbosity = lvlDebug;
Verbosity verbosity = lvlVomit; //Verbosity verbosity = lvlVomit;
static int nestingLevel = 0; static int nestingLevel = 0;

View file

@ -496,7 +496,7 @@ static void installDerivations(Globals & globals,
//Set the state indentifier if it is a state-component //Set the state indentifier if it is a state-component
printMsg(lvlError, format("New component to install DRV: '%1%'") % i->queryDrvPath(globals.state)); printMsg(lvlError, format("New component to install DRV: '%1%'") % i->queryDrvPath(globals.state));
Derivation drv = derivationFromPathTxn(noTxn, i->queryDrvPath(globals.state)); Derivation drv = derivationFromPath(i->queryDrvPath(globals.state));
if(isStateDrv(drv)) if(isStateDrv(drv))
{ {
DerivationStateOutputs stateOutputs = drv.stateOutputs; DerivationStateOutputs stateOutputs = drv.stateOutputs;

View file

@ -84,7 +84,7 @@ Derivation getDerivation(const string & fullPath, const Strings & program_args,
//Retrieve the derivation, there is only 1 drvPath in derivers //Retrieve the derivation, there is only 1 drvPath in derivers
derivationPath = *(derivers.begin()); derivationPath = *(derivers.begin());
Derivation drv = derivationFromPathTxn(noTxn, derivationPath); Derivation drv = derivationFromPath(derivationPath);
if(isStateComponent){ if(isStateComponent){
DerivationStateOutputs stateOutputs = drv.stateOutputs; DerivationStateOutputs stateOutputs = drv.stateOutputs;
@ -474,6 +474,9 @@ void run(Strings args)
return; return;
printMsg(lvlError, format("header: '%1%'") % nixExt3CowHeader); printMsg(lvlError, format("header: '%1%'") % nixExt3CowHeader);
printMsg(lvlError, format("Username fail: '%1%'") % uidToUsername(23423)); //Segfaults correctly
return; return;
*/ */
@ -551,9 +554,9 @@ void run(Strings args)
throw UsageError("only one operation may be specified"); throw UsageError("only one operation may be specified");
} }
//If no username given: take the username of the caller //If no username given get it
if(username == "") if(username == "")
username = int2String(geteuid()); username = queryCurrentUsername();
if (!op) throw UsageError("no operation specified"); if (!op) throw UsageError("no operation specified");

View file

@ -75,7 +75,7 @@ static Path realisePath(const Path & path)
PathSet paths; PathSet paths;
paths.insert(path); paths.insert(path);
store->buildDerivations(paths); store->buildDerivations(paths);
Path outPath = findOutput(derivationFromPathTxn(noTxn, path), "out"); Path outPath = findOutput(derivationFromPath(path), "out");
if (gcRoot == "") if (gcRoot == "")
printGCWarning(); printGCWarning();

View file

@ -337,23 +337,16 @@ static void performOp(Source & from, Sink & to, unsigned int op)
bool recursive = readInt(from) == 1; bool recursive = readInt(from) == 1;
string hashAlgo = readString(from); string hashAlgo = readString(from);
printMsg(lvlInfo, format("NIXWORKER: WOP 1"));
/* !!! uberquick hack */ /* !!! uberquick hack */
Path tmp = createTempDir(); Path tmp = createTempDir();
AutoDelete delTmp(tmp); AutoDelete delTmp(tmp);
Path tmp2 = tmp + "/" + baseName; Path tmp2 = tmp + "/" + baseName;
restorePath(tmp2, from); restorePath(tmp2, from);
printMsg(lvlInfo, format("NIXWORKER: WOP 2"));
startWork(); startWork();
Path path = store->addToStore(tmp2, fixed, recursive, hashAlgo); Path path = store->addToStore(tmp2, fixed, recursive, hashAlgo);
stopWork(); stopWork();
printMsg(lvlInfo, format("NIXWORKER: WOP 3 '%1%'") % path);
writeString(path, to); writeString(path, to);
printMsg(lvlInfo, format("NIXWORKER: WOP 4"));
break; break;
} }
@ -478,57 +471,122 @@ static void performOp(Source & from, Sink & to, unsigned int op)
} }
case wopSetStatePathsInterval: { case wopSetStatePathsInterval: {
PathSet statePaths = readStringSet(from);
IntVector intervals = readIntVector(from);
bool allZero = readInt(from) == 1;
startWork();
store->setStatePathsInterval(statePaths, intervals, allZero);
stopWork();
writeInt(1, to);
break; break;
} }
case wopGetStatePathsInterval: { case wopGetStatePathsInterval: {
PathSet statePaths = readStringSet(from);
startWork();
IntVector iv = store->getStatePathsInterval(statePaths);
stopWork();
writeIntVector(iv, to);
break; break;
} }
case wopIsStateComponent: { case wopIsStateComponent: {
Path path = readString(from);
startWork();
bool result = store->isStateComponent(path);
stopWork();
writeInt(result, to);
break; break;
} }
case wopStorePathRequisites: { case wopStorePathRequisites: {
Path storeOrstatePath = readString(from);
bool includeOutputs = readInt(from) == 1;
PathSet paths = readStringSet(from);
bool withComponents = readInt(from) == 1;
bool withState = readInt(from) == 1;
int revision = readInt(from);
startWork();
store->storePathRequisites(storeOrstatePath, includeOutputs, paths, withComponents, withState, revision);
stopWork();
writeInt(1, to);
break; break;
} }
case wopSetStateRevisions: { case wopSetStateRevisions: {
RevisionClosure revisions = readRevisionClosure(from);
Path rootStatePath = readString(from);
string comment = readString(from);
startWork();
store->setStateRevisions(revisions, rootStatePath, comment);
stopWork();
writeInt(1, to);
break; break;
} }
case wopQueryStateRevisions: { case wopQueryStateRevisions: {
Path statePath = readString(from);
int revision = readInt(from);
RevisionClosure revisions;
RevisionClosureTS timestamps;
startWork();
bool result = store->queryStateRevisions(statePath, revisions, timestamps, revision);
stopWork();
writeRevisionClosure(revisions, to);
writeRevisionClosureTS(timestamps, to);
writeInt(result, to);
break; break;
} }
case wopQueryAvailableStateRevisions: { case wopQueryAvailableStateRevisions: {
Path statePath = readString(from);
RevisionInfos revisions;
startWork();
bool result = store->queryAvailableStateRevisions(statePath, revisions);
stopWork();
writeRevisionInfos(revisions, to);
writeInt(result, to);
break; break;
} }
case wopCommitStatePath: { case wopCommitStatePath: {
Path statePath = readString(from);
startWork();
Snapshots ss = store->commitStatePath(statePath);
stopWork();
writeSnapshots(ss, to);
break; break;
} }
case wopScanAndUpdateAllReferences: { case wopScanAndUpdateAllReferences: {
Path statePath = readString(from);
bool recursive = readInt(from) == 1;
startWork();
store->scanAndUpdateAllReferences(statePath, recursive);
stopWork();
writeInt(1, to);
break; break;
} }
case wopToNonSharedPathSet: { case wopToNonSharedPathSet: {
PathSet statePaths = readStringSet(from);
startWork();
PathSet statePaths_ns = store->toNonSharedPathSet(statePaths);
stopWork();
writeStringSet(statePaths_ns, to);
break; break;
} }
case wopRevertToRevision: { case wopRevertToRevision: {
Path componentPath = readString(from);
Path derivationPath = readString(from);
Path statePath = readString(from);
int revision_arg = readInt(from);
bool recursive = readInt(from) == 1;
startWork();
store->revertToRevision(componentPath, derivationPath, statePath, revision_arg, recursive);
stopWork();
writeInt(1, to);
break; break;
} }