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 the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 #include "zypp/solver/detail/Helper.h"
23 #include "zypp/base/String.h"
24 #include "zypp/Capability.h"
25 #include "zypp/ResStatus.h"
26 #include "zypp/VendorAttr.h"
27 #include "zypp/base/Logger.h"
28 #include "zypp/base/String.h"
29 #include "zypp/base/Gettext.h"
30 #include "zypp/base/Algorithm.h"
31 #include "zypp/ResPool.h"
32 #include "zypp/ResFilters.h"
33 #include "zypp/ZConfig.h"
34 #include "zypp/sat/SATResolver.h"
35 #include "zypp/sat/Pool.h"
36 #include "zypp/sat/WhatProvides.h"
37 #include "zypp/solver/detail/ProblemSolutionCombi.h"
40 #include "satsolver/repo_solv.h"
41 #include "satsolver/poolarch.h"
42 #include "satsolver/evr.h"
43 #include "satsolver/poolvendor.h"
44 #include "satsolver/policy.h"
45 #include "satsolver/bitmap.h"
48 /////////////////////////////////////////////////////////////////////////
50 { ///////////////////////////////////////////////////////////////////////
51 ///////////////////////////////////////////////////////////////////////
53 { /////////////////////////////////////////////////////////////////////
54 /////////////////////////////////////////////////////////////////////
56 { ///////////////////////////////////////////////////////////////////
60 IMPL_PTR_TYPE(SATResolver);
62 //---------------------------------------------------------------------------
63 // Callbacks for SAT policies
64 //---------------------------------------------------------------------------
66 int vendorCheck (Pool *pool, Solvable *solvable1, Solvable *solvable2) {
67 // DBG << "vendorCheck: " << id2str(pool, solvable1->vendor) << " <--> " << id2str(pool, solvable1->vendor) << endl;
68 return VendorAttr::instance().equivalent(id2str(pool, solvable1->vendor), id2str(pool, solvable2->vendor)) ? 0:1;
73 itemToString (PoolItem item, bool shortVersion)
78 if (item->kind() != ResTraits<zypp::Package>::kind)
79 os << item->kind() << ':';
82 os << '-' << item->edition();
83 if (item->arch() != "") {
84 os << '.' << item->arch();
86 Repository s = item->repository();
88 string alias = s.info().alias();
90 && alias != "@system")
92 os << '[' << s.info().alias() << ']';
100 //---------------------------------------------------------------------------
103 SATResolver::dumpOn( std::ostream & os ) const
106 os << " fixsystem = " << _fixsystem << endl;
107 os << " allowdowngrade = " << _allowdowngrade << endl;
108 os << " allowarchchange = " << _allowarchchange << endl;
109 os << " allowvendorchange = " << _allowvendorchange << endl;
110 os << " allowuninstall = " << _allowuninstall << endl;
111 os << " updatesystem = " << _updatesystem << endl;
112 os << " allowvirtualconflicts = " << _allowvirtualconflicts << endl;
113 os << " noupdateprovide = " << _noupdateprovide << endl;
114 os << " dosplitprovides = " << _dosplitprovides << endl;
115 os << " onlyRequires = " << _onlyRequires << endl;
116 return os << "<resolver/>" << endl;
119 //---------------------------------------------------------------------------
121 SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
126 , _allowdowngrade(false)
127 , _allowarchchange(false)
128 , _allowvendorchange(false)
129 , _allowuninstall(false)
130 , _updatesystem(false)
131 , _allowvirtualconflicts(false)
132 , _noupdateprovide(false)
133 , _dosplitprovides(false)
134 , _onlyRequires(ZConfig::instance().solver_onlyRequires())
140 SATResolver::~SATResolver()
144 //---------------------------------------------------------------------------
148 SATResolver::pool (void) const
155 SATResolver::resetItemTransaction (PoolItem item)
158 for (PoolItemList::const_iterator iter = _items_to_remove.begin();
159 iter != _items_to_remove.end(); iter++) {
161 _items_to_remove.remove(*iter);
167 for (PoolItemList::const_iterator iter = _items_to_install.begin();
168 iter != _items_to_install.end(); iter++) {
170 _items_to_install.remove(*iter);
177 for (PoolItemList::const_iterator iter = _items_to_keep.begin();
178 iter != _items_to_keep.end(); iter++) {
180 _items_to_keep.remove(*iter);
187 for (PoolItemList::const_iterator iter = _items_to_lock.begin();
188 iter != _items_to_lock.end(); iter++) {
190 _items_to_lock.remove(*iter);
197 for (PoolItemList::const_iterator iter = _items_to_update.begin();
198 iter != _items_to_update.end(); iter++) {
200 _items_to_update.remove(*iter);
210 SATResolver::addPoolItemToInstall (PoolItem item)
212 resetItemTransaction (item);
213 _items_to_install.push_back (item);
214 _items_to_install.unique ();
219 SATResolver::addPoolItemsToInstallFromList (PoolItemList & rl)
221 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
222 addPoolItemToInstall (*iter);
228 SATResolver::addPoolItemToRemove (PoolItem item)
230 resetItemTransaction (item);
231 _items_to_remove.push_back (item);
232 _items_to_remove.unique ();
237 SATResolver::addPoolItemsToRemoveFromList (PoolItemList & rl)
239 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
240 addPoolItemToRemove (*iter);
245 SATResolver::addPoolItemToLock (PoolItem item)
247 resetItemTransaction (item);
248 _items_to_lock.push_back (item);
249 _items_to_lock.unique ();
253 SATResolver::addPoolItemToKeep (PoolItem item)
255 resetItemTransaction (item);
256 _items_to_keep.push_back (item);
257 _items_to_keep.unique ();
260 //---------------------------------------------------------------------------
262 // copy marked item from solution back to pool
263 // if data != NULL, set as APPL_LOW (from establishPool())
266 SATSolutionToPool (PoolItem item, const ResStatus & status, const ResStatus::TransactByValue causer)
269 item.status().resetTransact (causer);
270 item.status().resetWeak ();
274 // installation/deletion
275 if (status.isToBeInstalled()) {
276 r = item.status().setToBeInstalled (causer);
277 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") install !" << r);
279 else if (status.isToBeUninstalledDueToUpgrade()) {
280 r = item.status().setToBeUninstalledDueToUpgrade (causer);
281 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") upgrade !" << r);
283 else if (status.isToBeUninstalled()) {
284 r = item.status().setToBeUninstalled (causer);
285 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") remove !" << r);
289 if (status.isRecommended()) {
290 item.status().setRecommended(true);
291 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") recommended !" << r);
293 else if (status.isSuggested()) {
294 item.status().setSuggested(true);
295 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") suggested !" << r);
302 //----------------------------------------------------------------------------
303 // helper functions for distupgrade
304 //----------------------------------------------------------------------------
306 bool SATResolver::doesObsoleteItem (PoolItem candidate, PoolItem installed) {
307 Solvable *sCandidate = _SATPool->solvables + candidate.satSolvable().id();
308 ::_Repo *installedRepo = sat::Pool::instance().systemRepo().get();
310 Id p, *pp, obsolete, *obsoleteIt;
312 if ((!installedRepo || sCandidate->repo != installedRepo) && sCandidate->obsoletes) {
313 obsoleteIt = sCandidate->repo->idarraydata + sCandidate->obsoletes;
314 while ((obsolete = *obsoleteIt++) != 0)
316 for (pp = pool_whatprovides(_SATPool, obsolete) ; (p = *pp++) != 0; ) {
317 if (p > 0 && installed.satSolvable().id() == (sat::detail::SolvableIdType)p) {
318 MIL << candidate << " obsoletes " << installed << endl;
327 //----------------------------------------------------------------------------
328 //----------------------------------------------------------------------------
330 //----------------------------------------------------------------------------
331 //----------------------------------------------------------------------------
333 //----------------------------------------------------------------------------
334 // Helper functions for the ZYPP-Pool
335 //----------------------------------------------------------------------------
338 //------------------------------------------------------------------------------------------------------------
339 // This function loops over the pool and grabs all items
340 // It clears all previous bySolver() states also
342 // Every toBeInstalled is passed to zypp::solver:detail::Resolver.addPoolItemToInstall()
343 // Every toBeUninstalled is passed to zypp::solver:detail::Resolver.addPoolItemToRemove()
345 // Solver results must be written back to the pool.
346 //------------------------------------------------------------------------------------------------------------
349 struct SATCollectTransact : public resfilter::PoolItemFilterFunctor
351 SATResolver & resolver;
353 SATCollectTransact (SATResolver & r)
357 bool operator()( PoolItem item ) // only transacts() items go here
359 ResStatus status = item.status();
360 bool by_solver = (status.isBySolver() || status.isByApplLow());
363 _XDEBUG("Resetting " << item );
364 item.status().resetTransact( ResStatus::APPL_LOW );// clear any solver/establish transactions
365 return true; // back out here, dont re-queue former solver result
368 if (status.isToBeInstalled()) {
369 resolver.addPoolItemToInstall(item); // -> install!
371 else if (status.isToBeUninstalled()) {
372 resolver.addPoolItemToRemove(item); // -> remove !
374 else if (status.isLocked()
376 resolver.addPoolItemToLock (item);
378 else if (status.isKept()
380 resolver.addPoolItemToKeep (item);
388 //----------------------------------------------------------------------------
389 //----------------------------------------------------------------------------
391 //----------------------------------------------------------------------------
392 //----------------------------------------------------------------------------
395 class CheckIfUpdate : public resfilter::PoolItemFilterFunctor
401 : is_updated( false )
404 // check this item will be installed
406 bool operator()( PoolItem item )
408 if (item.status().isToBeInstalled())
418 class SetValidate : public resfilter::PoolItemFilterFunctor
421 Map installedmap, conflictsmap;
423 SetValidate(Solver *solv)
425 solver_create_state_maps(solv, &installedmap, &conflictsmap);
430 bool operator()( PoolItem item )
433 if (isKind<Product>(item.resolvable())) {
434 // FIXME This is a hack for registration 11.0 beta1
435 item.status().setSatisfied();
436 _XDEBUG("SATSolutionToPool(" << item << " ) satisfied. THIS IS A HACK !");
440 int ret = solvable_trivial_installable_map(item.satSolvable().get(), &installedmap, &conflictsmap);
441 item.status().setUndetermined();
444 item.status().setNonRelevant();
445 _XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
446 } else if (ret == 1) {
447 item.status().setSatisfied();
448 _XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
449 } else if (ret == 0) {
450 item.status().setBroken();
451 _XDEBUG("SATSolutionToPool(" << item << " ) broken !");
459 SATResolver::resolvePool(const CapabilitySet & requires_caps,
460 const CapabilitySet & conflict_caps)
462 SATCollectTransact info (*this);
464 MIL << "SATResolver::resolvePool()" << endl;
470 queue_free( &(_jobQueue) );
473 queue_init( &_jobQueue );
474 _items_to_install.clear();
475 _items_to_remove.clear();
476 _items_to_lock.clear();
477 _items_to_keep.clear();
479 invokeOnEach ( _pool.begin(), _pool.end(),
480 functor::functorRef<bool,PoolItem>(info) );
482 for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
485 Id id = (*iter)->satSolvable().id();
487 ERR << "Install: " << *iter << " not found" << endl;
489 MIL << "Install " << *iter << " with the SAT-Pool ID: " << id << endl;
490 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE );
491 queue_push( &(_jobQueue), id );
494 for (PoolItemList::const_iterator iter = _items_to_update.begin(); iter != _items_to_update.end(); iter++) {
497 Id id = (*iter)->satSolvable().id();
499 ERR << "Update explicit: " << *iter << " not found" << endl;
501 MIL << "Update explicit " << *iter << " with the SAT-Pool ID: " << id << endl;
502 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE_UPDATE );
503 queue_push( &(_jobQueue), id );
506 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
507 sat::detail::IdType ident( (*iter)->satSolvable().ident().id() );
508 MIL << "Delete " << *iter << " with the string ID: " << ident << endl;
509 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_NAME );
510 queue_push( &(_jobQueue), ident);
513 for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
514 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE_PROVIDES );
515 queue_push( &(_jobQueue), iter->id() );
516 MIL << "Requires " << *iter << endl;
519 for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
520 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES);
521 queue_push( &(_jobQueue), iter->id() );
522 MIL << "Conflicts " << *iter << endl;
525 for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); iter++) {
526 sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() );
527 if (iter->status().isInstalled()) {
528 MIL << "Lock installed item " << *iter << " with the string ID: " << ident << endl;
529 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE );
530 queue_push( &(_jobQueue), ident );
532 MIL << "Lock NOT installed item " << *iter << " with the string ID: " << ident << endl;
533 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE );
534 queue_push( &(_jobQueue), ident );
538 for (PoolItemList::const_iterator iter = _items_to_keep.begin(); iter != _items_to_keep.end(); iter++) {
539 sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() );
540 if (iter->status().isInstalled()) {
541 MIL << "Keep installed item " << *iter << " with the string ID: " << ident << endl;
542 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE | SOLVER_WEAK);
543 queue_push( &(_jobQueue), ident );
545 MIL << "Keep NOT installed item " << *iter << " with the string ID: " << ident << endl;
546 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | SOLVER_WEAK);
547 queue_push( &(_jobQueue), ident );
551 _solv = solver_create( _SATPool, sat::Pool::instance().systemRepo().get() );
552 _solv->vendorCheckCb = &vendorCheck;
553 _solv->fixsystem = _fixsystem;
554 _solv->updatesystem = _updatesystem;
555 _solv->allowdowngrade = _allowdowngrade;
556 _solv->allowuninstall = _allowuninstall;
557 _solv->allowarchchange = _allowarchchange;
558 _solv->dosplitprovides = _dosplitprovides;
559 _solv->noupdateprovide = _noupdateprovide;
560 _solv->dontinstallrecommended = _onlyRequires;
562 sat::Pool::instance().prepare();
565 MIL << "Starting solving...." << endl;
567 solver_solve( _solv, &(_jobQueue) );
568 MIL << "....Solver end" << endl;
570 // copying solution back to zypp pool
571 //-----------------------------------------
573 if (_solv->problems.count > 0 )
575 ERR << "Solverrun finished with an ERROR" << endl;
579 /* solvables to be installed */
580 for (int i = 0; i < _solv->decisionq.count; i++)
583 p = _solv->decisionq.elements[i];
584 if (p < 0 || !sat::Solvable(p))
586 if (sat::Solvable(p).repository().get() == _solv->installed)
589 PoolItem poolItem = _pool.find (sat::Solvable(p));
591 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
593 ERR << "id " << p << " not found in ZYPP pool." << endl;
597 /* solvables to be erased */
598 for (int i = _solv->installed->start; i < _solv->installed->start + _solv->installed->nsolvables; i++)
600 if (_solv->decisionmap[i] > 0)
603 PoolItem poolItem = _pool.find (sat::Solvable(i));
605 // Check if this is an update
607 invokeOnEach( _pool.byIdentBegin( poolItem ),
608 _pool.byIdentEnd( poolItem ),
609 resfilter::ByUninstalled(), // ByUninstalled
610 functor::functorRef<bool,PoolItem> (info) );
612 if (info.is_updated) {
613 SATSolutionToPool (poolItem, ResStatus::toBeUninstalledDueToUpgrade , ResStatus::SOLVER);
615 SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
618 ERR << "id " << i << " not found in ZYPP pool." << endl;
622 /* solvables which are recommended */
623 for (int i = 0; i < _solv->recommendations.count; i++)
626 p = _solv->recommendations.elements[i];
627 if (p < 0 || !sat::Solvable(p))
630 PoolItem poolItem = _pool.find (sat::Solvable(p));
632 ResStatus status = poolItem.status();
633 status.setRecommended (true);
634 SATSolutionToPool (poolItem, status, ResStatus::SOLVER);
636 ERR << "id " << p << " not found in ZYPP pool." << endl;
640 /* solvables which are suggested */
641 for (int i = 0; i < _solv->suggestions.count; i++)
644 p = _solv->suggestions.elements[i];
645 if (p < 0 || !sat::Solvable(p))
648 PoolItem poolItem = _pool.find (sat::Solvable(p));
650 ResStatus status = poolItem.status();
651 status.setSuggested (true);
652 SATSolutionToPool (poolItem, status, ResStatus::SOLVER);
654 ERR << "id " << p << " not found in ZYPP pool." << endl;
658 /* Write validation state back to pool */
659 SetValidate infoValidate(_solv);
660 invokeOnEach( _pool.begin(),
662 functor::not_c(resfilter::byKind<Package>()), // every solvable BUT packages
663 functor::functorRef<bool,PoolItem> (infoValidate) );
668 queue_free( &(_jobQueue) );
670 MIL << "SATResolver::resolvePool() done" << endl;
675 bool SATResolver::doUpdate()
677 MIL << "SATResolver::doUpdate()" << endl;
683 queue_free( &(_jobQueue) );
686 queue_init( &_jobQueue );
688 _solv = solver_create( _SATPool, sat::Pool::instance().systemRepo().get() );
689 _solv->vendorCheckCb = &vendorCheck;
691 _solv->updatesystem = true;
692 _solv->dontinstallrecommended = true; // #FIXME dontinstallrecommended maybe set to false if it works correctly
694 sat::Pool::instance().prepare();
697 MIL << "Starting solving for update...." << endl;
699 solver_solve( _solv, &(_jobQueue) );
700 MIL << "....Solver end" << endl;
702 // copying solution back to zypp pool
703 //-----------------------------------------
705 /* solvables to be installed */
706 for (int i = 0; i < _solv->decisionq.count; i++)
709 p = _solv->decisionq.elements[i];
710 if (p < 0 || !sat::Solvable(p))
712 if (sat::Solvable(p).repository().get() == _solv->installed)
715 PoolItem poolItem = _pool.find (sat::Solvable(p));
717 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
719 ERR << "id " << p << " not found in ZYPP pool." << endl;
723 /* solvables to be erased */
724 for (int i = _solv->installed->start; i < _solv->installed->start + _solv->installed->nsolvables; i++)
726 if (_solv->decisionmap[i] > 0)
729 PoolItem poolItem = _pool.find (sat::Solvable(i));
731 // Check if this is an update
733 invokeOnEach( _pool.byIdentBegin( poolItem ),
734 _pool.byIdentEnd( poolItem ),
735 resfilter::ByUninstalled(), // ByUninstalled
736 functor::functorRef<bool,PoolItem> (info) );
738 if (info.is_updated) {
739 SATSolutionToPool (poolItem, ResStatus::toBeUninstalledDueToUpgrade , ResStatus::SOLVER);
741 SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
744 ERR << "id " << i << " not found in ZYPP pool." << endl;
751 queue_free( &(_jobQueue) );
753 MIL << "SATResolver::doUpdate() done" << endl;
759 //----------------------------------------------------------------------------
760 //----------------------------------------------------------------------------
762 //----------------------------------------------------------------------------
763 //----------------------------------------------------------------------------
765 //----------------------------------------------------------------------------
767 //----------------------------------------------------------------------------
769 struct FindPackage : public resfilter::ResObjectFilterFunctor
771 ProblemSolutionCombi *problemSolution;
772 TransactionKind action;
773 FindPackage (ProblemSolutionCombi *p, const TransactionKind act)
774 : problemSolution (p)
779 bool operator()( PoolItem p)
781 problemSolution->addSingleAction (p, action);
787 string SATResolver::SATprobleminfoString(Id problem, string &detail)
790 Pool *pool = _solv->pool;
792 Id dep, source, target;
795 probr = solver_findproblemrule(_solv, problem);
796 switch (solver_problemruleinfo(_solv, &(_jobQueue), probr, &dep, &source, &target))
798 case SOLVER_PROBLEM_UPDATE_RULE:
799 s = pool_id2solvable(pool, source);
800 ret = str::form (_("problem with installed package %s"), solvable2str(pool, s));
802 case SOLVER_PROBLEM_JOB_RULE:
803 ret = str::form (_("conflicting requests"));
805 case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP:
806 ret = str::form (_("nothing provides requested %s"), dep2str(pool, dep));
808 case SOLVER_PROBLEM_NOT_INSTALLABLE:
809 s = pool_id2solvable(pool, source);
810 ret = str::form (_("%s is not installable"), solvable2str(pool, s));
812 case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP:
813 s = pool_id2solvable(pool, source);
814 ret = str::form (_("nothing provides %s needed by %s"), dep2str(pool, dep), solvable2str(pool, s));
816 case SOLVER_PROBLEM_SAME_NAME:
817 s = pool_id2solvable(pool, source);
818 s2 = pool_id2solvable(pool, target);
819 ret = str::form (_("cannot install both %s and %s"), solvable2str(pool, s), solvable2str(pool, s2));
821 case SOLVER_PROBLEM_PACKAGE_CONFLICT:
822 s = pool_id2solvable(pool, source);
823 s2 = pool_id2solvable(pool, target);
824 ret = str::form (_("%s conflicts with %s provided by %s"), solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2));
826 case SOLVER_PROBLEM_PACKAGE_OBSOLETES:
827 s = pool_id2solvable(pool, source);
828 s2 = pool_id2solvable(pool, target);
829 ret = str::form (_("%s obsoletes %s provided by %s"), solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2));
831 case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE:
832 s = pool_id2solvable(pool, source);
834 sat::WhatProvides possibleProviders(cap);
836 // check, if a provider will be deleted
837 typedef list<PoolItem> ProviderList;
838 ProviderList providerlistInstalled, providerlistUninstalled;
839 for_( iter1, possibleProviders.begin(), possibleProviders.end() ) {
840 PoolItem provider1 = ResPool::instance().find( *iter1 );
841 // find pair of an installed/uninstalled item with the same NVR
843 for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
844 PoolItem provider2 = ResPool::instance().find( *iter2 );
845 if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0
846 && ( (provider1.status().isInstalled() && provider2.status().isUninstalled())
847 || (provider2.status().isInstalled() && provider1.status().isUninstalled()) )) {
853 if (provider1.status().isInstalled())
854 providerlistInstalled.push_back(provider1);
856 providerlistUninstalled.push_back(provider1);
860 ret = str::form (_("%s requires %s, but this requirement cannot be provided"), solvable2str(pool, s), dep2str(pool, dep));
861 if (providerlistInstalled.size() > 0) {
862 detail += _("deleted providers: ");
863 for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) {
864 if (iter == providerlistInstalled.begin())
865 detail += itemToString (*iter, false);
867 detail += "\n " + itemToString (*iter, false);
870 if (providerlistUninstalled.size() > 0) {
871 if (detail.size() > 0)
872 detail += _("\nuninstallable providers: ");
874 detail = _("uninstallable providers: ");
875 for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
876 if (iter == providerlistUninstalled.begin())
877 detail += itemToString (*iter, false);
879 detail += "\n " + itemToString (*iter, false);
889 SATResolver::problems ()
891 ResolverProblemList resolverProblems;
892 if (_solv && _solv->problems.count) {
893 Pool *pool = _solv->pool;
896 Id problem, solution, element;
899 MIL << "Encountered problems! Here are the solutions:\n" << endl;
902 while ((problem = solver_next_problem(_solv, problem)) != 0) {
903 MIL << "Problem " << pcnt++ << ":" << endl;
904 MIL << "====================================" << endl;
906 string whatString = SATprobleminfoString (problem,detail);
907 MIL << whatString << endl;
908 MIL << "------------------------------------" << endl;
909 ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail);
911 while ((solution = solver_next_solution(_solv, problem, solution)) != 0) {
913 ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
914 while ((element = solver_next_solutionelement(_solv, problem, solution, element, &p, &rp)) != 0) {
916 /* job, rp is index into job queue */
917 what = _jobQueue.elements[rp];
918 switch (_jobQueue.elements[rp-1])
920 case SOLVER_INSTALL_SOLVABLE: {
921 s = pool->solvables + what;
922 PoolItem poolItem = _pool.find (sat::Solvable(what));
924 if (_solv->installed && s->repo == _solv->installed) {
925 problemSolution->addSingleAction (poolItem, REMOVE);
926 string description = str::form (_("do not keep %s installed"), solvable2str(pool, s) );
927 MIL << description << endl;
928 problemSolution->addDescription (description);
930 problemSolution->addSingleAction (poolItem, REMOVE);
931 string description = str::form (_("do not install %s"), solvable2str(pool, s));
932 MIL << description << endl;
933 problemSolution->addDescription (description);
936 ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << id2str(pool, s->name) << "-"
937 << id2str(pool, s->evr) << "." << id2str(pool, s->arch) << endl;
941 case SOLVER_ERASE_SOLVABLE: {
942 s = pool->solvables + what;
943 PoolItem poolItem = _pool.find (sat::Solvable(what));
945 if (_solv->installed && s->repo == _solv->installed) {
946 problemSolution->addSingleAction (poolItem, KEEP);
947 string description = str::form (_("keep %s"), solvable2str(pool, s));
948 MIL << description << endl;
949 problemSolution->addDescription (description);
951 problemSolution->addSingleAction (poolItem, INSTALL);
952 string description = str::form (_("do not forbid installation of %s"), solvable2str(pool, s));
953 MIL << description << endl;
954 problemSolution->addDescription (description);
957 ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." <<
958 id2str(pool, s->arch) << endl;
962 case SOLVER_INSTALL_SOLVABLE_NAME:
964 FindPackage info (problemSolution, KEEP);
965 IdString ident( what );
966 invokeOnEach( _pool.byIdentBegin( ident ),
967 _pool.byIdentEnd( ident ),
968 resfilter::ByUninstalled (),
969 functor::functorRef<bool,PoolItem> (info) );
970 string description = str::form (_("do not install %s"), ident.c_str() );
971 MIL << description << endl;
972 problemSolution->addDescription (description);
975 case SOLVER_ERASE_SOLVABLE_NAME:
977 FindPackage info (problemSolution, KEEP);
978 IdString ident( what );
979 invokeOnEach( _pool.byIdentBegin( ident ),
980 _pool.byIdentEnd( ident ),
981 functor::chain (resfilter::ByInstalled (), // ByInstalled
982 resfilter::ByTransact ()), // will be deinstalled
983 functor::functorRef<bool,PoolItem> (info) );
984 string description = str::form (_("keep %s"), ident.c_str());
985 MIL << description << endl;
986 problemSolution->addDescription (description);
989 case SOLVER_INSTALL_SOLVABLE_PROVIDES:
992 FOR_PROVIDES(p, pp, what);
994 PoolItem poolItem = _pool.find (sat::Solvable(p));
995 if (poolItem.status().isToBeInstalled()
996 || poolItem.status().staysUninstalled())
997 problemSolution->addSingleAction (poolItem, KEEP);
999 string description = str::form (_("do not ask to install a solvable providing %s"), dep2str(pool, what));
1000 MIL << description << endl;
1001 problemSolution->addDescription (description);
1004 case SOLVER_ERASE_SOLVABLE_PROVIDES:
1007 FOR_PROVIDES(p, pp, what);
1009 PoolItem poolItem = _pool.find (sat::Solvable(p));
1010 if (poolItem.status().isToBeUninstalled()
1011 || poolItem.status().staysInstalled())
1012 problemSolution->addSingleAction (poolItem, KEEP);
1014 string description = str::form (_("do not ask to delete all solvables providing %s"), dep2str(pool, what));
1015 MIL << description << endl;
1016 problemSolution->addDescription (description);
1019 case SOLVER_INSTALL_SOLVABLE_UPDATE:
1021 PoolItem poolItem = _pool.find (sat::Solvable(what));
1022 s = pool->solvables + what;
1024 if (_solv->installed && s->repo == _solv->installed) {
1025 problemSolution->addSingleAction (poolItem, KEEP);
1026 string description = str::form (_("do not install most recent version of %s"), solvable2str(pool, s));
1027 MIL << description << endl;
1028 problemSolution->addDescription (description);
1030 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl;
1033 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." <<
1034 id2str(pool, s->arch) << endl;
1039 MIL << "- do something different" << endl;
1040 ERR << "No valid solution available" << endl;
1044 /* policy, replace p with rp */
1045 s = pool->solvables + p;
1046 sd = rp ? pool->solvables + rp : 0;
1048 PoolItem itemFrom = _pool.find (sat::Solvable(p));
1053 PoolItem itemTo = _pool.find (sat::Solvable(rp));
1054 if (itemFrom && itemTo) {
1055 problemSolution->addSingleAction (itemTo, INSTALL);
1057 if (evrcmp(pool, s->evr, sd->evr, EVRCMP_COMPARE ) > 0)
1059 string description = str::form (_("downgrade of %s to %s"), solvable2str(pool, s), solvable2str(pool, sd));
1060 MIL << description << endl;
1061 problemSolution->addDescription (description);
1064 if (!_solv->allowarchchange && s->name == sd->name && s->arch != sd->arch && policy_illegal_archchange(_solv, s, sd))
1066 string description = str::form (_("architecture change of %s to %s"), solvable2str(pool, s), solvable2str(pool, sd));
1067 MIL << description << endl;
1068 problemSolution->addDescription (description);
1071 if (!_solv->allowvendorchange && s->name == sd->name && s->vendor != sd->vendor && policy_illegal_vendorchange(_solv, s, sd))
1073 string description = str::form (_("install %s (with vendor change)\n %s\n-->\n %s") ,
1074 solvable2str(pool, sd) , id2str(pool, s->vendor),
1075 string(sd->vendor ? id2str(pool, sd->vendor) : " (no vendor) ").c_str() );
1076 MIL << description << endl;
1077 problemSolution->addDescription (description);
1081 string description = str::form (_("replacement of %s with %s"), solvable2str(pool, s), solvable2str(pool, sd));
1082 MIL << description << endl;
1083 problemSolution->addDescription (description);
1086 ERR << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch)
1087 << " or " << id2str(pool, sd->name) << "-" << id2str(pool, sd->evr) << "." << id2str(pool, sd->arch) << " not found" << endl;
1093 string description = str::form (_("deinstallation of %s"), solvable2str(pool, s));
1094 MIL << description << endl;
1095 problemSolution->addDescription (description);
1096 problemSolution->addSingleAction (itemFrom, REMOVE);
1101 resolverProblem->addSolution (problemSolution,
1102 problemSolution->actionCount() > 1 ? true : false); // Solutions with more than 1 action will be shown first.
1103 MIL << "------------------------------------" << endl;
1106 resolverProblems.push_back (resolverProblem);
1109 return resolverProblems;
1113 SATResolver::applySolutions (const ProblemSolutionList & solutions)
1115 for (ProblemSolutionList::const_iterator iter = solutions.begin();
1116 iter != solutions.end(); ++iter) {
1117 ProblemSolution_Ptr solution = *iter;
1118 Resolver dummyResolver(_pool);
1119 if (!solution->apply (dummyResolver))
1126 ///////////////////////////////////////////////////////////////////
1127 };// namespace detail
1128 /////////////////////////////////////////////////////////////////////
1129 /////////////////////////////////////////////////////////////////////
1130 };// namespace solver
1131 ///////////////////////////////////////////////////////////////////////
1132 ///////////////////////////////////////////////////////////////////////
1134 /////////////////////////////////////////////////////////////////////////