X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=zypp%2Fsolver%2Fdetail%2FSATResolver.cc;h=f1e17539510f1b225cfa5b4803cd149b3b46e142;hb=83ae0a03ba583b177a13e092f34d715b42c17d45;hp=e7d35241348f073817b995bbcabff77c25a5502c;hpb=08f26f097972b4acf34123443b6730c4406038d8;p=platform%2Fupstream%2Flibzypp.git diff --git a/zypp/solver/detail/SATResolver.cc b/zypp/solver/detail/SATResolver.cc index e7d3524..f1e1753 100644 --- a/zypp/solver/detail/SATResolver.cc +++ b/zypp/solver/detail/SATResolver.cc @@ -18,13 +18,24 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307, USA. */ -#include +extern "C" +{ +#include +#include +#include +#include +#include +#include +#include +} + #include "zypp/solver/detail/Helper.h" #include "zypp/base/String.h" +#include "zypp/Product.h" #include "zypp/Capability.h" #include "zypp/ResStatus.h" #include "zypp/VendorAttr.h" -#include "zypp/base/Logger.h" +#include "zypp/base/LogTools.h" #include "zypp/base/String.h" #include "zypp/base/Gettext.h" #include "zypp/base/Algorithm.h" @@ -40,20 +51,31 @@ #include "zypp/solver/detail/SolverQueueItemInstall.h" #include "zypp/solver/detail/SolverQueueItemDelete.h" #include "zypp/solver/detail/SystemCheck.h" - -extern "C" { -#include "satsolver/repo_solv.h" -#include "satsolver/poolarch.h" -#include "satsolver/evr.h" -#include "satsolver/poolvendor.h" -#include "satsolver/policy.h" -#include "satsolver/bitmap.h" -#include "satsolver/queue.h" -} +#include "zypp/sat/Transaction.h" +#include "zypp/sat/Queue.h" ///////////////////////////////////////////////////////////////////////// namespace zypp { /////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////// + namespace env + { + inline bool HACKENV( const char * var_r, bool default_r ) + { + bool ret = default_r; + const char * val = ::getenv( var_r ); + if ( val ) + { + ret = str::strToBool( val, default_r ); + if ( ret != default_r ) + INT << "HACKENV " << var_r << " = " << ret << endl; + } + return ret; + } + } // namespace env + ///////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////// namespace solver { ///////////////////////////////////////////////////////////////////// @@ -65,43 +87,42 @@ using namespace std; IMPL_PTR_TYPE(SATResolver); +#define MAYBE_CLEANDEPS (cleandepsOnRemove()?SOLVER_CLEANDEPS:0) + //--------------------------------------------------------------------------- // Callbacks for SAT policies //--------------------------------------------------------------------------- -int vendorCheck (Pool *pool, Solvable *solvable1, Solvable *solvable2) { -// DBG << "vendorCheck: " << id2str(pool, solvable1->vendor) << " <--> " << id2str(pool, solvable1->vendor) << endl; - return VendorAttr::instance().equivalent(id2str(pool, solvable1->vendor), id2str(pool, solvable2->vendor)) ? 0:1; +int vendorCheck( Pool *pool, Solvable *solvable1, Solvable *solvable2 ) +{ + return VendorAttr::instance().equivalent( IdString(solvable1->vendor), + IdString(solvable2->vendor) ) ? 0 : 1; } -string -itemToString (PoolItem item, bool shortVersion) +inline std::string itemToString( const PoolItem & item ) { - ostringstream os; - if (!item) return ""; - - if (item->kind() != ResKind::package) - os << item->kind() << ':'; - os << item->name(); - if (!shortVersion) { - os << '-' << item->edition(); - if (item->arch() != "") { - os << '.' << item->arch(); - } - Repository s = item->repository(); - if (s) { - string alias = s.info().alias(); - if (!alias.empty() - && alias != "@system") - { - os << '[' << s.info().alias() << ']'; - } - } - } - return os.str(); + if ( !item ) + return std::string(); + + sat::Solvable slv( item.satSolvable() ); + std::string ret( slv.asString() ); // n-v-r.a + if ( ! slv.isSystem() ) + { + ret += "["; + ret += slv.repository().alias(); + ret += "]"; + } + return ret; } +inline PoolItem getPoolItem( Id id_r ) +{ + PoolItem ret( (sat::Solvable( id_r )) ); + if ( !ret && id_r ) + INT << "id " << id_r << " not found in ZYPP pool." << endl; + return ret; +} //--------------------------------------------------------------------------- @@ -110,20 +131,34 @@ SATResolver::dumpOn( std::ostream & os ) const { os << "" << endl; if (_solv) { - os << " fixsystem = " << _solv->fixsystem << endl; - os << " allowdowngrade = " << _solv->allowdowngrade << endl; - os << " allowarchchange = " << _solv->allowarchchange << endl; - os << " allowvendorchange = " << _solv->allowvendorchange << endl; - os << " allowuninstall = " << _solv->allowuninstall << endl; - os << " updatesystem = " << _solv->updatesystem << endl; - os << " allowvirtualconflicts = " << _solv->allowvirtualconflicts << endl; - os << " noupdateprovide = " << _solv->noupdateprovide << endl; - os << " dosplitprovides = " << _solv->dosplitprovides << endl; - os << " onlyRequires = " << _solv->dontinstallrecommended << endl; - os << " ignorealreadyrecommended = " << _solv->ignorealreadyrecommended << endl; - os << " distupgrade = " << _distupgrade << endl; - os << " distupgrade_removeunsupported = " << _distupgrade_removeunsupported << endl; - os << " solveSrcPackages = " << _solveSrcPackages << endl; +#define OUTS(X) os << " " << #X << "\t= " << solver_get_flag(_solv, SOLVER_FLAG_##X) << endl + OUTS( ALLOW_DOWNGRADE ); + OUTS( ALLOW_ARCHCHANGE ); + OUTS( ALLOW_VENDORCHANGE ); + OUTS( ALLOW_UNINSTALL ); + OUTS( NO_UPDATEPROVIDE ); + OUTS( SPLITPROVIDES ); + OUTS( IGNORE_RECOMMENDED ); + OUTS( ADD_ALREADY_RECOMMENDED ); + OUTS( NO_INFARCHCHECK ); + OUTS( ALLOW_NAMECHANGE ); + OUTS( KEEP_EXPLICIT_OBSOLETES ); + OUTS( BEST_OBEY_POLICY ); + OUTS( NO_AUTOTARGET ); + OUTS( DUP_ALLOW_DOWNGRADE ); + OUTS( DUP_ALLOW_ARCHCHANGE ); + OUTS( DUP_ALLOW_VENDORCHANGE ); + OUTS( DUP_ALLOW_NAMECHANGE ); + OUTS( KEEP_ORPHANS ); + OUTS( BREAK_ORPHANS ); + OUTS( FOCUS_INSTALLED ); + OUTS( YUM_OBSOLETES ); +#undef OUTS + os << " distupgrade = " << _distupgrade << endl; + os << " distupgrade_removeunsupported = " << _distupgrade_removeunsupported << endl; + os << " solveSrcPackages = " << _solveSrcPackages << endl; + os << " cleandepsOnRemove = " << _cleandepsOnRemove << endl; + os << " fixsystem = " << _fixsystem << endl; } else { os << ""; } @@ -139,35 +174,34 @@ SATResolver::SATResolver (const ResPool & pool, Pool *SATPool) , _fixsystem(false) , _allowdowngrade(false) , _allowarchchange(false) - , _allowvendorchange(false) + , _allowvendorchange(ZConfig::instance().solver_allowVendorChange()) , _allowuninstall(false) , _updatesystem(false) - , _allowvirtualconflicts(false) , _noupdateprovide(false) , _dosplitprovides(false) , _onlyRequires(ZConfig::instance().solver_onlyRequires()) - , _ignorealreadyrecommended(false) + , _ignorealreadyrecommended(true) , _distupgrade(false) , _distupgrade_removeunsupported(false) - + , _solveSrcPackages(false) + , _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove()) { } SATResolver::~SATResolver() { + solverEnd(); } //--------------------------------------------------------------------------- - ResPool SATResolver::pool (void) const { return _pool; } - void SATResolver::resetItemTransaction (PoolItem item) { @@ -372,40 +406,47 @@ class CheckIfUpdate : public resfilter::PoolItemFilterFunctor { public: bool is_updated; + bool multiversion; + sat::Solvable _installed; - CheckIfUpdate() + CheckIfUpdate( sat::Solvable installed_r ) : is_updated( false ) + , multiversion( installed_r.multiversionInstall() ) + , _installed( installed_r ) {} - // check this item will be installed + // check this item will be updated bool operator()( PoolItem item ) { - if (item.status().isToBeInstalled()) - { - is_updated = true; - return false; + if ( item.status().isToBeInstalled() ) + { + if ( ! multiversion || sameNVRA( _installed, item ) ) + { + is_updated = true; + return false; + } } return true; } }; -class CollectNonePackages : public resfilter::PoolItemFilterFunctor +class CollectPseudoInstalled : public resfilter::PoolItemFilterFunctor { public: Queue *solvableQueue; - CollectNonePackages( Queue *queue ) + CollectPseudoInstalled( Queue *queue ) :solvableQueue (queue) {} - // collecting none packges - + // collecting PseudoInstalled items bool operator()( PoolItem item ) { - queue_push(solvableQueue, item.satSolvable().id()); - return true; + if ( traits::isPseudoInstalled( item.satSolvable().kind() ) ) + queue_push( solvableQueue, item.satSolvable().id() ); + return true; } }; @@ -414,22 +455,40 @@ SATResolver::solving(const CapabilitySet & requires_caps, const CapabilitySet & conflict_caps) { _solv = solver_create( _SATPool ); - _solv->vendorCheckCb = &vendorCheck; - _solv->fixsystem = _fixsystem; - _solv->ignorealreadyrecommended = _ignorealreadyrecommended; - _solv->updatesystem = _updatesystem; - _solv->allowdowngrade = _allowdowngrade; - _solv->allowuninstall = _allowuninstall; - _solv->allowarchchange = _allowarchchange; - _solv->allowvendorchange = _allowvendorchange; - _solv->allowvirtualconflicts = _allowvirtualconflicts; - _solv->dosplitprovides = _dosplitprovides; - _solv->noupdateprovide = _noupdateprovide; - _solv->dontinstallrecommended = _onlyRequires; - _solv->distupgrade = _distupgrade; - _solv->distupgrade_removeunsupported = _distupgrade_removeunsupported; - - sat::Pool::instance().prepare(); + ::pool_set_custom_vendorcheck( _SATPool, &vendorCheck ); + if (_fixsystem) { + queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL); + queue_push( &(_jobQueue), 0 ); + } + if (_updatesystem) { + queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL); + queue_push( &(_jobQueue), 0 ); + } + if (_distupgrade) { + queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL); + queue_push( &(_jobQueue), 0 ); + } + if (_distupgrade_removeunsupported) { + queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL); + queue_push( &(_jobQueue), 0 ); + } + solver_set_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended); + solver_set_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade); + solver_set_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall); + solver_set_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange); + solver_set_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange); + solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides); + solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide); + solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires); + +#define HACKENV(X,D) solver_set_flag(_solv, X, env::HACKENV( #X, D ) ); + HACKENV( SOLVER_FLAG_DUP_ALLOW_DOWNGRADE, true ); + HACKENV( SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE, true ); + HACKENV( SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE,true ); + HACKENV( SOLVER_FLAG_DUP_ALLOW_NAMECHANGE, true ); +#undef HACKENV + + sat::Pool::instance().prepareForSolving(); // Solve ! MIL << "Starting solving...." << endl; @@ -443,21 +502,20 @@ SATResolver::solving(const CapabilitySet & requires_caps, _result_items_to_remove.clear(); /* solvables to be installed */ - for (int i = 0; i < _solv->decisionq.count; i++) + Queue decisionq; + queue_init(&decisionq); + solver_get_decisionqueue(_solv, &decisionq); + for ( int i = 0; i < decisionq.count; ++i ) { - Id p; - p = _solv->decisionq.elements[i]; - if (p < 0 || !sat::Solvable(p) || sat::Solvable(p).isSystem()) + sat::Solvable slv( decisionq.elements[i] ); + if ( !slv || slv.isSystem() ) continue; - PoolItem poolItem((sat::Solvable(p))); - if (poolItem) { - SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER); - _result_items_to_install.push_back (poolItem); - } else { - ERR << "id " << p << " not found in ZYPP pool." << endl; - } + PoolItem poolItem( slv ); + SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER); + _result_items_to_install.push_back (poolItem); } + queue_free(&decisionq); /* solvables to be erased */ Repository systemRepo( sat::Pool::instance().findSystemRepo() ); // don't create if it does not exist @@ -466,12 +524,12 @@ SATResolver::solving(const CapabilitySet & requires_caps, bool mustCheckObsoletes = false; for_( it, systemRepo.solvablesBegin(), systemRepo.solvablesEnd() ) { - if (_solv->decisionmap[it->id()] > 0) + if (solver_get_decisionlevel(_solv, it->id()) > 0) continue; - PoolItem poolItem( *it ); // Check if this is an update - CheckIfUpdate info; + CheckIfUpdate info( *it ); + PoolItem poolItem( *it ); invokeOnEach( _pool.byIdentBegin( poolItem ), _pool.byIdentEnd( poolItem ), resfilter::ByUninstalled(), // ByUninstalled @@ -498,69 +556,63 @@ SATResolver::solving(const CapabilitySet & requires_caps, } } } + + Queue recommendations; + Queue suggestions; + Queue orphaned; + Queue unneeded; + queue_init(&recommendations); + queue_init(&suggestions); + queue_init(&orphaned); + queue_init(&unneeded); + solver_get_recommendations(_solv, &recommendations, &suggestions, 0); + solver_get_orphaned(_solv, &orphaned); + solver_get_unneeded(_solv, &unneeded, 1); /* solvables which are recommended */ - for (int i = 0; i < _solv->recommendations.count; i++) + for ( int i = 0; i < recommendations.count; ++i ) { - Id p; - p = _solv->recommendations.elements[i]; - if (p < 0 || !sat::Solvable(p)) - continue; - - PoolItem poolItem = _pool.find (sat::Solvable(p)); - if (poolItem) { - poolItem.status().setRecommended(true); - _XDEBUG("SATSolutionToPool(" << poolItem << ") recommended !"); - } else { - ERR << "id " << p << " not found in ZYPP pool." << endl; - } + PoolItem poolItem( getPoolItem( recommendations.elements[i] ) ); + poolItem.status().setRecommended( true ); } /* solvables which are suggested */ - for (int i = 0; i < _solv->suggestions.count; i++) + for ( int i = 0; i < suggestions.count; ++i ) { - Id p; - p = _solv->suggestions.elements[i]; - if (p < 0 || !sat::Solvable(p)) - continue; - - PoolItem poolItem = _pool.find (sat::Solvable(p)); - if (poolItem) { - poolItem.status().setSuggested(true); - _XDEBUG("SATSolutionToPool(" << poolItem << ") suggested !"); - } else { - ERR << "id " << p << " not found in ZYPP pool." << endl; - } + PoolItem poolItem( getPoolItem( suggestions.elements[i] ) ); + poolItem.status().setSuggested( true ); } _problem_items.clear(); - /* solvables which are no longer supported */ - for (int i = 0; i < _solv->orphaned.count; i++) + /* solvables which are orphaned */ + for ( int i = 0; i < orphaned.count; ++i ) { - Id p; - p = _solv->orphaned.elements[i]; - if (p < 0 || !sat::Solvable(p)) - continue; - - PoolItem poolItem = _pool.find (sat::Solvable(p)); - if (poolItem) { - _problem_items.push_back(poolItem); - _XDEBUG( poolItem << " orphaned !"); - } else { - ERR << "id " << p << " not found in ZYPP pool." << endl; - } + PoolItem poolItem( getPoolItem( orphaned.elements[i] ) ); + poolItem.status().setOrphaned( true ); + _problem_items.push_back( poolItem ); + } + + /* solvables which are unneeded */ + for ( int i = 0; i < unneeded.count; ++i ) + { + PoolItem poolItem( getPoolItem( unneeded.elements[i] ) ); + poolItem.status().setUnneeded( true ); } + queue_free(&recommendations); + queue_free(&suggestions); + queue_free(&orphaned); + queue_free(&unneeded); + /* Write validation state back to pool */ Queue flags, solvableQueue; queue_init(&flags); queue_init(&solvableQueue); - CollectNonePackages collectNonePackages(&solvableQueue); + CollectPseudoInstalled collectPseudoInstalled(&solvableQueue); invokeOnEach( _pool.begin(), _pool.end(), - functor::not_c(resfilter::byKind()), // every solvable BUT packages - functor::functorRef (collectNonePackages) ); + functor::functorRef (collectPseudoInstalled) ); solver_trivial_installable(_solv, &solvableQueue, &flags ); for (int i = 0; i < solvableQueue.count; i++) { PoolItem item = _pool.find (sat::Solvable(solvableQueue.elements[i])); @@ -577,6 +629,9 @@ SATResolver::solving(const CapabilitySet & requires_caps, _XDEBUG("SATSolutionToPool(" << item << " ) broken !"); } } + queue_free(&(solvableQueue)); + queue_free(&flags); + // Solvables which were selected due requirements which have been made by the user will // be selected by APPL_LOW. We can't use any higher level, because this setting must @@ -602,15 +657,12 @@ SATResolver::solving(const CapabilitySet & requires_caps, } } - if (_solv->problems.count > 0 ) + if (solver_problem_count(_solv) > 0 ) { ERR << "Solverrun finished with an ERROR" << endl; return false; } - queue_free(&(solvableQueue)); - queue_free(&flags); - return true; } @@ -622,12 +674,8 @@ SATResolver::solverInit(const PoolItemList & weakItems) MIL << "SATResolver::solverInit()" << endl; - if (_solv) { - // remove old stuff - solver_free(_solv); - _solv = NULL; - queue_free( &(_jobQueue) ); - } + // remove old stuff + solverEnd(); queue_init( &_jobQueue ); _items_to_install.clear(); @@ -644,32 +692,70 @@ SATResolver::solverInit(const PoolItemList & weakItems) ERR << "Weaken: " << *iter << " not found" << endl; } MIL << "Weaken dependencies of " << *iter << endl; - queue_push( &(_jobQueue), SOLVER_WEAKEN_SOLVABLE_DEPS ); + queue_push( &(_jobQueue), SOLVER_WEAKENDEPS | SOLVER_SOLVABLE ); queue_push( &(_jobQueue), id ); } // Add rules for parallel installable resolvables with different versions - std::set parallel = ZConfig::instance().multiversion(); - for (std::set::const_iterator it = parallel.begin(); it != parallel.end(); ++it) { - queue_push( &(_jobQueue), SOLVER_NOOBSOLETES_SOLVABLE_NAME ); - queue_push( &(_jobQueue), it->id() ); + for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() ) + { + queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE_NAME ); + queue_push( &(_jobQueue), it->id() ); + } + + ::pool_add_userinstalled_jobs(_SATPool, sat::Pool::instance().autoInstalled(), &(_jobQueue), GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED); + + if ( _distupgrade ) + { + if ( ZConfig::instance().solverUpgradeRemoveDroppedPackages() ) + { + MIL << "Checking droplists ..." << endl; + // Dropped packages: look for 'weakremover()' provides + // in dup candidates of installed products. + ResPoolProxy proxy( ResPool::instance().proxy() ); + for_( it, proxy.byKindBegin(), proxy.byKindEnd() ) + { + if ( (*it)->onSystem() ) // (to install) or (not to delete) + { + Product::constPtr prodCand( (*it)->candidateAsKind() ); + if ( ! prodCand ) + continue; // product no longer available + + CapabilitySet droplist( prodCand->droplist() ); + dumpRangeLine( MIL << "Droplist for " << (*it)->candidateObj() << ": " << droplist.size() << " ", droplist.begin(), droplist.end() ) << endl; + for_( cap, droplist.begin(), droplist.end() ) + { + queue_push( &_jobQueue, SOLVER_DROP_ORPHANED | SOLVER_SOLVABLE_NAME ); + queue_push( &_jobQueue, cap->id() ); + } + } + } + } + else + { + MIL << "Droplist processing is disabled." << endl; + } } } void SATResolver::solverEnd() { - // cleanup + // cleanup + if ( _solv ) + { solver_free(_solv); _solv = NULL; queue_free( &(_jobQueue) ); + } } bool SATResolver::resolvePool(const CapabilitySet & requires_caps, const CapabilitySet & conflict_caps, - const PoolItemList & weakItems) + const PoolItemList & weakItems, + const std::set & upgradeRepos) { MIL << "SATResolver::resolvePool()" << endl; @@ -682,7 +768,7 @@ SATResolver::resolvePool(const CapabilitySet & requires_caps, ERR << "Install: " << *iter << " not found" << endl; } else { MIL << "Install " << *iter << endl; - queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE ); + queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE ); queue_push( &(_jobQueue), id ); } } @@ -693,19 +779,26 @@ SATResolver::resolvePool(const CapabilitySet & requires_caps, ERR << "Delete: " << *iter << " not found" << endl; } else { MIL << "Delete " << *iter << endl; - queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE ); + queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), id); } } + for_( iter, upgradeRepos.begin(), upgradeRepos.end() ) + { + queue_push( &(_jobQueue), SOLVER_DISTUPGRADE | SOLVER_SOLVABLE_REPO ); + queue_push( &(_jobQueue), iter->get()->repoid ); + MIL << "Upgrade repo " << *iter << endl; + } + for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) { - queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE_PROVIDES ); + queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES ); queue_push( &(_jobQueue), iter->id() ); MIL << "Requires " << *iter << endl; } for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) { - queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES); + queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), iter->id() ); MIL << "Conflicts " << *iter << endl; } @@ -718,9 +811,6 @@ SATResolver::resolvePool(const CapabilitySet & requires_caps, // solving bool ret = solving(requires_caps, conflict_caps); - // cleanup - if (ret) - solverEnd(); // remove solver only if no errors happend. Need it for solving problems (ret?MIL:WAR) << "SATResolver::resolvePool() done. Ret:" << ret << endl; return ret; @@ -748,14 +838,14 @@ SATResolver::resolveQueue(const SolverQueueItemList &requestQueue, ERR << "Install: " << *iter << " not found" << endl; } else { MIL << "Install " << *iter << endl; - queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE ); + queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE ); queue_push( &(_jobQueue), id ); } } for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) { sat::detail::IdType ident( (*iter)->satSolvable().ident().id() ); MIL << "Delete " << *iter << ident << endl; - queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_NAME ); + queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), ident); } @@ -768,15 +858,11 @@ SATResolver::resolveQueue(const SolverQueueItemList &requestQueue, // solving bool ret = solving(); - // cleanup - if (ret) - solverEnd(); // remove solver only if no errors happend. Need it for solving problems - MIL << "SATResolver::resolveQueue() done. Ret:" << ret << endl; return ret; } - +/** \todo duplicate code to be joined with \ref solving. */ void SATResolver::doUpdate() { MIL << "SATResolver::doUpdate()" << endl; @@ -791,12 +877,33 @@ void SATResolver::doUpdate() setLocks(); _solv = solver_create( _SATPool ); - _solv->vendorCheckCb = &vendorCheck; - - _solv->updatesystem = true; - _solv->dontinstallrecommended = true; // #FIXME dontinstallrecommended maybe set to false if it works correctly + ::pool_set_custom_vendorcheck( _SATPool, &vendorCheck ); + if (_fixsystem) { + queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL); + queue_push( &(_jobQueue), 0 ); + } + if (1) { + queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL); + queue_push( &(_jobQueue), 0 ); + } + if (_distupgrade) { + queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL); + queue_push( &(_jobQueue), 0 ); + } + if (_distupgrade_removeunsupported) { + queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL); + queue_push( &(_jobQueue), 0 ); + } + solver_set_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended); + solver_set_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade); + solver_set_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall); + solver_set_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange); + solver_set_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange); + solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides); + solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide); + solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires); - sat::Pool::instance().prepare(); + sat::Pool::instance().prepareForSolving(); // Solve ! MIL << "Starting solving for update...." << endl; @@ -808,13 +915,16 @@ void SATResolver::doUpdate() //----------------------------------------- /* solvables to be installed */ - for (int i = 0; i < _solv->decisionq.count; i++) + Queue decisionq; + queue_init(&decisionq); + solver_get_decisionqueue(_solv, &decisionq); + for (int i = 0; i < decisionq.count; i++) { Id p; - p = _solv->decisionq.elements[i]; + p = decisionq.elements[i]; if (p < 0 || !sat::Solvable(p)) continue; - if (sat::Solvable(p).repository().get() == _solv->installed) + if (sat::Solvable(p).repository().get() == _solv->pool->installed) continue; PoolItem poolItem = _pool.find (sat::Solvable(p)); @@ -824,17 +934,18 @@ void SATResolver::doUpdate() ERR << "id " << p << " not found in ZYPP pool." << endl; } } + queue_free(&decisionq); /* solvables to be erased */ - for (int i = _solv->installed->start; i < _solv->installed->start + _solv->installed->nsolvables; i++) + for (int i = _solv->pool->installed->start; i < _solv->pool->installed->start + _solv->pool->installed->nsolvables; i++) { - if (_solv->decisionmap[i] > 0) - continue; + if (solver_get_decisionlevel(_solv, i) > 0) + continue; - PoolItem poolItem = _pool.find (sat::Solvable(i)); + PoolItem poolItem( _pool.find( sat::Solvable(i) ) ); if (poolItem) { // Check if this is an update - CheckIfUpdate info; + CheckIfUpdate info( (sat::Solvable(i)) ); invokeOnEach( _pool.byIdentBegin( poolItem ), _pool.byIdentEnd( poolItem ), resfilter::ByUninstalled(), // ByUninstalled @@ -849,10 +960,6 @@ void SATResolver::doUpdate() ERR << "id " << i << " not found in ZYPP pool." << endl; } } - - // cleanup - solverEnd(); - MIL << "SATResolver::doUpdate() done" << endl; } @@ -892,27 +999,26 @@ struct FindPackage : public resfilter::ResObjectFilterFunctor // e.g. The release package has a buddy to the concerning product item. // This user want's the message "Product foo conflicts with product bar" and // NOT "package release-foo conflicts with package release-bar" +// (ma: that's why we should map just packages to buddies, not vice versa) //---------------------------------------------------------------------------- - - -PoolItem SATResolver::mapItem (const PoolItem &item) +inline sat::Solvable mapBuddy( const PoolItem & item_r ) { - sat::Solvable buddy = item.buddy(); - if (buddy != sat::Solvable()) - { - return _pool.find (buddy); - } - else - { - return item; - } + if ( item_r.satSolvable().isKind() ) + { + sat::Solvable buddy = item_r.buddy(); + if ( buddy ) + return buddy; + } + return item_r.satSolvable(); } +inline sat::Solvable mapBuddy( sat::Solvable item_r ) +{ return mapBuddy( PoolItem( item_r ) ); } -sat::Solvable SATResolver::mapSolvable (const Id &id) -{ - PoolItem item = _pool.find (sat::Solvable(id)); - return mapItem(item).satSolvable(); -} +PoolItem SATResolver::mapItem ( const PoolItem & item ) +{ return PoolItem( mapBuddy( item ) ); } + +sat::Solvable SATResolver::mapSolvable ( const Id & id ) +{ return mapBuddy( sat::Solvable(id) ); } string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreId) { @@ -923,59 +1029,78 @@ string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreI sat::Solvable s, s2; ignoreId = 0; + + // FIXME: solver_findallproblemrules to get all rules for this problem + // (the 'most relevabt' one returned by solver_findproblemrule is embedded probr = solver_findproblemrule(_solv, problem); - switch (solver_problemruleinfo(_solv, &(_jobQueue), probr, &dep, &source, &target)) + switch (solver_ruleinfo(_solv, probr, &source, &target, &dep)) { - case SOLVER_PROBLEM_DISTUPGRADE_RULE: + case SOLVER_RULE_DISTUPGRADE: s = mapSolvable (source); - ret = str::form (_("%s does not belong to a distupgrade repository"), solvable2str(pool, s.get())); + ret = str::form (_("%s does not belong to a distupgrade repository"), s.asString().c_str()); break; - case SOLVER_PROBLEM_INFARCH_RULE: + case SOLVER_RULE_INFARCH: s = mapSolvable (source); - ret = str::form (_("%s has inferior architecture"), solvable2str(pool, s.get())); + ret = str::form (_("%s has inferior architecture"), s.asString().c_str()); break; - case SOLVER_PROBLEM_UPDATE_RULE: + case SOLVER_RULE_UPDATE: s = mapSolvable (source); - ret = str::form (_("problem with installed package %s"), solvable2str(pool, s.get())); + ret = str::form (_("problem with installed package %s"), s.asString().c_str()); + break; + case SOLVER_RULE_JOB: + ret = _("conflicting requests"); break; - case SOLVER_PROBLEM_JOB_RULE: - ret = str::form (_("conflicting requests")); + case SOLVER_RULE_RPM: + ret = _("some dependency problem"); break; - case SOLVER_PROBLEM_RPM_RULE: - ret = str::form (_("some dependency problem")); + case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP: + ret = str::form (_("nothing provides requested %s"), pool_dep2str(pool, dep)); + detail += _("Have you enabled all requested repositories?"); break; - case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP: - ret = str::form (_("nothing provides requested %s"), dep2str(pool, dep)); + case SOLVER_RULE_JOB_UNKNOWN_PACKAGE: + ret = str::form (_("package %s does not exist"), pool_dep2str(pool, dep)); detail += _("Have you enabled all requested repositories?"); break; - case SOLVER_PROBLEM_NOT_INSTALLABLE: + case SOLVER_RULE_JOB_UNSUPPORTED: + ret = _("unsupported request"); + break; + case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM: + ret = str::form (_("%s is provided by the system and cannot be erased"), pool_dep2str(pool, dep)); + break; + case SOLVER_RULE_RPM_NOT_INSTALLABLE: s = mapSolvable (source); - ret = str::form (_("%s is not installable"), solvable2str(pool, s.get())); + ret = str::form (_("%s is not installable"), s.asString().c_str()); break; - case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP: + case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP: + ignoreId = source; // for setting weak dependencies s = mapSolvable (source); - ret = str::form (_("nothing provides %s needed by %s"), dep2str(pool, dep), solvable2str(pool, s.get())); + ret = str::form (_("nothing provides %s needed by %s"), pool_dep2str(pool, dep), s.asString().c_str()); break; - case SOLVER_PROBLEM_SAME_NAME: + case SOLVER_RULE_RPM_SAME_NAME: s = mapSolvable (source); s2 = mapSolvable (target); - ret = str::form (_("cannot install both %s and %s"), solvable2str(pool, s.get()), solvable2str(pool, s2.get())); + ret = str::form (_("cannot install both %s and %s"), s.asString().c_str(), s2.asString().c_str()); break; - case SOLVER_PROBLEM_PACKAGE_CONFLICT: + case SOLVER_RULE_RPM_PACKAGE_CONFLICT: s = mapSolvable (source); s2 = mapSolvable (target); - ret = str::form (_("%s conflicts with %s provided by %s"), solvable2str(pool, s.get()), dep2str(pool, dep), solvable2str(pool, s2.get())); + ret = str::form (_("%s conflicts with %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str()); break; - case SOLVER_PROBLEM_PACKAGE_OBSOLETES: + case SOLVER_RULE_RPM_PACKAGE_OBSOLETES: s = mapSolvable (source); s2 = mapSolvable (target); - ret = str::form (_("%s obsoletes %s provided by %s"), solvable2str(pool, s.get()), dep2str(pool, dep), solvable2str(pool, s2.get())); + ret = str::form (_("%s obsoletes %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str()); break; - case SOLVER_PROBLEM_SELF_CONFLICT: + case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES: s = mapSolvable (source); - ret = str::form (_("solvable %s conflicts with %s provided by itself"), solvable2str(pool, s.get()), dep2str(pool, dep)); + s2 = mapSolvable (target); + ret = str::form (_("installed %s obsoletes %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str()); + break; + case SOLVER_RULE_RPM_SELF_CONFLICT: + s = mapSolvable (source); + ret = str::form (_("solvable %s conflicts with %s provided by itself"), s.asString().c_str(), pool_dep2str(pool, dep)); break; - case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE: + case SOLVER_RULE_RPM_PACKAGE_REQUIRES: ignoreId = source; // for setting weak dependencies s = mapSolvable (source); Capability cap(dep); @@ -1005,14 +1130,14 @@ string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreI } } - ret = str::form (_("%s requires %s, but this requirement cannot be provided"), solvable2str(pool, s.get()), dep2str(pool, dep)); + ret = str::form (_("%s requires %s, but this requirement cannot be provided"), s.asString().c_str(), pool_dep2str(pool, dep)); if (providerlistInstalled.size() > 0) { detail += _("deleted providers: "); for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) { if (iter == providerlistInstalled.begin()) - detail += itemToString (*iter, false); + detail += itemToString( *iter ); else - detail += "\n " + itemToString (mapItem(*iter), false); + detail += "\n " + itemToString( mapItem(*iter) ); } } if (providerlistUninstalled.size() > 0) { @@ -1022,9 +1147,9 @@ string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreI detail = _("uninstallable providers: "); for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) { if (iter == providerlistUninstalled.begin()) - detail += itemToString (*iter, false); + detail += itemToString( *iter ); else - detail += "\n " + itemToString (mapItem(*iter), false); + detail += "\n " + itemToString( mapItem(*iter) ); } } break; @@ -1037,7 +1162,7 @@ ResolverProblemList SATResolver::problems () { ResolverProblemList resolverProblems; - if (_solv && _solv->problems.count) { + if (_solv && solver_problem_count(_solv)) { Pool *pool = _solv->pool; int pcnt; Id p, rp, what; @@ -1068,51 +1193,49 @@ SATResolver::problems () if (p == SOLVER_SOLUTION_JOB) { /* job, rp is index into job queue */ what = _jobQueue.elements[rp]; - switch (_jobQueue.elements[rp-1]) + switch (_jobQueue.elements[rp-1]&(SOLVER_SELECTMASK|SOLVER_JOBMASK)) { - case SOLVER_INSTALL_SOLVABLE: { + case SOLVER_INSTALL | SOLVER_SOLVABLE: { s = mapSolvable (what); PoolItem poolItem = _pool.find (s); if (poolItem) { - if (_solv->installed && s.get()->repo == _solv->installed) { + if (pool->installed && s.get()->repo == pool->installed) { problemSolution->addSingleAction (poolItem, REMOVE); - string description = str::form (_("do not keep %s installed"), solvable2str(pool, s.get()) ); + string description = str::form (_("do not keep %s installed"), s.asString().c_str() ); MIL << description << endl; problemSolution->addDescription (description); } else { problemSolution->addSingleAction (poolItem, KEEP); - string description = str::form (_("do not install %s"), solvable2str(pool, s.get())); + string description = str::form (_("do not install %s"), s.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); } } else { - ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << id2str(pool, s.get()->name) << "-" - << id2str(pool, s.get()->evr) << "." << id2str(pool, s.get()->arch) << endl; + ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << s.asString() << endl; } } break; - case SOLVER_ERASE_SOLVABLE: { + case SOLVER_ERASE | SOLVER_SOLVABLE: { s = mapSolvable (what); PoolItem poolItem = _pool.find (s); if (poolItem) { - if (_solv->installed && s.get()->repo == _solv->installed) { + if (pool->installed && s.get()->repo == pool->installed) { problemSolution->addSingleAction (poolItem, KEEP); - string description = str::form (_("keep %s"), solvable2str(pool, s.get())); + string description = str::form (_("keep %s"), s.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); } else { problemSolution->addSingleAction (poolItem, UNLOCK); - string description = str::form (_("do not forbid installation of %s"), itemToString(poolItem, false).c_str()); + string description = str::form (_("do not forbid installation of %s"), itemToString( poolItem ).c_str()); MIL << description << endl; problemSolution->addDescription (description); } } else { - ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << id2str(pool, s.get()->name) << "-" << id2str(pool, s.get()->evr) << "." << - id2str(pool, s.get()->arch) << endl; + ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << s.asString() << endl; } } break; - case SOLVER_INSTALL_SOLVABLE_NAME: + case SOLVER_INSTALL | SOLVER_SOLVABLE_NAME: { IdString ident( what ); SolverQueueItemInstall_Ptr install = @@ -1124,7 +1247,7 @@ SATResolver::problems () problemSolution->addDescription (description); } break; - case SOLVER_ERASE_SOLVABLE_NAME: + case SOLVER_ERASE | SOLVER_SOLVABLE_NAME: { // As we do not know, if this request has come from resolvePool or // resolveQueue we will have to take care for both cases. @@ -1145,7 +1268,7 @@ SATResolver::problems () problemSolution->addDescription (description); } break; - case SOLVER_INSTALL_SOLVABLE_PROVIDES: + case SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES: { problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_REQUIRE); string description = ""; @@ -1156,17 +1279,17 @@ SATResolver::problems () resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() ); resolverProblem->setDescription(_("This request will break your system!")); description = _("ignore the warning of a broken system"); - description += string(" (requires:")+dep2str(pool, what)+")"; + description += string(" (requires:")+pool_dep2str(pool, what)+")"; MIL << description << endl; problemSolution->addFrontDescription (description); } else { - description = str::form (_("do not ask to install a solvable providing %s"), dep2str(pool, what)); + description = str::form (_("do not ask to install a solvable providing %s"), pool_dep2str(pool, what)); MIL << description << endl; problemSolution->addDescription (description); } } break; - case SOLVER_ERASE_SOLVABLE_PROVIDES: + case SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES: { problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_CONFLICT); string description = ""; @@ -1177,33 +1300,32 @@ SATResolver::problems () resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() ); resolverProblem->setDescription(_("This request will break your system!")); description = _("ignore the warning of a broken system"); - description += string(" (conflicts:")+dep2str(pool, what)+")"; + description += string(" (conflicts:")+pool_dep2str(pool, what)+")"; MIL << description << endl; problemSolution->addFrontDescription (description); } else { - description = str::form (_("do not ask to delete all solvables providing %s"), dep2str(pool, what)); + description = str::form (_("do not ask to delete all solvables providing %s"), pool_dep2str(pool, what)); MIL << description << endl; problemSolution->addDescription (description); } } break; - case SOLVER_INSTALL_SOLVABLE_UPDATE: + case SOLVER_UPDATE | SOLVER_SOLVABLE: { s = mapSolvable (what); PoolItem poolItem = _pool.find (s); if (poolItem) { - if (_solv->installed && s.get()->repo == _solv->installed) { + if (pool->installed && s.get()->repo == pool->installed) { problemSolution->addSingleAction (poolItem, KEEP); - string description = str::form (_("do not install most recent version of %s"), solvable2str(pool, s.get())); + string description = str::form (_("do not install most recent version of %s"), s.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); } else { ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl; } } else { - ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << id2str(pool, s.get()->name) << "-" << id2str(pool, s.get()->evr) << "." << - id2str(pool, s.get()->arch) << endl; + ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << s.asString() << endl; } } break; @@ -1215,98 +1337,84 @@ SATResolver::problems () } else if (p == SOLVER_SOLUTION_INFARCH) { s = mapSolvable (rp); PoolItem poolItem = _pool.find (s); - if (_solv->installed && s.get()->repo == _solv->installed) { - problemSolution->addSingleAction (poolItem, KEEP); - string description = str::form (_("keep %s despite the inferior architecture"), solvable2str(pool, s.get())); + if (pool->installed && s.get()->repo == pool->installed) { + problemSolution->addSingleAction (poolItem, LOCK); + string description = str::form (_("keep %s despite the inferior architecture"), s.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); } else { problemSolution->addSingleAction (poolItem, INSTALL); - string description = str::form (_("install %s despite the inferior architecture"), solvable2str(pool, s.get())); + string description = str::form (_("install %s despite the inferior architecture"), s.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); } } else if (p == SOLVER_SOLUTION_DISTUPGRADE) { s = mapSolvable (rp); PoolItem poolItem = _pool.find (s); - if (_solv->installed && s.get()->repo == _solv->installed) { - problemSolution->addSingleAction (poolItem, KEEP); - string description = str::form (_("keep obsolete %s"), solvable2str(pool, s.get())); + if (pool->installed && s.get()->repo == pool->installed) { + problemSolution->addSingleAction (poolItem, LOCK); + string description = str::form (_("keep obsolete %s"), s.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); } else { problemSolution->addSingleAction (poolItem, INSTALL); - string description = str::form (_("install %s from excluded repository"), solvable2str(pool, s.get())); + string description = str::form (_("install %s from excluded repository"), s.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); } } else { /* policy, replace p with rp */ s = mapSolvable (p); - if (rp) - sd = mapSolvable (rp); - PoolItem itemFrom = _pool.find (s); - if (s == sd && _solv->distupgrade) - { - PoolItem poolItem = _pool.find (s); - if (poolItem) { - problemSolution->addSingleAction (poolItem, LOCK); // for solver reason: NOT weak lock. - string description = str::form (_("keep %s"), solvable2str(pool, s.get())); - MIL << description << endl; - problemSolution->addDescription (description); - } else { - ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << id2str(pool, s.get()->name) << "-" - << id2str(pool, s.get()->evr) << "." << id2str(pool, s.get()->arch) << endl; - } - } - else if (rp) + if (rp) { int gotone = 0; + sd = mapSolvable (rp); PoolItem itemTo = _pool.find (sd); if (itemFrom && itemTo) { problemSolution->addSingleAction (itemTo, INSTALL); + int illegal = policy_is_illegal(_solv, s.get(), sd.get(), 0); - if (evrcmp(pool, s.get()->evr, sd.get()->evr, EVRCMP_COMPARE ) > 0) + if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0) { - string description = str::form (_("downgrade of %s to %s"), solvable2str(pool, s.get()), solvable2str(pool, sd.get())); + string description = str::form (_("downgrade of %s to %s"), s.asString().c_str(), sd.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); gotone = 1; } - if (!_solv->allowarchchange && s.get()->name == sd.get()->name && s.get()->arch != sd.get()->arch - && policy_illegal_archchange(_solv, s.get(), sd.get())) + if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0) { - string description = str::form (_("architecture change of %s to %s"), solvable2str(pool, s.get()), solvable2str(pool, sd.get())); + string description = str::form (_("architecture change of %s to %s"), s.asString().c_str(), sd.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); gotone = 1; } - if (!_solv->allowvendorchange && s.get()->name == sd.get()->name && s.get()->vendor != sd.get()->vendor - && policy_illegal_vendorchange(_solv, s.get(), sd.get())) + if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0) { - string description = str::form (_("install %s (with vendor change)\n %s\n-->\n %s") , - solvable2str(pool, sd.get()) , id2str(pool, s.get()->vendor), - string(sd.get()->vendor ? id2str(pool, sd.get()->vendor) : " (no vendor) ").c_str() ); + IdString s_vendor( s.vendor() ); + IdString sd_vendor( sd.vendor() ); + string description = str::form (_("install %s (with vendor change)\n %s --> %s") , + sd.asString().c_str(), + ( s_vendor ? s_vendor.c_str() : " (no vendor) " ), + ( sd_vendor ? sd_vendor.c_str() : " (no vendor) " ) ); MIL << description << endl; problemSolution->addDescription (description); gotone = 1; } if (!gotone) { - string description = str::form (_("replacement of %s with %s"), solvable2str(pool, s.get()), solvable2str(pool, sd.get())); + string description = str::form (_("replacement of %s with %s"), s.asString().c_str(), sd.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); } } else { - ERR << id2str(pool, s.get()->name) << "-" << id2str(pool, s.get()->evr) << "." << id2str(pool, s.get()->arch) - << " or " << id2str(pool, sd.get()->name) << "-" << id2str(pool, sd.get()->evr) << "." << id2str(pool, sd.get()->arch) << " not found" << endl; + ERR << s.asString() << " or " << sd.asString() << " not found" << endl; } } else { if (itemFrom) { - string description = str::form (_("deinstallation of %s"), solvable2str(pool, s.get())); + string description = str::form (_("deinstallation of %s"), s.asString().c_str()); MIL << description << endl; problemSolution->addDescription (description); problemSolution->addSingleAction (itemFrom, REMOVE); @@ -1350,30 +1458,35 @@ SATResolver::applySolutions (const ProblemSolutionList & solutions) void SATResolver::setLocks() { - for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); iter++) { + for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); ++iter) { sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() ); if (iter->status().isInstalled()) { MIL << "Lock installed item " << *iter << endl; - queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE ); + queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE ); queue_push( &(_jobQueue), ident ); } else { MIL << "Lock NOT installed item " << *iter << endl; - queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE ); + queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), ident ); } } - for (PoolItemList::const_iterator iter = _items_to_keep.begin(); iter != _items_to_keep.end(); iter++) { - sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() ); - if (iter->status().isInstalled()) { - MIL << "Keep installed item " << *iter << endl; - queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE | SOLVER_WEAK); - queue_push( &(_jobQueue), ident ); - } else { - MIL << "Keep NOT installed item " << *iter << ident << endl; - queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | SOLVER_WEAK); - queue_push( &(_jobQueue), ident ); + /////////////////////////////////////////////////////////////////// + // Weak locks: Ignore if an item with this name is already installed. + // If it's not installed try to keep it this way using a weak delete + /////////////////////////////////////////////////////////////////// + std::set unifiedByName; + for (PoolItemList::const_iterator iter = _items_to_keep.begin(); iter != _items_to_keep.end(); ++iter) { + IdString ident( (*iter)->satSolvable().ident() ); + if ( unifiedByName.insert( ident ).second ) + { + if ( ! ui::Selectable::get( *iter )->hasInstalledObj() ) + { + MIL << "Keep NOT installed name " << ident << " (" << *iter << ")" << endl; + queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | SOLVER_WEAK | MAYBE_CLEANDEPS ); + queue_push( &(_jobQueue), ident.id() ); } + } } } @@ -1382,51 +1495,53 @@ void SATResolver::setSystemRequirements() CapabilitySet system_requires = SystemCheck::instance().requiredSystemCap(); CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap(); - for (CapabilitySet::const_iterator iter = system_requires.begin(); iter != system_requires.end(); iter++) { - queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE_PROVIDES); + for (CapabilitySet::const_iterator iter = system_requires.begin(); iter != system_requires.end(); ++iter) { + queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES ); queue_push( &(_jobQueue), iter->id() ); MIL << "SYSTEM Requires " << *iter << endl; } - for (CapabilitySet::const_iterator iter = system_conflicts.begin(); iter != system_conflicts.end(); iter++) { - queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES); + for (CapabilitySet::const_iterator iter = system_conflicts.begin(); iter != system_conflicts.end(); ++iter) { + queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), iter->id() ); MIL << "SYSTEM Conflicts " << *iter << endl; } - // try to prefer none architecture change if possible - // So the architecture of the "rpm" package should be prefered - - Capability cap("rpm"); - sat::WhatProvides rpmProviders(cap); - for_( iter2, rpmProviders.begin(), rpmProviders.end() ) { - if (iter2->isSystem()) { - sat::detail::IdType nid = iter2->ident().id(); - nid = rel2id(_SATPool, - nid, - iter2->arch().id(), REL_ARCH, true); - if (_distupgrade) - { - bool addRule = false; - Capability cap(nid); - sat::WhatProvides rpmProviders(cap); - for_( iter3, rpmProviders.begin(), rpmProviders.end() ) { - if ( !(iter3->isSystem())) { - addRule = true; - break; - } - } - if (!addRule) - break; - } + // Lock the architecture of the running systems rpm + // package on distupgrade. + if ( _distupgrade && ZConfig::instance().systemRoot() == "/" ) + { + ResPool pool( ResPool::instance() ); + IdString rpm( "rpm" ); + for_( it, pool.byIdentBegin(rpm), pool.byIdentEnd(rpm) ) + { + if ( (*it)->isSystem() ) + { + Capability archrule( (*it)->arch(), rpm.c_str(), Capability::PARSED ); + queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_NAME | SOLVER_ESSENTIAL ); + queue_push( &(_jobQueue), archrule.id() ); - queue_push(&(_jobQueue), SOLVER_INSTALL|SOLVABLE_NAME|SOLVER_ESSENTIAL); - queue_push(&(_jobQueue), nid); - break; - } + } + } } } +sat::StringQueue SATResolver::autoInstalled() const +{ + sat::StringQueue ret; + if ( _solv ) + ::solver_get_userinstalled( _solv, ret, GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED ); + return ret; +} + +sat::StringQueue SATResolver::userInstalled() const +{ + sat::StringQueue ret; + if ( _solv ) + ::solver_get_userinstalled( _solv, ret, GET_USERINSTALLED_NAMES ); + return ret; +} + /////////////////////////////////////////////////////////////////// };// namespace detail