From 2bafd166d900983d4c1974778f9ae5f76fa0fde3 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Mon, 2 Sep 2019 16:11:50 +0900 Subject: [PATCH] Imported Upstream version 16.4.1 --- VERSION.cmake | 4 +- package/libzypp.changes | 7 ++ zypp/Capability.cc | 2 - zypp/Package.cc | 5 + zypp/Product.cc | 2 +- zypp/media/MediaCurl.cc | 207 ++++++++++++++++++------------------ zypp/media/MediaCurl.h | 7 +- zypp/media/MediaMultiCurl.cc | 23 ++-- zypp/parser/yum/RepomdFileReader.cc | 4 +- zypp/repo/SrcPackageProvider.cc | 70 +----------- 10 files changed, 140 insertions(+), 191 deletions(-) diff --git a/VERSION.cmake b/VERSION.cmake index 7164303..04dabd5 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -61,8 +61,8 @@ SET(LIBZYPP_MAJOR "16") SET(LIBZYPP_COMPATMINOR "0") SET(LIBZYPP_MINOR "4") -SET(LIBZYPP_PATCH "0") +SET(LIBZYPP_PATCH "1") # -# LAST RELEASED: 16.4.0 (0) +# LAST RELEASED: 16.4.1 (0) # (The number in parenthesis is LIBZYPP_COMPATMINOR) #======= diff --git a/package/libzypp.changes b/package/libzypp.changes index 499e256..bac99fa 100644 --- a/package/libzypp.changes +++ b/package/libzypp.changes @@ -1,4 +1,11 @@ ------------------------------------------------------------------- +Fri Feb 3 13:40:04 CET 2017 - ma@suse.de + +- MediaMultiCurl: Trigger aliveCallback when downloading metalink + files (bsc#1021291) +- version 16.4.1 (0) + +------------------------------------------------------------------- Thu Jan 26 13:03:37 CET 2017 - ma@suse.de - Add API for updating the AutoInstalled db diff --git a/zypp/Capability.cc b/zypp/Capability.cc index 3147c8a..aa4b247 100644 --- a/zypp/Capability.cc +++ b/zypp/Capability.cc @@ -313,8 +313,6 @@ namespace zypp CapMatch Capability::_doMatch( sat::detail::IdType lhs, sat::detail::IdType rhs ) { -#warning MIGRATE TO SAT -#warning TESTCASE if ( lhs == rhs ) return CapMatch::yes; diff --git a/zypp/Package.cc b/zypp/Package.cc index 5916f4b..ea2db9c 100644 --- a/zypp/Package.cc +++ b/zypp/Package.cc @@ -92,6 +92,11 @@ namespace zypp case VendorSupportUnsupported: case VendorSupportACC: return true; + + case VendorSupportLevel1: + case VendorSupportLevel2: + case VendorSupportLevel3: + break; // intentionally no default: } return false; } diff --git a/zypp/Product.cc b/zypp/Product.cc index d5ef49b..80ae25e 100644 --- a/zypp/Product.cc +++ b/zypp/Product.cc @@ -215,7 +215,7 @@ namespace zypp { return Date( lookupNumAttribute( sat::SolvAttr::productEndOfLife ) );} bool Product::hasEndOfLife() const - { return( lookupNumAttribute( sat::SolvAttr::productEndOfLife, -1 ) != -1 ); } + { return( lookupNumAttribute( sat::SolvAttr::productEndOfLife, -1 ) != (unsigned long long)(-1) ); } bool Product::hasEndOfLife( Date & value ) const { diff --git a/zypp/media/MediaCurl.cc b/zypp/media/MediaCurl.cc index 4859bcf..121cf0f 100644 --- a/zypp/media/MediaCurl.cc +++ b/zypp/media/MediaCurl.cc @@ -156,25 +156,91 @@ namespace zypp { namespace { struct ProgressData { - ProgressData(CURL *_curl, const long _timeout, const zypp::Url &_url = zypp::Url(), - callback::SendReport *_report=NULL) - : curl(_curl) - , timeout(_timeout) - , reached(false) - , report(_report) - , drate_period(-1) - , dload_period(0) - , secs(0) - , drate_avg(-1) - , ltime( time(NULL)) - , dload( 0) - , uload( 0) - , url(_url) + ProgressData( CURL *_curl, time_t _timeout = 0, const Url & _url = Url(), + callback::SendReport *_report = nullptr ) + : curl( _curl ) + , url( _url ) + , timeout( _timeout ) + , reached( false ) + , report( _report ) {} - CURL *curl; - long timeout; - bool reached; + + CURL *curl; + Url url; + time_t timeout; + bool reached; callback::SendReport *report; + + time_t _timeStart = 0; ///< Start total stats + time_t _timeLast = 0; ///< Start last period(~1sec) + time_t _timeRcv = 0; ///< Start of no-data timeout + time_t _timeNow = 0; ///< Now + + double _dnlTotal = 0.0; ///< Bytes to download or 0 if unknown + double _dnlLast = 0.0; ///< Bytes downloaded at period start + double _dnlNow = 0.0; ///< Bytes downloaded now + + int _dnlPercent= 0; ///< Percent completed or 0 if _dnlTotal is unknown + + double _drateTotal= 0.0; ///< Download rate so far + double _drateLast = 0.0; ///< Download rate in last period + + void updateStats( double dltotal = 0.0, double dlnow = 0.0 ) + { + time_t now = _timeNow = time(0); + + // If called without args (0.0), recompute based on the last values seen + if ( dltotal && dltotal != _dnlTotal ) + _dnlTotal = dltotal; + + if ( dlnow && dlnow != _dnlNow ) + { + _timeRcv = now; + _dnlNow = dlnow; + } + else if ( !_dnlNow && !_dnlTotal ) + { + // Start time counting as soon as first data arrives. + // Skip the connection / redirection time at begin. + return; + } + + // init or reset if time jumps back + if ( !_timeStart || _timeStart > now ) + _timeStart = _timeLast = _timeRcv = now; + + // timeout condition + if ( timeout ) + reached = ( (now - _timeRcv) > timeout ); + + // percentage: + if ( _dnlTotal ) + _dnlPercent = int(_dnlNow * 100 / _dnlTotal); + + // download rates: + _drateTotal = _dnlNow / std::max( int(now - _timeStart), 1 ); + + if ( _timeLast < now ) + { + _drateLast = (_dnlNow - _dnlLast) / int(now - _timeLast); + // start new period + _timeLast = now; + _dnlLast = _dnlNow; + } + else if ( _timeStart == _timeLast ) + _drateLast = _drateTotal; + } + + int reportProgress() const + { + if ( reached ) + return 1; // no-data timeout + if ( report && !(*report)->progress( _dnlPercent, url, _drateTotal, _drateLast ) ) + return 1; // user requested abort + return 0; + } + + // download rate of the last period (cca 1 sec) double drate_period; // bytes downloaded at the start of the last period @@ -189,7 +255,6 @@ namespace zypp { double dload; // bytes uploaded at the moment the progress was last reported double uload; - zypp::Url url; }; /////////////////////////////////////////////////////////////////// @@ -1531,97 +1596,33 @@ void MediaCurl::getDirInfo( filesystem::DirContent & retlist, } /////////////////////////////////////////////////////////////////// +// +int MediaCurl::aliveCallback( void *clientp, double /*dltotal*/, double dlnow, double /*ultotal*/, double /*ulnow*/ ) +{ + ProgressData *pdata = reinterpret_cast( clientp ); + if( pdata ) + { + // Do not propagate dltotal in alive callbacks. MultiCurl uses this to + // prevent a percentage raise while downloading a metalink file. Download + // activity however is indicated by propagating the download rate (via dlnow). + pdata->updateStats( 0.0, dlnow ); + return pdata->reportProgress(); + } + return 0; +} -int MediaCurl::progressCallback( void *clientp, - double dltotal, double dlnow, - double ultotal, double ulnow) +int MediaCurl::progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow ) { - ProgressData *pdata = reinterpret_cast(clientp); - if( pdata) + ProgressData *pdata = reinterpret_cast( clientp ); + if( pdata ) { // work around curl bug that gives us old data long httpReturnCode = 0; - if (curl_easy_getinfo(pdata->curl, CURLINFO_RESPONSE_CODE, &httpReturnCode) != CURLE_OK || httpReturnCode == 0) - return 0; - - time_t now = time(NULL); - if( now > 0) - { - // reset time of last change in case initial time() - // failed or the time was adjusted (goes backward) - if( pdata->ltime <= 0 || pdata->ltime > now) - { - pdata->ltime = now; - } - - // start time counting as soon as first data arrives - // (skip the connection / redirection time at begin) - time_t dif = 0; - if (dlnow > 0 || ulnow > 0) - { - dif = (now - pdata->ltime); - dif = dif > 0 ? dif : 0; - - pdata->secs += dif; - } - - // update the drate_avg and drate_period only after a second has passed - // (this callback is called much more often than a second) - // otherwise the values would be far from accurate when measuring - // the time in seconds - //! \todo more accurate download rate computationn, e.g. compute average value from last 5 seconds, or work with milliseconds instead of seconds - - if ( pdata->secs > 1 && (dif > 0 || dlnow == dltotal )) - pdata->drate_avg = (dlnow / pdata->secs); - - if ( dif > 0 ) - { - pdata->drate_period = ((dlnow - pdata->dload_period) / dif); - pdata->dload_period = dlnow; - } - } - - // send progress report first, abort transfer if requested - if( pdata->report) - { - if (!(*(pdata->report))->progress(int( dltotal ? dlnow * 100 / dltotal : 0 ), - pdata->url, - pdata->drate_avg, - pdata->drate_period)) - { - return 1; // abort transfer - } - } - - // check if we there is a timeout set - if( pdata->timeout > 0) - { - if( now > 0) - { - bool progress = false; - - // update download data if changed, mark progress - if( dlnow != pdata->dload) - { - progress = true; - pdata->dload = dlnow; - pdata->ltime = now; - } - // update upload data if changed, mark progress - if( ulnow != pdata->uload) - { - progress = true; - pdata->uload = ulnow; - pdata->ltime = now; - } + if ( curl_easy_getinfo( pdata->curl, CURLINFO_RESPONSE_CODE, &httpReturnCode ) != CURLE_OK || httpReturnCode == 0 ) + return aliveCallback( clientp, dltotal, dlnow, ultotal, ulnow ); - if( !progress && (now >= (pdata->ltime + pdata->timeout))) - { - pdata->reached = true; - return 1; // aborts transfer - } - } - } + pdata->updateStats( dltotal, dlnow ); + return pdata->reportProgress(); } return 0; } diff --git a/zypp/media/MediaCurl.h b/zypp/media/MediaCurl.h index c78c7d9..d7b6100 100644 --- a/zypp/media/MediaCurl.h +++ b/zypp/media/MediaCurl.h @@ -113,9 +113,10 @@ class MediaCurl : public MediaHandler }; protected: - - static int progressCallback( void *clientp, double dltotal, double dlnow, - double ultotal, double ulnow ); +// /** Callback sending just an alive trigger to the UI, without stats (e.g. during metalink download). */ + static int aliveCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow ); + /** Callback reporting download progress. */ + static int progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow ); static CURL *progressCallback_getcurl( void *clientp ); /** * check the url is supported by the curl library diff --git a/zypp/media/MediaMultiCurl.cc b/zypp/media/MediaMultiCurl.cc index 8b2c83b..9f9a65d 100644 --- a/zypp/media/MediaMultiCurl.cc +++ b/zypp/media/MediaMultiCurl.cc @@ -1236,16 +1236,19 @@ static bool looks_like_metalink(const Pathname & file) } // here we try to suppress all progress coming from a metalink download +// bsc#1021291: Nevertheless send alive trigger (without stats), so UIs +// are able to abort a hanging metalink download via callback response. int MediaMultiCurl::progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { CURL *_curl = MediaCurl::progressCallback_getcurl(clientp); if (!_curl) - return 0; + return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow); + // work around curl bug that gives us old data long httpReturnCode = 0; if (curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &httpReturnCode ) != CURLE_OK || httpReturnCode == 0) - return 0; + return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow); char *ptr = NULL; bool ismetalink = false; @@ -1257,25 +1260,23 @@ int MediaMultiCurl::progressCallback( void *clientp, double dltotal, double dlno } if (!ismetalink && dlnow < 256) { - // can't tell yet, suppress callback - return 0; + // can't tell yet, ... + return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow); } if (!ismetalink) { FILE *fp = 0; - if (curl_easy_getinfo(_curl, CURLINFO_PRIVATE, &fp) != CURLE_OK) - return 0; - if (!fp) - return 0; /* hmm */ + if (curl_easy_getinfo(_curl, CURLINFO_PRIVATE, &fp) != CURLE_OK || !fp) + return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow); fflush(fp); ismetalink = looks_like_metalink_fd(fileno(fp)); DBG << "looks_like_metalink_fd: " << ismetalink << endl; } if (ismetalink) { - // we're downloading the metalink file. no progress please. - curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, 1L); - return 0; + // we're downloading the metalink file. Just trigger aliveCallbacks + curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, &MediaCurl::aliveCallback); + return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow); } curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, &MediaCurl::progressCallback); return MediaCurl::progressCallback(clientp, dltotal, dlnow, ultotal, ulnow); diff --git a/zypp/parser/yum/RepomdFileReader.cc b/zypp/parser/yum/RepomdFileReader.cc index 99908b0..55954b9 100644 --- a/zypp/parser/yum/RepomdFileReader.cc +++ b/zypp/parser/yum/RepomdFileReader.cc @@ -62,9 +62,9 @@ namespace zypp public: /** Ctro taking a ProcessResource2 callback */ Impl(const Pathname &repomd_file, const ProcessResource2 & callback ) - : _tag( tag_NONE ) + : _callback( callback ) + , _tag( tag_NONE ) , _type( ResourceType::NONE_e ) - , _callback( callback ) { Reader reader( repomd_file ); MIL << "Reading " << repomd_file << endl; diff --git a/zypp/repo/SrcPackageProvider.cc b/zypp/repo/SrcPackageProvider.cc index db977e9..6910083 100644 --- a/zypp/repo/SrcPackageProvider.cc +++ b/zypp/repo/SrcPackageProvider.cc @@ -21,86 +21,22 @@ using std::endl; /////////////////////////////////////////////////////////////////// namespace zypp -{ ///////////////////////////////////////////////////////////////// +{ /////////////////////////////////////////////////////////////////// namespace repo - { ///////////////////////////////////////////////////////////////// + { - /////////////////////////////////////////////////////////////////// - namespace - { ///////////////////////////////////////////////////////////////// - - typedef std::string (SrcPackage::*inlined)() const; - typedef OnMediaLocation (SrcPackage::*location)() const; - - /** Provide a SrcPackage in a local file. */ - ManagedFile doProvideSrcPackage( repo::RepoMediaAccess & access_r, - const SrcPackage & script_r, - inlined inlined_r, location location_r ) - { - ManagedFile ret; - - // 1st try inlined - std::string inlined( (script_r.*inlined_r)() ); - if ( ! inlined.empty() ) - { - // Take care the TmpFile goes out of scope BEFORE the - // ofstream opens the file again. - ret = ManagedFile( filesystem::TmpFile( filesystem::TmpPath::defaultLocation(), - "zypp-script-"+script_r.name() ), - filesystem::unlink ); - std::ofstream str( ret.value().c_str() ); - str << inlined << endl; - } - else - { - // otherwise try download - OnMediaLocation location( (script_r.*location_r)() ); - if ( ! location.filename().empty() ) - { - ret = access_r.provideFile( script_r.repoInfo(), location ); - } - else - { - // no script - return ManagedFile(); - } - } - - // HERE: got the script - filesystem::chmod( ret, 0700 ); - return ret; - } - - ///////////////////////////////////////////////////////////////// - } // namespace - /////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////// - // - // METHOD NAME : SrcPackageProvider::SrcPackageProvider - // METHOD TYPE : Ctor - // SrcPackageProvider::SrcPackageProvider( repo::RepoMediaAccess & access_r ) : _access( access_r ) {} - /////////////////////////////////////////////////////////////////// - // - // METHOD NAME : SrcPackageProvider::~SrcPackageProvider - // METHOD TYPE : Dtor - // SrcPackageProvider::~SrcPackageProvider() {} ManagedFile SrcPackageProvider::provideSrcPackage( const SrcPackage_constPtr & srcPackage_r ) const - { - return _access.provideFile( srcPackage_r->repoInfo(), srcPackage_r->location() ); - } + { return _access.provideFile( srcPackage_r->repoInfo(), srcPackage_r->location() ); } - ///////////////////////////////////////////////////////////////// } // namespace repo /////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////// } // namespace zypp /////////////////////////////////////////////////////////////////// -- 2.7.4