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
23 #include <solv/repo_solv.h>
24 #include <solv/poolarch.h>
26 #include <solv/poolvendor.h>
27 #include <solv/policy.h>
28 #include <solv/bitmap.h>
29 #include <solv/queue.h>
32 #include "zypp/solver/detail/Helper.h"
33 #include "zypp/base/String.h"
34 #include "zypp/Product.h"
35 #include "zypp/Capability.h"
36 #include "zypp/ResStatus.h"
37 #include "zypp/VendorAttr.h"
38 #include "zypp/base/LogTools.h"
39 #include "zypp/base/String.h"
40 #include "zypp/base/Gettext.h"
41 #include "zypp/base/Algorithm.h"
42 #include "zypp/ResPool.h"
43 #include "zypp/ResFilters.h"
44 #include "zypp/ZConfig.h"
45 #include "zypp/sat/Pool.h"
46 #include "zypp/sat/WhatProvides.h"
47 #include "zypp/sat/WhatObsoletes.h"
48 #include "zypp/solver/detail/SATResolver.h"
49 #include "zypp/solver/detail/ProblemSolutionCombi.h"
50 #include "zypp/solver/detail/ProblemSolutionIgnore.h"
51 #include "zypp/solver/detail/SolverQueueItemInstall.h"
52 #include "zypp/solver/detail/SolverQueueItemDelete.h"
53 #include "zypp/solver/detail/SystemCheck.h"
54 #include "zypp/sat/Transaction.h"
55 #include "zypp/sat/Queue.h"
57 /////////////////////////////////////////////////////////////////////////
59 { ///////////////////////////////////////////////////////////////////////
61 /////////////////////////////////////////////////////////////////////////
64 inline bool HACKENV( const char * var_r, bool default_r )
67 const char * val = ::getenv( var_r );
70 ret = str::strToBool( val, default_r );
71 if ( ret != default_r )
72 INT << "HACKENV " << var_r << " = " << ret << endl;
77 /////////////////////////////////////////////////////////////////////////
79 ///////////////////////////////////////////////////////////////////////
81 { /////////////////////////////////////////////////////////////////////
82 /////////////////////////////////////////////////////////////////////
84 { ///////////////////////////////////////////////////////////////////
88 IMPL_PTR_TYPE(SATResolver);
90 #define MAYBE_CLEANDEPS (cleandepsOnRemove()?SOLVER_CLEANDEPS:0)
92 //---------------------------------------------------------------------------
93 // Callbacks for SAT policies
94 //---------------------------------------------------------------------------
96 int vendorCheck( Pool *pool, Solvable *solvable1, Solvable *solvable2 )
98 return VendorAttr::instance().equivalent( IdString(solvable1->vendor),
99 IdString(solvable2->vendor) ) ? 0 : 1;
103 inline std::string itemToString( const PoolItem & item )
106 return std::string();
108 sat::Solvable slv( item.satSolvable() );
109 std::string ret( slv.asString() ); // n-v-r.a
110 if ( ! slv.isSystem() )
113 ret += slv.repository().alias();
119 inline PoolItem getPoolItem( Id id_r )
121 PoolItem ret( (sat::Solvable( id_r )) );
123 INT << "id " << id_r << " not found in ZYPP pool." << endl;
127 //---------------------------------------------------------------------------
130 SATResolver::dumpOn( std::ostream & os ) const
132 os << "<resolver>" << endl;
134 #define OUTS(X) os << " " << #X << "\t= " << solver_get_flag(_solv, SOLVER_FLAG_##X) << endl
135 OUTS( ALLOW_DOWNGRADE );
136 OUTS( ALLOW_ARCHCHANGE );
137 OUTS( ALLOW_VENDORCHANGE );
138 OUTS( ALLOW_UNINSTALL );
139 OUTS( NO_UPDATEPROVIDE );
140 OUTS( SPLITPROVIDES );
141 OUTS( IGNORE_RECOMMENDED );
142 OUTS( ADD_ALREADY_RECOMMENDED );
143 OUTS( NO_INFARCHCHECK );
144 OUTS( ALLOW_NAMECHANGE );
145 OUTS( KEEP_EXPLICIT_OBSOLETES );
146 OUTS( BEST_OBEY_POLICY );
147 OUTS( NO_AUTOTARGET );
148 OUTS( DUP_ALLOW_DOWNGRADE );
149 OUTS( DUP_ALLOW_ARCHCHANGE );
150 OUTS( DUP_ALLOW_VENDORCHANGE );
151 OUTS( DUP_ALLOW_NAMECHANGE );
152 OUTS( KEEP_ORPHANS );
153 OUTS( BREAK_ORPHANS );
154 OUTS( FOCUS_INSTALLED );
155 OUTS( YUM_OBSOLETES );
157 os << " distupgrade = " << _distupgrade << endl;
158 os << " distupgrade_removeunsupported = " << _distupgrade_removeunsupported << endl;
159 os << " solveSrcPackages = " << _solveSrcPackages << endl;
160 os << " cleandepsOnRemove = " << _cleandepsOnRemove << endl;
161 os << " fixsystem = " << _fixsystem << endl;
165 return os << "<resolver/>" << endl;
168 //---------------------------------------------------------------------------
170 SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
175 , _allowdowngrade(false)
176 , _allowarchchange(false)
177 , _allowvendorchange(ZConfig::instance().solver_allowVendorChange())
178 , _allowuninstall(false)
179 , _dup_allowdowngrade( true )
180 , _dup_allownamechange( true )
181 , _dup_allowarchchange( true )
182 , _dup_allowvendorchange( true )
183 , _updatesystem(false)
184 , _noupdateprovide(false)
185 , _dosplitprovides(true)
186 , _onlyRequires(ZConfig::instance().solver_onlyRequires())
187 , _ignorealreadyrecommended(true)
188 , _distupgrade(false)
189 , _distupgrade_removeunsupported(false)
190 , _solveSrcPackages(false)
191 , _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove())
196 SATResolver::~SATResolver()
201 //---------------------------------------------------------------------------
204 SATResolver::pool (void) const
210 SATResolver::resetItemTransaction (PoolItem item)
213 for (PoolItemList::const_iterator iter = _items_to_remove.begin();
214 iter != _items_to_remove.end(); ++iter) {
216 _items_to_remove.remove(*iter);
222 for (PoolItemList::const_iterator iter = _items_to_install.begin();
223 iter != _items_to_install.end(); ++iter) {
225 _items_to_install.remove(*iter);
232 for (PoolItemList::const_iterator iter = _items_to_keep.begin();
233 iter != _items_to_keep.end(); ++iter) {
235 _items_to_keep.remove(*iter);
242 for (PoolItemList::const_iterator iter = _items_to_lock.begin();
243 iter != _items_to_lock.end(); ++iter) {
245 _items_to_lock.remove(*iter);
255 SATResolver::addPoolItemToInstall (PoolItem item)
257 resetItemTransaction (item);
258 _items_to_install.push_back (item);
259 _items_to_install.unique ();
264 SATResolver::addPoolItemsToInstallFromList (PoolItemList & rl)
266 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
267 addPoolItemToInstall (*iter);
273 SATResolver::addPoolItemToRemove (PoolItem item)
275 resetItemTransaction (item);
276 _items_to_remove.push_back (item);
277 _items_to_remove.unique ();
282 SATResolver::addPoolItemsToRemoveFromList (PoolItemList & rl)
284 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
285 addPoolItemToRemove (*iter);
290 SATResolver::addPoolItemToLock (PoolItem item)
292 resetItemTransaction (item);
293 _items_to_lock.push_back (item);
294 _items_to_lock.unique ();
298 SATResolver::addPoolItemToKeep (PoolItem item)
300 resetItemTransaction (item);
301 _items_to_keep.push_back (item);
302 _items_to_keep.unique ();
305 //---------------------------------------------------------------------------
307 // copy marked item from solution back to pool
308 // if data != NULL, set as APPL_LOW (from establishPool())
311 SATSolutionToPool (PoolItem item, const ResStatus & status, const ResStatus::TransactByValue causer)
314 item.status().resetTransact (causer);
315 item.status().resetWeak ();
319 // installation/deletion
320 if (status.isToBeInstalled()) {
321 r = item.status().setToBeInstalled (causer);
322 _XDEBUG("SATSolutionToPool install returns " << item << ", " << r);
324 else if (status.isToBeUninstalledDueToUpgrade()) {
325 r = item.status().setToBeUninstalledDueToUpgrade (causer);
326 _XDEBUG("SATSolutionToPool upgrade returns " << item << ", " << r);
328 else if (status.isToBeUninstalled()) {
329 r = item.status().setToBeUninstalled (causer);
330 _XDEBUG("SATSolutionToPool remove returns " << item << ", " << r);
336 //----------------------------------------------------------------------------
337 //----------------------------------------------------------------------------
339 //----------------------------------------------------------------------------
340 //----------------------------------------------------------------------------
342 //----------------------------------------------------------------------------
343 // Helper functions for the ZYPP-Pool
344 //----------------------------------------------------------------------------
347 //------------------------------------------------------------------------------------------------------------
348 // This function loops over the pool and grabs all items
349 // It clears all previous bySolver() states also
351 // Every toBeInstalled is passed to zypp::solver:detail::Resolver.addPoolItemToInstall()
352 // Every toBeUninstalled is passed to zypp::solver:detail::Resolver.addPoolItemToRemove()
354 // Solver results must be written back to the pool.
355 //------------------------------------------------------------------------------------------------------------
358 struct SATCollectTransact : public resfilter::PoolItemFilterFunctor
360 SATResolver & resolver;
362 SATCollectTransact (SATResolver & r)
366 bool operator()( PoolItem item ) // only transacts() items go here
368 ResStatus status = item.status();
369 bool by_solver = (status.isBySolver() || status.isByApplLow());
372 item.status().resetTransact( ResStatus::APPL_LOW );// clear any solver/establish transactions
373 return true; // back out here, dont re-queue former solver result
376 if ( item.satSolvable().isKind<SrcPackage>() && ! resolver.solveSrcPackages() )
378 // Later we may continue on a per source package base.
379 return true; // dont process this source package.
382 if (status.isToBeInstalled()) {
383 resolver.addPoolItemToInstall(item); // -> install!
385 else if (status.isToBeUninstalled()) {
386 resolver.addPoolItemToRemove(item); // -> remove !
388 else if (status.isLocked()
390 resolver.addPoolItemToLock (item);
392 else if (status.isKept()
394 resolver.addPoolItemToKeep (item);
402 //----------------------------------------------------------------------------
403 //----------------------------------------------------------------------------
405 //----------------------------------------------------------------------------
406 //----------------------------------------------------------------------------
409 class CheckIfUpdate : public resfilter::PoolItemFilterFunctor
414 sat::Solvable _installed;
416 CheckIfUpdate( sat::Solvable installed_r )
417 : is_updated( false )
418 , multiversion( installed_r.multiversionInstall() )
419 , _installed( installed_r )
422 // check this item will be updated
424 bool operator()( PoolItem item )
426 if ( item.status().isToBeInstalled() )
428 if ( ! multiversion || sameNVRA( _installed, item ) )
439 class CollectPseudoInstalled : public resfilter::PoolItemFilterFunctor
442 Queue *solvableQueue;
444 CollectPseudoInstalled( Queue *queue )
445 :solvableQueue (queue)
448 // collecting PseudoInstalled items
449 bool operator()( PoolItem item )
451 if ( traits::isPseudoInstalled( item.satSolvable().kind() ) )
452 queue_push( solvableQueue, item.satSolvable().id() );
458 SATResolver::solving(const CapabilitySet & requires_caps,
459 const CapabilitySet & conflict_caps)
461 _solv = solver_create( _SATPool );
462 ::pool_set_custom_vendorcheck( _SATPool, &vendorCheck );
464 queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
465 queue_push( &(_jobQueue), 0 );
468 queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL);
469 queue_push( &(_jobQueue), 0 );
472 queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL);
473 queue_push( &(_jobQueue), 0 );
475 if (_distupgrade_removeunsupported) {
476 queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
477 queue_push( &(_jobQueue), 0 );
479 solver_set_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
480 solver_set_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
481 solver_set_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
482 solver_set_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
483 solver_set_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
484 solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
485 solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
486 solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
487 DBG << "main.cc: " << _dup_allowdowngrade << " / " << solver_get_flag(_solv, SOLVER_FLAG_DUP_ALLOW_DOWNGRADE ) << endl;
488 solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_DOWNGRADE, _dup_allowdowngrade );
489 solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE, _dup_allownamechange );
490 solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE, _dup_allowarchchange );
491 solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_NAMECHANGE, _dup_allowvendorchange );
492 DBG << "main.cc: " << _dup_allowdowngrade << " / " << solver_get_flag(_solv, SOLVER_FLAG_DUP_ALLOW_DOWNGRADE ) << endl;
494 #define HACKENV(X,D) solver_set_flag(_solv, X, env::HACKENV( #X, D ) );
495 HACKENV( SOLVER_FLAG_DUP_ALLOW_DOWNGRADE, _dup_allowdowngrade );
496 HACKENV( SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE, _dup_allownamechange );
497 HACKENV( SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE,_dup_allowarchchange );
498 HACKENV( SOLVER_FLAG_DUP_ALLOW_NAMECHANGE, _dup_allowvendorchange );
501 sat::Pool::instance().prepareForSolving();
504 MIL << "Starting solving...." << endl;
506 solver_solve( _solv, &(_jobQueue) );
507 MIL << "....Solver end" << endl;
509 // copying solution back to zypp pool
510 //-----------------------------------------
511 _result_items_to_install.clear();
512 _result_items_to_remove.clear();
514 /* solvables to be installed */
516 queue_init(&decisionq);
517 solver_get_decisionqueue(_solv, &decisionq);
518 for ( int i = 0; i < decisionq.count; ++i )
520 sat::Solvable slv( decisionq.elements[i] );
521 if ( !slv || slv.isSystem() )
524 PoolItem poolItem( slv );
525 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
526 _result_items_to_install.push_back (poolItem);
528 queue_free(&decisionq);
530 /* solvables to be erased */
531 Repository systemRepo( sat::Pool::instance().findSystemRepo() ); // don't create if it does not exist
532 if ( systemRepo && ! systemRepo.solvablesEmpty() )
534 bool mustCheckObsoletes = false;
535 for_( it, systemRepo.solvablesBegin(), systemRepo.solvablesEnd() )
537 if (solver_get_decisionlevel(_solv, it->id()) > 0)
540 // Check if this is an update
541 CheckIfUpdate info( *it );
542 PoolItem poolItem( *it );
543 invokeOnEach( _pool.byIdentBegin( poolItem ),
544 _pool.byIdentEnd( poolItem ),
545 resfilter::ByUninstalled(), // ByUninstalled
546 functor::functorRef<bool,PoolItem> (info) );
548 if (info.is_updated) {
549 SATSolutionToPool( poolItem, ResStatus::toBeUninstalledDueToUpgrade, ResStatus::SOLVER );
551 SATSolutionToPool( poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER );
552 if ( ! mustCheckObsoletes )
553 mustCheckObsoletes = true; // lazy check for UninstalledDueToObsolete
555 _result_items_to_remove.push_back (poolItem);
557 if ( mustCheckObsoletes )
559 sat::WhatObsoletes obsoleted( _result_items_to_install.begin(), _result_items_to_install.end() );
560 for_( it, obsoleted.poolItemBegin(), obsoleted.poolItemEnd() )
562 ResStatus & status( it->status() );
563 // WhatObsoletes contains installed items only!
564 if ( status.transacts() && ! status.isToBeUninstalledDueToUpgrade() )
565 status.setToBeUninstalledDueToObsolete();
570 Queue recommendations;
574 queue_init(&recommendations);
575 queue_init(&suggestions);
576 queue_init(&orphaned);
577 queue_init(&unneeded);
578 solver_get_recommendations(_solv, &recommendations, &suggestions, 0);
579 solver_get_orphaned(_solv, &orphaned);
580 solver_get_unneeded(_solv, &unneeded, 1);
581 /* solvables which are recommended */
582 for ( int i = 0; i < recommendations.count; ++i )
584 PoolItem poolItem( getPoolItem( recommendations.elements[i] ) );
585 poolItem.status().setRecommended( true );
588 /* solvables which are suggested */
589 for ( int i = 0; i < suggestions.count; ++i )
591 PoolItem poolItem( getPoolItem( suggestions.elements[i] ) );
592 poolItem.status().setSuggested( true );
595 _problem_items.clear();
596 /* solvables which are orphaned */
597 for ( int i = 0; i < orphaned.count; ++i )
599 PoolItem poolItem( getPoolItem( orphaned.elements[i] ) );
600 poolItem.status().setOrphaned( true );
601 _problem_items.push_back( poolItem );
604 /* solvables which are unneeded */
605 for ( int i = 0; i < unneeded.count; ++i )
607 PoolItem poolItem( getPoolItem( unneeded.elements[i] ) );
608 poolItem.status().setUnneeded( true );
611 queue_free(&recommendations);
612 queue_free(&suggestions);
613 queue_free(&orphaned);
614 queue_free(&unneeded);
616 /* Write validation state back to pool */
617 Queue flags, solvableQueue;
620 queue_init(&solvableQueue);
622 CollectPseudoInstalled collectPseudoInstalled(&solvableQueue);
623 invokeOnEach( _pool.begin(),
625 functor::functorRef<bool,PoolItem> (collectPseudoInstalled) );
626 solver_trivial_installable(_solv, &solvableQueue, &flags );
627 for (int i = 0; i < solvableQueue.count; i++) {
628 PoolItem item = _pool.find (sat::Solvable(solvableQueue.elements[i]));
629 item.status().setUndetermined();
631 if (flags.elements[i] == -1) {
632 item.status().setNonRelevant();
633 _XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
634 } else if (flags.elements[i] == 1) {
635 item.status().setSatisfied();
636 _XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
637 } else if (flags.elements[i] == 0) {
638 item.status().setBroken();
639 _XDEBUG("SATSolutionToPool(" << item << " ) broken !");
642 queue_free(&(solvableQueue));
646 // Solvables which were selected due requirements which have been made by the user will
647 // be selected by APPL_LOW. We can't use any higher level, because this setting must
648 // not serve as a request for the next solver run. APPL_LOW is reset before solving.
649 for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
650 sat::WhatProvides rpmProviders(*iter);
651 for_( iter2, rpmProviders.begin(), rpmProviders.end() ) {
652 PoolItem poolItem(*iter2);
653 if (poolItem.status().isToBeInstalled()) {
654 MIL << "User requirement " << *iter << " sets " << poolItem << endl;
655 poolItem.status().setTransactByValue (ResStatus::APPL_LOW);
659 for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
660 sat::WhatProvides rpmProviders(*iter);
661 for_( iter2, rpmProviders.begin(), rpmProviders.end() ) {
662 PoolItem poolItem(*iter2);
663 if (poolItem.status().isToBeUninstalled()) {
664 MIL << "User conflict " << *iter << " sets " << poolItem << endl;
665 poolItem.status().setTransactByValue (ResStatus::APPL_LOW);
670 if (solver_problem_count(_solv) > 0 )
672 ERR << "Solverrun finished with an ERROR" << endl;
681 SATResolver::solverInit(const PoolItemList & weakItems)
683 SATCollectTransact info (*this);
685 MIL << "SATResolver::solverInit()" << endl;
690 queue_init( &_jobQueue );
691 _items_to_install.clear();
692 _items_to_remove.clear();
693 _items_to_lock.clear();
694 _items_to_keep.clear();
696 invokeOnEach ( _pool.begin(), _pool.end(),
697 functor::functorRef<bool,PoolItem>(info) );
699 for (PoolItemList::const_iterator iter = weakItems.begin(); iter != weakItems.end(); iter++) {
700 Id id = (*iter)->satSolvable().id();
702 ERR << "Weaken: " << *iter << " not found" << endl;
704 MIL << "Weaken dependencies of " << *iter << endl;
705 queue_push( &(_jobQueue), SOLVER_WEAKENDEPS | SOLVER_SOLVABLE );
706 queue_push( &(_jobQueue), id );
709 // Add rules for parallel installable resolvables with different versions
710 for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() )
712 queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE_NAME );
713 queue_push( &(_jobQueue), it->id() );
716 ::pool_add_userinstalled_jobs(_SATPool, sat::Pool::instance().autoInstalled(), &(_jobQueue), GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED);
720 if ( ZConfig::instance().solverUpgradeRemoveDroppedPackages() )
722 MIL << "Checking droplists ..." << endl;
723 // Dropped packages: look for 'weakremover()' provides
724 // in dup candidates of installed products.
725 ResPoolProxy proxy( ResPool::instance().proxy() );
726 for_( it, proxy.byKindBegin<Product>(), proxy.byKindEnd<Product>() )
728 if ( (*it)->onSystem() ) // (to install) or (not to delete)
730 Product::constPtr prodCand( (*it)->candidateAsKind<Product>() );
732 continue; // product no longer available
734 CapabilitySet droplist( prodCand->droplist() );
735 dumpRangeLine( MIL << "Droplist for " << (*it)->candidateObj() << ": " << droplist.size() << " ", droplist.begin(), droplist.end() ) << endl;
736 for_( cap, droplist.begin(), droplist.end() )
738 queue_push( &_jobQueue, SOLVER_DROP_ORPHANED | SOLVER_SOLVABLE_NAME );
739 queue_push( &_jobQueue, cap->id() );
746 MIL << "Droplist processing is disabled." << endl;
752 SATResolver::solverEnd()
759 queue_free( &(_jobQueue) );
765 SATResolver::resolvePool(const CapabilitySet & requires_caps,
766 const CapabilitySet & conflict_caps,
767 const PoolItemList & weakItems,
768 const std::set<Repository> & upgradeRepos)
770 MIL << "SATResolver::resolvePool()" << endl;
773 solverInit(weakItems);
775 for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
776 Id id = (*iter)->satSolvable().id();
778 ERR << "Install: " << *iter << " not found" << endl;
780 MIL << "Install " << *iter << endl;
781 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
782 queue_push( &(_jobQueue), id );
786 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
787 Id id = (*iter)->satSolvable().id();
789 ERR << "Delete: " << *iter << " not found" << endl;
791 MIL << "Delete " << *iter << endl;
792 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS );
793 queue_push( &(_jobQueue), id);
797 for_( iter, upgradeRepos.begin(), upgradeRepos.end() )
799 queue_push( &(_jobQueue), SOLVER_DISTUPGRADE | SOLVER_SOLVABLE_REPO );
800 queue_push( &(_jobQueue), iter->get()->repoid );
801 MIL << "Upgrade repo " << *iter << endl;
804 for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
805 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
806 queue_push( &(_jobQueue), iter->id() );
807 MIL << "Requires " << *iter << endl;
810 for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
811 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
812 queue_push( &(_jobQueue), iter->id() );
813 MIL << "Conflicts " << *iter << endl;
816 // set requirements for a running system
817 setSystemRequirements();
819 // set locks for the solver
823 bool ret = solving(requires_caps, conflict_caps);
825 (ret?MIL:WAR) << "SATResolver::resolvePool() done. Ret:" << ret << endl;
831 SATResolver::resolveQueue(const SolverQueueItemList &requestQueue,
832 const PoolItemList & weakItems)
834 MIL << "SATResolver::resolvQueue()" << endl;
837 solverInit(weakItems);
839 // generate solver queue
840 for (SolverQueueItemList::const_iterator iter = requestQueue.begin(); iter != requestQueue.end(); iter++) {
841 (*iter)->addRule(_jobQueue);
844 // Add addition item status to the resolve-queue cause these can be set by problem resolutions
845 for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
846 Id id = (*iter)->satSolvable().id();
848 ERR << "Install: " << *iter << " not found" << endl;
850 MIL << "Install " << *iter << endl;
851 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
852 queue_push( &(_jobQueue), id );
855 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
856 sat::detail::IdType ident( (*iter)->satSolvable().ident().id() );
857 MIL << "Delete " << *iter << ident << endl;
858 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | MAYBE_CLEANDEPS );
859 queue_push( &(_jobQueue), ident);
862 // set requirements for a running system
863 setSystemRequirements();
865 // set locks for the solver
869 bool ret = solving();
871 MIL << "SATResolver::resolveQueue() done. Ret:" << ret << endl;
875 /** \todo duplicate code to be joined with \ref solving. */
876 void SATResolver::doUpdate()
878 MIL << "SATResolver::doUpdate()" << endl;
881 solverInit(PoolItemList());
883 // set requirements for a running system
884 setSystemRequirements();
886 // set locks for the solver
889 _solv = solver_create( _SATPool );
890 ::pool_set_custom_vendorcheck( _SATPool, &vendorCheck );
892 queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
893 queue_push( &(_jobQueue), 0 );
896 queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL);
897 queue_push( &(_jobQueue), 0 );
900 queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL);
901 queue_push( &(_jobQueue), 0 );
903 if (_distupgrade_removeunsupported) {
904 queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
905 queue_push( &(_jobQueue), 0 );
907 solver_set_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
908 solver_set_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
909 solver_set_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
910 solver_set_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
911 solver_set_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
912 solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
913 solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
914 solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
916 sat::Pool::instance().prepareForSolving();
919 MIL << "Starting solving for update...." << endl;
921 solver_solve( _solv, &(_jobQueue) );
922 MIL << "....Solver end" << endl;
924 // copying solution back to zypp pool
925 //-----------------------------------------
927 /* solvables to be installed */
929 queue_init(&decisionq);
930 solver_get_decisionqueue(_solv, &decisionq);
931 for (int i = 0; i < decisionq.count; i++)
934 p = decisionq.elements[i];
935 if (p < 0 || !sat::Solvable(p))
937 if (sat::Solvable(p).repository().get() == _solv->pool->installed)
940 PoolItem poolItem = _pool.find (sat::Solvable(p));
942 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
944 ERR << "id " << p << " not found in ZYPP pool." << endl;
947 queue_free(&decisionq);
949 /* solvables to be erased */
950 for (int i = _solv->pool->installed->start; i < _solv->pool->installed->start + _solv->pool->installed->nsolvables; i++)
952 if (solver_get_decisionlevel(_solv, i) > 0)
955 PoolItem poolItem( _pool.find( sat::Solvable(i) ) );
957 // Check if this is an update
958 CheckIfUpdate info( (sat::Solvable(i)) );
959 invokeOnEach( _pool.byIdentBegin( poolItem ),
960 _pool.byIdentEnd( poolItem ),
961 resfilter::ByUninstalled(), // ByUninstalled
962 functor::functorRef<bool,PoolItem> (info) );
964 if (info.is_updated) {
965 SATSolutionToPool (poolItem, ResStatus::toBeUninstalledDueToUpgrade , ResStatus::SOLVER);
967 SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
970 ERR << "id " << i << " not found in ZYPP pool." << endl;
973 MIL << "SATResolver::doUpdate() done" << endl;
978 //----------------------------------------------------------------------------
979 //----------------------------------------------------------------------------
981 //----------------------------------------------------------------------------
982 //----------------------------------------------------------------------------
984 //----------------------------------------------------------------------------
986 //----------------------------------------------------------------------------
988 struct FindPackage : public resfilter::ResObjectFilterFunctor
990 ProblemSolutionCombi *problemSolution;
991 TransactionKind action;
992 FindPackage (ProblemSolutionCombi *p, const TransactionKind act)
993 : problemSolution (p)
998 bool operator()( PoolItem p)
1000 problemSolution->addSingleAction (p, action);
1006 //----------------------------------------------------------------------------
1007 // Checking if this solvable/item has a buddy which reflect the real
1008 // user visible description of an item
1009 // e.g. The release package has a buddy to the concerning product item.
1010 // This user want's the message "Product foo conflicts with product bar" and
1011 // NOT "package release-foo conflicts with package release-bar"
1012 // (ma: that's why we should map just packages to buddies, not vice versa)
1013 //----------------------------------------------------------------------------
1014 inline sat::Solvable mapBuddy( const PoolItem & item_r )
1016 if ( item_r.satSolvable().isKind<Package>() )
1018 sat::Solvable buddy = item_r.buddy();
1022 return item_r.satSolvable();
1024 inline sat::Solvable mapBuddy( sat::Solvable item_r )
1025 { return mapBuddy( PoolItem( item_r ) ); }
1027 PoolItem SATResolver::mapItem ( const PoolItem & item )
1028 { return PoolItem( mapBuddy( item ) ); }
1030 sat::Solvable SATResolver::mapSolvable ( const Id & id )
1031 { return mapBuddy( sat::Solvable(id) ); }
1033 string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreId)
1036 Pool *pool = _solv->pool;
1038 Id dep, source, target;
1039 sat::Solvable s, s2;
1043 // FIXME: solver_findallproblemrules to get all rules for this problem
1044 // (the 'most relevabt' one returned by solver_findproblemrule is embedded
1045 probr = solver_findproblemrule(_solv, problem);
1046 switch (solver_ruleinfo(_solv, probr, &source, &target, &dep))
1048 case SOLVER_RULE_DISTUPGRADE:
1049 s = mapSolvable (source);
1050 ret = str::form (_("%s does not belong to a distupgrade repository"), s.asString().c_str());
1052 case SOLVER_RULE_INFARCH:
1053 s = mapSolvable (source);
1054 ret = str::form (_("%s has inferior architecture"), s.asString().c_str());
1056 case SOLVER_RULE_UPDATE:
1057 s = mapSolvable (source);
1058 ret = str::form (_("problem with installed package %s"), s.asString().c_str());
1060 case SOLVER_RULE_JOB:
1061 ret = _("conflicting requests");
1063 case SOLVER_RULE_RPM:
1064 ret = _("some dependency problem");
1066 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP:
1067 ret = str::form (_("nothing provides requested %s"), pool_dep2str(pool, dep));
1068 detail += _("Have you enabled all requested repositories?");
1070 case SOLVER_RULE_JOB_UNKNOWN_PACKAGE:
1071 ret = str::form (_("package %s does not exist"), pool_dep2str(pool, dep));
1072 detail += _("Have you enabled all requested repositories?");
1074 case SOLVER_RULE_JOB_UNSUPPORTED:
1075 ret = _("unsupported request");
1077 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM:
1078 ret = str::form (_("%s is provided by the system and cannot be erased"), pool_dep2str(pool, dep));
1080 case SOLVER_RULE_RPM_NOT_INSTALLABLE:
1081 s = mapSolvable (source);
1082 ret = str::form (_("%s is not installable"), s.asString().c_str());
1084 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP:
1085 ignoreId = source; // for setting weak dependencies
1086 s = mapSolvable (source);
1087 ret = str::form (_("nothing provides %s needed by %s"), pool_dep2str(pool, dep), s.asString().c_str());
1089 case SOLVER_RULE_RPM_SAME_NAME:
1090 s = mapSolvable (source);
1091 s2 = mapSolvable (target);
1092 ret = str::form (_("cannot install both %s and %s"), s.asString().c_str(), s2.asString().c_str());
1094 case SOLVER_RULE_RPM_PACKAGE_CONFLICT:
1095 s = mapSolvable (source);
1096 s2 = mapSolvable (target);
1097 ret = str::form (_("%s conflicts with %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1099 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES:
1100 s = mapSolvable (source);
1101 s2 = mapSolvable (target);
1102 ret = str::form (_("%s obsoletes %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1104 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES:
1105 s = mapSolvable (source);
1106 s2 = mapSolvable (target);
1107 ret = str::form (_("installed %s obsoletes %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1109 case SOLVER_RULE_RPM_SELF_CONFLICT:
1110 s = mapSolvable (source);
1111 ret = str::form (_("solvable %s conflicts with %s provided by itself"), s.asString().c_str(), pool_dep2str(pool, dep));
1113 case SOLVER_RULE_RPM_PACKAGE_REQUIRES:
1114 ignoreId = source; // for setting weak dependencies
1115 s = mapSolvable (source);
1116 Capability cap(dep);
1117 sat::WhatProvides possibleProviders(cap);
1119 // check, if a provider will be deleted
1120 typedef list<PoolItem> ProviderList;
1121 ProviderList providerlistInstalled, providerlistUninstalled;
1122 for_( iter1, possibleProviders.begin(), possibleProviders.end() ) {
1123 PoolItem provider1 = ResPool::instance().find( *iter1 );
1124 // find pair of an installed/uninstalled item with the same NVR
1126 for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
1127 PoolItem provider2 = ResPool::instance().find( *iter2 );
1128 if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0
1129 && ( (provider1.status().isInstalled() && provider2.status().isUninstalled())
1130 || (provider2.status().isInstalled() && provider1.status().isUninstalled()) )) {
1136 if (provider1.status().isInstalled())
1137 providerlistInstalled.push_back(provider1);
1139 providerlistUninstalled.push_back(provider1);
1143 ret = str::form (_("%s requires %s, but this requirement cannot be provided"), s.asString().c_str(), pool_dep2str(pool, dep));
1144 if (providerlistInstalled.size() > 0) {
1145 detail += _("deleted providers: ");
1146 for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) {
1147 if (iter == providerlistInstalled.begin())
1148 detail += itemToString( *iter );
1150 detail += "\n " + itemToString( mapItem(*iter) );
1153 if (providerlistUninstalled.size() > 0) {
1154 if (detail.size() > 0)
1155 detail += _("\nuninstallable providers: ");
1157 detail = _("uninstallable providers: ");
1158 for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
1159 if (iter == providerlistUninstalled.begin())
1160 detail += itemToString( *iter );
1162 detail += "\n " + itemToString( mapItem(*iter) );
1172 SATResolver::problems ()
1174 ResolverProblemList resolverProblems;
1175 if (_solv && solver_problem_count(_solv)) {
1176 Pool *pool = _solv->pool;
1179 Id problem, solution, element;
1180 sat::Solvable s, sd;
1182 CapabilitySet system_requires = SystemCheck::instance().requiredSystemCap();
1183 CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap();
1185 MIL << "Encountered problems! Here are the solutions:\n" << endl;
1188 while ((problem = solver_next_problem(_solv, problem)) != 0) {
1189 MIL << "Problem " << pcnt++ << ":" << endl;
1190 MIL << "====================================" << endl;
1193 string whatString = SATprobleminfoString (problem,detail,ignoreId);
1194 MIL << whatString << endl;
1195 MIL << "------------------------------------" << endl;
1196 ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail);
1199 while ((solution = solver_next_solution(_solv, problem, solution)) != 0) {
1201 ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
1202 while ((element = solver_next_solutionelement(_solv, problem, solution, element, &p, &rp)) != 0) {
1203 if (p == SOLVER_SOLUTION_JOB) {
1204 /* job, rp is index into job queue */
1205 what = _jobQueue.elements[rp];
1206 switch (_jobQueue.elements[rp-1]&(SOLVER_SELECTMASK|SOLVER_JOBMASK))
1208 case SOLVER_INSTALL | SOLVER_SOLVABLE: {
1209 s = mapSolvable (what);
1210 PoolItem poolItem = _pool.find (s);
1212 if (pool->installed && s.get()->repo == pool->installed) {
1213 problemSolution->addSingleAction (poolItem, REMOVE);
1214 string description = str::form (_("remove lock to allow removal of %s"), s.asString().c_str() );
1215 MIL << description << endl;
1216 problemSolution->addDescription (description);
1218 problemSolution->addSingleAction (poolItem, KEEP);
1219 string description = str::form (_("do not install %s"), s.asString().c_str());
1220 MIL << description << endl;
1221 problemSolution->addDescription (description);
1224 ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << s.asString() << endl;
1228 case SOLVER_ERASE | SOLVER_SOLVABLE: {
1229 s = mapSolvable (what);
1230 PoolItem poolItem = _pool.find (s);
1232 if (pool->installed && s.get()->repo == pool->installed) {
1233 problemSolution->addSingleAction (poolItem, KEEP);
1234 string description = str::form (_("keep %s"), s.asString().c_str());
1235 MIL << description << endl;
1236 problemSolution->addDescription (description);
1238 problemSolution->addSingleAction (poolItem, UNLOCK);
1239 string description = str::form (_("remove lock to allow installation of %s"), itemToString( poolItem ).c_str());
1240 MIL << description << endl;
1241 problemSolution->addDescription (description);
1244 ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << s.asString() << endl;
1248 case SOLVER_INSTALL | SOLVER_SOLVABLE_NAME:
1250 IdString ident( what );
1251 SolverQueueItemInstall_Ptr install =
1252 new SolverQueueItemInstall(_pool, ident.asString(), false );
1253 problemSolution->addSingleAction (install, REMOVE_SOLVE_QUEUE_ITEM);
1255 string description = str::form (_("do not install %s"), ident.c_str() );
1256 MIL << description << endl;
1257 problemSolution->addDescription (description);
1260 case SOLVER_ERASE | SOLVER_SOLVABLE_NAME:
1262 // As we do not know, if this request has come from resolvePool or
1263 // resolveQueue we will have to take care for both cases.
1264 IdString ident( what );
1265 FindPackage info (problemSolution, KEEP);
1266 invokeOnEach( _pool.byIdentBegin( ident ),
1267 _pool.byIdentEnd( ident ),
1268 functor::chain (resfilter::ByInstalled (), // ByInstalled
1269 resfilter::ByTransact ()), // will be deinstalled
1270 functor::functorRef<bool,PoolItem> (info) );
1272 SolverQueueItemDelete_Ptr del =
1273 new SolverQueueItemDelete(_pool, ident.asString(), false );
1274 problemSolution->addSingleAction (del, REMOVE_SOLVE_QUEUE_ITEM);
1276 string description = str::form (_("keep %s"), ident.c_str());
1277 MIL << description << endl;
1278 problemSolution->addDescription (description);
1281 case SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES:
1283 problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_REQUIRE);
1284 string description = "";
1286 // Checking if this problem solution would break your system
1287 if (system_requires.find(Capability(what)) != system_requires.end()) {
1288 // Show a better warning
1289 resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() );
1290 resolverProblem->setDescription(_("This request will break your system!"));
1291 description = _("ignore the warning of a broken system");
1292 description += string(" (requires:")+pool_dep2str(pool, what)+")";
1293 MIL << description << endl;
1294 problemSolution->addFrontDescription (description);
1296 description = str::form (_("do not ask to install a solvable providing %s"), pool_dep2str(pool, what));
1297 MIL << description << endl;
1298 problemSolution->addDescription (description);
1302 case SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES:
1304 problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_CONFLICT);
1305 string description = "";
1307 // Checking if this problem solution would break your system
1308 if (system_conflicts.find(Capability(what)) != system_conflicts.end()) {
1309 // Show a better warning
1310 resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() );
1311 resolverProblem->setDescription(_("This request will break your system!"));
1312 description = _("ignore the warning of a broken system");
1313 description += string(" (conflicts:")+pool_dep2str(pool, what)+")";
1314 MIL << description << endl;
1315 problemSolution->addFrontDescription (description);
1318 description = str::form (_("do not ask to delete all solvables providing %s"), pool_dep2str(pool, what));
1319 MIL << description << endl;
1320 problemSolution->addDescription (description);
1324 case SOLVER_UPDATE | SOLVER_SOLVABLE:
1326 s = mapSolvable (what);
1327 PoolItem poolItem = _pool.find (s);
1329 if (pool->installed && s.get()->repo == pool->installed) {
1330 problemSolution->addSingleAction (poolItem, KEEP);
1331 string description = str::form (_("do not install most recent version of %s"), s.asString().c_str());
1332 MIL << description << endl;
1333 problemSolution->addDescription (description);
1335 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl;
1338 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << s.asString() << endl;
1343 MIL << "- do something different" << endl;
1344 ERR << "No valid solution available" << endl;
1347 } else if (p == SOLVER_SOLUTION_INFARCH) {
1348 s = mapSolvable (rp);
1349 PoolItem poolItem = _pool.find (s);
1350 if (pool->installed && s.get()->repo == pool->installed) {
1351 problemSolution->addSingleAction (poolItem, LOCK);
1352 string description = str::form (_("keep %s despite the inferior architecture"), s.asString().c_str());
1353 MIL << description << endl;
1354 problemSolution->addDescription (description);
1356 problemSolution->addSingleAction (poolItem, INSTALL);
1357 string description = str::form (_("install %s despite the inferior architecture"), s.asString().c_str());
1358 MIL << description << endl;
1359 problemSolution->addDescription (description);
1361 } else if (p == SOLVER_SOLUTION_DISTUPGRADE) {
1362 s = mapSolvable (rp);
1363 PoolItem poolItem = _pool.find (s);
1364 if (pool->installed && s.get()->repo == pool->installed) {
1365 problemSolution->addSingleAction (poolItem, LOCK);
1366 string description = str::form (_("keep obsolete %s"), s.asString().c_str());
1367 MIL << description << endl;
1368 problemSolution->addDescription (description);
1370 problemSolution->addSingleAction (poolItem, INSTALL);
1371 string description = str::form (_("install %s from excluded repository"), s.asString().c_str());
1372 MIL << description << endl;
1373 problemSolution->addDescription (description);
1376 /* policy, replace p with rp */
1377 s = mapSolvable (p);
1378 PoolItem itemFrom = _pool.find (s);
1383 sd = mapSolvable (rp);
1384 PoolItem itemTo = _pool.find (sd);
1385 if (itemFrom && itemTo) {
1386 problemSolution->addSingleAction (itemTo, INSTALL);
1387 int illegal = policy_is_illegal(_solv, s.get(), sd.get(), 0);
1389 if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0)
1391 string description = str::form (_("downgrade of %s to %s"), s.asString().c_str(), sd.asString().c_str());
1392 MIL << description << endl;
1393 problemSolution->addDescription (description);
1396 if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0)
1398 string description = str::form (_("architecture change of %s to %s"), s.asString().c_str(), sd.asString().c_str());
1399 MIL << description << endl;
1400 problemSolution->addDescription (description);
1403 if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0)
1405 IdString s_vendor( s.vendor() );
1406 IdString sd_vendor( sd.vendor() );
1407 string description = str::form (_("install %s (with vendor change)\n %s --> %s") ,
1408 sd.asString().c_str(),
1409 ( s_vendor ? s_vendor.c_str() : " (no vendor) " ),
1410 ( sd_vendor ? sd_vendor.c_str() : " (no vendor) " ) );
1411 MIL << description << endl;
1412 problemSolution->addDescription (description);
1416 string description = str::form (_("replacement of %s with %s"), s.asString().c_str(), sd.asString().c_str());
1417 MIL << description << endl;
1418 problemSolution->addDescription (description);
1421 ERR << s.asString() << " or " << sd.asString() << " not found" << endl;
1427 string description = str::form (_("deinstallation of %s"), s.asString().c_str());
1428 MIL << description << endl;
1429 problemSolution->addDescription (description);
1430 problemSolution->addSingleAction (itemFrom, REMOVE);
1435 resolverProblem->addSolution (problemSolution,
1436 problemSolution->actionCount() > 1 ? true : false); // Solutions with more than 1 action will be shown first.
1437 MIL << "------------------------------------" << endl;
1441 // There is a possibility to ignore this error by setting weak dependencies
1442 PoolItem item = _pool.find (sat::Solvable(ignoreId));
1443 ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(resolverProblem, item);
1444 resolverProblem->addSolution (problemSolution,
1445 false); // Solutions will be shown at the end
1446 MIL << "ignore some dependencies of " << item << endl;
1447 MIL << "------------------------------------" << endl;
1451 resolverProblems.push_back (resolverProblem);
1454 return resolverProblems;
1458 SATResolver::applySolutions (const ProblemSolutionList & solutions)
1460 for (ProblemSolutionList::const_iterator iter = solutions.begin();
1461 iter != solutions.end(); ++iter) {
1462 ProblemSolution_Ptr solution = *iter;
1463 Resolver dummyResolver(_pool);
1464 if (!solution->apply (dummyResolver))
1469 void SATResolver::setLocks()
1471 for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); ++iter) {
1472 sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() );
1473 if (iter->status().isInstalled()) {
1474 MIL << "Lock installed item " << *iter << endl;
1475 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
1476 queue_push( &(_jobQueue), ident );
1478 MIL << "Lock NOT installed item " << *iter << endl;
1479 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS );
1480 queue_push( &(_jobQueue), ident );
1484 ///////////////////////////////////////////////////////////////////
1485 // Weak locks: Ignore if an item with this name is already installed.
1486 // If it's not installed try to keep it this way using a weak delete
1487 ///////////////////////////////////////////////////////////////////
1488 std::set<IdString> unifiedByName;
1489 for (PoolItemList::const_iterator iter = _items_to_keep.begin(); iter != _items_to_keep.end(); ++iter) {
1490 IdString ident( (*iter)->satSolvable().ident() );
1491 if ( unifiedByName.insert( ident ).second )
1493 if ( ! ui::Selectable::get( *iter )->hasInstalledObj() )
1495 MIL << "Keep NOT installed name " << ident << " (" << *iter << ")" << endl;
1496 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | SOLVER_WEAK | MAYBE_CLEANDEPS );
1497 queue_push( &(_jobQueue), ident.id() );
1503 void SATResolver::setSystemRequirements()
1505 CapabilitySet system_requires = SystemCheck::instance().requiredSystemCap();
1506 CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap();
1508 for (CapabilitySet::const_iterator iter = system_requires.begin(); iter != system_requires.end(); ++iter) {
1509 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
1510 queue_push( &(_jobQueue), iter->id() );
1511 MIL << "SYSTEM Requires " << *iter << endl;
1514 for (CapabilitySet::const_iterator iter = system_conflicts.begin(); iter != system_conflicts.end(); ++iter) {
1515 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
1516 queue_push( &(_jobQueue), iter->id() );
1517 MIL << "SYSTEM Conflicts " << *iter << endl;
1520 // Lock the architecture of the running systems rpm
1521 // package on distupgrade.
1522 if ( _distupgrade && ZConfig::instance().systemRoot() == "/" )
1524 ResPool pool( ResPool::instance() );
1525 IdString rpm( "rpm" );
1526 for_( it, pool.byIdentBegin(rpm), pool.byIdentEnd(rpm) )
1528 if ( (*it)->isSystem() )
1530 Capability archrule( (*it)->arch(), rpm.c_str(), Capability::PARSED );
1531 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_NAME | SOLVER_ESSENTIAL );
1532 queue_push( &(_jobQueue), archrule.id() );
1539 sat::StringQueue SATResolver::autoInstalled() const
1541 sat::StringQueue ret;
1543 ::solver_get_userinstalled( _solv, ret, GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED );
1547 sat::StringQueue SATResolver::userInstalled() const
1549 sat::StringQueue ret;
1551 ::solver_get_userinstalled( _solv, ret, GET_USERINSTALLED_NAMES );
1556 ///////////////////////////////////////////////////////////////////
1557 };// namespace detail
1558 /////////////////////////////////////////////////////////////////////
1559 /////////////////////////////////////////////////////////////////////
1560 };// namespace solver
1561 ///////////////////////////////////////////////////////////////////////
1562 ///////////////////////////////////////////////////////////////////////
1564 /////////////////////////////////////////////////////////////////////////