From 76151d28819cd2c6434129bf68c7490d0b824a8b Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Mon, 2 Sep 2019 16:12:33 +0900 Subject: [PATCH] Imported Upstream version 16.6.0 --- VERSION.cmake | 6 +- package/libzypp.changes | 6 ++ tests/data/PoolReuseIds/SeqA/repo.xml | 56 ++++++++++++++++++ tests/data/PoolReuseIds/SeqA/solver-test.xml | 6 ++ tests/data/PoolReuseIds/SeqB/oper.xml | 56 ++++++++++++++++++ tests/data/PoolReuseIds/SeqB/solver-test.xml | 6 ++ tests/zypp/CMakeLists.txt | 1 + tests/zypp/ExtendedPool_test.cc | 85 ++++++++++++++++++++++++++++ zypp/pool/PoolImpl.h | 5 +- zypp/sat/Pool.cc | 3 + zypp/sat/Pool.h | 3 + zypp/sat/detail/PoolImpl.cc | 3 + zypp/sat/detail/PoolImpl.h | 8 ++- 13 files changed, 239 insertions(+), 5 deletions(-) create mode 100644 tests/data/PoolReuseIds/SeqA/repo.xml create mode 100644 tests/data/PoolReuseIds/SeqA/solver-test.xml create mode 100644 tests/data/PoolReuseIds/SeqB/oper.xml create mode 100644 tests/data/PoolReuseIds/SeqB/solver-test.xml create mode 100644 tests/zypp/ExtendedPool_test.cc diff --git a/VERSION.cmake b/VERSION.cmake index f511320..fb81279 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -60,9 +60,9 @@ # SET(LIBZYPP_MAJOR "16") SET(LIBZYPP_COMPATMINOR "0") -SET(LIBZYPP_MINOR "5") -SET(LIBZYPP_PATCH "2") +SET(LIBZYPP_MINOR "6") +SET(LIBZYPP_PATCH "0") # -# LAST RELEASED: 16.5.2 (0) +# LAST RELEASED: 16.6.0 (0) # (The number in parenthesis is LIBZYPP_COMPATMINOR) #======= diff --git a/package/libzypp.changes b/package/libzypp.changes index ec07cc1..72d7623 100644 --- a/package/libzypp.changes +++ b/package/libzypp.changes @@ -1,4 +1,10 @@ ------------------------------------------------------------------- +Mon Mar 27 17:10:52 CEST 2017 - ma@suse.de + +- Fix invalidation of PoolItems if Pool IDs are reused (bsc#1028661) +- version 16.6.0 (0) + +------------------------------------------------------------------- Mon Mar 27 09:33:26 CEST 2017 - ma@suse.de - Fix X-libcurl-Empty-Header-Workaround (bsc#1030919) diff --git a/tests/data/PoolReuseIds/SeqA/repo.xml b/tests/data/PoolReuseIds/SeqA/repo.xml new file mode 100644 index 0000000..10581db --- /dev/null +++ b/tests/data/PoolReuseIds/SeqA/repo.xml @@ -0,0 +1,56 @@ + + + package + unkown + + x86_64 + 4 + 1 + + + + patch + unkown + + x86_64 + 4 + 1 + + + + pattern + unkown + + x86_64 + 4 + 1 + + + + product + unkown + + x86_64 + 4 + 1 + + + + srcpackage + unkown + + x86_64 + 4 + 1 + + + + application + unkown + + x86_64 + 4 + 1 + + + diff --git a/tests/data/PoolReuseIds/SeqA/solver-test.xml b/tests/data/PoolReuseIds/SeqA/solver-test.xml new file mode 100644 index 0000000..8a8f376 --- /dev/null +++ b/tests/data/PoolReuseIds/SeqA/solver-test.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/data/PoolReuseIds/SeqB/oper.xml b/tests/data/PoolReuseIds/SeqB/oper.xml new file mode 100644 index 0000000..868b0c4 --- /dev/null +++ b/tests/data/PoolReuseIds/SeqB/oper.xml @@ -0,0 +1,56 @@ + + + application + unkown + + x86_64 + 4 + 1 + + + + package + unkown + + x86_64 + 4 + 1 + + + + patch + unkown + + x86_64 + 4 + 1 + + + + pattern + unkown + + x86_64 + 4 + 1 + + + + product + unkown + + x86_64 + 4 + 1 + + + + srcpackage + unkown + + x86_64 + 4 + 1 + + + diff --git a/tests/data/PoolReuseIds/SeqB/solver-test.xml b/tests/data/PoolReuseIds/SeqB/solver-test.xml new file mode 100644 index 0000000..8fe6348 --- /dev/null +++ b/tests/data/PoolReuseIds/SeqB/solver-test.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/zypp/CMakeLists.txt b/tests/zypp/CMakeLists.txt index 2a1f137..6992f8d 100644 --- a/tests/zypp/CMakeLists.txt +++ b/tests/zypp/CMakeLists.txt @@ -16,6 +16,7 @@ ADD_TESTS( Digest Deltarpm Edition + ExtendedPool Fetcher FileChecker Flags diff --git a/tests/zypp/ExtendedPool_test.cc b/tests/zypp/ExtendedPool_test.cc new file mode 100644 index 0000000..3324cb5 --- /dev/null +++ b/tests/zypp/ExtendedPool_test.cc @@ -0,0 +1,85 @@ +#include + +#include + +#include "TestSetup.h" +#include + +#include +#include + +using boost::unit_test::test_case; +using std::cin; +using std::cout; +using std::cerr; +using std::endl; +using namespace zypp; + +static TestSetup test; + +void testcase_init() +{ +// cout << "+++[repoinit]=======================" << endl; + test.loadTestcaseRepos( TESTS_SRC_DIR"/data/PoolReuseIds/SeqA" ); +// for ( auto && pi : ResPool::instance() ) +// cout << pi << " " << pi.resolvable() << endl; +// cout << "---[repoinit]=======================" << endl; +} + +void testcase_init2() +{ +// cout << "+++[repoinit2]=======================" << endl; + sat::Pool::instance().reposEraseAll(); + test.loadTestcaseRepos( TESTS_SRC_DIR"/data/PoolReuseIds/SeqB" ); +// for ( auto && pi : ResPool::instance() ) +// cout << pi << " " << pi.resolvable() << endl; +// cout << "---[repoinit2]=======================" << endl; +} + +void checkpi( const PoolItem & pi ) +{ + BOOST_CHECK( pi.resolvable() ); + BOOST_CHECK_EQUAL( pi.id(), pi.resolvable()->id() ); + BOOST_CHECK_EQUAL( bool(asKind( pi.resolvable() )), isKind(pi) ); + BOOST_CHECK_EQUAL( bool(asKind( pi.resolvable() )), isKind(pi) ); + BOOST_CHECK_EQUAL( bool(asKind( pi.resolvable() )), isKind(pi) ); + BOOST_CHECK_EQUAL( bool(asKind( pi.resolvable() )), isKind(pi) ); + BOOST_CHECK_EQUAL( bool(asKind( pi.resolvable() )), isKind(pi) ); + BOOST_CHECK_EQUAL( bool(asKind( pi.resolvable() )), isKind(pi) ); +} + +void repocheck() +{ +// cout << "+++[repocheck]======================" << endl; + for ( auto && pi : ResPool::instance() ) + { +// cout << "??? " << pi << endl; + checkpi( pi ); + } +// cout << "---[repocheck]======================" << endl; +} + +/////////////////////////////////////////////////////////////////// +// Check that after ERASING ALL REPOS and loading a new one, ResPool +// actually creates new PoolItems rather than reusing already existing +// ones. +// +// Adding/removing repos will not reuse poolIDs unless actually all +// repos are removed from the pool. In this case ResPool must invalidate +// ALL existing PoolItems (especially the Resolvable Pointers inside). +// +// SeqA SeqB +// (1)package - (1)application +// (2)pattern - (2)package +// ... ... +// +// The two test repos have Resolvables of different kind in different +// order. If ResPool fails to recreate the PoolItem, we'll experience +// cast errors. PoolItem(1) will claim to be an application, but the +// Resolvable is still the original one created for a package... +/////////////////////////////////////////////////////////////////// + +BOOST_AUTO_TEST_CASE(t_1) { testcase_init(); } +BOOST_AUTO_TEST_CASE(t_2) { repocheck(); } +BOOST_AUTO_TEST_CASE(t_4) { testcase_init2(); } +BOOST_AUTO_TEST_CASE(t_5) { repocheck(); } diff --git a/zypp/pool/PoolImpl.h b/zypp/pool/PoolImpl.h index 24249bc..807f4a7 100644 --- a/zypp/pool/PoolImpl.h +++ b/zypp/pool/PoolImpl.h @@ -306,6 +306,7 @@ namespace zypp { sat::Pool pool( satpool() ); bool addedItems = false; + bool reusedIDs = _watcherIDs.remember( pool.serialIDs() ); std::list addedProducts; _store.resize( pool.capacity() ); @@ -321,7 +322,7 @@ namespace zypp // the PoolItem got invalidated (e.g unloaded repo) pi = PoolItem(); } - else if ( s && ! pi ) + else if ( reusedIDs || (s && ! pi) ) { // new PoolItem to add pi = PoolItem::makePoolItem( s ); // the only way to create a new one! @@ -398,6 +399,8 @@ namespace zypp private: /** Watch sat pools serial number. */ SerialNumberWatcher _watcher; + /** Watch sat pools Serial number of IDs - changes whenever resusePoolIDs==true - ResPool must also invalidate it's PoolItems! */ + SerialNumberWatcher _watcherIDs; mutable ContainerT _store; mutable DefaultIntegral _storeDirty; mutable Id2ItemT _id2item; diff --git a/zypp/sat/Pool.cc b/zypp/sat/Pool.cc index 831c4af..890eb3f 100644 --- a/zypp/sat/Pool.cc +++ b/zypp/sat/Pool.cc @@ -55,6 +55,9 @@ namespace zypp const SerialNumber & Pool::serial() const { return myPool().serial(); } + const SerialNumber & Pool::serialIDs() const + { return myPool().serialIDs(); } + void Pool::prepare() const { return myPool().prepare(); } diff --git a/zypp/sat/Pool.h b/zypp/sat/Pool.h index 0bdddd5..160d9a7 100644 --- a/zypp/sat/Pool.h +++ b/zypp/sat/Pool.h @@ -64,6 +64,9 @@ namespace zypp /** Housekeeping data serial number. */ const SerialNumber & serial() const; + /** Serial number changing whenever resusePoolIDs==true was used. ResPool must also invalidate it's PoolItems! */ + const SerialNumber & serialIDs() const; + /** Update housekeeping data if necessary (e.g. whatprovides). */ void prepare() const; diff --git a/zypp/sat/detail/PoolImpl.cc b/zypp/sat/detail/PoolImpl.cc index a0af21e..a5d042d 100644 --- a/zypp/sat/detail/PoolImpl.cc +++ b/zypp/sat/detail/PoolImpl.cc @@ -313,7 +313,10 @@ namespace zypp // If the last repo is removed clear the pool to actually reuse all IDs. // NOTE: the explicit ::repo_free above asserts all solvables are memset(0)! if ( !_pool->urepos ) + { + _serialIDs.setDirty(); // Indicate resusePoolIDs - ResPool must also invalidate it's PoolItems ::pool_freeallrepos( _pool, /*resusePoolIDs*/true ); + } } int PoolImpl::_addSolv( CRepo * repo_r, FILE * file_r ) diff --git a/zypp/sat/detail/PoolImpl.h b/zypp/sat/detail/PoolImpl.h index 92a81a4..2552f05 100644 --- a/zypp/sat/detail/PoolImpl.h +++ b/zypp/sat/detail/PoolImpl.h @@ -66,6 +66,10 @@ namespace zypp const SerialNumber & serial() const { return _serial; } + /** Serial number changing whenever resusePoolIDs==true was used. ResPool must also invalidate it's PoolItems! */ + const SerialNumber & serialIDs() const + { return _serialIDs; } + /** Update housekeeping data (e.g. whatprovides). * \todo actually requires a watcher. */ @@ -311,8 +315,10 @@ namespace zypp private: /** sat-pool. */ CPool * _pool; - /** Serial number. */ + /** Serial number - changes with each Pool content change. */ SerialNumber _serial; + /** Serial number of IDs - changes whenever resusePoolIDs==true - ResPool must also invalidate it's PoolItems! */ + SerialNumber _serialIDs; /** Watch serial number. */ SerialNumberWatcher _watcher; /** Additional \ref RepoInfo. */ -- 2.7.4