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(runtimeStateArgs == ""){
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 createDirsBeforeInstallS = bool2string(createDirsBeforeInstall);
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)
drv.stateOutputDirs[(*i).path] = *(i);

View file

@ -1830,7 +1830,7 @@ void DerivationGoal::computeClosure()
}
txn.commit();
/* It is now safe to delete the lock files, since all future
lockers will see that the output paths are valid; they will not
create new lock files with the same names as the old (unlinked)

View file

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

View file

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

View file

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

View file

@ -9,16 +9,29 @@
namespace nix {
Derivation derivationFromPathTxn(const Transaction & txn, const Path & drvPath)
Derivation derivationFromPathPrivate(const bool dotxn, const Transaction & txn, const Path & drvPath)
{
assertStorePath(drvPath);
ensurePathTxn(txn, drvPath);
if(dotxn)
ensurePathTxn(txn, drvPath);
else
store->ensurePath(drvPath);
ATerm t = ATreadFromNamedFile(drvPath.c_str());
if (!t)
throw Error(format("cannot read aterm from `%1%'") % drvPath);
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)
{
computeFSClosureTxn(noTxn, path, paths, withComponents, withState, revision, flipDirection);

View file

@ -12,6 +12,9 @@ namespace nix {
ensurePath(). */
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
closure of `storePath'; that is, all paths than can be directly or
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);
dumpPath(srcPath, to, filter);
processStderr();
printMsg(lvlInfo, format("REMOTESTORE: ADD TO STORE REMOTE 1"));
Path path = readStorePath(from);
printMsg(lvlInfo, format("REMOTESTORE: ADD TO STORE REMOTE 2"));
return path;
}
@ -396,6 +394,14 @@ void RemoteStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
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)
{
writeInt(wopQueryDerivers, to);
@ -498,13 +504,6 @@ void RemoteStore::scanAndUpdateAllReferences(const Path & statePath, const bool
readInt(from);
}
Path RemoteStore::queryDeriver(const Path & path)
{
writeInt(wopQueryDeriver, to);
writeString(path, to);
processStderr();
return readStorePath(from);
}
PathSet RemoteStore::toNonSharedPathSet(const PathSet & statePaths)
{

View file

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

View file

@ -117,7 +117,7 @@ unsigned int readInt(Source & source)
unsigned char buf[8];
source(buf, sizeof(buf));
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
buf[0] |
(buf[1] << 8) |

View file

@ -370,9 +370,9 @@ void writeStringToFile(const Path & path, const string & s)
LogType logType = ltPretty;
//Verbosity verbosity = lvlInfo;
Verbosity verbosity = lvlInfo;
//Verbosity verbosity = lvlDebug;
Verbosity verbosity = lvlVomit;
//Verbosity verbosity = lvlVomit;
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
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))
{
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
derivationPath = *(derivers.begin());
Derivation drv = derivationFromPathTxn(noTxn, derivationPath);
Derivation drv = derivationFromPath(derivationPath);
if(isStateComponent){
DerivationStateOutputs stateOutputs = drv.stateOutputs;
@ -474,6 +474,9 @@ void run(Strings args)
return;
printMsg(lvlError, format("header: '%1%'") % nixExt3CowHeader);
printMsg(lvlError, format("Username fail: '%1%'") % uidToUsername(23423)); //Segfaults correctly
return;
*/
@ -551,9 +554,9 @@ void run(Strings args)
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 == "")
username = int2String(geteuid());
username = queryCurrentUsername();
if (!op) throw UsageError("no operation specified");

View file

@ -75,7 +75,7 @@ static Path realisePath(const Path & path)
PathSet paths;
paths.insert(path);
store->buildDerivations(paths);
Path outPath = findOutput(derivationFromPathTxn(noTxn, path), "out");
Path outPath = findOutput(derivationFromPath(path), "out");
if (gcRoot == "")
printGCWarning();
@ -100,7 +100,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
*i = fixPath(*i);
if (opArgs.size() > 1) {
PathSet drvPaths;
for (Strings::iterator i = opArgs.begin();

View file

@ -337,23 +337,16 @@ static void performOp(Source & from, Sink & to, unsigned int op)
bool recursive = readInt(from) == 1;
string hashAlgo = readString(from);
printMsg(lvlInfo, format("NIXWORKER: WOP 1"));
/* !!! uberquick hack */
Path tmp = createTempDir();
AutoDelete delTmp(tmp);
Path tmp2 = tmp + "/" + baseName;
restorePath(tmp2, from);
printMsg(lvlInfo, format("NIXWORKER: WOP 2"));
startWork();
Path path = store->addToStore(tmp2, fixed, recursive, hashAlgo);
stopWork();
printMsg(lvlInfo, format("NIXWORKER: WOP 3 '%1%'") % path);
writeString(path, to);
printMsg(lvlInfo, format("NIXWORKER: WOP 4"));
break;
}
@ -478,57 +471,122 @@ static void performOp(Source & from, Sink & to, unsigned int op)
}
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;
}
case wopGetStatePathsInterval: {
PathSet statePaths = readStringSet(from);
startWork();
IntVector iv = store->getStatePathsInterval(statePaths);
stopWork();
writeIntVector(iv, to);
break;
}
case wopIsStateComponent: {
Path path = readString(from);
startWork();
bool result = store->isStateComponent(path);
stopWork();
writeInt(result, to);
break;
}
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;
}
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;
}
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;
}
case wopQueryAvailableStateRevisions: {
Path statePath = readString(from);
RevisionInfos revisions;
startWork();
bool result = store->queryAvailableStateRevisions(statePath, revisions);
stopWork();
writeRevisionInfos(revisions, to);
writeInt(result, to);
break;
}
case wopCommitStatePath: {
Path statePath = readString(from);
startWork();
Snapshots ss = store->commitStatePath(statePath);
stopWork();
writeSnapshots(ss, to);
break;
}
case wopScanAndUpdateAllReferences: {
Path statePath = readString(from);
bool recursive = readInt(from) == 1;
startWork();
store->scanAndUpdateAllReferences(statePath, recursive);
stopWork();
writeInt(1, to);
break;
}
case wopToNonSharedPathSet: {
PathSet statePaths = readStringSet(from);
startWork();
PathSet statePaths_ns = store->toNonSharedPathSet(statePaths);
stopWork();
writeStringSet(statePaths_ns, to);
break;
}
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;
}