From 35e239af33ff5a0354edbe779cb0a0a011538828 Mon Sep 17 00:00:00 2001 From: Wouter den Breejen Date: Tue, 4 Sep 2007 17:09:26 +0000 Subject: [PATCH] EOF --- src/libexpr/primops.cc | 22 +-------------------- src/libstore/build.cc | 2 +- src/libstore/db.cc | 2 ++ src/libstore/local-store.cc | 19 ++++++++++--------- src/libstore/store-state.cc | 2 +- src/libutil/util.cc | 32 +++++++++++++++---------------- src/libutil/util.hh | 7 +++---- src/nix-env/nix-env.cc | 38 +++++++++++++++++++------------------ src/nix-state/nix-state.cc | 20 +++++++++++++++---- 9 files changed, 70 insertions(+), 74 deletions(-) diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 3be6d5937..607baf3d0 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -509,23 +509,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) } } - else if(key == "solidStateDependency"){ - - /* - ATermList es; - value = evalExpr(state, value); - if (!matchList(value, es)) { - static bool haveWarned = false; - warnOnce(haveWarned, "the `solidStateDependencies' attribute should evaluate to a list"); - es = flattenList(state, value); - } - for (ATermIterator i(es); i; ++i) { - string s = coerceToString(state, *i, context, true); - drv.solidStateDeps.insert(s); - } - */ - externalState = coerceToString(state, value, context, true); - } + else if(key == "solidStateDependency"){ externalState = coerceToString(state, value, context, true); } else if(key == "shareType") { shareType = coerceToString(state, value, context, true); } else if(key == "synchronization") { syncState = coerceToString(state, value, context, true); } else if(key == "disableState") { disableState = evalBool(state, value); } @@ -619,10 +603,6 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) * We also add runtimeStateArgs for the hash calc in hashDerivationModulo(...) to check if its needs to take the stateIdentiefier into account in the hash */ - //TODO CHECK DRVS ARE CREATED BY THE USER AND NOT DAEMON ??????????????????????????? - //queryCallingUsername() - //THERE ARE 2 CALLS TO DerivationStateOutput below !!!!!!!!!!!!!!!!!!!!!! - if(enableState && !disableState){ if(runtimeStateArgs == ""){ string enableStateS = bool2string("true"); diff --git a/src/libstore/build.cc b/src/libstore/build.cc index a960460ee..5100f9c46 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1831,7 +1831,7 @@ void DerivationGoal::computeClosure() if(sharedState != ""){ //Remove state path deletePathWrapped(statePath); - sharePath(sharedState, statePath); + symlinkPath(sharedState, statePath); //Set in database setSharedStateTxn(txn, sharedState, statePath); diff --git a/src/libstore/db.cc b/src/libstore/db.cc index bb5eecf6e..09cfafcc9 100644 --- a/src/libstore/db.cc +++ b/src/libstore/db.cc @@ -383,12 +383,14 @@ void Database::setString(const Transaction & txn, TableId table, const string & key, const string & data) { checkInterrupt(); + printMsg(lvlError, format("SS: '%1%'") % data); try { Db * db = getDb(table); Dbt kt((void *) key.c_str(), key.length()); Dbt dt((void *) data.c_str(), data.length()); db->put(txn.txn, &kt, &dt, 0); } catch (DbException e) { rethrow(e); } + printMsg(lvlError, format("SETTEDS")); } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 8bfae9831..1a8496054 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -501,7 +501,6 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath, } else throw Error(format("Path '%1%' is not a valid component or state path") % store_or_statePath); - } void queryXReferencesTxn(const Transaction & txn, const Path & store_or_statePath, PathSet & references, const bool component_or_state, const unsigned int revision, const unsigned int timestamp) @@ -695,18 +694,18 @@ void setDeriver(const Transaction & txn, const Path & storePath, const Path & de * into account. This function is used to update derivations that have only changed in their sub state * paths that need to be versioned for example. We assume newdrv is the newest. */ -PathSet mergeNewDerivationIntoList(const Path & storepath, const Path & newdrv, const PathSet drvs, bool deleteDrvs) +PathSet mergeNewDerivationIntoListTxn(const Transaction txn, const Path & storepath, const Path & newdrv, const PathSet drvs, bool deleteDrvs) { PathSet newdrvs; - Derivation drv = derivationFromPathTxn(noTxn, newdrv); + Derivation drv = derivationFromPathTxn(txn, newdrv); string identifier = drv.stateOutputs.find("state")->second.stateIdentifier; string user = drv.stateOutputs.find("state")->second.username; for (PathSet::iterator i = drvs.begin(); i != drvs.end(); ++i) //Check if we need to remove old drvs { Path drv = *i; - Derivation getdrv = derivationFromPathTxn(noTxn, drv); + Derivation getdrv = derivationFromPathTxn(txn, drv); string getIdentifier = getdrv.stateOutputs.find("state")->second.stateIdentifier; string getUser = getdrv.stateOutputs.find("state")->second.username; @@ -739,14 +738,17 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path string user = drv.stateOutputs.find("state")->second.username; PathSet currentDerivers = queryDerivers(txn, storePath, identifier, user); - PathSet updatedDerivers = mergeNewDerivationIntoList(storePath, deriver, currentDerivers, true); + PathSet updatedDerivers = mergeNewDerivationIntoListTxn(txn, storePath, deriver, currentDerivers, true); Strings data; for (PathSet::iterator i = updatedDerivers.begin(); i != updatedDerivers.end(); ++i) //Convert Paths to Strings data.push_back(*i); + for (Strings::iterator i = data.begin(); i != data.end(); ++i) + printMsg(lvlError, format("AA: %1%") % *i); nixDB.setStrings(txn, dbDerivers, storePath, data); //update the derivers db. + printMsg(lvlError, format("%BB")); nixDB.setString(txn, dbStateInfo, storePath, ""); //update the dbinfo db. (maybe TODO) } @@ -1728,6 +1730,9 @@ bool querySolidStateReferencesTxn(const Transaction & txn, const Path & statePat void setSharedStateTxn(const Transaction & txn, const Path & fromExisting, const Path & toNew) { + //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! LEGALITY CHECK IF THE PATH MAY BE SHARED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //TODO + //Remove earlier entries nixDB.delPair(txn, dbSharedState, toNew); @@ -1737,10 +1742,6 @@ void setSharedStateTxn(const Transaction & txn, const Path & fromExisting, const void LocalStore::setSharedState(const Path & fromExisting, const Path & toNew) { - //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! LEGALITY CHECK IF THE PATH MAY BE SHARED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - //TODO - - // Transaction txn(nixDB); setSharedStateTxn(txn, fromExisting, toNew); txn.commit(); diff --git a/src/libstore/store-state.cc b/src/libstore/store-state.cc index 979d87442..e913fc370 100644 --- a/src/libstore/store-state.cc +++ b/src/libstore/store-state.cc @@ -40,7 +40,7 @@ void createSubStateDirsTxn(const Transaction & txn, const DerivationStateOutputD //TODO /* - if( ! IsDirectory( ....... ) ){ + if( ! DirectoryExist( ....... ) ){ } else printMsg(lvlTalkative, format("Statedir %1% already exists, so dont ........ ???? ") % ...); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 4a1f9ebe4..e5e94beb6 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -462,7 +462,8 @@ void readFull(int fd, unsigned char * buf, size_t count) if (errno == EINTR) continue; throw SysError("reading from file"); } - if (res == 0) throw EndOfFile("unexpected end-of-file"); + if (res == 0) + throw EndOfFile("unexpected end-of-file (in readFull so deamon communication)"); count -= res; buf += res; } @@ -1167,7 +1168,7 @@ bool FileExist(const string FileName) } //TODO Does this work on windows? -bool IsDirectory(const string FileName) +bool DirectoryExist(const string FileName) { const char* FileName_C = FileName.c_str(); struct stat my_stat; @@ -1175,6 +1176,17 @@ bool IsDirectory(const string FileName) return ((my_stat.st_mode & S_IFDIR) != 0); } +//TODO Does this work on windows? + +bool IsSymlink(const string FileName) +{ + const char* FileName_C = FileName.c_str(); + struct stat my_stat; + if (lstat(FileName_C, &my_stat) != 0) return false; + return (S_ISLNK(my_stat.st_mode) != 0); +} + + /* string getCallingUserName() { @@ -1280,26 +1292,14 @@ void symlinkPath(const Path & fromExisting, const Path & toNew) p_args.push_back(fromExisting); p_args.push_back(toNew); runProgram_AndPrintOutput("ln", true, p_args, "ln"); - - printMsg(lvlError, format("ln -sf %1% %2%") % fromExisting % toNew); -} - -void sharePath(const Path & fromExisting, const Path & toNew) -{ - symlinkPath(fromExisting, toNew); + //printMsg(lvlError, format("ln -sf %1% %2%") % fromExisting % toNew); } void copyContents(const Path & from, const Path & to) { Strings p_args; p_args.push_back("-R"); - p_args.push_back(from + "/*"); - p_args.push_back(to); - runProgram_AndPrintOutput("cp", true, p_args, "cp"); - - p_args.clear(); - p_args.push_back("-R"); - p_args.push_back(from + "/.*"); //Also copy the hidden files + p_args.push_back(from + "/"); //the / makes sure it copys the contents of the dir, not just the symlink p_args.push_back(to); runProgram_AndPrintOutput("cp", true, p_args, "cp"); } diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 5f3f6ca2f..767f5544a 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -43,8 +43,10 @@ bool pathExists(const Path & path); bool FileExist(const string FileName); /* Return true if the given dir exists. */ -bool IsDirectory(const string FileName); +bool DirectoryExist(const string FileName); +/* Return true if the given filename is a symlink. */ +bool IsSymlink(const string FileName); /* Read the contents (target) of a symbolic link. The result is not in any way canonicalised. */ @@ -330,9 +332,6 @@ string padd(const string & s, char c , unsigned int size, bool front = false); /* Symlinks one path to the other */ void symlinkPath(const Path & fromExisting, const Path & toNew); -/* Exactly the same as symlinkPath */ -void sharePath(const Path & fromExisting, const Path & toNew); - /* Copy all files and folders recursively (also the hidden ones) from the dir from/... to the dir to/... */ void copyContents(const Path & from, const Path & to); diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 8dd6ccdd7..905b656be 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -513,8 +513,6 @@ static void installDerivations(Globals & globals, string externalState = stateOutputs.find("state")->second.externalState; Path statePath = stateOutputs.find("state")->second.statepath; if(externalState != ""){ - if(stateIdentifier != "") - externalState = externalState + "-" + stateIdentifier; externalStates[statePath] = externalState; } } @@ -615,7 +613,7 @@ static void installDerivations(Globals & globals, printMsg(lvlError, format("Sharing state from old <-- new component '%1%' <-- '%2%'") % i->first % i->second); deletePath(i->second); //Remove contents of current new state path - sharePath(i->first, i->second); //Share new statepath to the old statepath + symlinkPath(i->first, i->second); //Share new statepath to the old statepath //Set in database store->setSharedState(i->first, i->second); @@ -629,31 +627,35 @@ static void installDerivations(Globals & globals, //1. If dir externalState exists, we move its data into the statePath //2. We ensure that the parent dir of externalState exists so we can create a symlink - if(IsDirectory(externalState)){ - copyContents(externalState, statePath); - - //TODO !!!!!!!!!!!!!! - //cp: cannot stat `/home/wouterdb/test/aaaaaaaa-test/*': No such file or directory - //error: program `cp' failed with exit code 1 + if(DirectoryExist(externalState)){ + + //We cannot copy into itself so we have to test that + if(IsSymlink(externalState)){ + Path read_statePath = readLink(externalState); + assert(store->isValidStatePath(read_statePath)); + PathSet comparePaths; + comparePaths.insert(statePath); + comparePaths.insert(read_statePath); + if(store->toNonSharedPathSet(comparePaths).size() != 1) + copyContents(externalState, statePath); + } + else + copyContents(externalState, statePath); deletePath(externalState); } else{ - //Ensure parent dir - //outsidestorePath - //ensureDirExists(); + string externalState_p = externalState; + if(externalState_p[externalState_p.length() - 1] == '/') + externalState_p.erase(externalState_p.length(),1); + externalState_p = externalState_p.substr(0,externalState_p.find_last_of('/')); + ensureDirExists(externalState_p); } - //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! these last 2 items should be done by the store I think for security reasons !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // /nix/state should be root.nixbl and 775 - //Now we create a symlink externalState --> statePath printMsg(lvlError, format("SYMLINK: '%1%' --> '%2%'") % externalState % statePath); symlinkPath(statePath, externalState); - - //SET IN DB !!! - //TODO } } diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index c33ecb0d1..99492224d 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -457,10 +457,10 @@ void run(Strings args) printMsg(lvlError, format("NOW: '%1%'") % FileExist("/nix/store/65c7p6c8j0vy6b8fjgq84zziiavswqha-hellohardcodedstateworld-1.0/") ); printMsg(lvlError, format("NOW: '%1%'") % FileExist("/nix/store/65c7p6c8j0vy6b8fjgq84zziiavswqha-hellohardcodedstateworld-1.0/bin/hello") ); - printMsg(lvlError, format("NOW: '%1%'") % IsDirectory("/nix/store/65c7p6c8j0vy6b8fjgq84zziiavswqha-hellohardcodedstateworld-1.0/") ); - printMsg(lvlError, format("NOW: '%1%'") % IsDirectory("/nix/store/65c7p6c8j0vy6b8fjgq84zziiavswqha-hellohardcodedstateworld-1.0/bin/hello") ); + printMsg(lvlError, format("NOW: '%1%'") % DirectoryExist("/nix/store/65c7p6c8j0vy6b8fjgq84zziiavswqha-hellohardcodedstateworld-1.0/") ); + printMsg(lvlError, format("NOW: '%1%'") % DirectoryExist("/nix/store/65c7p6c8j0vy6b8fjgq84zziiavswqha-hellohardcodedstateworld-1.0/bin/hello") ); printMsg(lvlError, format("NOW: '%1%'") % FileExist("/nix/store/65c7p6c8j0vy6b8fjgq8") ); - printMsg(lvlError, format("NOW: '%1%'") % IsDirectory("/nix/store/65c7p6c8j0vy6b8fjg") ); + printMsg(lvlError, format("NOW: '%1%'") % DirectoryExist("/nix/store/65c7p6c8j0vy6b8fjg") ); store = openStore(); @@ -498,7 +498,19 @@ void run(Strings args) sharedWith = getSharedWithPathSetRecTxn(noTxn, "/nix/state/7c9azkk6qfk18hsvw4a5d8vk1p6qryk0-hellohardcodedstateworld-1.0-test"); for (PathSet::const_iterator j = sharedWith.begin(); j != sharedWith.end(); ++j) printMsg(lvlError, format("RootSP SW '%1%'") % *j); - + + + printMsg(lvlError, format("ISL 1 '%1%'") % IsSymlink("/home/wouterdb/test/aaaaaaaa-test")); + printMsg(lvlError, format("ISL 2 '%1%'") % IsSymlink("/home/wouterdb/test/aad")); + printMsg(lvlError, format("ISL 1 '%1%'") % readLink("/home/wouterdb/test/aaaaaaaa-test")); + + PathSet comparePaths; + comparePaths.insert("/nix/state/rxi9isplmqvgjp7xrrq2zlz0s2w5h0mh-hellohardcodedstateworld-solid-1.0-test"); + comparePaths.insert("/nix/state/7c9azkk6qfk18hsvw4a5d8vk1p6qryk0-hellohardcodedstateworld-1.0-test"); + PathSet comparePaths_result = store->toNonSharedPathSet(comparePaths); + for (PathSet::const_iterator j = comparePaths_result.begin(); j != comparePaths_result.end(); ++j) + printMsg(lvlError, format("RES '%1%'") % *j); + return; */