From: Michael Andres Date: Thu, 27 Nov 2008 23:10:35 +0000 (+0000) Subject: - Take into account the requirements of all obsoleted packages uninstall X-Git-Tag: 6.6.0~141 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=797a9269c315b84bde9b2d1c22fb1d6a2a9de5fb;p=platform%2Fupstream%2Flibzypp.git - Take into account the requirements of all obsoleted packages uninstall scripts when computing the installation order. (bnc #439802) --- diff --git a/VERSION.cmake b/VERSION.cmake index 18c3e4e6e..40c2a1e8c 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -61,8 +61,8 @@ SET(LIBZYPP_MAJOR "5") SET(LIBZYPP_COMPATMINOR "23") SET(LIBZYPP_MINOR "24") -SET(LIBZYPP_PATCH "2") +SET(LIBZYPP_PATCH "3") # -# LAST RELEASED: 5.24.2 (23) +# LAST RELEASED: 5.24.3 (23) # (The number in parenthesis is LIBZYPP_COMPATMINOR) #======= diff --git a/devel/devel.ma/Iorder.cc b/devel/devel.ma/Iorder.cc index 1d588b254..b8534c4de 100644 --- a/devel/devel.ma/Iorder.cc +++ b/devel/devel.ma/Iorder.cc @@ -1,48 +1,67 @@ #include "Tools.h" #include +#include +#include #include "zypp/pool/GetResolvablesToInsDel.h" Pathname mroot( "/tmp/Bb" ); TestSetup test( mroot, Arch_ppc64 ); -bool checkCaps( Capabilities caps_r ); +#define LCStack "IOrder::Stack" +#define LCCache "IOrder::Cache" +#define LCVerbose "IOrder::Verbose" -struct RunableCache +bool progressReceiver( const ProgressData & v ) +{ + DBG << "...->" << v << endl; + return true; +} + +struct RunnableCache { typedef std::tr1::unordered_map CacheType; typedef std::vector AnalyzeStack; - RunableCache() + RunnableCache() : _ltag( "[0000]" ) {} /** - * Test whether there is a runable provider for each requirement. + * Test whether there is a runnable provider for each requirement. */ - bool isRunable( const PoolItem & pi ) const - { return isRunable( pi.satSolvable() ); } + bool isRunnable( const PoolItem & pi ) const + { return isRunnable( pi.satSolvable() ); } - bool isRunable( sat::Solvable solv_r ) const + bool isRunnable( sat::Solvable solv_r ) const { - tribool & cent( get( solv_r ) ); - if ( indeterminate( cent ) ) - return (cent = analyze( solv_r )); - return cent; + SEC << "Runnable? " << solv_r << endl; + if ( _isRunnable( solv_r ) ) + { + MIL << "Runnable: " << solv_r << endl; + return true; + } + ERR << "NotRunnable: " << solv_r << endl; + return false; } /** - * Test whether there is a runable provider for each pre-requirement. + * Test whether there is a runnable provider for each pre-requirement. */ bool isInstallable( const PoolItem & pi ) const { return isInstallable( pi.satSolvable() ); } bool isInstallable( sat::Solvable solv_r ) const { - tribool & cent( get( solv_r ) ); - if ( cent ) - return true; // if runable then also installable. - return checkCaps( solv_r.prerequires() ); + SEC << "Installable? " << solv_r << endl; + tribool & cent( get( solv_r ) ); // if (cached) runnable then also installable. + if ( cent || checkCaps( solv_r.prerequires() ) ) + { + MIL << "Installable: " << solv_r << endl; + return true; + } + ERR << "NotInstallable: " << solv_r << endl; + return false; } /** Clear the cache. */ @@ -51,83 +70,90 @@ struct RunableCache _cache.clear(); _stack.clear(); _ltag = "[0000]"; + _INT(LCCache) << "Cache cleared!" << endl; } private: + /** Internal version without loging for recursive calls. */ + bool _isRunnable( const PoolItem & pi ) const + { return _isRunnable( pi.satSolvable() ); } + + bool _isRunnable( sat::Solvable solv_r ) const + { + tribool & cent( get( solv_r ) ); + if ( indeterminate( cent ) ) + cent = analyze( solv_r ); + return cent; + } + /** - * Determine whether this solvable is runable. + * Determine whether this solvable is runnable. */ bool analyze( sat::Solvable solv_r ) const { if ( ! push( solv_r ) ) { if ( _stack.back() != solv_r ) - SEC << _ltag << "??Already on stack: " << solv_r << " " << _stack << endl; + _SEC(LCStack) << _ltag << "** CYCLE: " << solv_r << " " << _stack << endl; // else it's a self requirement return true; // assume runnable? } - - INT << _ltag << "->" << solv_r << " " << _stack << endl; + _INT(LCStack) << _ltag << "->" << solv_r << " " << _stack << endl; bool ret = checkCaps( solv_r.requires() ); - if ( ! ret ) - { - ERR << " Not runable: " << solv_r << endl; - } - INT << _ltag << "<-" << solv_r << " " << _stack << endl; - + _INT(LCStack) << _ltag << "<-" << solv_r << " " << _stack << endl; if ( ! pop( solv_r ) ) { - INT << "Stack corrupted! Expect " << solv_r << " " << _stack << endl; + _SEC(LCStack) << "** Stack corrupted! Expect " << solv_r << " " << _stack << endl; } return ret; } /** - * For each capability find a runable provider. + * For each capability find a runnable provider. */ bool checkCaps( Capabilities caps_r ) const { for_( it, caps_r.begin(), caps_r.end() ) { - if ( ! findRunableProvider( *it ) ) + if ( ! findRunnableProvider( *it ) ) return false; } return true; } /** - * Find a runable provider of a capability on system. + * Find a runnable provider of a capability on system. * - * A runable package is already installed and all of - * its requirements are met by runable packages. + * A runnable package is already installed and all of + * its requirements are met by runnable packages. */ - bool findRunableProvider( Capability cap_r ) const + bool findRunnableProvider( Capability cap_r ) const { - _MIL("findRunableProvider") << _ltag << " " << cap_r << endl; + _MIL(LCVerbose) << _ltag << " " << cap_r << endl; sat::WhatProvides prv( cap_r ); for_( pit, prv.begin(), prv.end() ) { if ( ! *pit ) { - _DBG("findRunableProvider") << _ltag << " by system" << endl; + _DBG(LCVerbose) << _ltag << " by system" << endl; return true; // noSolvable provides: i.e. system provides } PoolItem pi( *pit ); if ( pi.status().onSystem() ) { - if ( isRunable( pi ) ) + if ( _isRunnable( pi ) ) { - _DBG("findRunableProvider") << _ltag << " " << pi << endl; + _DBG(LCVerbose) << _ltag << " " << pi << endl; return true; } else { - _WAR("findRunableProvider") << _ltag << " " << pi << endl; + _WAR(LCVerbose) << _ltag << " " << pi << endl; } } } - ERR << _ltag << " NO on system provider for " << cap_r << endl; + ERR << _ltag << " NO runnable provider for " << cap_r << endl; return false; } @@ -138,7 +164,7 @@ struct RunableCache if ( find( _stack.begin(), _stack.end(), solv_r ) == _stack.end() ) { _stack.push_back( solv_r ); - _ltag = str::form( "[%04u]", _stack.size() ); + _ltag = str::form( "[%04lu]", _stack.size() ); return true; } // cycle? @@ -151,7 +177,7 @@ struct RunableCache if ( _stack.back() == solv_r ) { _stack.pop_back(); - _ltag = str::form( "[%04u]", _stack.size() ); + _ltag = str::form( "[%0l4u]", _stack.size() ); return true; } // stack corrupted? @@ -172,7 +198,7 @@ struct RunableCache mutable std::string _ltag; }; -RunableCache rcache; +RunnableCache rcache; //================================================== @@ -239,6 +265,104 @@ inline void restore() test.poolProxy().restoreState(); } +void display( const pool::GetResolvablesToInsDel & collect, std::set interested ) +{ + USR << "======================================================================" << endl; + USR << "=== DELETE" << endl; + USR << "======================================================================" << endl; + if ( 1 ) + { + ProgressData tics( collect._toDelete.size() ); + tics.name( "DELETE" ); + tics.sendTo( &progressReceiver ); + tics.toMin(); + + for_( it, collect._toDelete.begin(), collect._toDelete.end() ) + { + tics.incr(); + + it->status().setTransact( true, ResStatus::USER ); +// vdumpPoolStats( SEC << "Transacting:"<< endl, +// make_filter_begin(pool), +// make_filter_end(pool) ) << endl; + + if ( !interested.empty() && interested.find( it->satSolvable().ident() ) == interested.end() ) + { + MIL << "..." << *it << endl; + continue; + } + + rcache.clear(); + if ( ! rcache.isInstallable( *it ) ) + { + USR << "FAILED DEL " << *it << endl; + } + } + } + + USR << "======================================================================" << endl; + USR << "=== INSTALL" << endl; + USR << "======================================================================" << endl; + if ( 1 ) + { + ProgressData tics( collect._toInstall.size() ); + tics.name( "INSTALL" ); + tics.sendTo( progressReceiver ); + tics.toMin(); + + + for_( it, collect._toInstall.begin(), collect._toInstall.end() ) + { + tics.incr(); + + ui::Selectable::Ptr p( ui::Selectable::get( *it ) ); + p->setCandidate( *it ); + p->setToInstall(); // also deletes the installed one +// vdumpPoolStats( SEC << "Transacting:"<< endl, +// make_filter_begin(pool), +// make_filter_end(pool) ) << endl; + + + if ( !interested.empty() && interested.find( p->ident() ) == interested.end() ) + { + MIL << "..." << *it << endl; + continue; + } + + rcache.clear(); + + sat::WhatObsoletes obs( *it ); + for_( it, obs.begin(), obs.end() ) + { + if ( ! rcache.isInstallable( *it ) ) + { + USR << "FAILED OBS " << *it << endl; + } + } + + if ( ! rcache.isInstallable( *it ) ) + { + USR << "FAILED INS " << *it << endl; + } + } + } +} + +void display( const pool::GetResolvablesToInsDel & collect, IdString ident_r ) +{ + std::set interested; + interested.insert( ident_r ); + display( collect, interested ); +} + + +void display( const pool::GetResolvablesToInsDel & collect ) +{ + std::set interested; + display( collect, interested ); +} + + /****************************************************************** ** ** FUNCTION NAME : main @@ -262,8 +386,8 @@ int main( int argc, char * argv[] ) if ( 0 ) { - PoolItem p = getPi( "bash", Edition("3.1-24.14"), Arch("ppc64") ); - p.status().setTransact( true, ResStatus::USER ); + PoolItem pi = getPi( "bash", Edition("3.1-24.14"), Arch("ppc64") ); + pi.status().setTransact( true, ResStatus::USER ); } save(); @@ -278,97 +402,19 @@ int main( int argc, char * argv[] ) make_filter_end(pool) ) << endl; pool::GetResolvablesToInsDel collect( pool, pool::GetResolvablesToInsDel::ORDER_BY_MEDIANR ); - restore(); - vdumpPoolStats( USR << "Transacting:"<< endl, - make_filter_begin(pool), - make_filter_end(pool) ) << endl; - - { - for_( it, collect._toDelete.begin(), collect._toDelete.end() ) - { - it->status().setTransact( true, ResStatus::USER ); - SEC << *it << endl; -// vdumpPoolStats( SEC << "Transacting:"<< endl, -// make_filter_begin(pool), -// make_filter_end(pool) ) << endl; - - (rcache.isInstallable( *it ) ? MIL : ERR) << *it << " deletable?" << endl; - } - } - - if ( 0 ) { - for_( it, collect._toInstall.begin(), collect._toInstall.end() ) - { - it->status().setTransact( true, ResStatus::USER ); - SEC << *it << endl; -// vdumpPoolStats( SEC << "Transacting:"<< endl, -// make_filter_begin(pool), -// make_filter_end(pool) ) << endl; - (rcache.isInstallable( *it ) ? MIL : ERR) << *it << " installable?" << endl; - } - } - - -#if 0 - //getPi<>( "", "", Edition(""), Arch("") ); - getPi( "SUSE_SLES", Edition("11"), Arch("ppc64") ).status().setTransact( true, ResStatus::USER ); - getPi( "sles-release", Edition("11-54.3"), Arch("ppc64") ).status().setTransact( true, ResStatus::USER ); - - ResPool pool( test.pool() ); - vdumpPoolStats( USR << "Transacting:"<< endl, - make_filter_begin(pool), - make_filter_end(pool) ) << endl; - upgrade(); - vdumpPoolStats( USR << "Transacting:"<< endl, - make_filter_begin(pool), - make_filter_end(pool) ) << endl; - - pool::GetResolvablesToInsDel collect( pool, pool::GetResolvablesToInsDel::ORDER_BY_MEDIANR ); - MIL << "GetResolvablesToInsDel:" << endl << collect << endl; - - if ( 1 ) - { - // Collect until the 1st package from an unwanted media occurs. - // Further collection could violate install order. - bool hitUnwantedMedia = false; - typedef pool::GetResolvablesToInsDel::PoolItemList PoolItemList; - PoolItemList::iterator fst=collect._toInstall.end(); - for ( PoolItemList::iterator it = collect._toInstall.begin(); it != collect._toInstall.end(); ++it) - { - ResObject::constPtr res( it->resolvable() ); - - if ( hitUnwantedMedia - || ( res->mediaNr() && res->mediaNr() != 1 ) ) - { - if ( !hitUnwantedMedia ) - fst=it; - hitUnwantedMedia = true; - } - } - dumpRange( WAR << "toInstall1: " << endl, - collect._toInstall.begin(), fst ) << endl; - dumpRange( WAR << "toInstall2: " << endl, - fst, collect._toInstall.end() ) << endl; - dumpRange( ERR << "toDelete: " << endl, - collect._toDelete.begin(), collect._toDelete.end() ) << endl; - } - else - { - dumpRange( WAR << "toInstall: " << endl, - collect._toInstall.begin(), collect._toInstall.end() ) << endl; - dumpRange( ERR << "toDelete: " << endl, - collect._toDelete.begin(), collect._toDelete.end() ) << endl; - } - INT << "===[END]============================================" << endl << endl; - return 0; -#endif + USR << ui::Selectable::get( "libcdio" ) << endl; + USR << ui::Selectable::get( "libcdio7" ) << endl; + std::set interested; + //interested.insert( IdString("libcdio") ); + //interested.insert( IdString("libcdio7") ); + restore(); + display( collect, interested ); - INT << "===[END]============================================" << endl << endl; + INT << "===[END]============================================" << endl << endl; zypp::base::LogControl::TmpLineWriter shutUp; return 0; } - diff --git a/package/libzypp.changes b/package/libzypp.changes index 83bc3b5c9..4a089c781 100644 --- a/package/libzypp.changes +++ b/package/libzypp.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Fri Nov 28 00:05:17 CET 2008 - ma@calvin.km13.de + +- Take into account the requirements of all obsoleted packages uninstall + scripts when computing the installation order. (bnc #439802) +- revision 11823 +- version 5.24.3 (23) + ------------------------------------------------------------------- Thu Nov 27 14:45:07 CET 2008 - dmacvicar@suse.de diff --git a/zypp/solver/detail/InstallOrder.cc b/zypp/solver/detail/InstallOrder.cc index 0ca4d492c..68925f2d6 100644 --- a/zypp/solver/detail/InstallOrder.cc +++ b/zypp/solver/detail/InstallOrder.cc @@ -38,6 +38,7 @@ #include "zypp/ResStatus.h" #include "zypp/NameKindProxy.h" #include "zypp/sat/Pool.h" +#include ///////////////////////////////////////////////////////////////////////// namespace zypp @@ -196,12 +197,12 @@ InstallOrder::rdfsvisit (const PoolItem item) // items prereq CapabilitySet prq( item->dep(Dep::PREREQUIRES).begin(), item->dep(Dep::PREREQUIRES).end() ); - // an installed items prereq (in case they are reqired for uninstall scripts) - NameKindProxy nkp( _pool, item->name(), item->kind() ); - if ( ! nkp.installedEmpty() ) + // any obsoleted items prereq (in case they are reqired for uninstall scripts) + sat::WhatObsoletes obs( item ); + for_( it, obs.begin(), obs.end() ) { - prq.insert( (*nkp.installedBegin())->dep(Dep::PREREQUIRES).begin(), - (*nkp.installedBegin())->dep(Dep::PREREQUIRES).end() ); + Capabilities p( it->prerequires() ); + prq.insert( p.begin(), p.end() ); } // put prerequires first and requires last on list to ensure // that prerequires are processed first