From a3cc709e0efc9c47fb8968f568f4b836330cb301 Mon Sep 17 00:00:00 2001 From: Michael Andres Date: Thu, 29 Apr 2010 17:09:32 +0200 Subject: [PATCH] Support solver option cleandepsOnRemove: Cleanup when deleting packages - zypp.conf option: solver.cleandepsOnRemove (default false) - Resolver::setCleandepsOnRemove --- libzypp.spec.cmake | 2 +- zypp.conf | 9 +++++++++ zypp/Resolver.cc | 22 +++++++++++++--------- zypp/Resolver.h | 27 ++++++++++++++++++++------- zypp/ZConfig.cc | 9 +++++++++ zypp/ZConfig.h | 5 +++++ zypp/solver/detail/Resolver.cc | 23 +++++++++++++++++++++-- zypp/solver/detail/Resolver.h | 8 ++++++-- zypp/solver/detail/SATResolver.cc | 22 +++++++++++++--------- zypp/solver/detail/SATResolver.h | 4 ++++ zypp/solver/detail/SolverQueueItemDelete.cc | 7 +++++-- 11 files changed, 106 insertions(+), 32 deletions(-) diff --git a/libzypp.spec.cmake b/libzypp.spec.cmake index 0a50dd3..1aea545 100644 --- a/libzypp.spec.cmake +++ b/libzypp.spec.cmake @@ -31,7 +31,7 @@ BuildRequires: openssl-devel BuildRequires: libudev-devel BuildRequires: boost-devel dejagnu doxygen gcc-c++ gettext-devel graphviz libxml2-devel -BuildRequires: libsatsolver-devel >= 0.14.13 +BuildRequires: libsatsolver-devel >= 0.14.17 %if 0%{?suse_version} %requires_eq satsolver-tools %else diff --git a/zypp.conf b/zypp.conf index 3bbb6e4..190f5c6 100644 --- a/zypp.conf +++ b/zypp.conf @@ -264,6 +264,15 @@ # solver.allowVendorChange = false ## +## Cleanup when deleting packages. Whether the solver should per default +## try to remove packages exclusively required by the ones he's asked to delete. +## +## Valid values: boolean +## Default value: false +## +# solver.cleandepsOnRemove = false + +## ## This file contains requirements/conflicts which fulfill the ## needs of a running system. ## For example the system would be broken if not glibc or kernel is diff --git a/zypp/Resolver.cc b/zypp/Resolver.cc index db9ff6c..ad1fe4a 100644 --- a/zypp/Resolver.cc +++ b/zypp/Resolver.cc @@ -33,9 +33,8 @@ namespace zypp // METHOD TYPE : Ctor // Resolver::Resolver( const ResPool & pool ) - { - _pimpl = new solver::detail::Resolver(pool); - } + : _pimpl( new Impl(pool) ) + {} /////////////////////////////////////////////////////////////////// // @@ -75,14 +74,14 @@ namespace zypp { _pimpl->doUpdate(); } void Resolver::setForceResolve( bool yesno_r ) { _pimpl->setForceResolve( yesno_r ); } - bool Resolver::forceResolve() { return _pimpl->forceResolve(); } + bool Resolver::forceResolve() const { return _pimpl->forceResolve(); } void Resolver::setIgnoreAlreadyRecommended( bool yesno_r) { _pimpl->setIgnoreAlreadyRecommended( yesno_r ); } - bool Resolver::ignoreAlreadyRecommended() { return _pimpl->ignoreAlreadyRecommended(); } + bool Resolver::ignoreAlreadyRecommended() const { return _pimpl->ignoreAlreadyRecommended(); } void Resolver::setOnlyRequires( bool yesno_r ) { _pimpl->setOnlyRequires( yesno_r ); } void Resolver::resetOnlyRequires() { _pimpl->setOnlyRequires( indeterminate ); } - bool Resolver::onlyRequires() { return _pimpl->onlyRequires(); } + bool Resolver::onlyRequires() const { return _pimpl->onlyRequires(); } bool Resolver::upgradeMode() const { return _pimpl->isUpgradeMode(); } @@ -98,6 +97,10 @@ namespace zypp void Resolver::setDefaultSolveSrcPackages() { _pimpl->setSolveSrcPackages( indeterminate ); } bool Resolver::solveSrcPackages() const { return _pimpl->solveSrcPackages(); } + void Resolver::setCleandepsOnRemove( bool yesno_r ) { _pimpl->setCleandepsOnRemove( yesno_r ); } + void Resolver::setDefaultCleandepsOnRemove() { _pimpl->setCleandepsOnRemove( indeterminate ); } + bool Resolver::cleandepsOnRemove() const { return _pimpl->cleandepsOnRemove(); } + void Resolver::addUpgradeRepo( Repository repo_r ) { _pimpl->addUpgradeRepo( repo_r ); } bool Resolver::upgradingRepo( Repository repo_r ) const { return _pimpl->upgradingRepo( repo_r ); } void Resolver::removeUpgradeRepo( Repository repo_r ) { _pimpl->removeUpgradeRepo( repo_r ); } @@ -108,8 +111,8 @@ namespace zypp void Resolver::removeRequire( const Capability & capability ) { _pimpl->removeExtraRequire( capability ); } void Resolver::removeConflict( const Capability & capability ){ _pimpl->removeExtraConflict( capability ); } - CapabilitySet Resolver::getRequire() { return _pimpl->extraRequires(); } - CapabilitySet Resolver::getConflict() { return _pimpl->extraConflicts(); } + CapabilitySet Resolver::getRequire() const { return _pimpl->extraRequires(); } + CapabilitySet Resolver::getConflict() const { return _pimpl->extraConflicts(); } std::list Resolver::problematicUpdateItems() const { return _pimpl->problematicUpdateItems(); } @@ -135,7 +138,8 @@ namespace zypp void Resolver::reset() { _pimpl->reset( false ); /* Do not keep extra requires/conflicts */ } - + std::ostream & operator<<( std::ostream & str, const Resolver & obj ) + { return str << *obj._pimpl; } ///////////////////////////////////////////////////////////////// } // namespace zypp diff --git a/zypp/Resolver.h b/zypp/Resolver.h index 74db641..4ad256b 100644 --- a/zypp/Resolver.h +++ b/zypp/Resolver.h @@ -161,14 +161,14 @@ namespace zypp * This behaviour is favourited by ZMD. **/ void setForceResolve( bool force ); - bool forceResolve(); + bool forceResolve() const; /** * Ignore recommended packages that were already recommended by * the installed packages **/ void setIgnoreAlreadyRecommended( bool yesno_r ); - bool ignoreAlreadyRecommended(); + bool ignoreAlreadyRecommended() const; /** * Setting whether required packages are installed ONLY @@ -177,7 +177,7 @@ namespace zypp **/ void setOnlyRequires( bool yesno_r ); void resetOnlyRequires(); // set back to default (described in zypp.conf) - bool onlyRequires(); + bool onlyRequires() const; /** * Whether the \ref Resolver is in upgrade mode. @@ -218,6 +218,14 @@ namespace zypp void setDefaultSolveSrcPackages(); bool solveSrcPackages() const; + /** + * Cleanup when deleting packages. Whether the solver should per default + * try to remove packages exclusively required by the ones he's asked to delete. + */ + void setCleandepsOnRemove( bool yesno_r ); + void setDefaultCleandepsOnRemove(); // set back to default (in zypp.conf) + bool cleandepsOnRemove() const; + /** \name Upgrade to content of a specific repository. * \note This is an ordinary solver request. You should simply * \ref resolvePool to execute, and not \ref doUpgrade. @@ -275,13 +283,13 @@ namespace zypp * Get all the additional requirements set by \ref addRequire(Capability). * */ - CapabilitySet getRequire(); + CapabilitySet getRequire() const; /** * Get all the additional conflicts set by \ref addConflict(Capability). * */ - CapabilitySet getConflict(); + CapabilitySet getConflict() const; /** * Generates a solver Testcase of the current state @@ -357,12 +365,17 @@ namespace zypp solver::detail::ItemCapKindList installedSatisfied( const PoolItem & item ); - private: - solver::detail::Resolver_Ptr _pimpl; + friend std::ostream & operator<<( std::ostream & str, const Resolver & obj ); + + typedef solver::detail::Resolver Impl; + zypp::RW_pointer > _pimpl; }; /////////////////////////////////////////////////////////////////// + /** \relates Resolver Stream output */ + std::ostream & operator<<( std::ostream & str, const Resolver & obj ); + ///////////////////////////////////////////////////////////////// } // namespace zypp /////////////////////////////////////////////////////////////////// diff --git a/zypp/ZConfig.cc b/zypp/ZConfig.cc index 16bf5ef..9ab5442 100644 --- a/zypp/ZConfig.cc +++ b/zypp/ZConfig.cc @@ -229,6 +229,7 @@ namespace zypp , commit_downloadMode ( DownloadDefault ) , solver_onlyRequires ( false ) , solver_allowVendorChange ( false ) + , solver_cleandepsOnRemove ( false ) , solver_upgradeTestcasesToKeep ( 2 ) , solverUpgradeRemoveDroppedPackages( true ) , apply_locks_file ( true ) @@ -356,6 +357,10 @@ namespace zypp { solver_allowVendorChange.set( str::strToBool( value, solver_allowVendorChange ) ); } + else if ( entry == "solver.cleandepsOnRemove" ) + { + solver_cleandepsOnRemove.set( str::strToBool( value, solver_cleandepsOnRemove ) ); + } else if ( entry == "solver.upgradeTestcasesToKeep" ) { solver_upgradeTestcasesToKeep.set( str::strtonum( value ) ); @@ -479,6 +484,7 @@ namespace zypp Option solver_onlyRequires; Option solver_allowVendorChange; + Option solver_cleandepsOnRemove; Option solver_upgradeTestcasesToKeep; DefaultOption solverUpgradeRemoveDroppedPackages; @@ -702,6 +708,9 @@ namespace zypp bool ZConfig::solver_allowVendorChange() const { return _pimpl->solver_allowVendorChange; } + bool ZConfig::solver_cleandepsOnRemove() const + { return _pimpl->solver_cleandepsOnRemove; } + Pathname ZConfig::solver_checkSystemFile() const { return ( _pimpl->solver_checkSystemFile.empty() ? (configPath()/"systemCheck") : _pimpl->solver_checkSystemFile ); } diff --git a/zypp/ZConfig.h b/zypp/ZConfig.h index b569a18..4af55bf 100644 --- a/zypp/ZConfig.h +++ b/zypp/ZConfig.h @@ -254,6 +254,11 @@ namespace zypp bool solver_allowVendorChange() const; /** + * Whether removing a package should also remove no longer needed requirements. + */ + bool solver_cleandepsOnRemove() const; + + /** * When committing a dist upgrade (e.g. zypper dup) * a solver testcase is written. It is needed in bugreports, * in case something went wrong. This returns the number of diff --git a/zypp/solver/detail/Resolver.cc b/zypp/solver/detail/Resolver.cc index 2e38463..ed804aa 100644 --- a/zypp/solver/detail/Resolver.cc +++ b/zypp/solver/detail/Resolver.cc @@ -58,7 +58,19 @@ IMPL_PTR_TYPE(Resolver); std::ostream & Resolver::dumpOn( std::ostream & os ) const { - return os << ""; + os << "" << endl; + #define OUTS(t) os << " " << #t << ":\t" << t << endl; + OUTS( _forceResolve ); + OUTS( _upgradeMode ); + OUTS( _updateMode ); + OUTS( _verifying ); + OUTS( _onlyRequires ); + OUTS( _allowVendorChange ); + OUTS( _solveSrcPackages ); + OUTS( _cleandepsOnRemove ); + OUTS( _ignoreAlreadyRecommended ); + #undef OUT + return os << ""; } @@ -75,7 +87,8 @@ Resolver::Resolver (const ResPool & pool) , _onlyRequires ( ZConfig::instance().solver_onlyRequires() ) , _allowVendorChange ( ZConfig::instance().solver_allowVendorChange() ) , _solveSrcPackages ( false ) - , _ignoreAlreadyRecommended (false) + , _cleandepsOnRemove ( ZConfig::instance().solver_cleandepsOnRemove() ) + , _ignoreAlreadyRecommended (true) { sat::Pool satPool( sat::Pool::instance() ); @@ -100,6 +113,11 @@ void Resolver::setOnlyRequires( TriBool state_r ) _onlyRequires = indeterminate(state_r) ? ZConfig::instance().solver_onlyRequires() : bool(state_r); } +void Resolver::setCleandepsOnRemove( TriBool state_r ) +{ + _cleandepsOnRemove = indeterminate(state_r) ? ZConfig::instance().solver_cleandepsOnRemove() : bool(state_r); +} + //--------------------------------------------------------------------------- ResPool Resolver::pool() const @@ -272,6 +290,7 @@ void Resolver::solverInit() _satResolver->setNoupdateprovide (false); _satResolver->setDosplitprovides (false); _satResolver->setSolveSrcPackages ( solveSrcPackages() ); + _satResolver->setCleandepsOnRemove ( cleandepsOnRemove() ); if (_upgradeMode) { // may overwrite some settings diff --git a/zypp/solver/detail/Resolver.h b/zypp/solver/detail/Resolver.h index ee4ee7b..77a0969 100644 --- a/zypp/solver/detail/Resolver.h +++ b/zypp/solver/detail/Resolver.h @@ -113,6 +113,7 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable { // packages, hardware packages (modalias) bool _allowVendorChange; // whether the solver should allow or disallow vendor changes. bool _solveSrcPackages; // whether to generate solver jobs for selected source packges. + bool _cleandepsOnRemove; // whether removing a package should also remove no longer needed requirements bool _ignoreAlreadyRecommended; //ignore recommended packages that have already been recommended by the installed packages //@} @@ -168,8 +169,8 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable { void removeQueueItem( SolverQueueItem_Ptr item ); void addQueueItem( SolverQueueItem_Ptr item ); - CapabilitySet extraRequires() { return _extra_requires; } - CapabilitySet extraConflicts() { return _extra_conflicts; } + CapabilitySet extraRequires() const { return _extra_requires; } + CapabilitySet extraConflicts() const { return _extra_conflicts; } void addWeak( const PoolItem & item ); @@ -204,6 +205,9 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable { bool solveSrcPackages() const { return _solveSrcPackages; } void setSolveSrcPackages( TriBool state_r ) { _solveSrcPackages = indeterminate(state_r) ? false : bool(state_r); } + + bool cleandepsOnRemove() const { return _cleandepsOnRemove; } + void setCleandepsOnRemove( TriBool state_r ); //@} ResolverProblemList problems() const; diff --git a/zypp/solver/detail/SATResolver.cc b/zypp/solver/detail/SATResolver.cc index 77ee6b8..8ebef38 100644 --- a/zypp/solver/detail/SATResolver.cc +++ b/zypp/solver/detail/SATResolver.cc @@ -66,6 +66,8 @@ using namespace std; IMPL_PTR_TYPE(SATResolver); +#define MAYBE_CLEANDEPS (cleandepsOnRemove()?SOLVER_CLEANDEPS:0) + //--------------------------------------------------------------------------- // Callbacks for SAT policies //--------------------------------------------------------------------------- @@ -121,6 +123,7 @@ SATResolver::dumpOn( std::ostream & os ) const os << " distupgrade = " << _distupgrade << endl; os << " distupgrade_removeunsupported = " << _distupgrade_removeunsupported << endl; os << " solveSrcPackages = " << _solveSrcPackages << endl; + os << " cleandepsOnRemove = " << _cleandepsOnRemove << endl; } else { os << ""; } @@ -136,16 +139,17 @@ SATResolver::SATResolver (const ResPool & pool, Pool *SATPool) , _fixsystem(false) , _allowdowngrade(false) , _allowarchchange(false) - , _allowvendorchange(false) + , _allowvendorchange(ZConfig::instance().solver_allowVendorChange()) , _allowuninstall(false) , _updatesystem(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()) { } @@ -694,7 +698,7 @@ 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_SOLVABLE | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), id); } } @@ -713,7 +717,7 @@ SATResolver::resolvePool(const CapabilitySet & requires_caps, } 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_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), iter->id() ); MIL << "Conflicts " << *iter << endl; } @@ -763,7 +767,7 @@ SATResolver::resolveQueue(const SolverQueueItemList &requestQueue, 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_SOLVABLE_NAME | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), ident); } @@ -1379,7 +1383,7 @@ void SATResolver::setLocks() queue_push( &(_jobQueue), ident ); } else { MIL << "Lock NOT installed item " << *iter << endl; - queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE ); + queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), ident ); } } @@ -1392,7 +1396,7 @@ void SATResolver::setLocks() queue_push( &(_jobQueue), ident ); } else { MIL << "Keep NOT installed item " << *iter << ident << endl; - queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | SOLVER_WEAK); + queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | SOLVER_WEAK | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), ident ); } } @@ -1410,7 +1414,7 @@ void SATResolver::setSystemRequirements() } for (CapabilitySet::const_iterator iter = system_conflicts.begin(); iter != system_conflicts.end(); iter++) { - queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES); + queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS ); queue_push( &(_jobQueue), iter->id() ); MIL << "SYSTEM Conflicts " << *iter << endl; } diff --git a/zypp/solver/detail/SATResolver.h b/zypp/solver/detail/SATResolver.h index 5ac68b3..56140d0 100644 --- a/zypp/solver/detail/SATResolver.h +++ b/zypp/solver/detail/SATResolver.h @@ -97,6 +97,7 @@ class SATResolver : public base::ReferenceCounted, private base::NonCopyable { bool _distupgrade; bool _distupgrade_removeunsupported; bool _solveSrcPackages; // false: generate no job rule for source packages selected in the pool + bool _cleandepsOnRemove; // whether removing a package should also remove no longer needed requirements // ---------------------------------- methods std::string SATprobleminfoString (Id problem, std::string &detail, Id &ignoreId); @@ -201,6 +202,9 @@ class SATResolver : public base::ReferenceCounted, private base::NonCopyable { bool solveSrcPackages() const { return _solveSrcPackages; } void setSolveSrcPackages( bool state_r ) { _solveSrcPackages = state_r; } + bool cleandepsOnRemove() const { return _cleandepsOnRemove; } + void setCleandepsOnRemove( bool state_r ) { _cleandepsOnRemove = state_r; } + PoolItemList problematicUpdateItems( void ) const { return _problem_items; } PoolItemList resultItemsToInstall () { return _result_items_to_install; } diff --git a/zypp/solver/detail/SolverQueueItemDelete.cc b/zypp/solver/detail/SolverQueueItemDelete.cc index 70c2b28..91a75ec 100644 --- a/zypp/solver/detail/SolverQueueItemDelete.cc +++ b/zypp/solver/detail/SolverQueueItemDelete.cc @@ -24,6 +24,7 @@ extern "C" #include "zypp/base/Logger.h" #include "zypp/IdString.h" +#include "zypp/Resolver.h" #include "zypp/solver/detail/SolverQueueItemDelete.h" ///////////////////////////////////////////////////////////////////////// @@ -69,11 +70,13 @@ SolverQueueItemDelete::~SolverQueueItemDelete() bool SolverQueueItemDelete::addRule (_Queue & q) { +#define MAYBE_CLEANDEPS (pool().resolver().cleandepsOnRemove()?SOLVER_CLEANDEPS:0) + ::Id id = IdString(_name).id(); if (_soft) { - queue_push( &(q), SOLVER_ERASE_SOLVABLE_NAME | SOLVER_WEAK); + queue_push( &(q), SOLVER_ERASE_SOLVABLE_NAME | SOLVER_WEAK | MAYBE_CLEANDEPS ); } else { - queue_push( &(q), SOLVER_ERASE_SOLVABLE_NAME ); + queue_push( &(q), SOLVER_ERASE_SOLVABLE_NAME | MAYBE_CLEANDEPS ); } queue_push( &(q), id); -- 2.7.4