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 #define ZYPP_USE_RESOLVER_INTERNALS
34 #include "zypp/base/String.h"
35 #include "zypp/Product.h"
36 #include "zypp/Capability.h"
37 #include "zypp/ResStatus.h"
38 #include "zypp/VendorAttr.h"
39 #include "zypp/base/LogTools.h"
40 #include "zypp/base/String.h"
41 #include "zypp/base/Gettext.h"
42 #include "zypp/base/Algorithm.h"
43 #include "zypp/ResPool.h"
44 #include "zypp/ResFilters.h"
45 #include "zypp/ZConfig.h"
46 #include "zypp/sat/Pool.h"
47 #include "zypp/sat/WhatProvides.h"
48 #include "zypp/sat/WhatObsoletes.h"
49 #include "zypp/solver/detail/Resolver.h"
50 #include "zypp/solver/detail/SATResolver.h"
51 #include "zypp/solver/detail/ProblemSolutionCombi.h"
52 #include "zypp/solver/detail/ProblemSolutionIgnore.h"
53 #include "zypp/solver/detail/SolverQueueItemInstall.h"
54 #include "zypp/solver/detail/SolverQueueItemDelete.h"
55 #include "zypp/solver/detail/SystemCheck.h"
56 #include "zypp/solver/detail/SolutionAction.h"
57 #include "zypp/solver/detail/SolverQueueItem.h"
58 #include "zypp/sat/Transaction.h"
59 #include "zypp/sat/Queue.h"
61 #include "zypp/sat/detail/PoolImpl.h"
63 #define XDEBUG(x) do { if (base::logger::isExcessive()) XXX << x << std::endl;} while (0)
65 /////////////////////////////////////////////////////////////////////////
67 { ///////////////////////////////////////////////////////////////////////
69 /////////////////////////////////////////////////////////////////////////
72 inline bool HACKENV( const char * var_r, bool default_r )
75 const char * val = ::getenv( var_r );
78 ret = str::strToBool( val, default_r );
79 if ( ret != default_r )
80 INT << "HACKENV " << var_r << " = " << ret << endl;
85 /////////////////////////////////////////////////////////////////////////
87 ///////////////////////////////////////////////////////////////////////
89 { /////////////////////////////////////////////////////////////////////
90 /////////////////////////////////////////////////////////////////////
92 { ///////////////////////////////////////////////////////////////////
96 IMPL_PTR_TYPE(SATResolver);
98 #define MAYBE_CLEANDEPS (cleandepsOnRemove()?SOLVER_CLEANDEPS:0)
100 //---------------------------------------------------------------------------
101 // Callbacks for SAT policies
102 //---------------------------------------------------------------------------
104 int vendorCheck( sat::detail::CPool *pool, Solvable *solvable1, Solvable *solvable2 )
106 return VendorAttr::instance().equivalent( IdString(solvable1->vendor),
107 IdString(solvable2->vendor) ) ? 0 : 1;
111 inline std::string itemToString( const PoolItem & item )
114 return std::string();
116 sat::Solvable slv( item.satSolvable() );
117 std::string ret( slv.asString() ); // n-v-r.a
118 if ( ! slv.isSystem() )
121 ret += slv.repository().alias();
127 inline PoolItem getPoolItem( Id id_r )
129 PoolItem ret( (sat::Solvable( id_r )) );
131 INT << "id " << id_r << " not found in ZYPP pool." << endl;
135 //---------------------------------------------------------------------------
138 SATResolver::dumpOn( std::ostream & os ) const
140 os << "<resolver>" << endl;
142 #define OUTS(X) os << " " << #X << "\t= " << solver_get_flag(_satSolver, SOLVER_FLAG_##X) << endl
143 OUTS( ALLOW_DOWNGRADE );
144 OUTS( ALLOW_ARCHCHANGE );
145 OUTS( ALLOW_VENDORCHANGE );
146 OUTS( ALLOW_NAMECHANGE );
147 OUTS( ALLOW_UNINSTALL );
148 OUTS( NO_UPDATEPROVIDE );
149 OUTS( SPLITPROVIDES );
150 OUTS( IGNORE_RECOMMENDED );
151 OUTS( ADD_ALREADY_RECOMMENDED );
152 OUTS( NO_INFARCHCHECK );
153 OUTS( KEEP_EXPLICIT_OBSOLETES );
154 OUTS( BEST_OBEY_POLICY );
155 OUTS( NO_AUTOTARGET );
156 OUTS( DUP_ALLOW_DOWNGRADE );
157 OUTS( DUP_ALLOW_ARCHCHANGE );
158 OUTS( DUP_ALLOW_VENDORCHANGE );
159 OUTS( DUP_ALLOW_NAMECHANGE );
160 OUTS( KEEP_ORPHANS );
161 OUTS( BREAK_ORPHANS );
162 OUTS( FOCUS_INSTALLED );
163 OUTS( YUM_OBSOLETES );
165 os << " distupgrade = " << _distupgrade << endl;
166 os << " distupgrade_removeunsupported = " << _distupgrade_removeunsupported << endl;
167 os << " solveSrcPackages = " << _solveSrcPackages << endl;
168 os << " cleandepsOnRemove = " << _cleandepsOnRemove << endl;
169 os << " fixsystem = " << _fixsystem << endl;
173 return os << "<resolver/>" << endl;
176 //---------------------------------------------------------------------------
178 // NOTE: flag defaults must be in sync with ZVARDEFAULT in Resolver.cc
179 SATResolver::SATResolver (const ResPool & pool, sat::detail::CPool *satPool)
184 , _allowdowngrade ( false )
185 , _allownamechange ( true ) // bsc#1071466
186 , _allowarchchange ( false )
187 , _allowvendorchange ( ZConfig::instance().solver_allowVendorChange() )
188 , _allowuninstall ( false )
189 , _updatesystem(false)
190 , _noupdateprovide ( false )
191 , _dosplitprovides ( true )
192 , _onlyRequires(ZConfig::instance().solver_onlyRequires())
193 , _ignorealreadyrecommended(true)
194 , _distupgrade(false)
195 , _distupgrade_removeunsupported(false)
196 , _dup_allowdowngrade ( ZConfig::instance().solver_dupAllowDowngrade() )
197 , _dup_allownamechange ( ZConfig::instance().solver_dupAllowNameChange() )
198 , _dup_allowarchchange ( ZConfig::instance().solver_dupAllowArchChange() )
199 , _dup_allowvendorchange ( ZConfig::instance().solver_dupAllowVendorChange() )
200 , _solveSrcPackages(false)
201 , _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove())
206 SATResolver::~SATResolver()
211 //---------------------------------------------------------------------------
214 SATResolver::pool (void) const
219 //---------------------------------------------------------------------------
221 // copy marked item from solution back to pool
222 // if data != NULL, set as APPL_LOW (from establishPool())
225 SATSolutionToPool (PoolItem item, const ResStatus & status, const ResStatus::TransactByValue causer)
228 item.status().resetTransact (causer);
229 item.status().resetWeak ();
233 // installation/deletion
234 if (status.isToBeInstalled()) {
235 r = item.status().setToBeInstalled (causer);
236 XDEBUG("SATSolutionToPool install returns " << item << ", " << r);
238 else if (status.isToBeUninstalledDueToUpgrade()) {
239 r = item.status().setToBeUninstalledDueToUpgrade (causer);
240 XDEBUG("SATSolutionToPool upgrade returns " << item << ", " << r);
242 else if (status.isToBeUninstalled()) {
243 r = item.status().setToBeUninstalled (causer);
244 XDEBUG("SATSolutionToPool remove returns " << item << ", " << r);
250 //----------------------------------------------------------------------------
251 //----------------------------------------------------------------------------
253 //----------------------------------------------------------------------------
254 //----------------------------------------------------------------------------
255 /////////////////////////////////////////////////////////////////////////
256 /// \class SATCollectTransact
257 /// \brief Commit helper functor distributing PoolItem by status into lists
259 /// On the fly it clears all PoolItem bySolver/ByApplLow status.
260 /// The lists are cleared in the Ctor, populated by \ref operator().
261 /////////////////////////////////////////////////////////////////////////
262 struct SATCollectTransact : public resfilter::PoolItemFilterFunctor
264 SATCollectTransact( PoolItemList & items_to_install_r,
265 PoolItemList & items_to_remove_r,
266 PoolItemList & items_to_lock_r,
267 PoolItemList & items_to_keep_r,
268 bool solveSrcPackages_r )
269 : _items_to_install( items_to_install_r )
270 , _items_to_remove( items_to_remove_r )
271 , _items_to_lock( items_to_lock_r )
272 , _items_to_keep( items_to_keep_r )
273 , _solveSrcPackages( solveSrcPackages_r )
275 _items_to_install.clear();
276 _items_to_remove.clear();
277 _items_to_lock.clear();
278 _items_to_keep.clear();
281 bool operator()( const PoolItem & item_r )
284 ResStatus & itemStatus( item_r.status() );
285 bool by_solver = ( itemStatus.isBySolver() || itemStatus.isByApplLow() );
289 // Clear former solver/establish resultd
290 itemStatus.resetTransact( ResStatus::APPL_LOW );
291 return true; // -> back out here, don't re-queue former results
294 if ( !_solveSrcPackages && item_r.isKind<SrcPackage>() )
296 // Later we may continue on a per source package base.
297 return true; // dont process this source package.
300 switch ( itemStatus.getTransactValue() )
302 case ResStatus::TRANSACT:
303 itemStatus.isUninstalled() ? _items_to_install.push_back( item_r )
304 : _items_to_remove.push_back( item_r ); break;
305 case ResStatus::LOCKED: _items_to_lock.push_back( item_r ); break;
306 case ResStatus::KEEP_STATE: _items_to_keep.push_back( item_r ); break;
312 PoolItemList & _items_to_install;
313 PoolItemList & _items_to_remove;
314 PoolItemList & _items_to_lock;
315 PoolItemList & _items_to_keep;
316 bool _solveSrcPackages;
319 /////////////////////////////////////////////////////////////////////////
322 //----------------------------------------------------------------------------
323 //----------------------------------------------------------------------------
325 //----------------------------------------------------------------------------
326 //----------------------------------------------------------------------------
329 class CheckIfUpdate : public resfilter::PoolItemFilterFunctor
333 sat::Solvable _installed;
335 CheckIfUpdate( const sat::Solvable & installed_r )
336 : is_updated( false )
337 , _installed( installed_r )
340 // check this item will be updated
342 bool operator()( const PoolItem & item )
344 if ( item.status().isToBeInstalled() )
346 if ( ! item.multiversionInstall() || sameNVRA( _installed, item ) )
357 class CollectPseudoInstalled : public resfilter::PoolItemFilterFunctor
360 Queue *solvableQueue;
362 CollectPseudoInstalled( Queue *queue )
363 :solvableQueue (queue)
366 // collecting PseudoInstalled items
367 bool operator()( PoolItem item )
369 if ( traits::isPseudoInstalled( item.satSolvable().kind() ) )
370 queue_push( solvableQueue, item.satSolvable().id() );
376 SATResolver::solving(const CapabilitySet & requires_caps,
377 const CapabilitySet & conflict_caps)
379 _satSolver = solver_create( _satPool );
380 ::pool_set_custom_vendorcheck( _satPool, &vendorCheck );
382 queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
383 queue_push( &(_jobQueue), 0 );
386 queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL);
387 queue_push( &(_jobQueue), 0 );
390 queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL);
391 queue_push( &(_jobQueue), 0 );
393 if (_distupgrade_removeunsupported) {
394 queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
395 queue_push( &(_jobQueue), 0 );
397 solver_set_flag(_satSolver, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
398 solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
399 solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_NAMECHANGE, _allownamechange);
400 solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
401 solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
402 solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
403 solver_set_flag(_satSolver, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
404 solver_set_flag(_satSolver, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
405 solver_set_flag(_satSolver, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
406 solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_DOWNGRADE, _dup_allowdowngrade );
407 solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_NAMECHANGE, _dup_allownamechange );
408 solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE, _dup_allowarchchange );
409 solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE, _dup_allowvendorchange );
411 #define HACKENV(X,D) solver_set_flag(_satSolver, X, env::HACKENV( #X, D ) );
412 HACKENV( SOLVER_FLAG_DUP_ALLOW_DOWNGRADE, _dup_allowdowngrade );
413 HACKENV( SOLVER_FLAG_DUP_ALLOW_NAMECHANGE, _dup_allownamechange );
414 HACKENV( SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE, _dup_allowarchchange );
415 HACKENV( SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE,_dup_allowvendorchange );
418 sat::Pool::instance().prepare();
421 MIL << "Starting solving...." << endl;
423 solver_solve( _satSolver, &(_jobQueue) );
424 MIL << "....Solver end" << endl;
426 // copying solution back to zypp pool
427 //-----------------------------------------
428 _result_items_to_install.clear();
429 _result_items_to_remove.clear();
431 /* solvables to be installed */
433 queue_init(&decisionq);
434 solver_get_decisionqueue(_satSolver, &decisionq);
435 for ( int i = 0; i < decisionq.count; ++i )
437 sat::Solvable slv( decisionq.elements[i] );
438 if ( !slv || slv.isSystem() )
441 PoolItem poolItem( slv );
442 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
443 _result_items_to_install.push_back( poolItem );
445 queue_free(&decisionq);
447 /* solvables to be erased */
448 Repository systemRepo( sat::Pool::instance().findSystemRepo() ); // don't create if it does not exist
449 if ( systemRepo && ! systemRepo.solvablesEmpty() )
451 bool mustCheckObsoletes = false;
452 for_( it, systemRepo.solvablesBegin(), systemRepo.solvablesEnd() )
454 if (solver_get_decisionlevel(_satSolver, it->id()) > 0)
457 // Check if this is an update
458 CheckIfUpdate info( *it );
459 PoolItem poolItem( *it );
460 invokeOnEach( _pool.byIdentBegin( poolItem ),
461 _pool.byIdentEnd( poolItem ),
462 resfilter::ByUninstalled(), // ByUninstalled
463 functor::functorRef<bool,PoolItem> (info) );
465 if (info.is_updated) {
466 SATSolutionToPool( poolItem, ResStatus::toBeUninstalledDueToUpgrade, ResStatus::SOLVER );
468 SATSolutionToPool( poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER );
469 if ( ! mustCheckObsoletes )
470 mustCheckObsoletes = true; // lazy check for UninstalledDueToObsolete
472 _result_items_to_remove.push_back (poolItem);
474 if ( mustCheckObsoletes )
476 sat::WhatObsoletes obsoleted( _result_items_to_install.begin(), _result_items_to_install.end() );
477 for_( it, obsoleted.poolItemBegin(), obsoleted.poolItemEnd() )
479 ResStatus & status( it->status() );
480 // WhatObsoletes contains installed items only!
481 if ( status.transacts() && ! status.isToBeUninstalledDueToUpgrade() )
482 status.setToBeUninstalledDueToObsolete();
487 Queue recommendations;
491 queue_init(&recommendations);
492 queue_init(&suggestions);
493 queue_init(&orphaned);
494 queue_init(&unneeded);
495 solver_get_recommendations(_satSolver, &recommendations, &suggestions, 0);
496 solver_get_orphaned(_satSolver, &orphaned);
497 solver_get_unneeded(_satSolver, &unneeded, 1);
498 /* solvables which are recommended */
499 for ( int i = 0; i < recommendations.count; ++i )
501 PoolItem poolItem( getPoolItem( recommendations.elements[i] ) );
502 poolItem.status().setRecommended( true );
505 /* solvables which are suggested */
506 for ( int i = 0; i < suggestions.count; ++i )
508 PoolItem poolItem( getPoolItem( suggestions.elements[i] ) );
509 poolItem.status().setSuggested( true );
512 _problem_items.clear();
513 /* solvables which are orphaned */
514 for ( int i = 0; i < orphaned.count; ++i )
516 PoolItem poolItem( getPoolItem( orphaned.elements[i] ) );
517 poolItem.status().setOrphaned( true );
518 _problem_items.push_back( poolItem );
521 /* solvables which are unneeded */
522 for ( int i = 0; i < unneeded.count; ++i )
524 PoolItem poolItem( getPoolItem( unneeded.elements[i] ) );
525 poolItem.status().setUnneeded( true );
528 queue_free(&recommendations);
529 queue_free(&suggestions);
530 queue_free(&orphaned);
531 queue_free(&unneeded);
533 /* Write validation state back to pool */
534 Queue flags, solvableQueue;
537 queue_init(&solvableQueue);
539 CollectPseudoInstalled collectPseudoInstalled(&solvableQueue);
540 invokeOnEach( _pool.begin(),
542 functor::functorRef<bool,PoolItem> (collectPseudoInstalled) );
543 solver_trivial_installable(_satSolver, &solvableQueue, &flags );
544 for (int i = 0; i < solvableQueue.count; i++) {
545 PoolItem item = _pool.find (sat::Solvable(solvableQueue.elements[i]));
546 item.status().setUndetermined();
548 if (flags.elements[i] == -1) {
549 item.status().setNonRelevant();
550 XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
551 } else if (flags.elements[i] == 1) {
552 item.status().setSatisfied();
553 XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
554 } else if (flags.elements[i] == 0) {
555 item.status().setBroken();
556 XDEBUG("SATSolutionToPool(" << item << " ) broken !");
559 queue_free(&(solvableQueue));
563 // Solvables which were selected due requirements which have been made by the user will
564 // be selected by APPL_LOW. We can't use any higher level, because this setting must
565 // not serve as a request for the next solver run. APPL_LOW is reset before solving.
566 for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
567 sat::WhatProvides rpmProviders(*iter);
568 for_( iter2, rpmProviders.begin(), rpmProviders.end() ) {
569 PoolItem poolItem(*iter2);
570 if (poolItem.status().isToBeInstalled()) {
571 MIL << "User requirement " << *iter << " sets " << poolItem << endl;
572 poolItem.status().setTransactByValue (ResStatus::APPL_LOW);
576 for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
577 sat::WhatProvides rpmProviders(*iter);
578 for_( iter2, rpmProviders.begin(), rpmProviders.end() ) {
579 PoolItem poolItem(*iter2);
580 if (poolItem.status().isToBeUninstalled()) {
581 MIL << "User conflict " << *iter << " sets " << poolItem << endl;
582 poolItem.status().setTransactByValue (ResStatus::APPL_LOW);
587 if (solver_problem_count(_satSolver) > 0 )
589 ERR << "Solverrun finished with an ERROR" << endl;
598 SATResolver::solverInit(const PoolItemList & weakItems)
601 MIL << "SATResolver::solverInit()" << endl;
605 queue_init( &_jobQueue );
607 // clear and rebuild: _items_to_install, _items_to_remove, _items_to_lock, _items_to_keep
609 SATCollectTransact collector( _items_to_install, _items_to_remove, _items_to_lock, _items_to_keep, solveSrcPackages() );
610 invokeOnEach ( _pool.begin(), _pool.end(), functor::functorRef<bool,PoolItem>( collector ) );
613 for (PoolItemList::const_iterator iter = weakItems.begin(); iter != weakItems.end(); iter++) {
614 Id id = (*iter)->satSolvable().id();
616 ERR << "Weaken: " << *iter << " not found" << endl;
618 MIL << "Weaken dependencies of " << *iter << endl;
619 queue_push( &(_jobQueue), SOLVER_WEAKENDEPS | SOLVER_SOLVABLE );
620 queue_push( &(_jobQueue), id );
623 // Ad rules for changed requestedLocales
624 const auto & trackedLocaleIds( myPool().trackedLocaleIds() );
625 for ( const auto & locale : trackedLocaleIds.added() )
627 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
628 queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
631 for ( const auto & locale : trackedLocaleIds.removed() )
633 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | SOLVER_CLEANDEPS ); // needs uncond. SOLVER_CLEANDEPS!
634 queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
637 // Add rules for parallel installable resolvables with different versions
638 for ( const sat::Solvable & solv : myPool().multiversionList() )
640 queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE );
641 queue_push( &(_jobQueue), solv.id() );
644 ::pool_add_userinstalled_jobs(_satPool, sat::Pool::instance().autoInstalled(), &(_jobQueue), GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED);
648 if ( ZConfig::instance().solverUpgradeRemoveDroppedPackages() )
650 MIL << "Checking droplists ..." << endl;
651 // Dropped packages: look for 'weakremover()' provides
652 // in dup candidates of installed products.
653 ResPoolProxy proxy( ResPool::instance().proxy() );
654 for_( it, proxy.byKindBegin<Product>(), proxy.byKindEnd<Product>() )
656 if ( (*it)->onSystem() ) // (to install) or (not to delete)
658 Product::constPtr prodCand( (*it)->candidateAsKind<Product>() );
660 continue; // product no longer available
662 CapabilitySet droplist( prodCand->droplist() );
663 dumpRangeLine( MIL << "Droplist for " << (*it)->candidateObj() << ": " << droplist.size() << " ", droplist.begin(), droplist.end() ) << endl;
664 for_( cap, droplist.begin(), droplist.end() )
666 queue_push( &_jobQueue, SOLVER_DROP_ORPHANED | SOLVER_SOLVABLE_NAME );
667 queue_push( &_jobQueue, cap->id() );
674 MIL << "Droplist processing is disabled." << endl;
680 SATResolver::solverEnd()
685 solver_free(_satSolver);
687 queue_free( &(_jobQueue) );
693 SATResolver::resolvePool(const CapabilitySet & requires_caps,
694 const CapabilitySet & conflict_caps,
695 const PoolItemList & weakItems,
696 const std::set<Repository> & upgradeRepos)
698 MIL << "SATResolver::resolvePool()" << endl;
701 solverInit(weakItems);
703 for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
704 Id id = (*iter)->satSolvable().id();
706 ERR << "Install: " << *iter << " not found" << endl;
708 MIL << "Install " << *iter << endl;
709 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
710 queue_push( &(_jobQueue), id );
714 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
715 Id id = (*iter)->satSolvable().id();
717 ERR << "Delete: " << *iter << " not found" << endl;
719 MIL << "Delete " << *iter << endl;
720 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS );
721 queue_push( &(_jobQueue), id);
725 for_( iter, upgradeRepos.begin(), upgradeRepos.end() )
727 queue_push( &(_jobQueue), SOLVER_DISTUPGRADE | SOLVER_SOLVABLE_REPO );
728 queue_push( &(_jobQueue), iter->get()->repoid );
729 MIL << "Upgrade repo " << *iter << endl;
732 for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
733 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
734 queue_push( &(_jobQueue), iter->id() );
735 MIL << "Requires " << *iter << endl;
738 for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
739 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
740 queue_push( &(_jobQueue), iter->id() );
741 MIL << "Conflicts " << *iter << endl;
744 // set requirements for a running system
745 setSystemRequirements();
747 // set locks for the solver
751 bool ret = solving(requires_caps, conflict_caps);
753 (ret?MIL:WAR) << "SATResolver::resolvePool() done. Ret:" << ret << endl;
759 SATResolver::resolveQueue(const SolverQueueItemList &requestQueue,
760 const PoolItemList & weakItems)
762 MIL << "SATResolver::resolvQueue()" << endl;
765 solverInit(weakItems);
767 // generate solver queue
768 for (SolverQueueItemList::const_iterator iter = requestQueue.begin(); iter != requestQueue.end(); iter++) {
769 (*iter)->addRule(_jobQueue);
772 // Add addition item status to the resolve-queue cause these can be set by problem resolutions
773 for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
774 Id id = (*iter)->satSolvable().id();
776 ERR << "Install: " << *iter << " not found" << endl;
778 MIL << "Install " << *iter << endl;
779 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
780 queue_push( &(_jobQueue), id );
783 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
784 sat::detail::IdType ident( (*iter)->satSolvable().ident().id() );
785 MIL << "Delete " << *iter << ident << endl;
786 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | MAYBE_CLEANDEPS );
787 queue_push( &(_jobQueue), ident);
790 // set requirements for a running system
791 setSystemRequirements();
793 // set locks for the solver
797 bool ret = solving();
799 MIL << "SATResolver::resolveQueue() done. Ret:" << ret << endl;
803 /** \todo duplicate code to be joined with \ref solving. */
804 void SATResolver::doUpdate()
806 MIL << "SATResolver::doUpdate()" << endl;
809 solverInit(PoolItemList());
811 // set requirements for a running system
812 setSystemRequirements();
814 // set locks for the solver
817 _satSolver = solver_create( _satPool );
818 ::pool_set_custom_vendorcheck( _satPool, &vendorCheck );
820 queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
821 queue_push( &(_jobQueue), 0 );
824 queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL);
825 queue_push( &(_jobQueue), 0 );
828 queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL);
829 queue_push( &(_jobQueue), 0 );
831 if (_distupgrade_removeunsupported) {
832 queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
833 queue_push( &(_jobQueue), 0 );
835 solver_set_flag(_satSolver, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
836 solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
837 solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_NAMECHANGE, _allownamechange);
838 solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
839 solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
840 solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
841 solver_set_flag(_satSolver, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
842 solver_set_flag(_satSolver, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
843 solver_set_flag(_satSolver, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
845 sat::Pool::instance().prepare();
848 MIL << "Starting solving for update...." << endl;
850 solver_solve( _satSolver, &(_jobQueue) );
851 MIL << "....Solver end" << endl;
853 // copying solution back to zypp pool
854 //-----------------------------------------
856 /* solvables to be installed */
858 queue_init(&decisionq);
859 solver_get_decisionqueue(_satSolver, &decisionq);
860 for (int i = 0; i < decisionq.count; i++)
863 p = decisionq.elements[i];
864 if (p < 0 || !sat::Solvable(p))
866 if (sat::Solvable(p).repository().get() == _satSolver->pool->installed)
869 PoolItem poolItem = _pool.find (sat::Solvable(p));
871 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
873 ERR << "id " << p << " not found in ZYPP pool." << endl;
876 queue_free(&decisionq);
878 /* solvables to be erased */
879 for (int i = _satSolver->pool->installed->start; i < _satSolver->pool->installed->start + _satSolver->pool->installed->nsolvables; i++)
881 if (solver_get_decisionlevel(_satSolver, i) > 0)
884 PoolItem poolItem( _pool.find( sat::Solvable(i) ) );
886 // Check if this is an update
887 CheckIfUpdate info( (sat::Solvable(i)) );
888 invokeOnEach( _pool.byIdentBegin( poolItem ),
889 _pool.byIdentEnd( poolItem ),
890 resfilter::ByUninstalled(), // ByUninstalled
891 functor::functorRef<bool,PoolItem> (info) );
893 if (info.is_updated) {
894 SATSolutionToPool (poolItem, ResStatus::toBeUninstalledDueToUpgrade , ResStatus::SOLVER);
896 SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
899 ERR << "id " << i << " not found in ZYPP pool." << endl;
902 MIL << "SATResolver::doUpdate() done" << endl;
907 //----------------------------------------------------------------------------
908 //----------------------------------------------------------------------------
910 //----------------------------------------------------------------------------
911 //----------------------------------------------------------------------------
913 //----------------------------------------------------------------------------
915 //----------------------------------------------------------------------------
917 struct FindPackage : public resfilter::ResObjectFilterFunctor
919 ProblemSolutionCombi *problemSolution;
920 TransactionKind action;
921 FindPackage (ProblemSolutionCombi *p, const TransactionKind act)
922 : problemSolution (p)
927 bool operator()( PoolItem p)
929 problemSolution->addSingleAction (p, action);
935 //----------------------------------------------------------------------------
936 // Checking if this solvable/item has a buddy which reflect the real
937 // user visible description of an item
938 // e.g. The release package has a buddy to the concerning product item.
939 // This user want's the message "Product foo conflicts with product bar" and
940 // NOT "package release-foo conflicts with package release-bar"
941 // (ma: that's why we should map just packages to buddies, not vice versa)
942 //----------------------------------------------------------------------------
943 inline sat::Solvable mapBuddy( const PoolItem & item_r )
945 if ( item_r.satSolvable().isKind<Package>() )
947 sat::Solvable buddy = item_r.buddy();
951 return item_r.satSolvable();
953 inline sat::Solvable mapBuddy( sat::Solvable item_r )
954 { return mapBuddy( PoolItem( item_r ) ); }
956 PoolItem SATResolver::mapItem ( const PoolItem & item )
957 { return PoolItem( mapBuddy( item ) ); }
959 sat::Solvable SATResolver::mapSolvable ( const Id & id )
960 { return mapBuddy( sat::Solvable(id) ); }
962 string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreId)
965 sat::detail::CPool *pool = _satSolver->pool;
967 Id dep, source, target;
972 // FIXME: solver_findallproblemrules to get all rules for this problem
973 // (the 'most relevabt' one returned by solver_findproblemrule is embedded
974 probr = solver_findproblemrule(_satSolver, problem);
975 switch (solver_ruleinfo(_satSolver, probr, &source, &target, &dep))
977 case SOLVER_RULE_DISTUPGRADE:
978 s = mapSolvable (source);
979 ret = str::form (_("%s does not belong to a distupgrade repository"), s.asString().c_str());
981 case SOLVER_RULE_INFARCH:
982 s = mapSolvable (source);
983 ret = str::form (_("%s has inferior architecture"), s.asString().c_str());
985 case SOLVER_RULE_UPDATE:
986 s = mapSolvable (source);
987 ret = str::form (_("problem with installed package %s"), s.asString().c_str());
989 case SOLVER_RULE_JOB:
990 ret = _("conflicting requests");
992 case SOLVER_RULE_RPM:
993 ret = _("some dependency problem");
995 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP:
996 ret = str::form (_("nothing provides requested %s"), pool_dep2str(pool, dep));
997 detail += _("Have you enabled all requested repositories?");
999 case SOLVER_RULE_JOB_UNKNOWN_PACKAGE:
1000 ret = str::form (_("package %s does not exist"), pool_dep2str(pool, dep));
1001 detail += _("Have you enabled all requested repositories?");
1003 case SOLVER_RULE_JOB_UNSUPPORTED:
1004 ret = _("unsupported request");
1006 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM:
1007 ret = str::form (_("%s is provided by the system and cannot be erased"), pool_dep2str(pool, dep));
1009 case SOLVER_RULE_RPM_NOT_INSTALLABLE:
1010 s = mapSolvable (source);
1011 ret = str::form (_("%s is not installable"), s.asString().c_str());
1013 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP:
1014 ignoreId = source; // for setting weak dependencies
1015 s = mapSolvable (source);
1016 ret = str::form (_("nothing provides %s needed by %s"), pool_dep2str(pool, dep), s.asString().c_str());
1018 case SOLVER_RULE_RPM_SAME_NAME:
1019 s = mapSolvable (source);
1020 s2 = mapSolvable (target);
1021 ret = str::form (_("cannot install both %s and %s"), s.asString().c_str(), s2.asString().c_str());
1023 case SOLVER_RULE_RPM_PACKAGE_CONFLICT:
1024 s = mapSolvable (source);
1025 s2 = mapSolvable (target);
1026 ret = str::form (_("%s conflicts with %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1028 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES:
1029 s = mapSolvable (source);
1030 s2 = mapSolvable (target);
1031 ret = str::form (_("%s obsoletes %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1033 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES:
1034 s = mapSolvable (source);
1035 s2 = mapSolvable (target);
1036 ret = str::form (_("installed %s obsoletes %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1038 case SOLVER_RULE_RPM_SELF_CONFLICT:
1039 s = mapSolvable (source);
1040 ret = str::form (_("solvable %s conflicts with %s provided by itself"), s.asString().c_str(), pool_dep2str(pool, dep));
1042 case SOLVER_RULE_RPM_PACKAGE_REQUIRES:
1043 ignoreId = source; // for setting weak dependencies
1044 s = mapSolvable (source);
1045 Capability cap(dep);
1046 sat::WhatProvides possibleProviders(cap);
1048 // check, if a provider will be deleted
1049 typedef list<PoolItem> ProviderList;
1050 ProviderList providerlistInstalled, providerlistUninstalled;
1051 for_( iter1, possibleProviders.begin(), possibleProviders.end() ) {
1052 PoolItem provider1 = ResPool::instance().find( *iter1 );
1053 // find pair of an installed/uninstalled item with the same NVR
1055 for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
1056 PoolItem provider2 = ResPool::instance().find( *iter2 );
1057 if (compareByNVR (provider1,provider2) == 0
1058 && ( (provider1.status().isInstalled() && provider2.status().isUninstalled())
1059 || (provider2.status().isInstalled() && provider1.status().isUninstalled()) )) {
1065 if (provider1.status().isInstalled())
1066 providerlistInstalled.push_back(provider1);
1068 providerlistUninstalled.push_back(provider1);
1072 ret = str::form (_("%s requires %s, but this requirement cannot be provided"), s.asString().c_str(), pool_dep2str(pool, dep));
1073 if (providerlistInstalled.size() > 0) {
1074 detail += _("deleted providers: ");
1075 for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) {
1076 if (iter == providerlistInstalled.begin())
1077 detail += itemToString( *iter );
1079 detail += "\n " + itemToString( mapItem(*iter) );
1082 if (providerlistUninstalled.size() > 0) {
1083 if (detail.size() > 0)
1084 detail += _("\nnot installable providers: ");
1086 detail = _("not installable providers: ");
1087 for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
1088 if (iter == providerlistUninstalled.begin())
1089 detail += itemToString( *iter );
1091 detail += "\n " + itemToString( mapItem(*iter) );
1101 SATResolver::problems ()
1103 ResolverProblemList resolverProblems;
1104 if (_satSolver && solver_problem_count(_satSolver)) {
1105 sat::detail::CPool *pool = _satSolver->pool;
1108 Id problem, solution, element;
1109 sat::Solvable s, sd;
1111 CapabilitySet system_requires = SystemCheck::instance().requiredSystemCap();
1112 CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap();
1114 MIL << "Encountered problems! Here are the solutions:\n" << endl;
1117 while ((problem = solver_next_problem(_satSolver, problem)) != 0) {
1118 MIL << "Problem " << pcnt++ << ":" << endl;
1119 MIL << "====================================" << endl;
1122 string whatString = SATprobleminfoString (problem,detail,ignoreId);
1123 MIL << whatString << endl;
1124 MIL << "------------------------------------" << endl;
1125 ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail);
1128 while ((solution = solver_next_solution(_satSolver, problem, solution)) != 0) {
1130 ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi;
1131 while ((element = solver_next_solutionelement(_satSolver, problem, solution, element, &p, &rp)) != 0) {
1132 if (p == SOLVER_SOLUTION_JOB) {
1133 /* job, rp is index into job queue */
1134 what = _jobQueue.elements[rp];
1135 switch (_jobQueue.elements[rp-1]&(SOLVER_SELECTMASK|SOLVER_JOBMASK))
1137 case SOLVER_INSTALL | SOLVER_SOLVABLE: {
1138 s = mapSolvable (what);
1139 PoolItem poolItem = _pool.find (s);
1141 if (pool->installed && s.get()->repo == pool->installed) {
1142 problemSolution->addSingleAction (poolItem, REMOVE);
1143 string description = str::form (_("remove lock to allow removal of %s"), s.asString().c_str() );
1144 MIL << description << endl;
1145 problemSolution->addDescription (description);
1147 problemSolution->addSingleAction (poolItem, KEEP);
1148 string description = str::form (_("do not install %s"), s.asString().c_str());
1149 MIL << description << endl;
1150 problemSolution->addDescription (description);
1153 ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << s.asString() << endl;
1157 case SOLVER_ERASE | SOLVER_SOLVABLE: {
1158 s = mapSolvable (what);
1159 PoolItem poolItem = _pool.find (s);
1161 if (pool->installed && s.get()->repo == pool->installed) {
1162 problemSolution->addSingleAction (poolItem, KEEP);
1163 string description = str::form (_("keep %s"), s.asString().c_str());
1164 MIL << description << endl;
1165 problemSolution->addDescription (description);
1167 problemSolution->addSingleAction (poolItem, UNLOCK);
1168 string description = str::form (_("remove lock to allow installation of %s"), itemToString( poolItem ).c_str());
1169 MIL << description << endl;
1170 problemSolution->addDescription (description);
1173 ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << s.asString() << endl;
1177 case SOLVER_INSTALL | SOLVER_SOLVABLE_NAME:
1179 IdString ident( what );
1180 SolverQueueItemInstall_Ptr install =
1181 new SolverQueueItemInstall(_pool, ident.asString(), false );
1182 problemSolution->addSingleAction (install, REMOVE_SOLVE_QUEUE_ITEM);
1184 string description = str::form (_("do not install %s"), ident.c_str() );
1185 MIL << description << endl;
1186 problemSolution->addDescription (description);
1189 case SOLVER_ERASE | SOLVER_SOLVABLE_NAME:
1191 // As we do not know, if this request has come from resolvePool or
1192 // resolveQueue we will have to take care for both cases.
1193 IdString ident( what );
1194 FindPackage info (problemSolution, KEEP);
1195 invokeOnEach( _pool.byIdentBegin( ident ),
1196 _pool.byIdentEnd( ident ),
1197 functor::chain (resfilter::ByInstalled (), // ByInstalled
1198 resfilter::ByTransact ()), // will be deinstalled
1199 functor::functorRef<bool,PoolItem> (info) );
1201 SolverQueueItemDelete_Ptr del =
1202 new SolverQueueItemDelete(_pool, ident.asString(), false );
1203 problemSolution->addSingleAction (del, REMOVE_SOLVE_QUEUE_ITEM);
1205 string description = str::form (_("keep %s"), ident.c_str());
1206 MIL << description << endl;
1207 problemSolution->addDescription (description);
1210 case SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES:
1212 problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_REQUIRE);
1213 string description = "";
1215 // Checking if this problem solution would break your system
1216 if (system_requires.find(Capability(what)) != system_requires.end()) {
1217 // Show a better warning
1218 resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() );
1219 resolverProblem->setDescription(_("This request will break your system!"));
1220 description = _("ignore the warning of a broken system");
1221 description += string(" (requires:")+pool_dep2str(pool, what)+")";
1222 MIL << description << endl;
1223 problemSolution->addFrontDescription (description);
1225 description = str::form (_("do not ask to install a solvable providing %s"), pool_dep2str(pool, what));
1226 MIL << description << endl;
1227 problemSolution->addDescription (description);
1231 case SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES:
1233 problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_CONFLICT);
1234 string description = "";
1236 // Checking if this problem solution would break your system
1237 if (system_conflicts.find(Capability(what)) != system_conflicts.end()) {
1238 // Show a better warning
1239 resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() );
1240 resolverProblem->setDescription(_("This request will break your system!"));
1241 description = _("ignore the warning of a broken system");
1242 description += string(" (conflicts:")+pool_dep2str(pool, what)+")";
1243 MIL << description << endl;
1244 problemSolution->addFrontDescription (description);
1247 description = str::form (_("do not ask to delete all solvables providing %s"), pool_dep2str(pool, what));
1248 MIL << description << endl;
1249 problemSolution->addDescription (description);
1253 case SOLVER_UPDATE | SOLVER_SOLVABLE:
1255 s = mapSolvable (what);
1256 PoolItem poolItem = _pool.find (s);
1258 if (pool->installed && s.get()->repo == pool->installed) {
1259 problemSolution->addSingleAction (poolItem, KEEP);
1260 string description = str::form (_("do not install most recent version of %s"), s.asString().c_str());
1261 MIL << description << endl;
1262 problemSolution->addDescription (description);
1264 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl;
1267 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << s.asString() << endl;
1272 MIL << "- do something different" << endl;
1273 ERR << "No valid solution available" << endl;
1276 } else if (p == SOLVER_SOLUTION_INFARCH) {
1277 s = mapSolvable (rp);
1278 PoolItem poolItem = _pool.find (s);
1279 if (pool->installed && s.get()->repo == pool->installed) {
1280 problemSolution->addSingleAction (poolItem, LOCK);
1281 string description = str::form (_("keep %s despite the inferior architecture"), s.asString().c_str());
1282 MIL << description << endl;
1283 problemSolution->addDescription (description);
1285 problemSolution->addSingleAction (poolItem, INSTALL);
1286 string description = str::form (_("install %s despite the inferior architecture"), s.asString().c_str());
1287 MIL << description << endl;
1288 problemSolution->addDescription (description);
1290 } else if (p == SOLVER_SOLUTION_DISTUPGRADE) {
1291 s = mapSolvable (rp);
1292 PoolItem poolItem = _pool.find (s);
1293 if (pool->installed && s.get()->repo == pool->installed) {
1294 problemSolution->addSingleAction (poolItem, LOCK);
1295 string description = str::form (_("keep obsolete %s"), s.asString().c_str());
1296 MIL << description << endl;
1297 problemSolution->addDescription (description);
1299 problemSolution->addSingleAction (poolItem, INSTALL);
1300 string description = str::form (_("install %s from excluded repository"), s.asString().c_str());
1301 MIL << description << endl;
1302 problemSolution->addDescription (description);
1305 /* policy, replace p with rp */
1306 s = mapSolvable (p);
1307 PoolItem itemFrom = _pool.find (s);
1312 sd = mapSolvable (rp);
1313 PoolItem itemTo = _pool.find (sd);
1314 if (itemFrom && itemTo) {
1315 problemSolution->addSingleAction (itemTo, INSTALL);
1316 int illegal = policy_is_illegal(_satSolver, s.get(), sd.get(), 0);
1318 if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0)
1320 string description = str::form (_("downgrade of %s to %s"), s.asString().c_str(), sd.asString().c_str());
1321 MIL << description << endl;
1322 problemSolution->addDescription (description);
1325 if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0)
1327 string description = str::form (_("architecture change of %s to %s"), s.asString().c_str(), sd.asString().c_str());
1328 MIL << description << endl;
1329 problemSolution->addDescription (description);
1332 if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0)
1334 IdString s_vendor( s.vendor() );
1335 IdString sd_vendor( sd.vendor() );
1336 string description = str::form (_("install %s (with vendor change)\n %s --> %s") ,
1337 sd.asString().c_str(),
1338 ( s_vendor ? s_vendor.c_str() : " (no vendor) " ),
1339 ( sd_vendor ? sd_vendor.c_str() : " (no vendor) " ) );
1340 MIL << description << endl;
1341 problemSolution->addDescription (description);
1345 string description = str::form (_("replacement of %s with %s"), s.asString().c_str(), sd.asString().c_str());
1346 MIL << description << endl;
1347 problemSolution->addDescription (description);
1350 ERR << s.asString() << " or " << sd.asString() << " not found" << endl;
1356 string description = str::form (_("deinstallation of %s"), s.asString().c_str());
1357 MIL << description << endl;
1358 problemSolution->addDescription (description);
1359 problemSolution->addSingleAction (itemFrom, REMOVE);
1364 resolverProblem->addSolution (problemSolution,
1365 problemSolution->actionCount() > 1 ? true : false); // Solutions with more than 1 action will be shown first.
1366 MIL << "------------------------------------" << endl;
1370 // There is a possibility to ignore this error by setting weak dependencies
1371 PoolItem item = _pool.find (sat::Solvable(ignoreId));
1372 ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(item);
1373 resolverProblem->addSolution (problemSolution,
1374 false); // Solutions will be shown at the end
1375 MIL << "ignore some dependencies of " << item << endl;
1376 MIL << "------------------------------------" << endl;
1380 resolverProblems.push_back (resolverProblem);
1383 return resolverProblems;
1386 void SATResolver::applySolutions( const ProblemSolutionList & solutions )
1387 { Resolver( _pool ).applySolutions( solutions ); }
1389 void SATResolver::setLocks()
1391 for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); ++iter) {
1392 sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() );
1393 if (iter->status().isInstalled()) {
1394 MIL << "Lock installed item " << *iter << endl;
1395 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
1396 queue_push( &(_jobQueue), ident );
1398 MIL << "Lock NOT installed item " << *iter << endl;
1399 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS );
1400 queue_push( &(_jobQueue), ident );
1404 ///////////////////////////////////////////////////////////////////
1405 // Weak locks: Ignore if an item with this name is already installed.
1406 // If it's not installed try to keep it this way using a weak delete
1407 ///////////////////////////////////////////////////////////////////
1408 std::set<IdString> unifiedByName;
1409 for (PoolItemList::const_iterator iter = _items_to_keep.begin(); iter != _items_to_keep.end(); ++iter) {
1410 IdString ident( (*iter)->satSolvable().ident() );
1411 if ( unifiedByName.insert( ident ).second )
1413 if ( ! ui::Selectable::get( *iter )->hasInstalledObj() )
1415 MIL << "Keep NOT installed name " << ident << " (" << *iter << ")" << endl;
1416 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | SOLVER_WEAK | MAYBE_CLEANDEPS );
1417 queue_push( &(_jobQueue), ident.id() );
1423 void SATResolver::setSystemRequirements()
1425 CapabilitySet system_requires = SystemCheck::instance().requiredSystemCap();
1426 CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap();
1428 for (CapabilitySet::const_iterator iter = system_requires.begin(); iter != system_requires.end(); ++iter) {
1429 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
1430 queue_push( &(_jobQueue), iter->id() );
1431 MIL << "SYSTEM Requires " << *iter << endl;
1434 for (CapabilitySet::const_iterator iter = system_conflicts.begin(); iter != system_conflicts.end(); ++iter) {
1435 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
1436 queue_push( &(_jobQueue), iter->id() );
1437 MIL << "SYSTEM Conflicts " << *iter << endl;
1440 // Lock the architecture of the running systems rpm
1441 // package on distupgrade.
1442 if ( _distupgrade && ZConfig::instance().systemRoot() == "/" )
1444 ResPool pool( ResPool::instance() );
1445 IdString rpm( "rpm" );
1446 for_( it, pool.byIdentBegin(rpm), pool.byIdentEnd(rpm) )
1448 if ( (*it)->isSystem() )
1450 Capability archrule( (*it)->arch(), rpm.c_str(), Capability::PARSED );
1451 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_NAME | SOLVER_ESSENTIAL );
1452 queue_push( &(_jobQueue), archrule.id() );
1459 sat::StringQueue SATResolver::autoInstalled() const
1461 sat::StringQueue ret;
1463 ::solver_get_userinstalled( _satSolver, ret, GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED );
1467 sat::StringQueue SATResolver::userInstalled() const
1469 sat::StringQueue ret;
1471 ::solver_get_userinstalled( _satSolver, ret, GET_USERINSTALLED_NAMES );
1476 ///////////////////////////////////////////////////////////////////
1477 };// namespace detail
1478 /////////////////////////////////////////////////////////////////////
1479 /////////////////////////////////////////////////////////////////////
1480 };// namespace solver
1481 ///////////////////////////////////////////////////////////////////////
1482 ///////////////////////////////////////////////////////////////////////
1484 /////////////////////////////////////////////////////////////////////////