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"
26 #include "zypp/solver/detail/SATResolver.h"
28 #include "zypp/Capabilities.h"
29 #include "zypp/ZConfig.h"
30 #include "zypp/base/Logger.h"
31 #include "zypp/base/String.h"
32 #include "zypp/base/Gettext.h"
33 #include "zypp/base/Algorithm.h"
34 #include "zypp/ResPool.h"
35 #include "zypp/ResFilters.h"
36 #include "zypp/sat/Pool.h"
37 #include "zypp/sat/Solvable.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(indeterminate)
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();
260 Resolver::solverInit()
262 // Solving with the satsolver
263 static bool poolDumped = false;
264 MIL << "-------------- Calling SAT Solver -------------------" << endl;
265 if ( getenv("ZYPP_FULLLOG") ) {
266 Testcase testcase("/var/log/YaST2/autoTestcase");
268 testcase.createTestcase (*this, true, false); // dump pool
271 testcase.createTestcase (*this, false, false); // write control file only
275 _satResolver->setFixsystem(false);
276 _satResolver->setAllowdowngrade(false);
277 _satResolver->setAllowarchchange(false);
278 _satResolver->setAllowvendorchange(false);
279 _satResolver->setAllowuninstall(false);
280 _satResolver->setUpdatesystem(false);
281 _satResolver->setAllowvirtualconflicts(false);
282 _satResolver->setNoupdateprovide(true);
283 _satResolver->setDosplitprovides(false);
286 _satResolver->setAllowdowngrade(true);
287 _satResolver->setAllowarchchange(true);
288 _satResolver->setUpdatesystem(true);
289 _satResolver->setDosplitprovides(true);
293 _satResolver->setAllowuninstall(true);
295 if (_onlyRequires == indeterminate)
296 _satResolver->setOnlyRequires(ZConfig::instance().solver_onlyRequires());
297 else if (_onlyRequires)
298 _satResolver->setOnlyRequires(true);
300 _satResolver->setOnlyRequires(false);
303 _satResolver->setFixsystem(true);
307 Resolver::resolvePool()
310 return _satResolver->resolvePool(_extra_requires, _extra_conflicts);
314 Resolver::resolveQueue(solver::detail::SolverQueueItemList & queue)
317 return _satResolver->resolveQueue(queue);
322 ///////////////////////////////////////////////////////////////////
325 // METHOD NAME : Resolver::checkUnmaintainedItems
328 // DESCRIPTION : Unmaintained packages which does not fit to
329 // the updated system (broken dependencies) will be
332 void Resolver::checkUnmaintainedItems () {
334 MIL << "Checking unmaintained items....." << endl;
336 while (!resolvePool() && solverRuns++ < MAXSOLVERRUNS) {
337 ResolverProblemList problemList = problems();
338 ProblemSolutionList solutionList;
339 PoolItemList problemItemList;
341 for (ResolverProblemList::iterator iter = problemList.begin(); iter != problemList.end(); ++iter) {
342 ResolverProblem problem = **iter;
343 DBG << "Problem:" << endl;
344 DBG << problem.description() << endl;
345 DBG << problem.details() << endl;
347 ProblemSolutionList solutions = problem.solutions();
348 for (ProblemSolutionList::const_iterator iterSolution = solutions.begin();
349 iterSolution != solutions.end(); ++iterSolution) {
350 ProblemSolution_Ptr solution = *iterSolution;
351 DBG << " Solution:" << endl;
352 DBG << " " << solution->description() << endl;
353 DBG << " " << solution->details() << endl;
354 solver::detail::CSolutionActionList actionList = solution->actions();
355 bool fitUnmaintained = false;
356 PoolItemList deletedItems;
357 for (CSolutionActionList::const_iterator iterActions = actionList.begin();
358 iterActions != actionList.end(); ++iterActions) {
359 TransactionSolutionAction_constPtr transactionAction = dynamic_pointer_cast<const TransactionSolutionAction>(*iterActions);
360 if (transactionAction &&
361 transactionAction->action() == REMOVE
362 && _unmaintained_items.find(transactionAction->item()) != _unmaintained_items.end()) {
363 // The solution contains unmaintained items ONLY which will be deleted. So take this solution
364 fitUnmaintained = true;
365 deletedItems.push_back (transactionAction->item());
367 fitUnmaintained = false;
370 if (fitUnmaintained) {
371 MIL << "Problem:" << endl;
372 MIL << problem.description() << endl;
373 MIL << problem.details() << endl;
374 MIL << "Will be solved by removing unmaintained package(s)............" << endl;
375 MIL << " Solution:" << endl;
376 MIL << " " << solution->description() << endl;
377 MIL << " " << solution->details() << endl;
378 solutionList.push_back (solution);
379 problemItemList.insert (problemItemList.end(), deletedItems.begin(), deletedItems.end() );
380 break; // not regarding the other solutions
385 if (!solutionList.empty()) {
386 applySolutions (solutionList);
387 // list of problematic items after doUpgrade() which is show to the user
388 _problem_items.insert (_problem_items.end(), problemItemList.begin(), problemItemList.end());
389 _problem_items.unique();
391 // break cause there is no other solution available by the next run
392 solverRuns = MAXSOLVERRUNS;
398 ///////////////////////////////////////////////////////////////////
399 };// namespace detail
400 /////////////////////////////////////////////////////////////////////
401 /////////////////////////////////////////////////////////////////////
402 };// namespace solver
403 ///////////////////////////////////////////////////////////////////////
404 ///////////////////////////////////////////////////////////////////////
406 /////////////////////////////////////////////////////////////////////////