# See './mkChangelog -h' for help.
#
SET(LIBZYPP_MAJOR "14")
-SET(LIBZYPP_COMPATMINOR "28")
-SET(LIBZYPP_MINOR "28")
+SET(LIBZYPP_COMPATMINOR "29")
+SET(LIBZYPP_MINOR "29")
SET(LIBZYPP_PATCH "0")
#
-# LAST RELEASED: 14.28.0 (28)
+# LAST RELEASED: 14.29.0 (29)
# (The number in parenthesis is LIBZYPP_COMPATMINOR)
#=======
-------------------------------------------------------------------
+Tue Sep 16 10:45:39 CEST 2014 - ma@suse.de
+
+- DiskUsageCounter: Support setting 'growonly' partition hint
+ (bnc#896176)
+- version 14.29.0 (29)
+
+-------------------------------------------------------------------
Fri Sep 5 12:46:57 CEST 2014 - ma@suse.de
- Make Repository::isUpdateRepo also check for being referenced
# to find the KeyRingTest receiver
INCLUDE_DIRECTORIES( ${LIBZYPP_SOURCE_DIR}/tests/zypp )
-ADD_TESTS(RepoVariables ExtendedMetadata PluginServices MirrorList)
+ADD_TESTS(RepoVariables ExtendedMetadata PluginServices MirrorList DUdata)
--- /dev/null
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <list>
+#include <string>
+
+#include <boost/test/auto_unit_test.hpp>
+
+#include "zypp/base/Logger.h"
+#include "zypp/base/Exception.h"
+#include "zypp/RepoManager.h"
+#include "zypp/ResPool.h"
+#include "zypp/sat/Pool.h"
+#include "zypp/PoolQuery.h"
+
+#include "KeyRingTestReceiver.h"
+#include "TestSetup.h"
+
+using boost::unit_test::test_case;
+
+using namespace std;
+using namespace zypp;
+using namespace zypp::repo;
+using namespace zypp::filesystem;
+
+#define TEST_DIR TESTS_SRC_DIR "/repo/susetags/data/dudata"
+
+PoolItem piFind( const std::string & name_r, const std::string & ver_r, bool installed_r = false )
+{
+ PoolQuery q;
+ q.addDependency( sat::SolvAttr::name, name_r, Rel::EQ, Edition(ver_r) );
+ q.setStatusFilterFlags( installed_r ? PoolQuery::INSTALLED_ONLY : PoolQuery::UNINSTALLED_ONLY );
+ if ( q.size() != 1 )
+ ZYPP_THROW(Exception(q.size()?"Ambiguous!":"Missing!"));
+ return PoolItem( *q.begin() );
+}
+
+typedef std::pair<ByteCount,ByteCount> ByteSet;
+namespace std
+{
+ inline std::ostream & operator<<( std::ostream & str, const ByteSet & obj )
+ { return str << "<" << obj.first << "," << obj.second << ">"; }
+}
+
+inline ByteSet mkByteSet( const DiskUsageCounter::MountPointSet & mps_r )
+{ return ByteSet( mps_r.begin()->commitDiff(), (++mps_r.begin())->commitDiff() ); }
+
+inline ByteSet mkByteSet( int grow_r , int norm_r )
+{ return ByteSet( ByteCount( grow_r, ByteCount::K ), ByteCount( norm_r, ByteCount::K ) ); }
+
+inline ByteSet getSize( const DiskUsageCounter & duc_r, const PoolItem & pi_r )
+{ return mkByteSet( duc_r.disk_usage( pi_r ) ); }
+
+inline ByteSet getSize( const DiskUsageCounter & duc_r, const ResPool & pool_r )
+{ return mkByteSet( duc_r.disk_usage( pool_r ) ); }
+
+inline void XLOG( const DiskUsageCounter & duc_r, const ResPool & pool_r )
+{
+ for( const auto & pi : pool_r )
+ {
+ USR << pi << endl;
+ }
+ WAR << duc_r.disk_usage( pool_r ) << endl;
+}
+
+BOOST_AUTO_TEST_CASE(dudata)
+{
+ //KeyRingTestReceiver rec;
+ // rec.answerAcceptUnknownKey(true);
+ //rec.answerAcceptUnsignedFile(true);
+ // rec.answerImportKey(true);
+
+ Pathname repodir( TEST_DIR );
+ TestSetup test( Arch_x86_64 );
+ test.loadTargetRepo( repodir/"system" );
+ test.loadRepo( repodir/"repo", "repo" );
+
+ ResPool pool( ResPool::instance() );
+ PoolItem ins( piFind( "dutest", "1.0", true ) );
+ PoolItem up1( piFind( "dutest", "1.0" ) );
+ PoolItem up2( piFind( "dutest", "2.0" ) );
+ PoolItem up3( piFind( "dutest", "3.0" ) );
+
+ DiskUsageCounter duc( { DiskUsageCounter::MountPoint( "/grow", DiskUsageCounter::MountPoint::Hint_growonly ),
+ DiskUsageCounter::MountPoint( "/norm" ) } );
+ //XLOG( duc, pool );
+
+ BOOST_CHECK_EQUAL( getSize( duc, ins ), mkByteSet( 5, 5 ) );
+ BOOST_CHECK_EQUAL( getSize( duc, up1 ), mkByteSet( 15, 15 ) );
+ BOOST_CHECK_EQUAL( getSize( duc, up2 ), mkByteSet( 45, 45 ) );
+ BOOST_CHECK_EQUAL( getSize( duc, up3 ), mkByteSet( 0, 0 ) );
+
+ // delete installed size 5 g n
+ ins.status().setTransact( true, ResStatus::USER );
+ BOOST_CHECK_EQUAL( getSize( duc, pool ), mkByteSet( 0, -5 ) );
+ ins.status().setTransact( false, ResStatus::USER );
+
+ // install known DU size 15 g n
+ up1.status().setTransact( true, ResStatus::USER );
+ BOOST_CHECK_EQUAL( getSize( duc, pool ), mkByteSet( 15, 15 ) ); // (multi)install (old stays)
+ ins.status().setTransact( true, ResStatus::USER );
+ BOOST_CHECK_EQUAL( getSize( duc, pool ), mkByteSet( 15, 10 ) ); // update (old goes)
+ ins.status().setTransact( false, ResStatus::USER );
+ up1.status().setTransact( false, ResStatus::USER );
+
+ // install unknown DU size 0/installed g n
+ up3.status().setTransact( true, ResStatus::USER );
+ BOOST_CHECK_EQUAL( getSize( duc, pool ), mkByteSet( 5, 0 ) ); // (multi)install (n could be 5 too, but satsolver does not know about multinstall)
+ ins.status().setTransact( true, ResStatus::USER );
+ BOOST_CHECK_EQUAL( getSize( duc, pool ), mkByteSet( 5, 0 ) ); // update (old goes)
+ ins.status().setTransact( false, ResStatus::USER );
+ up3.status().setTransact( false, ResStatus::USER );
+}
--- /dev/null
+META SHA1 b75eeb1b3d231ccb6322c91417050520f992949c packages
+META SHA1 cb96552f7a57eb21f3279310c1c339e6b22924d8 packages.DU
--- /dev/null
+SUSE Linux Products GmbH
+20070705102239
+1
--- /dev/null
+=Ver: 2.0
+##----------------------------------------
+=Pkg: dutest 1.0 1 x86_64
+##----------------------------------------
+=Pkg: dutest 2.0 1 x86_64
+##----------------------------------------
+=Pkg: dutest 3.0 1 x86_64
+##----------------------------------------
--- /dev/null
+=Ver: 2.0
+##----------------------------------------
+## / localK subK localF subF
+##----------------------------------------
+=Pkg: dutest 1.0 1 x86_64
++Dir:
+/norm 15 0 1 0
+/grow 15 0 1 0
+-Dir:
+##----------------------------------------
+=Pkg: dutest 2.0 1 x86_64
++Dir:
+/norm 45 0 1 0
+/grow 45 0 1 0
+-Dir:
+##----------------------------------------
--- /dev/null
+META SHA1 95a347a40f621834a870e10b8914c9442c2dc355 packages
+META SHA1 7d11955486b049be5f601b82acc18bfc73c22f39 packages.DU
--- /dev/null
+SUSE Linux Products GmbH
+20070705102239
+1
--- /dev/null
+=Ver: 2.0
+##----------------------------------------
+=Pkg: dutest 1.0 1 x86_64
+##----------------------------------------
--- /dev/null
+=Ver: 2.0
+##----------------------------------------
+## / localK subK localF subF
+##----------------------------------------
+=Pkg: dutest 1.0 1 x86_64
++Dir:
+/norm 5 0 1 0
+/grow 5 0 1 0
+-Dir:
+##----------------------------------------
sat::Pool satpool( sat::Pool::instance() );
// init libsolv result vector with mountpoints
- static const ::DUChanges _initdu = { 0, 0, 0 };
+ static const ::DUChanges _initdu = { 0, 0, 0, 0 };
std::vector< ::DUChanges> duchanges( result.size(), _initdu );
{
unsigned idx = 0;
for_( it, result.begin(), result.end() )
{
duchanges[idx].path = it->dir.c_str();
+ if ( it->growonly )
+ duchanges[idx].flags |= DUCHANGES_ONLYADD;
++idx;
}
}
-
// now calc...
::pool_calc_duchanges( satpool.get(),
const_cast<Bitmap &>(installedmap_r),
//
// Check whether mounted readonly
//
- bool ro = false;
+ MountPoint::HintFlags hints;
std::vector<std::string> flags;
str::split( words[3], std::back_inserter(flags), "," );
for ( unsigned i = 0; i < flags.size(); ++i ) {
if ( flags[i] == "ro" ) {
- ro = true;
+ hints |= MountPoint::Hint_readonly;
break;
}
}
- if ( ro ) {
+ if ( hints.testFlag( MountPoint::Hint_readonly ) ) {
DBG << "Filter ro mount point : " << l << std::endl;
continue;
}
}
ret.insert( DiskUsageCounter::MountPoint( mp, sb.f_bsize,
((long long)sb.f_blocks)*sb.f_bsize/1024,
- ((long long)(sb.f_blocks - sb.f_bfree))*sb.f_bsize/1024, 0LL, ro ) );
+ ((long long)(sb.f_blocks - sb.f_bfree))*sb.f_bsize/1024, 0LL, hints ) );
}
}
}
<< " ts: " << obj.totalSize()
<< " us: " << obj.usedSize()
<< " (+-: " << obj.commitDiff()
- << ")]";
+ << ")" << (obj.readonly?"r":"") << (obj.growonly?"g":"") << " ]";
return str;
}
+ std::ostream & operator<<( std::ostream & str, const DiskUsageCounter::MountPointSet & obj )
+ { return dumpRange( str, obj.begin(), obj.end() ); }
+
/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////
#include "zypp/ResPool.h"
#include "zypp/Bitmap.h"
+#include "zypp/base/Flags.h"
///////////////////////////////////////////////////////////////////
namespace zypp
///////////////////////////////////////////////////////////////////
struct MountPoint
{
+ friend std::ostream & operator<<( std::ostream & str, const MountPoint & obj );
std::string dir; ///< Directory name
long long block_size; ///< Block size of the filesystem in B (0 if you don't care)
long long total_size; ///< Total size of the filesystem in KiB (0 if you don't care)
long long used_size; ///< Used size of the filesystem in KiB (0 if you don't care)
mutable long long pkg_size; ///< Used size after installation in KiB (computed by \ref DiskUsageCoutner)
- bool readonly; ///< hint for readonly partitions
+ // hint bits:
+ bool readonly:1; ///< hint for readonly partitions
+ bool growonly:1; ///< hint for growonly partitions (e.g. snapshotting btrfs)
+
+
+ /** HinFlags for ctor */
+ enum Hint
+ {
+ NoHint = 0,
+ Hint_readonly = (1<<0), ///< readonly partitions
+ Hint_growonly = (1<<1), ///< growonly partitions (e.g. snapshotting btrfs)
+ };
+ ZYPP_DECLARE_FLAGS(HintFlags,Hint);
+
/** Ctor initialize directory and sizes */
- MountPoint( const std::string & d = "/", long long bs = 0LL, long long total = 0LL, long long used = 0LL, long long pkg = 0LL, bool ro=false)
- : dir(d), block_size(bs), total_size(total), used_size(used), pkg_size(pkg), readonly(ro)
+ MountPoint( const std::string & d = "/",
+ long long bs = 0LL, long long total = 0LL, long long used = 0LL, long long pkg = 0LL,
+ HintFlags hints = NoHint )
+ : dir(d)
+ , block_size(bs), total_size(total), used_size(used), pkg_size(pkg)
+ , readonly(hints.testFlag(Hint_readonly))
+ , growonly(hints.testFlag(Hint_growonly))
{}
- /** \overload to allow e.g. initiailzer lists
+ /** \overload <tt>const char *</tt> to allow e.g. initiailzer lists
* \code
* MountPointSet( { "/", "/usr", "/var" } )
* \endcode
*/
- MountPoint( const char * d, long long bs = 0LL, long long total = 0LL, long long used = 0LL, long long pkg = 0LL, bool ro=false)
- : dir(d?d:""), block_size(bs), total_size(total), used_size(used), pkg_size(pkg), readonly(ro)
+ MountPoint( const char * d, long long bs = 0LL, long long total = 0LL, long long used = 0LL, long long pkg = 0LL, HintFlags hints = NoHint )
+ : MountPoint( std::string(d?d:""), bs, total, used, pkg, hints )
+ {}
+
+ /** \overload just name and hints, all sizes 0 */
+ MountPoint( const std::string & d, HintFlags hints )
+ : MountPoint( d, 0LL, 0LL, 0LL, 0LL, hints )
+ {}
+ /** \overload just name and hints, all sizes 0 */
+ MountPoint( const char * d, HintFlags hints )
+ : MountPoint( std::string(d?d:""), hints )
+ {}
+ /** \overload just name and hints, all sizes 0 */
+ MountPoint( const std::string & d, Hint hint ) // !explicitly overload to prevent propagation enum value -> long long
+ : MountPoint( d, HintFlags(hint) )
+ {}
+ /** \overload just name and hints, all sizes 0 */
+ MountPoint( const char * d, Hint hint ) // !explicitly overload to prevent propagation enum value -> long long
+ : MountPoint( std::string(d?d:""), HintFlags(hint) )
+ {}
+
+
+ /** \deprecated Use HintFlags instead of a trailing 'bool ro' argument.
+ * \code
+ * - MountPoint( "/usr", ..., true ); // readonly
+ * + MountPoint( "/usr", ..., MountPoint::Hint_readonly );
+ * \endcode
+ */
+ ZYPP_DEPRECATED MountPoint( const std::string & d, long long bs, long long total, long long used, long long pkg, bool ro )
+ : MountPoint( d, bs, total, used, pkg, HintFlags(ro?Hint_readonly:NoHint) )
{}
+ /** \deprecated Use HintFlags instead of a trailing 'bool ro' argument.
+ * \code
+ * - MountPoint( "/usr", ..., true ); // readonly
+ * + MountPoint( "/usr", ..., MountPoint::Hint_readonly );
+ * \endcode
+ */
+ ZYPP_DEPRECATED MountPoint( const char * d, long long bs, long long total, long long used, long long pkg, bool ro )
+ : MountPoint( d, bs, total, used, pkg, HintFlags(ro?Hint_readonly:NoHint) )
+ {}
+
/** Sort by directory name */
bool operator<( const MountPoint & rhs ) const
};
///////////////////////////////////////////////////////////////////
+ ZYPP_DECLARE_OPERATORS_FOR_FLAGS(DiskUsageCounter::MountPoint::HintFlags);
+
/** \relates DiskUsageCounter::MountPoint Stream output */
std::ostream & operator<<( std::ostream & str, const DiskUsageCounter::MountPoint & obj );
+ /** \relates DiskUsageCounter::MountPointSet Stream output */
+ std::ostream & operator<<( std::ostream & str, const DiskUsageCounter::MountPointSet & obj );
+
+ /** \relates DiskUsageCounter Stream output */
+ inline std::ostream & operator<<( std::ostream & str, const DiskUsageCounter & obj )
+ { return str << obj.getMountPoints(); }
+
/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////