Author: schubi2
Date: Thu Nov 8 15:56:31 2007
New Revision: 7760
URL: http://svn.opensuse.org/viewcvs/zypp?rev=7760&view=rev
Log:
Error handling added.
Modified:
trunk/libzypp/zypp/sat/SATResolver.cc
trunk/libzypp/zypp/sat/SATResolver.h
Modified: trunk/libzypp/zypp/sat/SATResolver.cc
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/sat/SATResolver.cc?rev=7760&r1=7759&r2=7760&view=diff
==============================================================================
--- trunk/libzypp/zypp/sat/SATResolver.cc (original)
+++ trunk/libzypp/zypp/sat/SATResolver.cc Thu Nov 8 15:56:31 2007
@@ -14,7 +14,7 @@
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
+ * along with this program; if not, write the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307, USA.
*/
@@ -31,10 +31,13 @@
#include "zypp/ResFilters.h"
#include "zypp/CapFilters.h"
#include "zypp/sat/SATResolver.h"
+#include "zypp/solver/detail/ProblemSolutionCombi.h"
extern "C" {
#include "satsolver/repo_solv.h"
#include "satsolver/poolarch.h"
+#include "satsolver/evr.h"
+#include "satsolver/poolvendor.h"
}
/////////////////////////////////////////////////////////////////////////
@@ -81,6 +84,7 @@
SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
: _pool (pool)
, _SATPool (SATPool)
+ , solv(NULL)
, _timeout_seconds (0)
, _maxSolverPasses (0)
, _testing (false)
@@ -270,7 +274,7 @@
kind = ResTraitszypp::Language::kind;
}
else {
- ERR << "get_poolItem unknown kind '" << str << "'" << endl;
+ ERR << "string2kind unknown kind '" << str << "'" << endl;
}
}
return kind;
@@ -500,8 +504,6 @@
resfilter::ByKeep( ), // collect keeps from Pool to resolver queue
functor::functorRef(info) );
- Queue trials;
-
for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
PoolItem_Ref r = *iter;
@@ -509,8 +511,8 @@
if (id == ID_NULL) {
ERR << "Install: " << *iter << " not found" << endl;
}
- queue_push( &(trials), SOLVER_INSTALL_SOLVABLE );
- queue_push( &(trials), id );
+ queue_push( &(jobQueue), SOLVER_INSTALL_SOLVABLE );
+ queue_push( &(jobQueue), id );
}
for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
@@ -519,8 +521,8 @@
iter->resolvable()->name().c_str()
);
Id id = str2id( _SATPool, packageName.c_str(), 1 );
- queue_push( &(trials), SOLVER_ERASE_SOLVABLE_NAME );
- queue_push( &(trials), id);
+ queue_push( &(jobQueue), SOLVER_ERASE_SOLVABLE_NAME );
+ queue_push( &(jobQueue), id);
}
// Searching concerning system repo
@@ -534,7 +536,7 @@
}
}
- Solver *solv = solver_create( _SATPool, systemRepo );
+ solv = solver_create( _SATPool, systemRepo );
solv->fixsystem = false;
solv->updatesystem = false;
solv->allowdowngrade = false;
@@ -543,7 +545,7 @@
_SATPool->verbose = true;
// Solve !
- solve( solv, &(trials) );
+ solve( solv, &(jobQueue) );
// copying solution back to zypp pool
//-----------------------------------------
@@ -625,12 +627,301 @@
// clean up
solver_free(solv);
- queue_free( &(trials) );
+ solv = NULL;
+ queue_free( &(jobQueue) );
return true;
}
+//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+// error handling
+//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+
+
+
+ResolverProblemList
+SATResolver::problems () const
+{
+ ResolverProblemList resolverProblems;
+ if (solv && solv->problems.count)
+ {
+ Queue problems;
+ Queue solution;
+ Id *problem;
+ Id why, what;
+ int j, ji, pcnt, i;
+ Rule *r;
+ Solvable *s;
+ Pool *pool = solv->pool;
+
+ queue_clone(&problems, &solv->problems);
+ queue_init(&solution);
+ MIL << "Encountered problems! Here are the solutions:\n" << endl;
+ problem = problems.elements;
+ pcnt = 1;
+ MIL << "Problem " << pcnt << ":" << endl;
+ MIL << "====================================" << endl;
+ string whatString = str::form (_("Problem %d:"), pcnt);
+ ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, "");
+
+ for (i = 0; i < problems.count; i++)
+ {
+ Id v = problems.elements[i];
+ if (v == 0)
+ {
+ if (i + 1 == problems.count)
+ break;
+ // save old problem
+ resolverProblems.push_back (resolverProblem);
+ MIL << "Problem " << ++pcnt << ":" << endl;
+ MIL << "====================================" << endl;
+ // generate new problem
+ string what = str::form (_("Problem %d:"), pcnt);
+ resolverProblem = new ResolverProblem (what, "");
+ problem = problems.elements + i + 1;
+ continue;
+ }
+ if (v >= solv->jobrules && v < solv->systemrules)
+ {
+ ji = solv->ruletojob.elements[v - solv->jobrules];
+ for (j = 0; ; j++)
+ {
+ if (problem[j] >= solv->jobrules && problem[j] < solv->systemrules && ji == solv->ruletojob.elements[problem[j] - solv->jobrules])
+ break;
+ }
+ if (problem + j < problems.elements + i)
+ continue;
+ }
+ refine_suggestion(solv, problem, v, &solution);
+
+ ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
+
+ for (j = 0; j < solution.count; j++)
+ {
+ r = solv->rules + solution.elements[j];
+ why = solution.elements[j];
+#if 0
+ printrule(solv, r);
+#endif
+ if (why >= solv->jobrules && why < solv->systemrules)
+ {
+ ji = solv->ruletojob.elements[why - solv->jobrules];
+ what = jobQueue.elements[ji + 1];
+ switch (jobQueue.elements[ji])
+ {
+ case SOLVER_INSTALL_SOLVABLE: {
+ s = pool->solvables + what;
+ std::vectorstd::string nameVector;
+ string kindName(id2str(_SATPool, s->name));
+
+ // expect "<kind>::<name>"
+ unsigned count = str::split( kindName, std::back_inserter(nameVector), ":" );
+ PoolItem_Ref poolItem;
+ if (count >= 2) {
+ poolItem = get_poolItem (_pool,
+ s->repo ? string(repo_name(s->repo)) : "", //repo
+ nameVector[1], // name
+ nameVector[0], // kind,
+ string(id2str(_SATPool, s->evr)),
+ string(id2str(_SATPool, s->arch)));
+ }
+ if (poolItem) {
+ if (what >= solv->installed->start && what < solv->installed->start + solv->installed->nsolvables) {
+ problemSolution->addSingleAction (poolItem, REMOVE);
+ MIL << "- do not keep " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch) <<
+ " installed" << endl;
+ } else {
+ problemSolution->addSingleAction (poolItem, KEEP);
+ MIL << "- do not install " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch) <<
+ endl;
+ }
+ } else {
+ ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << id2str(pool, s->name) << "-"
+ << id2str(pool, s->evr) << "." << id2str(pool, s->arch) << endl;
+ }
+ }
+ break;
+ case SOLVER_ERASE_SOLVABLE: {
+ s = pool->solvables + what;
+ std::vectorstd::string nameVector;
+ string kindName(id2str(_SATPool, s->name));
+
+ // expect "<kind>::<name>"
+ unsigned count = str::split( kindName, std::back_inserter(nameVector), ":" );
+ PoolItem_Ref poolItem;
+
+ if (count >= 2) {
+ poolItem = get_poolItem (_pool,
+ s->repo ? string(repo_name(s->repo)) : "", //repo
+ nameVector[1], // name
+ nameVector[0], // kind,
+ string(id2str(_SATPool, s->evr)),
+ string(id2str(_SATPool, s->arch)));
+ }
+ if (poolItem) {
+ if (what >= solv->installed->start && what < solv->installed->start + solv->installed->nsolvables) {
+ problemSolution->addSingleAction (poolItem, KEEP);
+ MIL << "- do not deinstall " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch) <<
+ endl;
+ } else {
+ problemSolution->addSingleAction (poolItem, INSTALL);
+ MIL << "- do not forbid installation of " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "."
+ << id2str(pool, s->arch) << endl;
+ }
+ } else {
+ ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." <<
+ id2str(pool, s->arch) << endl;
+ }
+ }
+ break;
+ case SOLVER_INSTALL_SOLVABLE_NAME:
+ MIL << "- do not install "<< id2str(pool, what) << endl;;
+ ERR << "No valid solution available" << endl;
+ break;
+ case SOLVER_ERASE_SOLVABLE_NAME:
+ MIL << "- do not deinstall " << id2str(pool, what) << endl;
+ ERR << "No valid solution available" << endl;
+ break;
+ case SOLVER_INSTALL_SOLVABLE_PROVIDES:
+ MIL << "- do not install a solvable providing " << dep2str(pool, what) << endl;
+ ERR << "No valid solution available" << endl;
+ break;
+ case SOLVER_ERASE_SOLVABLE_PROVIDES:
+ MIL << "- do not deinstall all solvables providing " << dep2str(pool, what) << endl;
+ ERR << "No valid solution available" << endl;
+ break;
+ case SOLVER_INSTALL_SOLVABLE_UPDATE:
+ s = pool->solvables + what;
+ MIL << "- do not install most recent version of " << id2str(pool, s->name) << "-" << id2str(pool, s->evr)
+ << "." << id2str(pool, s->arch) << endl;
+ ERR << "No valid solution available" << endl;
+ break;
+ default:
+ MIL << "- do something different" << endl;
+ ERR << "No valid solution available" << endl;
+ break;
+ }
+ }
+ else if (why >= solv->systemrules && why < solv->weakrules)
+ {
+ Solvable *sd = 0;
+ s = pool->solvables + solv->installed->start + (why - solv->systemrules);
+ if (solv->weaksystemrules && solv->weaksystemrules[why - solv->systemrules])
+ {
+ Id *dp = pool->whatprovidesdata + solv->weaksystemrules[why - solv->systemrules];
+ for (; *dp; dp++)
+ {
+ if (*dp >= solv->installed->start && *dp < solv->installed->start + solv->installed->nsolvables)
+ continue;
+ if (solv->decisionmap[*dp] > 0)
+ {
+ sd = pool->solvables + *dp;
+ break;
+ }
+ }
+ }
+
+ std::vectorstd::string nameVector;
+ string kindNameFrom(id2str(_SATPool, s->name));
+ // expect "<kind>::<name>"
+ unsigned count = str::split( kindNameFrom, std::back_inserter(nameVector), ":" );
+ PoolItem_Ref itemFrom;
+
+ if (count >= 2) {
+ itemFrom = get_poolItem (_pool,
+ s->repo ? string(repo_name(s->repo)) : "", //repo
+ nameVector[1], // name
+ nameVector[0], // kind,
+ string(id2str(_SATPool, s->evr)),
+ string(id2str(_SATPool, s->arch)));
+ }
+ if (sd)
+ {
+ int gotone = 0;
+
+ string kindNameTo(id2str(_SATPool, sd->name));
+ // expect "<kind>::<name>"
+ count = str::split( kindNameTo, std::back_inserter(nameVector), ":" );
+ PoolItem_Ref itemTo;
+ if (count >= 2) {
+ itemTo = get_poolItem (_pool,
+ sd->repo ? string(repo_name(s->repo)) : "", //repo
+ nameVector[1], // name
+ nameVector[0], // kind,
+ string(id2str(_SATPool, sd->evr)),
+ string(id2str(_SATPool, sd->arch)));
+ }
+ if (itemFrom && itemTo) {
+ problemSolution->addSingleAction (itemTo, INSTALL);
+ problemSolution->addSingleAction (itemFrom, REMOVE);
+
+ if (evrcmp(pool, sd->evr, s->evr) < 0)
+ {
+ MIL << "- allow downgrade of " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch)
+ << " to " << id2str(pool, sd->name) << "-" << id2str(pool, sd->evr) << "." << id2str(pool, sd->arch) << endl;
+ gotone = 1;
+ }
+ if (!solv->allowarchchange && s->name == sd->name && archchanges(pool, sd, s))
+ {
+ MIL << "- allow architecture change of " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch)
+ << " to " << id2str(pool, sd->name) << "-" << id2str(pool, sd->evr) << "." << id2str(pool, sd->arch) << endl;
+ gotone = 1;
+ }
+ if (!solv->allowvendorchange && s->name == sd->name && s->vendor != sd->vendor && pool_vendor2mask(pool, s->vendor) && (pool_vendor2mask(pool, s->vendor) & pool_vendor2mask(pool, sd->vendor)) == 0)
+ {
+ MIL << "- allow vendor change of " << id2str(pool, s->vendor) << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch)
+ << " to " << string(sd->vendor ? id2str(pool, sd->vendor) : " (no vendor) ") << id2str(pool, sd->name) << "-" << id2str(pool, sd->evr) << "." << id2str(pool, sd->arch) << endl;
+ gotone = 1;
+ }
+ if (!gotone) {
+ MIL << "- allow replacement of " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch)
+ << " to " << id2str(pool, sd->name) << "-" << id2str(pool, sd->evr) << "." << id2str(pool, sd->arch) << endl;
+ }
+ } else {
+ ERR << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch)
+ << " or " << id2str(pool, sd->name) << "-" << id2str(pool, sd->evr) << "." << id2str(pool, sd->arch) << " not found" << endl;
+ }
+ }
+ else
+ {
+ if (itemFrom) {
+ problemSolution->addSingleAction (itemFrom, REMOVE);
+ MIL << "- allow replacement of " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch) << endl;
+ }
+ }
+ }
+ }
+ resolverProblem->addSolution (problemSolution);
+ MIL << "------------------------------------" << endl;
+ }
+
+ // save last problem
+ resolverProblems.push_back (resolverProblem);
+
+ queue_free(&solution);
+ queue_free(&problems);
+ }
+
+ return resolverProblems;
+}
+
+void
+SATResolver::applySolutions (const ProblemSolutionList & solutions)
+{
+ for (ProblemSolutionList::const_iterator iter = solutions.begin();
+ iter != solutions.end(); ++iter) {
+ ProblemSolution_Ptr solution = *iter;
+ Resolver dummyResolver(_pool);
+ if (!solution->apply (dummyResolver))
+ break;
+ }
+}
+
+
+
///////////////////////////////////////////////////////////////////
};// namespace detail
/////////////////////////////////////////////////////////////////////
Modified: trunk/libzypp/zypp/sat/SATResolver.h
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/sat/SATResolver.h?rev=7760&r1=7759&r2=7760&view=diff
==============================================================================
--- trunk/libzypp/zypp/sat/SATResolver.h (original)
+++ trunk/libzypp/zypp/sat/SATResolver.h Thu Nov 8 15:56:31 2007
@@ -60,6 +60,8 @@
private:
ResPool _pool;
Pool *_SATPool;
+ Solver *solv;
+ Queue jobQueue;
unsigned _timeout_seconds;
unsigned _maxSolverPasses;
@@ -97,8 +99,8 @@
bool resolvePool();
-// ResolverProblemList problems () const;
-// void applySolutions (const ProblemSolutionList &solutions);
+ ResolverProblemList problems () const;
+ void applySolutions (const ProblemSolutionList &solutions);
Arch architecture() const { return _architecture; }
void setArchitecture( const Arch & arch) { _architecture = arch; }
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org