1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
4 * Copyright (C) 2000-2002 Ximian, Inc.
5 * Copyright (C) 2005 SUSE Linux Products GmbH
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 #include <boost/static_assert.hpp>
23 #include "zypp/solver/detail/Resolver.h"
24 #include "zypp/solver/detail/Helper.h"
25 #include "zypp/solver/detail/Testcase.h"
27 #include "zypp/Capabilities.h"
28 #include "zypp/ZConfig.h"
29 #include "zypp/base/Logger.h"
30 #include "zypp/base/String.h"
31 #include "zypp/base/Gettext.h"
32 #include "zypp/base/Algorithm.h"
33 #include "zypp/ResPool.h"
34 #include "zypp/ResFilters.h"
35 #include "zypp/sat/Pool.h"
36 #include "zypp/sat/Solvable.h"
37 #include "zypp/sat/SATResolver.h"
39 #define MAXSOLVERRUNS 5
41 /////////////////////////////////////////////////////////////////////////
43 { ///////////////////////////////////////////////////////////////////////
44 ///////////////////////////////////////////////////////////////////////
46 { /////////////////////////////////////////////////////////////////////
47 /////////////////////////////////////////////////////////////////////
49 { ///////////////////////////////////////////////////////////////////
53 IMPL_PTR_TYPE(Resolver);
56 //---------------------------------------------------------------------------
60 Resolver::dumpOn( std::ostream & os ) const
62 return os << "<resolver/>";
66 //---------------------------------------------------------------------------
68 Resolver::Resolver (const ResPool & pool)
71 , _poolchanged(_pool.serial() )
72 , _forceResolve(false)
75 , _onlyRequires(DEFAULT)
78 sat::Pool satPool( sat::Pool::instance() );
79 _satResolver = new SATResolver(_pool, satPool.get());
87 //---------------------------------------------------------------------------
90 Resolver::pool (void) const
96 Resolver::reset (bool keepExtras )
101 _extra_requires.clear();
102 _extra_conflicts.clear();
110 return _satResolver->doUpdate();
112 ERR << "SAT solver has not been initialized." << endl;
118 Resolver::addExtraRequire (const Capability & capability)
120 _extra_requires.insert (capability);
124 Resolver::removeExtraRequire (const Capability & capability)
126 _extra_requires.erase (capability);
130 Resolver::addExtraConflict (const Capability & capability)
132 _extra_conflicts.insert (capability);
136 Resolver::removeExtraConflict (const Capability & capability)
138 _extra_conflicts.erase (capability);
142 Resolver::addIgnoreConflict (const PoolItem item,
143 const Capability & capability)
145 _ignoreConflicts.insert(make_pair(item, capability));
149 Resolver::addIgnoreRequires (const PoolItem item,
150 const Capability & capability)
152 _ignoreRequires.insert(make_pair(item, capability));
156 Resolver::addIgnoreObsoletes (const PoolItem item,
157 const Capability & capability)
159 _ignoreObsoletes.insert(make_pair(item, capability));
163 Resolver::addIgnoreInstalledItem (const PoolItem item)
165 _ignoreInstalledItem.push_back (item);
169 Resolver::addIgnoreArchitectureItem (const PoolItem item)
171 _ignoreArchitectureItem.push_back (item);
175 Resolver::addIgnoreVendorItem (const PoolItem item)
177 _ignoreVendorItem.push_back (item);
180 //---------------------------------------------------------------------------
182 struct UndoTransact : public resfilter::PoolItemFilterFunctor
184 ResStatus::TransactByValue resStatus;
185 UndoTransact ( const ResStatus::TransactByValue &status)
189 bool operator()( PoolItem item ) // only transacts() items go here
191 item.status().resetTransact( resStatus );// clear any solver/establish transactions
197 struct DoTransact : public resfilter::PoolItemFilterFunctor
199 ResStatus::TransactByValue resStatus;
200 DoTransact ( const ResStatus::TransactByValue &status)
204 bool operator()( PoolItem item ) // only transacts() items go here
206 item.status().setTransact( true, resStatus );
213 Resolver::verifySystem ()
215 UndoTransact resetting (ResStatus::APPL_HIGH);
217 _DEBUG ("Resolver::verifySystem() ");
221 invokeOnEach ( _pool.begin(), _pool.end(),
222 resfilter::ByTransact( ), // Resetting all transcations
223 functor::functorRef<bool,PoolItem>(resetting) );
225 return resolvePool();
229 //----------------------------------------------------------------------------
235 UndoTransact info(ResStatus::APPL_LOW);
236 MIL << "*** undo ***" << endl;
237 invokeOnEach ( _pool.begin(), _pool.end(),
238 resfilter::ByTransact( ), // collect transacts from Pool to resolver queue
239 functor::functorRef<bool,PoolItem>(info) );
240 // These conflict should be ignored of the concering item
241 _ignoreConflicts.clear();
242 // These requires should be ignored of the concering item
243 _ignoreRequires.clear();
244 // These obsoletes should be ignored of the concering item
245 _ignoreObsoletes.clear();
246 // Ignore architecture of the item
247 _ignoreArchitecture.clear();
248 // Ignore the status "installed" of the item
249 _ignoreInstalledItem.clear();
250 // Ignore the architecture of the item
251 _ignoreArchitectureItem.clear();
252 // Ignore the vendor of the item
253 _ignoreVendorItem.clear();
261 Resolver::resolvePool()
264 // Solving with the satsolver
265 static bool poolDumped = false;
266 MIL << "-------------- Calling SAT Solver -------------------" << endl;
267 if ( getenv("ZYPP_FULLLOG") ) {
268 Testcase testcase("/var/log/YaST2/autoTestcase");
270 testcase.createTestcase (*this, true, false); // dump pool
273 testcase.createTestcase (*this, false, false); // write control file only
277 MIL << "------SAT-Pool------" << endl;
278 for (sat::Pool::SolvableIterator i = satPool.solvablesBegin();
279 i != satPool.solvablesEnd(); i++ ) {
280 MIL << *i << " ID: " << i->id() << endl;
282 MIL << "------SAT-Pool end------" << endl;
284 _satResolver->setFixsystem(false);
285 _satResolver->setAllowdowngrade(false);
286 _satResolver->setAllowarchchange(false);
287 _satResolver->setAllowvendorchange(false);
288 _satResolver->setAllowuninstall(false);
289 _satResolver->setUpdatesystem(false);
290 _satResolver->setAllowvirtualconflicts(false);
291 _satResolver->setNoupdateprovide(true);
292 _satResolver->setDosplitprovides(false);
295 _satResolver->setAllowdowngrade(true);
296 _satResolver->setAllowarchchange(true);
297 _satResolver->setUpdatesystem(true);
298 _satResolver->setDosplitprovides(true);
302 _satResolver->setAllowuninstall(true);
304 switch (_onlyRequires) {
306 _satResolver->setOnlyRequires(ZConfig::instance().solver_onlyRequires());
308 _satResolver->setOnlyRequires(true);
310 _satResolver->setOnlyRequires(false);
314 _satResolver->setFixsystem(true);
316 return _satResolver->resolvePool(_extra_requires, _extra_conflicts);
320 ///////////////////////////////////////////////////////////////////
323 // METHOD NAME : Resolver::checkUnmaintainedItems
326 // DESCRIPTION : Unmaintained packages which does not fit to
327 // the updated system (broken dependencies) will be
330 void Resolver::checkUnmaintainedItems () {
332 MIL << "Checking unmaintained items....." << endl;
334 while (!resolvePool() && solverRuns++ < MAXSOLVERRUNS) {
335 ResolverProblemList problemList = problems();
336 ProblemSolutionList solutionList;
337 PoolItemList problemItemList;
339 for (ResolverProblemList::iterator iter = problemList.begin(); iter != problemList.end(); ++iter) {
340 ResolverProblem problem = **iter;
341 DBG << "Problem:" << endl;
342 DBG << problem.description() << endl;
343 DBG << problem.details() << endl;
345 ProblemSolutionList solutions = problem.solutions();
346 for (ProblemSolutionList::const_iterator iterSolution = solutions.begin();
347 iterSolution != solutions.end(); ++iterSolution) {
348 ProblemSolution_Ptr solution = *iterSolution;
349 DBG << " Solution:" << endl;
350 DBG << " " << solution->description() << endl;
351 DBG << " " << solution->details() << endl;
352 solver::detail::CSolutionActionList actionList = solution->actions();
353 bool fitUnmaintained = false;
354 PoolItemList deletedItems;
355 for (CSolutionActionList::const_iterator iterActions = actionList.begin();
356 iterActions != actionList.end(); ++iterActions) {
357 TransactionSolutionAction_constPtr transactionAction = dynamic_pointer_cast<const TransactionSolutionAction>(*iterActions);
358 if (transactionAction &&
359 transactionAction->action() == REMOVE
360 && _unmaintained_items.find(transactionAction->item()) != _unmaintained_items.end()) {
361 // The solution contains unmaintained items ONLY which will be deleted. So take this solution
362 fitUnmaintained = true;
363 deletedItems.push_back (transactionAction->item());
365 fitUnmaintained = false;
368 if (fitUnmaintained) {
369 MIL << "Problem:" << endl;
370 MIL << problem.description() << endl;
371 MIL << problem.details() << endl;
372 MIL << "Will be solved by removing unmaintained package(s)............" << endl;
373 MIL << " Solution:" << endl;
374 MIL << " " << solution->description() << endl;
375 MIL << " " << solution->details() << endl;
376 solutionList.push_back (solution);
377 problemItemList.insert (problemItemList.end(), deletedItems.begin(), deletedItems.end() );
378 break; // not regarding the other solutions
383 if (!solutionList.empty()) {
384 applySolutions (solutionList);
385 // list of problematic items after doUpgrade() which is show to the user
386 _problem_items.insert (_problem_items.end(), problemItemList.begin(), problemItemList.end());
387 _problem_items.unique();
389 // break cause there is no other solution available by the next run
390 solverRuns = MAXSOLVERRUNS;
396 ///////////////////////////////////////////////////////////////////
397 };// namespace detail
398 /////////////////////////////////////////////////////////////////////
399 /////////////////////////////////////////////////////////////////////
400 };// namespace solver
401 ///////////////////////////////////////////////////////////////////////
402 ///////////////////////////////////////////////////////////////////////
404 /////////////////////////////////////////////////////////////////////////