1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-25 19:51:00 +01:00

* Fixed very old transactional bug that caused a freeze sometimes

* State components that get their state at runtime can now be (un)installed with nix-env
This commit is contained in:
Wouter den Breejen 2007-08-17 15:35:34 +00:00
parent 05297240ea
commit 53a6b9aaa5
20 changed files with 186 additions and 87 deletions

View file

@ -10,9 +10,12 @@ STDOUT->autoflush(1);
my $out = $ENV{"out"};
mkdir "$out", 0755 || die "error creating $out";
sub readlink_or_StateWrapper;
my $symlinks = 0;
my %path_identifier;
my %path_state_identifier;
my %path_runtimeArgs;
my $nixBinDir = $ENV{"nixBinDir"};
my $nixStore = $ENV{"nixStore"};
@ -22,12 +25,13 @@ my $nixStore = $ENV{"nixStore"};
sub createLinks {
my $srcDir = shift;
#Lookup each $stateIdentifiers in $path_identifier
#Lookup each $stateIdentifiers in $path_state_identifier
#we strip $srcDir to its rootdir e.g. /nix/store/......./
my @srcDirParts = split /\// , substr($srcDir, length ($nixStore), length ($srcDir));
my $srcDirRoot = $nixStore . "/" . $srcDirParts[1];
# print "srcDirRoot $srcDirRoot \n";
my $pkgStateIdentifier = $path_identifier{$srcDirRoot};
my $pkgStateIdentifier = $path_state_identifier{$srcDirRoot};
my $pkgRuntimeStateArgs = $path_runtimeArgs{$srcDirRoot};
my $dstDir = shift;
my $ignoreCollisions = shift;
@ -93,7 +97,7 @@ sub createLinks {
if( $parentDir eq "bin" || $parentDir eq "sbin"){ #hacky....
print "STATELINK $srcFile to $dstFile \n";
print "STATELINK $srcFile to $dstFile - $pkgStateIdentifier \n";
my $new_dstFile;
my $new_stateIdentifier;
@ -106,23 +110,29 @@ sub createLinks {
$new_stateIdentifier = $pkgStateIdentifier;
}
if (-l $new_dstFile) {
# We also check with -e if the wrapperscript-file exists, and if is it a symlink (with -l)
if (-l $new_dstFile || -e $new_dstFile) {
if (!$ignoreCollisions) {
my $target = readlink $new_dstFile;
die "(state) collission between `$srcFile' and `$target'";
my $target = readlink_or_StateWrapper $new_dstFile;
die "(state) collission between `$srcFile' and `$target' (over $new_dstFile)";
}
}
sysopen (DSTFILEHANDLE, $new_dstFile, O_RDWR|O_EXCL|O_CREAT, 0755);
printf DSTFILEHANDLE "#! @shell@ \n";
printf DSTFILEHANDLE "$nixBinDir/nix-state --run --identifier=$new_stateIdentifier $srcFile \"\$@\" \n";
if($pkgRuntimeStateArgs eq "__NOARGS__")
{ printf DSTFILEHANDLE "$nixBinDir/nix-state --run --identifier=$new_stateIdentifier $srcFile \"\$@\" \n"; }
else
{ printf DSTFILEHANDLE "$nixBinDir/nix-state --run --identifier=$new_stateIdentifier $srcFile \"\$@\" $pkgRuntimeStateArgs \n"; } # TODO, maybe first R.T.A. then other args ?
close (DSTFILEHANDLE);
}
}
else{
if (-l $dstFile) {
if (-l $dstFile || -e $dstFile) {
if (!$ignoreCollisions) {
my $target = readlink $dstFile;
my $target = readlink_or_StateWrapper $dstFile;
die "collission between `$srcFile' and `$target'";
}
}
@ -162,18 +172,37 @@ sub addPkg {
}
}
sub readlink_or_StateWrapper {
my $src = shift;
my $target;
if (-l $src)
{ $target = readlink $src; }
else{
open(DAT, $src) || die("Could not open file!");
my @raw_data=<DAT>;
close(DAT);
$target = $raw_data[1];
}
return $target
}
# Symlink to the packages that have been installed explicitly by the user.
my @storePaths = split ' ', $ENV{"derivations"};
my @stateIdentifiers = split ' ', $ENV{"stateIdentifiers"};
my @runtimeStateArgs = split ' ', $ENV{"runtimeStateArgs_arg"};
my $si_counter = 0;
foreach my $pkgDir (@storePaths) { #Commented the sort out
#Link each $pkgDir to a $stateIdentifiers in $path_identifier
#print "SP: $pkgDir \n";
$path_identifier{$pkgDir} = $stateIdentifiers[$si_counter];
#print "SI: $path_identifier{$pkgDir} \n";
#Link each $pkgDir to a $stateIdentifiers in $path_state_identifier
$path_state_identifier{$pkgDir} = $stateIdentifiers[$si_counter];
$path_runtimeArgs{$pkgDir} = $runtimeStateArgs[$si_counter];
# print "SP: $pkgDir \n";
# print "SI: $path_state_identifier{$pkgDir} \n";
# print "RT: $path_runtimeArgs{$pkgDir} \n";
addPkg($pkgDir, 0);
$si_counter++;
@ -193,8 +222,6 @@ while (scalar(keys %postponed) > 0) {
}
}
print STDERR "created $symlinks symlinks in user environment\n";
symlink($ENV{"manifest"}, "$out/manifest") or die "cannot create manifest";

View file

@ -1,10 +1,11 @@
{system, derivations, stateIdentifiers, manifest, nixBinDir, nixStore}:
{system, derivations, stateIdentifiers, runtimeStateArgs, manifest, nixBinDir, nixStore}:
derivation {
name = "user-environment";
system = system;
builder = ./builder.pl;
derivations = derivations;
runtimeStateArgs_arg = runtimeStateArgs;
stateIdentifiers = stateIdentifiers;
manifest = manifest;
inherit nixBinDir nixStore;

View file

@ -59,6 +59,29 @@ string DrvInfo::queryStateIdentifier(EvalState & state) const
return stateIdentifier;
}
string DrvInfo::queryRuntimeStateArgs(EvalState & state) const
{
if (runtimeStateArgs == "") {
ATermMap attrs2 = *attrs;
for (ATermMap::const_iterator i = attrs2.begin(); i != attrs2.end(); ++i) {
string key = (string)aterm2String(i->key); //cast because aterm2String returns a char*
if(key == "runtimeStateArgs"){
PathSet context;
string value = coerceToString(state, i->value, context);
(string &) runtimeStateArgs = value;
}
}
//If still empty
if (trim(runtimeStateArgs) == "")
(string &) runtimeStateArgs = "__NOARGS__";
}
return runtimeStateArgs;
}
MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const
{

View file

@ -21,6 +21,7 @@ private:
string drvPath;
string outPath;
string stateIdentifier;
string runtimeStateArgs;
public:
string name;
@ -35,6 +36,7 @@ public:
string queryDrvPath(EvalState & state) const;
string queryOutPath(EvalState & state) const;
string queryStateIdentifier(EvalState & state) const;
string queryRuntimeStateArgs(EvalState & state) const;
MetaInfo queryMetaInfo(EvalState & state) const;
void setDrvPath(const string & s)
@ -52,6 +54,11 @@ public:
stateIdentifier = s;
}
void setRuntimeStateArgs(const string & s)
{
runtimeStateArgs = s;
}
void setMetaInfo(const MetaInfo & meta);
};

View file

@ -347,7 +347,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
DerivationStateOutput drvso = drv.stateOutputs["state"];
if(drvso.runtimeStateParamters != ""){ //Has runtime parameters --> Clear all state parameters
if(drvso.runtimeStateArgs != ""){ //Has runtime parameters --> Clear all state parameters
drv.stateOutputs.clear();
drv.stateOutputDirs.clear();
drv.env["statePath"] = "";
@ -365,7 +365,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
{
Hash h = state.drvHashes[i->first];
if (h.type == htUnknown) {
Derivation drv2 = derivationFromPath(i->first);
Derivation drv2 = derivationFromPathTxn(noTxn, i->first);
h = hashDerivationModulo(state, drv2);
state.drvHashes[i->first] = h;
}
@ -421,7 +421,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
string syncState = "none";
string stateIdentifier = "";
bool createDirsBeforeInstall = false;
string runtimeStateParamters = "";
string runtimeStateArgs = "";
string sharedState = "";
vector<DerivationStateOutputDir> stateDirs;
@ -526,7 +526,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
else if(key == "disableState") { disableState = evalBool(state, value); }
else if(key == "identifier"){ stateIdentifier = coerceToString(state, value, context, true); }
else if(key == "createDirsBeforeInstall"){ createDirsBeforeInstall = evalBool(state, value); }
else if(key == "runtimeStateParamters"){ runtimeStateParamters = coerceToString(state, value, context, true); }
else if(key == "runtimeStateArgs"){ runtimeStateArgs = coerceToString(state, value, context, true); }
else if(key == "shareStateFrom"){ sharedState = coerceToString(state, value, context, true); }
/* All other attributes are passed to the builder through
@ -611,12 +611,12 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
/* If there are no runtime paratermers, then we need to take the the stateIdentifier into account for the hash calcaulation below: hashDerivationModulo(...)
* We also add enableState to make it parse the drv to a state-drv
* We also add runtimeStateParamters for the hash calc in hashDerivationModulo(...) to check if its needs to take the stateIdentiefier into account in the hash
* We also add runtimeStateArgs for the hash calc in hashDerivationModulo(...) to check if its needs to take the stateIdentiefier into account in the hash
*/
if(enableState && !disableState){
if(runtimeStateParamters == ""){
if(runtimeStateArgs == ""){
string enableStateS = bool2string("true");
drv.stateOutputs["state"] = DerivationStateOutput("", "", "", "", stateIdentifier, enableStateS, "", "", "", runtimeStateParamters, getCallingUserName(), "", false);
drv.stateOutputs["state"] = DerivationStateOutput("", "", "", "", stateIdentifier, enableStateS, "", "", "", runtimeStateArgs, getCallingUserName(), "", false);
}
}
@ -652,7 +652,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, runtimeStateParamters, getCallingUserName(), sharedState);
shareType, syncState, createDirsBeforeInstallS, runtimeStateArgs, getCallingUserName(), sharedState);
for(vector<DerivationStateOutputDir>::iterator i = stateDirs.begin(); i != stateDirs.end(); ++i)
drv.stateOutputDirs[(*i).path] = *(i);

View file

@ -7,7 +7,7 @@ libstore_la_SOURCES = \
pkginclude_HEADERS = \
store-api.hh local-store.hh remote-store.hh derivations.hh misc.hh \
globals.hh db.hh references.hh pathlocks.hh \
worker-protocol.hh store-state.hh
worker-protocol.hh store-state.hh build.hh
libstore_la_LIBADD = ../libutil/libutil.la \
../libext3cow/libext3cow.la \

View file

@ -6,6 +6,7 @@
#include "db.hh"
#include "util.hh"
#include "store-state.hh"
#include "build.hh"
#include <map>
#include <iostream>
@ -770,7 +771,7 @@ void DerivationGoal::haveDerivation()
assert(store->isValidPath(drvPath));
/* Get the derivation. */
drv = derivationFromPath(drvPath);
drv = derivationFromPathTxn(noTxn, drvPath);
for (DerivationOutputs::iterator i = drv.outputs.begin();
i != drv.outputs.end(); ++i)
@ -1319,7 +1320,7 @@ bool DerivationGoal::prepareBuild()
`*i' as input paths. Only add the closures of output paths
that are specified as inputs. */
assert(store->isValidPath(i->first));
Derivation inDrv = derivationFromPath(i->first);
Derivation inDrv = derivationFromPathTxn(noTxn, i->first);
for (StringSet::iterator j = i->second.begin(); j != i->second.end(); ++j)
if (inDrv.outputs.find(*j) != inDrv.outputs.end()){
computeFSClosure(inDrv.outputs[*j].path, inputPaths, true, false, -1); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE (done?)
@ -2600,10 +2601,12 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
}
void LocalStore::ensurePath(const Path & path)
void ensurePathTxn(const Transaction & txn, const Path & path)
{
/* If the path is already valid, we're done. */
if (store->isValidPath(path)) return;
if (isValidPathTxn(txn, path))
return;
Worker worker;
GoalPtr goal = worker.makeSubstitutionGoal(path);
@ -2615,5 +2618,10 @@ void LocalStore::ensurePath(const Path & path)
throw Error(format("path `%1%' does not exist and cannot be created") % path);
}
void LocalStore::ensurePath(const Path & path)
{
ensurePathTxn(noTxn, path);
}
}

12
src/libstore/build.hh Normal file
View file

@ -0,0 +1,12 @@
#ifndef BUILD_HH_
#define BUILD_HH_
#include "db.hh"
namespace nix {
void ensurePathTxn(const Transaction & txn, const Path & path);
}
#endif /*BUILD_HH_*/

View file

@ -701,7 +701,7 @@ bool Database::queryStateRevisions(const Transaction & txn, TableId revisions_ta
//query state versioined directorys/files
vector<Path> sortedPaths;
Derivation drv = derivationFromPath(queryStatePathDrvTxn(txn, getStatePath));
Derivation drv = derivationFromPathTxn(txn, queryStatePathDrvTxn(txn, getStatePath));
DerivationStateOutputs stateOutputs = drv.stateOutputs;
DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs;
for (DerivationStateOutputDirs::const_iterator j = stateOutputDirs.begin(); j != stateOutputDirs.end(); ++j){

View file

@ -66,8 +66,8 @@ void throwBadDrv(ATerm t)
Derivation parseDerivation(ATerm t)
{
Derivation drv;
ATermList outs, solidStateDeps, inDrvs, inSrcs, args, bnds;
ATermList stateOuts = ATempty, stateOutDirs = ATempty;
ATermList outs, inDrvs, inSrcs, args, bnds;
ATermList stateOuts = ATempty, stateOutDirs = ATempty, solidStateDeps = ATempty;
ATerm builder, platform;
@ -93,8 +93,8 @@ Derivation parseDerivation(ATerm t)
{
//parse state part
for (ATermIterator i(stateOuts); i; ++i) {
ATerm id, statepath, componentHash, hashAlgo, hash, stateIdentifier, enabled, shareType, synchronization, createDirsBeforeInstall, runtimeStateParamters, username, sharedState;
if (!matchDerivationStateOutput(*i, id, statepath, componentHash, hashAlgo, hash, stateIdentifier, enabled, shareType, synchronization, createDirsBeforeInstall, runtimeStateParamters, username, sharedState))
ATerm id, statepath, componentHash, hashAlgo, hash, stateIdentifier, enabled, shareType, synchronization, createDirsBeforeInstall, runtimeStateArgs, username, sharedState;
if (!matchDerivationStateOutput(*i, id, statepath, componentHash, hashAlgo, hash, stateIdentifier, enabled, shareType, synchronization, createDirsBeforeInstall, runtimeStateArgs, username, sharedState))
throwBadDrv(t);
DerivationStateOutput stateOut;
stateOut.statepath = aterm2String(statepath);
@ -107,7 +107,7 @@ Derivation parseDerivation(ATerm t)
stateOut.shareType = aterm2String(shareType);
stateOut.synchronization = aterm2String(synchronization);
stateOut.createDirsBeforeInstall = aterm2String(createDirsBeforeInstall);
stateOut.runtimeStateParamters = aterm2String(runtimeStateParamters);
stateOut.runtimeStateArgs = aterm2String(runtimeStateArgs);
stateOut.username = aterm2String(username);
stateOut.sharedState = aterm2String(sharedState);
drv.stateOutputs[aterm2String(id)] = stateOut;
@ -199,7 +199,7 @@ ATerm unparseDerivation(const Derivation & drv)
toATerm(i->second.shareType),
toATerm(i->second.synchronization),
toATerm(i->second.createDirsBeforeInstall),
toATerm(i->second.runtimeStateParamters),
toATerm(i->second.runtimeStateArgs),
toATerm(i->second.username),
toATerm(i->second.sharedState)
));

View file

@ -49,7 +49,7 @@ struct DerivationStateOutput
string commitBinaries; //TODO list of binaries that need (or not) to be committed when these binaries are called
string createDirsBeforeInstall; //if true: creates state dirs before installation
string runtimeStateParamters; //if not empty: these are the runtime parameters where state can be found (you can use $statepath here)
string runtimeStateArgs; //if not empty: these are the runtime parameters where state can be found (you can use $statepath here)
string username;
@ -60,7 +60,7 @@ struct DerivationStateOutput
}
//TODO add const ??
DerivationStateOutput(Path statepath, string componentHash, string hashAlgo, string hash, string stateIdentifier, string enabled, string shareType, string synchronization, string createDirsBeforeInstall, string runtimeStateParamters, string username, string sharedState, bool check=true)
DerivationStateOutput(Path statepath, string componentHash, string hashAlgo, string hash, string stateIdentifier, string enabled, string shareType, string synchronization, string createDirsBeforeInstall, string runtimeStateArgs, string username, string sharedState, bool check=true)
{
if(check){
if(shareType != "none" && shareType != "full" && shareType != "group")
@ -71,6 +71,10 @@ struct DerivationStateOutput
throw Error(format("Username cannot be empty"));
if(stateIdentifier == "__EMTPY__" || stateIdentifier == "__NOSTATE__")
throw Error(format("the stateIdenfier cannot be this value '%1%'") % stateIdentifier);
if(runtimeStateArgs == "__NOARGS__")
throw Error(format("the runtimeStateArgs cannot be this value '%1%'") % runtimeStateArgs);
}
//TODO
@ -86,7 +90,7 @@ struct DerivationStateOutput
this->shareType = shareType;
this->synchronization = synchronization;
this->createDirsBeforeInstall = createDirsBeforeInstall;
this->runtimeStateParamters = runtimeStateParamters;
this->runtimeStateArgs = runtimeStateArgs;
this->username = username;
this->sharedState = sharedState;
}
@ -112,7 +116,7 @@ struct DerivationStateOutput
this->shareType = "";
this->synchronization = "";
this->createDirsBeforeInstall = "";
this->runtimeStateParamters = "";
this->runtimeStateArgs = "";
//this->username; //Changes the statepath directly
this->sharedState = "";

View file

@ -489,7 +489,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
for (PathSet::iterator i = livePaths.begin();
i != livePaths.end(); ++i)
if (isDerivation(*i)) {
Derivation drv = derivationFromPath(*i);
Derivation drv = derivationFromPathTxn(noTxn, *i);
for (DerivationOutputs::iterator j = drv.outputs.begin();
j != drv.outputs.end(); ++j)
if (store->isValidPath(j->second.path))

View file

@ -453,7 +453,6 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
throw Error(format("cannot set references for path `%1%' which is invalid and has no substitutes") % store_or_statePath);
printMsg(lvlError, format("Setting references for %1% (revision:%2%)") % store_or_statePath % int2String(revision));
/*
for (PathSet::iterator i = references.begin(); i != references.end(); ++i)
printMsg(lvlError, format("'%2%' has references: %1%") % *i % store_or_statePath);
@ -463,6 +462,8 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
if(isRealisablePath(txn, store_or_statePath))
{
printMsg(lvlError, format("Setting references for storepath '%1%'") % store_or_statePath);
//Just overwrite the old references, since there is oly 1 revision of a storePath
Paths oldReferences_c_c;
@ -481,6 +482,8 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
else if(isRealisableStatePath(txn, store_or_statePath))
{
printMsg(lvlError, format("Setting references for statepath '%1%' (revision:%2%)") % store_or_statePath % int2String(revision));
//Write references to a special revision (since there are multiple revisions of a statePath)
//query the references of revision (-1 is query the latest references)
@ -498,7 +501,7 @@ 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 int revision, int timestamp)
@ -693,9 +696,7 @@ void setDeriver(const Transaction & txn, const Path & storePath, const Path & de
if (!isRealisablePath(txn, storePath))
throw Error(format("path `%1%' is not valid") % storePath);
//printMsg(lvlError, format("Ttttttttttttttttttttttttt %1%") % deriver);
if (isStateDrvPathTxn(txn, deriver)){ //Redirect if its a state component //hanges somtimes !!!!!!!!!!!!!!!!!!!
if (isStateDrvPathTxn(txn, deriver)){ //Redirect if its a state component
addStateDeriver(txn, storePath, deriver);
}
else{
@ -712,14 +713,14 @@ PathSet mergeNewDerivationIntoList(const Path & storepath, const Path & newdrv,
{
PathSet newdrvs;
Derivation drv = derivationFromPath(newdrv);
Derivation drv = derivationFromPathTxn(noTxn, 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 = derivationFromPath(drv);
Derivation getdrv = derivationFromPathTxn(noTxn, drv);
string getIdentifier = getdrv.stateOutputs.find("state")->second.stateIdentifier;
string getUser = getdrv.stateOutputs.find("state")->second.username;
@ -747,7 +748,7 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path
if (!isRealisablePath(txn, storePath))
throw Error(format("path `%1%' is not valid") % storePath);
Derivation drv = derivationFromPath(deriver);
Derivation drv = derivationFromPathTxn(txn, deriver);
string identifier = drv.stateOutputs.find("state")->second.stateIdentifier;
string user = drv.stateOutputs.find("state")->second.username;
@ -786,8 +787,7 @@ bool LocalStore::isStateComponent(const Path & storePath)
bool isStateDrvPathTxn(const Transaction & txn, const Path & drvPath)
{
//printMsg(lvlError, format("Sssssssssssssssssss %1%") % drvPath);
Derivation drv = derivationFromPath(drvPath);
Derivation drv = derivationFromPathTxn(txn, drvPath);
return isStateDrvTxn(txn, drv);
}
@ -817,7 +817,7 @@ Path queryDeriver(const Transaction & txn, const Path & storePath)
bool b = nixDB.queryString(txn, dbDerivers, storePath, deriver);
Derivation drv = derivationFromPath(deriver);
Derivation drv = derivationFromPathTxn(txn, deriver);
if (isStateDrvTxn(txn, drv))
throw Error(format("This deriver `%1%' is a state deriver, u should use queryDerivers instead of queryDeriver") % deriver);
@ -843,7 +843,7 @@ PathSet queryDerivers(const Transaction & txn, const Path & storePath, const str
for (Strings::iterator i = alldata.begin(); i != alldata.end(); ++i) { //filter on username and identifier
string derivationpath = (*i);
Derivation drv = derivationFromPath(derivationpath);
Derivation drv = derivationFromPathTxn(txn, derivationpath);
if (drv.outputs.size() != 1)
throw Error(format("The call queryDerivers with storepath %1% is not a statePath") % storePath);
@ -1093,8 +1093,9 @@ void registerValidPaths(const Transaction & txn, const ValidPathInfos & infos)
//We cannot check the statePath since registerValidPath is called twice, first for the component path, and then for the state path....
if(isStorePath_b)
if(isStorePath_b){
setDeriver(txn, i->path, i->deriver);
}
//TODO maybe also set a state deriver into dbStateDerivers .... well state is already linked to a drvpath in dbValidStatePaths ....
}
@ -1649,7 +1650,7 @@ void storePathRequisitesTxn(const Transaction & txn, const Path & storeOrstatePa
for (PathSet::iterator i = paths.begin();
i != paths.end(); ++i)
if (isDerivation(*i)) {
Derivation drv = derivationFromPath(*i);
Derivation drv = derivationFromPathTxn(txn, *i);
for (DerivationOutputs::iterator j = drv.outputs.begin();
j != drv.outputs.end(); ++j)
if (isValidPathTxn(txn, j->second.path))
@ -1816,9 +1817,8 @@ PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePa
Path statePath_ns = toNonSharedPathTxn(txn, statePath);
PathSet empty;
return getSharedWithPathSetRecTxn_private(txn, statePath_ns, empty);
}
}
/* Upgrade from schema 1 (Nix <= 0.7) to schema 2 (Nix >= 0.8). */
static void upgradeStore07()
{

View file

@ -244,6 +244,8 @@ PathSet toNonSharedPathSetTxn(const Transaction & txn, const PathSet & statePath
Path toNonSharedPathTxn(const Transaction & txn, const Path & statePath);
PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePath);
void ensurePathTxn(const Transaction & txn, const Path & path);
}

View file

@ -9,13 +9,13 @@
namespace nix {
Derivation derivationFromPath(const Path & drvPath)
Derivation derivationFromPathTxn(const Transaction & txn, const Path & drvPath)
{
assertStorePath(drvPath);
store->ensurePath(drvPath);
//printMsg(lvlError, format("uuuuuuuuuuuuuuuuuu"));
ensurePathTxn(txn, drvPath);
ATerm t = ATreadFromNamedFile(drvPath.c_str());
if (!t) throw Error(format("cannot read aterm from `%1%'") % drvPath);
if (!t)
throw Error(format("cannot read aterm from `%1%'") % drvPath);
return parseDerivation(t);
}
@ -103,7 +103,7 @@ void queryMissing(const PathSet & targets,
if (isDerivation(p)) {
if (!store->isValidPath(p)) continue;
Derivation drv = derivationFromPath(p);
Derivation drv = derivationFromPathTxn(noTxn, p);
bool mustBuild = false;
for (DerivationOutputs::iterator i = drv.outputs.begin();

View file

@ -10,7 +10,7 @@ namespace nix {
/* Read a derivation, after ensuring its existence through
ensurePath(). */
Derivation derivationFromPath(const Path & drvPath);
Derivation derivationFromPathTxn(const Transaction & txn, 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

View file

@ -73,7 +73,7 @@ Snapshots commitStatePathTxn(const Transaction & txn, const Path & statePath)
throw Error(format("path `%1%' is not a valid state path") % statePath);
//queryDeriversStatePath??
Derivation drv = derivationFromPath(queryStatePathDrvTxn(txn, statePath));
Derivation drv = derivationFromPathTxn(txn, queryStatePathDrvTxn(txn, statePath));
DerivationStateOutputs stateOutputs = drv.stateOutputs;
DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs;

View file

@ -162,6 +162,7 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
ATermList manifest = ATempty;
ATermList inputs = ATempty;
ATermList stateIdentifiers = ATempty;
ATermList runtimeStateArgs = ATempty;
for (DrvInfos::const_iterator i = elems.begin();
i != elems.end(); ++i)
{
@ -193,6 +194,8 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
//Insert the new stateIdentifier into the stateIdentifiers Atermlist
stateIdentifiers = ATinsert(stateIdentifiers, makeStr(i->queryStateIdentifier(state)));
//Insert the new runtime state args into the runtimeStateArgs Atermlist
runtimeStateArgs = ATinsert(runtimeStateArgs, makeStr(i->queryRuntimeStateArgs(state)));
inputs = ATinsert(inputs, makeStr(i->queryOutPath(state)));
@ -207,25 +210,34 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
}
//printMsg(lvlError, format("TEST '%1%'") % atPrint(canonicaliseExpr(makeList(ATreverse(stateIdentifiers)))) );
//printMsg(lvlError, format("TEST '%1%'") % atPrint(canonicaliseExpr(makeList(ATreverse(runtimeStateArgs)))) );
/* Also write a copy of the list of inputs to the store; we need
it for future modifications of the environment. */
Path manifestFile = store->addTextToStore("env-manifest", atPrint(canonicaliseExpr(makeList(ATreverse(manifest)))), references);
Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList6(
makeBind(toATerm("system"),
makeStr(thisSystem), makeNoPos()),
makeBind(toATerm("derivations"),
makeList(ATreverse(manifest)), makeNoPos()),
makeBind(toATerm("stateIdentifiers"),
makeList(ATreverse(stateIdentifiers)), makeNoPos()),
makeBind(toATerm("manifest"),
makeStr(manifestFile, singleton<PathSet>(manifestFile)), makeNoPos()),
makeBind(toATerm("nixBinDir"),
makeStr(nixBinDir), makeNoPos()),
Expr topLevel = makeCall(envBuilder, makeAttrs(
ATinsert(
ATmakeList6(
makeBind(toATerm("system"),
makeStr(thisSystem), makeNoPos()),
makeBind(toATerm("derivations"),
makeList(ATreverse(manifest)), makeNoPos()),
makeBind(toATerm("stateIdentifiers"),
makeList(ATreverse(stateIdentifiers)), makeNoPos()),
makeBind(toATerm("runtimeStateArgs"),
makeList(ATreverse(runtimeStateArgs)), makeNoPos()),
makeBind(toATerm("manifest"),
makeStr(manifestFile, singleton<PathSet>(manifestFile)), makeNoPos()),
makeBind(toATerm("nixBinDir"),
makeStr(nixBinDir), makeNoPos()) )
,
makeBind(toATerm("nixStore"),
makeStr(nixStore), makeNoPos())
)));
)
));
/* Instantiate it. */
debug(format("evaluating builder expression `%1%'") % topLevel);
@ -391,7 +403,7 @@ static void queryInstSources(EvalState & state,
if (isDerivation(*i)) {
elem.setDrvPath(*i);
elem.setOutPath(findOutput(derivationFromPath(*i), "out"));
elem.setOutPath(findOutput(derivationFromPathTxn(noTxn, *i), "out"));
if (name.size() >= drvExtension.size() &&
string(name, name.size() - drvExtension.size()) == drvExtension)
@ -484,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 = derivationFromPath(i->queryDrvPath(globals.state));
Derivation drv = derivationFromPathTxn(noTxn, i->queryDrvPath(globals.state));
if(store->isStateDrv(drv))
{
DerivationStateOutputs stateOutputs = drv.stateOutputs;
@ -515,6 +527,7 @@ static void installDerivations(Globals & globals,
{
DrvName drvName(i->name);
//We may need to share state
if (!globals.preserveInstalled && newNames.find(drvName.name) != newNames.end()){
//******** We're gonna check if the component and state indentifiers are the same,
@ -530,7 +543,7 @@ static void installDerivations(Globals & globals,
for (DrvInfos::iterator j = newElems.begin(); j != newElems.end(); ++j) {
DrvName newDrvName(j->name);
if(newDrvName.name == drvName.name){
Derivation newDrv = derivationFromPath(j->queryDrvPath(globals.state));
Derivation newDrv = derivationFromPathTxn(noTxn, j->queryDrvPath(globals.state));
DerivationStateOutputs newStateOutputs = newDrv.stateOutputs;
newStateIdentifier = newStateOutputs.find("state")->second.stateIdentifier;
newStatePath = newDrv.stateOutputs.find("state")->second.statepath;
@ -540,6 +553,8 @@ static void installDerivations(Globals & globals,
}
//printMsg(lvlError, format("old '%1%' new '%2%'") % oldStateIdentifier % newStateIdentifier);
//if it doesnt need to share state with some other component
//&& the identifiers are equal
if( newSharedState == ""
&&
(oldStateIdentifier == newStateIdentifier
@ -553,7 +568,7 @@ static void installDerivations(Globals & globals,
throw Error(format("Internal Error: There is not exactly one deriver with state_identifier '%1%' for path '%2%'")
% newStateIdentifier % i->queryOutPath(globals.state));
Path oldDrvPath = *(derivers.begin());
Derivation oldDrv = derivationFromPath(oldDrvPath);
Derivation oldDrv = derivationFromPathTxn(noTxn, oldDrvPath);
oldStatePath = oldDrv.stateOutputs.find("state")->second.statepath;
//SharePaths

View file

@ -83,7 +83,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 = derivationFromPath(derivationPath);
Derivation drv = derivationFromPathTxn(noTxn, derivationPath);
if(isStateComponent){
DerivationStateOutputs stateOutputs = drv.stateOutputs;
@ -275,7 +275,7 @@ static void revertToRevision(Strings opFlags, Strings opArgs)
int timestamp = getTimestamps[statePath];
//get its derivation-state-items
Derivation statePath_drv = derivationFromPath(queryStatePathDrvTxn(noTxn, statePath));
Derivation statePath_drv = derivationFromPathTxn(noTxn, queryStatePathDrvTxn(noTxn, statePath));
DerivationStateOutputDirs stateOutputDirs = statePath_drv.stateOutputDirs;
//TODO Sort snapshots??? eg first restore root, then the subdirs??

View file

@ -75,7 +75,7 @@ static Path realisePath(const Path & path)
PathSet paths;
paths.insert(path);
store->buildDerivations(paths);
Path outPath = findOutput(derivationFromPath(path), "out");
Path outPath = findOutput(derivationFromPathTxn(noTxn, path), "out");
if (gcRoot == "")
printGCWarning();
@ -184,7 +184,7 @@ static Path maybeUseOutput(const Path & storePath, bool useOutput, bool forceRea
if (forceRealise)
realisePath(storePath);
if (useOutput && isDerivation(storePath)) {
Derivation drv = derivationFromPath(storePath);
Derivation drv = derivationFromPathTxn(noTxn, storePath);
return findOutput(drv, "out");
}
else return storePath;
@ -290,7 +290,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
{
*i = fixPath(*i);
if (forceRealise) realisePath(*i);
Derivation drv = derivationFromPath(*i);
Derivation drv = derivationFromPathTxn(noTxn, *i);
cout << format("%1%\n") % findOutput(drv, "out");
}
break;
@ -342,7 +342,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
i != opArgs.end(); ++i)
{
Path path = useDeriver(fixPath(*i));
Derivation drv = derivationFromPath(path);
Derivation drv = derivationFromPathTxn(noTxn, path);
StringPairs::iterator j = drv.env.find(bindingName);
if (j == drv.env.end())
throw Error(format("derivation `%1%' has no environment binding named `%2%'")