mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 12:10:59 +01:00
Fixed bug in build.cc All paths are now correctly scanned for the statpaths from the derivation inputs
This commit is contained in:
parent
c370c9f535
commit
1c3ec86c39
3 changed files with 92 additions and 36 deletions
|
|
@ -579,6 +579,10 @@ private:
|
||||||
immediate input paths). */
|
immediate input paths). */
|
||||||
PathSet inputPaths;
|
PathSet inputPaths;
|
||||||
|
|
||||||
|
/* All input-state-paths (that is, the union of FS closures of the
|
||||||
|
immediate input paths). */
|
||||||
|
PathSet inputStatePaths;
|
||||||
|
|
||||||
/* Referenceable paths (i.e., input and output paths). */
|
/* Referenceable paths (i.e., input and output paths). */
|
||||||
PathSet allPaths;
|
PathSet allPaths;
|
||||||
|
|
||||||
|
|
@ -773,12 +777,11 @@ void DerivationGoal::haveDerivation()
|
||||||
i != drv.outputs.end(); ++i)
|
i != drv.outputs.end(); ++i)
|
||||||
store->addTempRoot(i->second.path);
|
store->addTempRoot(i->second.path);
|
||||||
|
|
||||||
|
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Also add a temproot for state ????????????
|
||||||
|
|
||||||
/* Check what outputs paths are not already valid. */
|
/* Check what outputs paths are not already valid. */
|
||||||
PathSet invalidOutputs = checkPathValidity(false);
|
PathSet invalidOutputs = checkPathValidity(false);
|
||||||
|
|
||||||
//Just before we build the drvs, we already put in the database which component path is a state component path
|
|
||||||
printMsg(lvlError, format("updateAllStateDerivations %1%") % drvPath);
|
|
||||||
|
|
||||||
/* If they are all valid, then we're done. */
|
/* If they are all valid, then we're done. */
|
||||||
if (invalidOutputs.size() == 0) {
|
if (invalidOutputs.size() == 0) {
|
||||||
amDone(ecSuccess);
|
amDone(ecSuccess);
|
||||||
|
|
@ -1304,6 +1307,10 @@ bool DerivationGoal::prepareBuild()
|
||||||
allPaths.insert(i->second.path);
|
allPaths.insert(i->second.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The state output is a referenceable path */
|
||||||
|
if(store->isStateDrv(drv))
|
||||||
|
allStatePaths.insert(drv.stateOutputs.find("state")->second.statepath);
|
||||||
|
|
||||||
/* Determine the full set of input paths. */
|
/* Determine the full set of input paths. */
|
||||||
|
|
||||||
/* First, the input derivations. */
|
/* First, the input derivations. */
|
||||||
|
|
@ -1315,8 +1322,10 @@ bool DerivationGoal::prepareBuild()
|
||||||
assert(store->isValidPath(i->first));
|
assert(store->isValidPath(i->first));
|
||||||
Derivation inDrv = derivationFromPath(i->first);
|
Derivation inDrv = derivationFromPath(i->first);
|
||||||
for (StringSet::iterator j = i->second.begin(); j != i->second.end(); ++j)
|
for (StringSet::iterator j = i->second.begin(); j != i->second.end(); ++j)
|
||||||
if (inDrv.outputs.find(*j) != inDrv.outputs.end())
|
if (inDrv.outputs.find(*j) != inDrv.outputs.end()){
|
||||||
computeFSClosure(inDrv.outputs[*j].path, inputPaths, true, false); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE
|
computeFSClosure(inDrv.outputs[*j].path, inputPaths, true, false); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE (done?)
|
||||||
|
computeFSClosure(inDrv.outputs[*j].path, inputStatePaths, false, true); //TODO!!!!!!!!!!!!! HOW CAN THESE PATHS ALREADY BE VALID ..... ?????????????????????
|
||||||
|
}
|
||||||
else
|
else
|
||||||
throw BuildError(
|
throw BuildError(
|
||||||
format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'")
|
format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'")
|
||||||
|
|
@ -1324,12 +1333,16 @@ bool DerivationGoal::prepareBuild()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Second, the input sources. */
|
/* Second, the input sources. */
|
||||||
for (PathSet::iterator i = drv.inputSrcs.begin(); i != drv.inputSrcs.end(); ++i)
|
for (PathSet::iterator i = drv.inputSrcs.begin(); i != drv.inputSrcs.end(); ++i){
|
||||||
computeFSClosure(*i, inputPaths, true, false); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE
|
computeFSClosure(*i, inputPaths, true, false); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE (done?)
|
||||||
|
computeFSClosure(*i, inputStatePaths, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
debug(format("added input paths %1%") % showPaths(inputPaths));
|
debug(format("added input paths %1%") % showPaths(inputPaths));
|
||||||
|
debug(format("added input state paths %1%") % showPaths(inputStatePaths));
|
||||||
|
|
||||||
allPaths.insert(inputPaths.begin(), inputPaths.end());
|
allPaths.insert(inputPaths.begin(), inputPaths.end());
|
||||||
|
allStatePaths.insert(inputStatePaths.begin(), inputStatePaths.end());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1629,12 +1642,15 @@ void DerivationGoal::computeClosure()
|
||||||
if(!drv.stateOutputs.find("state")->second.getCreateDirsBeforeInstall())
|
if(!drv.stateOutputs.find("state")->second.getCreateDirsBeforeInstall())
|
||||||
createStateDirs(drv.stateOutputDirs, drv.stateOutputs, drv.env);
|
createStateDirs(drv.stateOutputDirs, drv.stateOutputs, drv.env);
|
||||||
|
|
||||||
|
for (PathSet::iterator i = allPaths.begin(); i != allPaths.end(); ++i)
|
||||||
|
printMsg(lvlError, format("allPaths: %1%") % *i);
|
||||||
|
for (PathSet::iterator i = allStatePaths.begin(); i != allStatePaths.end(); ++i)
|
||||||
|
printMsg(lvlError, format("allStatePaths: %1%") % *i);
|
||||||
|
|
||||||
/* Check whether the output paths were created, and grep each
|
/* Check whether the output paths were created, and grep each
|
||||||
output path to determine what other paths it references. Also make all
|
output path to determine what other paths it references. Also make all
|
||||||
output paths read-only. */
|
output paths read-only. */
|
||||||
for (DerivationOutputs::iterator i = drv.outputs.begin();
|
for (DerivationOutputs::iterator i = drv.outputs.begin(); i != drv.outputs.end(); ++i)
|
||||||
i != drv.outputs.end(); ++i)
|
|
||||||
{
|
{
|
||||||
Path path = i->second.path;
|
Path path = i->second.path;
|
||||||
if (!pathExists(path)) {
|
if (!pathExists(path)) {
|
||||||
|
|
@ -1689,6 +1705,10 @@ void DerivationGoal::computeClosure()
|
||||||
/* For this output path, find the references to other paths contained in it. */
|
/* For this output path, find the references to other paths contained in it. */
|
||||||
PathSet references = scanForReferences(path, allPaths);
|
PathSet references = scanForReferences(path, allPaths);
|
||||||
|
|
||||||
|
//TODO comment
|
||||||
|
PathSet output_state_references = scanForReferences(path, allStatePaths);
|
||||||
|
allStateReferences[path] = output_state_references;
|
||||||
|
|
||||||
/* For debugging, print out the referenced and unreferenced
|
/* For debugging, print out the referenced and unreferenced
|
||||||
paths. */
|
paths. */
|
||||||
for (PathSet::iterator i = inputPaths.begin();
|
for (PathSet::iterator i = inputPaths.begin();
|
||||||
|
|
@ -1721,6 +1741,20 @@ void DerivationGoal::computeClosure()
|
||||||
contentHashes[path] = hashPath(htSHA256, path);
|
contentHashes[path] = hashPath(htSHA256, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Scan the state Path
|
||||||
|
/* For this state-output path, find the references to other paths contained in it.
|
||||||
|
* Get the state paths (instead of out paths) from all components, and then call
|
||||||
|
* scanForReferences().
|
||||||
|
*/
|
||||||
|
//If state is enabled: Seaches for state and component references in the state path
|
||||||
|
if(isStateDrvTxn(noTxn, drv)){ //TODO
|
||||||
|
Path statePath = drv.stateOutputs.find("state")->second.statepath;
|
||||||
|
printMsg(lvlTalkative, format("scanning for component and state references inside `%1%'") % statePath);
|
||||||
|
|
||||||
|
state_references = scanForReferences(statePath, allPaths);
|
||||||
|
state_stateReferences = scanForReferences(statePath, allStatePaths);
|
||||||
|
}
|
||||||
|
|
||||||
/* Register each output path as valid, and register the sets of
|
/* Register each output path as valid, and register the sets of
|
||||||
paths referenced by each of them. This is wrapped in one
|
paths referenced by each of them. This is wrapped in one
|
||||||
database transaction to ensure that if we crash, either
|
database transaction to ensure that if we crash, either
|
||||||
|
|
@ -1739,14 +1773,34 @@ void DerivationGoal::computeClosure()
|
||||||
i != drv.outputs.end(); ++i)
|
i != drv.outputs.end(); ++i)
|
||||||
{
|
{
|
||||||
//printMsg(lvlError, format("SetValidPath: %1%") % i->second.path);
|
//printMsg(lvlError, format("SetValidPath: %1%") % i->second.path);
|
||||||
|
/*
|
||||||
registerValidPath(txn, i->second.path,
|
registerValidPath(txn, i->second.path,
|
||||||
contentHashes[i->second.path],
|
contentHashes[i->second.path],
|
||||||
allReferences[i->second.path],
|
allReferences[i->second.path],
|
||||||
PathSet(), //dummy stateReferences
|
PathSet(), //dummy stateReferences
|
||||||
|
drvPath);*/
|
||||||
|
|
||||||
|
registerValidPath(txn,
|
||||||
|
i->second.path, //component path
|
||||||
|
contentHashes[i->second.path],
|
||||||
|
allReferences[i->second.path], //set of component-references
|
||||||
|
allStateReferences[i->second.path], //set of state-references
|
||||||
drvPath);
|
drvPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Register the state path valid
|
||||||
|
if(isStateDrvTxn(txn, drv))
|
||||||
|
{
|
||||||
|
Path statePath = drv.stateOutputs.find("state")->second.statepath;
|
||||||
|
|
||||||
|
registerValidPath(txn,
|
||||||
|
statePath,
|
||||||
|
Hash(), //emtpy hash
|
||||||
|
state_references,
|
||||||
|
state_stateReferences,
|
||||||
|
drvPath);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We first register alls paths as valid, and only scan for component references.
|
* We first register alls paths as valid, and only scan for component references.
|
||||||
* Now that those paths are registered as valid, we're able to call queryDeriversStatePath
|
* Now that those paths are registered as valid, we're able to call queryDeriversStatePath
|
||||||
|
|
@ -1758,6 +1812,10 @@ void DerivationGoal::computeClosure()
|
||||||
* [scan for and state references and component references in the state path] //3,4
|
* [scan for and state references and component references in the state path] //3,4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//TODO REMOVE?
|
||||||
|
/*
|
||||||
PathSet allStatePaths2;
|
PathSet allStatePaths2;
|
||||||
for (PathSet::const_iterator i = allPaths.begin(); i != allPaths.end(); i++){
|
for (PathSet::const_iterator i = allPaths.begin(); i != allPaths.end(); i++){
|
||||||
Path componentPath = *i;
|
Path componentPath = *i;
|
||||||
|
|
@ -1796,7 +1854,7 @@ void DerivationGoal::computeClosure()
|
||||||
/* For this state-output path, find the references to other paths contained in it.
|
/* For this state-output path, find the references to other paths contained in it.
|
||||||
* Get the state paths (instead of out paths) from all components, and then call
|
* Get the state paths (instead of out paths) from all components, and then call
|
||||||
* scanForReferences().
|
* scanForReferences().
|
||||||
*/
|
* /
|
||||||
//If state is enabled: Seaches for state and component references in the state path
|
//If state is enabled: Seaches for state and component references in the state path
|
||||||
if(isStateDrvTxn(txn, drv)){
|
if(isStateDrvTxn(txn, drv)){
|
||||||
Path statePath = drv.stateOutputs.find("state")->second.statepath;
|
Path statePath = drv.stateOutputs.find("state")->second.statepath;
|
||||||
|
|
@ -1828,11 +1886,10 @@ void DerivationGoal::computeClosure()
|
||||||
state_references,
|
state_references,
|
||||||
state_stateReferences,
|
state_stateReferences,
|
||||||
drvPath);
|
drvPath);
|
||||||
|
|
||||||
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
// WE NOW ONLY REGISTER COMPONETS PATHS WITH registerValidPath BUT WE SHOULD ALSO REGISTER STATE PAHTS AS VALID AND SET THEIR REFERENCES !!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
/* It is now safe to delete the lock files, since all future
|
/* It is now safe to delete the lock files, since all future
|
||||||
|
|
|
||||||
|
|
@ -398,7 +398,7 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
||||||
if (references.size() > 0 && !isRealisableComponentOrStatePath(txn, store_or_statePath))
|
if (references.size() > 0 && !isRealisableComponentOrStatePath(txn, store_or_statePath))
|
||||||
throw Error(format("cannot set references for path `%1%' which is invalid and has no substitutes") % 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("REGISTER: %1%") % store_or_statePath);
|
//printMsg(lvlError, format("REGISTER: %1%") % store_or_statePath);
|
||||||
|
|
||||||
Paths oldReferences;
|
Paths oldReferences;
|
||||||
nixDB.queryStrings(txn, dbReferences, store_or_statePath, oldReferences);
|
nixDB.queryStrings(txn, dbReferences, store_or_statePath, oldReferences);
|
||||||
|
|
@ -410,7 +410,7 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
||||||
|
|
||||||
if (oldReferences2 == references && oldStateReferences2 == stateReferences) return;
|
if (oldReferences2 == references && oldStateReferences2 == stateReferences) return;
|
||||||
|
|
||||||
printMsg(lvlError, format("REGISTER2: %1%") % store_or_statePath);
|
//printMsg(lvlError, format("REGISTER2: %1%") % store_or_statePath);
|
||||||
|
|
||||||
nixDB.setStrings(txn, dbReferences, store_or_statePath,
|
nixDB.setStrings(txn, dbReferences, store_or_statePath,
|
||||||
Paths(references.begin(), references.end()));
|
Paths(references.begin(), references.end()));
|
||||||
|
|
@ -511,19 +511,16 @@ void setDeriver(const Transaction & txn, const Path & storePath, const Path & de
|
||||||
assertStorePath(storePath);
|
assertStorePath(storePath);
|
||||||
if (deriver == "") return;
|
if (deriver == "") return;
|
||||||
assertStorePath(deriver);
|
assertStorePath(deriver);
|
||||||
printMsg(lvlError, format("yyyyyyyyyyyyyyyyyyyyyyyyy")); //hanged !!!!!!!!
|
|
||||||
|
|
||||||
if (!isRealisablePath(txn, storePath))
|
if (!isRealisablePath(txn, storePath))
|
||||||
throw Error(format("path `%1%' is not valid") % storePath);
|
throw Error(format("path `%1%' is not valid") % storePath);
|
||||||
|
|
||||||
printMsg(lvlError, format("Ttttttttttttttttttttttttt %1%") % deriver);
|
printMsg(lvlError, format("Ttttttttttttttttttttttttt %1%") % deriver);
|
||||||
|
|
||||||
if (isStateDrvPathTxn(txn, deriver)){ //Redirect if its a state component
|
if (isStateDrvPathTxn(txn, deriver)){ //Redirect if its a state component //hanges somtimes !!!!!!!!!!!!!!!!!!!
|
||||||
printMsg(lvlError, format("bbbbbbbbbbbbbbb"));
|
|
||||||
addStateDeriver(txn, storePath, deriver);
|
addStateDeriver(txn, storePath, deriver);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
printMsg(lvlError, format("ccccccccccccccccccc"));
|
|
||||||
nixDB.setString(txn, dbDerivers, storePath, deriver);
|
nixDB.setString(txn, dbDerivers, storePath, deriver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,22 +25,24 @@ void computeFSClosure(const Path & path, PathSet & paths, const bool & withCompo
|
||||||
if(!withComponents && !withState)
|
if(!withComponents && !withState)
|
||||||
throw Error(format("Useless call to computeFSClosure, at leat withComponents or withState must be true"));
|
throw Error(format("Useless call to computeFSClosure, at leat withComponents or withState must be true"));
|
||||||
|
|
||||||
//if withComponents is false .....
|
//TODO MAYBE EDIT: HOW CAN THESE PATHS ALREADY BE VALID SOMETIMES ..... ?????????????????????
|
||||||
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
for (PathSet::iterator i = allPaths.begin(); i != allPaths.end(); ++i)
|
||||||
|
if ( !store->isValidPath(*i) && !store->isValidStatePath(*i) )
|
||||||
|
throw Error(format("Not a state or store path: ") % *i);
|
||||||
|
|
||||||
//if withState is false, we filter out all state paths
|
//if withState is false, we filter out all state paths
|
||||||
if(withState == false){
|
if( withComponents && !withState ){
|
||||||
for (PathSet::iterator i = allPaths.begin(); i != allPaths.end(); ++i){
|
for (PathSet::iterator i = allPaths.begin(); i != allPaths.end(); ++i)
|
||||||
if ( ! store->isValidStatePath(*i) ){
|
if ( store->isValidPath(*i) )
|
||||||
paths.insert(*i);
|
paths.insert(*i);
|
||||||
|
|
||||||
//TODO (OBSOLETE) CHECK TO SEE IF THERE WERE NO /NIX/STATE PATHS THAT ARENT VALID AT THIS POINT, REMOVE THIS IN THE FUTURE
|
|
||||||
string test = "/nix/state";
|
|
||||||
if((*i).substr(0, test.size()) == test)
|
|
||||||
throw Error(format("THIS CANNOT HAPPEN ! computeFSClosure is called before the state path was valid...."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//if withComponents is false, we filter out all component paths
|
||||||
|
else if( !withComponents && withState ){
|
||||||
|
for (PathSet::iterator i = allPaths.begin(); i != allPaths.end(); ++i)
|
||||||
|
if ( store->isValidStatePath(*i) )
|
||||||
|
paths.insert(*i);
|
||||||
|
}
|
||||||
|
//all
|
||||||
else{
|
else{
|
||||||
paths = allPaths;
|
paths = allPaths;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue