PackageKit/PackageKit-zypp-backend-improve-refresh-cache.patch
Dominique Leuenberger 522b94c796 Accepting request 537457 from home:JonathanKang:branches:GNOME:Factory
- Modify PackageKit-zypp-backend-improve-refresh-cache.patch:
  Prevent PK from being killed by unhandled exceptions
  (boo#1064380).

OBS-URL: https://build.opensuse.org/request/show/537457
OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/PackageKit?expand=0&rev=302
2017-10-30 08:14:12 +00:00

121 lines
3.6 KiB
Diff

Index: PackageKit-1.1.7/backends/zypp/pk-backend-zypp.cpp
===================================================================
--- PackageKit-1.1.7.orig/backends/zypp/pk-backend-zypp.cpp
+++ PackageKit-1.1.7/backends/zypp/pk-backend-zypp.cpp
@@ -986,20 +986,27 @@ static gboolean
zypp_refresh_meta_and_cache (RepoManager &manager, RepoInfo &repo, bool force = false)
{
try {
- if (manager.checkIfToRefreshMetadata (repo, repo.url()) //RepoManager::RefreshIfNeededIgnoreDelay)
- != RepoManager::REFRESH_NEEDED)
- return TRUE;
-
sat::Pool pool = sat::Pool::instance ();
- // Erase old solv file
- pool.reposErase (repo.alias ());
+
manager.refreshMetadata (repo, force ?
RepoManager::RefreshForced :
RepoManager::RefreshIfNeededIgnoreDelay);
manager.buildCache (repo, force ?
RepoManager::BuildForced :
RepoManager::BuildIfNeeded);
- manager.loadFromCache (repo);
+ try
+ {
+ manager.loadFromCache (repo);
+ }
+ catch (const Exception &exp)
+ {
+ // cachefile has old fomat (or is corrupted): rebuild it
+ manager.cleanCache (repo);
+ manager.buildCache (repo, force ?
+ RepoManager::BuildForced :
+ RepoManager::BuildIfNeeded);
+ manager.loadFromCache (repo);
+ }
return TRUE;
} catch (const AbortTransactionException &ex) {
return FALSE;
@@ -1580,9 +1587,30 @@ zypp_refresh_cache (PkBackendJob *job, Z
if (zypp == NULL)
return FALSE;
filesystem::Pathname pathname("/");
- // This call is needed to refresh system rpmdb status while refresh cache
- zypp->finishTarget ();
- zypp->initializeTarget (pathname);
+
+ bool poolIsClean = sat::Pool::instance ().reposEmpty ();
+ // Erase and reload all if pool is too holey (densyity [100: good | 0 bad])
+ // NOTE sat::Pool::capacity() > 2 is asserted in division
+ if (!poolIsClean &&
+ sat::Pool::instance ().solvablesSize () * 100 / sat::Pool::instance ().capacity () < 33)
+ {
+ sat::Pool::instance ().reposEraseAll ();
+ poolIsClean = true;
+ }
+
+ Target_Ptr target = zypp->getTarget ();
+ if (!target)
+ {
+ zypp->initializeTarget (pathname); // initial target
+ target = zypp->getTarget ();
+ }
+ else
+ {
+ // load rpmdb trusted keys into zypp keyring
+ target->rpmDb ().exportTrustedKeysInZyppKeyRing ();
+ }
+ // load installed packages to pool
+ target->load ();
pk_backend_job_set_status (job, PK_STATUS_ENUM_REFRESH_CACHE);
pk_backend_job_set_percentage (job, 0);
@@ -1600,6 +1628,22 @@ zypp_refresh_cache (PkBackendJob *job, Z
return FALSE;
}
+ if (!poolIsClean)
+ {
+ std::vector<std::string> aliasesToRemove;
+
+ for (const Repository &poolrepo : zypp->pool ().knownRepositories ())
+ {
+ if (!(poolrepo.isSystemRepo () || manager.hasRepo (poolrepo.alias ())))
+ aliasesToRemove.push_back (poolrepo.alias ());
+ }
+
+ for (const std::string &aliasToRemove : aliasesToRemove)
+ {
+ sat::Pool::instance ().reposErase (aliasToRemove);
+ }
+ }
+
int i = 1;
int num_of_repos = repos.size ();
gchar *repo_messages = NULL;
@@ -1614,7 +1658,11 @@ zypp_refresh_cache (PkBackendJob *job, Z
// skip disabled repos
if (repo.enabled () == false)
+ {
+ if (!poolIsClean)
+ sat::Pool::instance ().reposErase (repo.alias ());
continue;
+ }
// do as zypper does
if (!force && !repo.autorefresh())
@@ -1623,7 +1671,11 @@ zypp_refresh_cache (PkBackendJob *job, Z
// skip changeable media (DVDs and CDs). Without doing this,
// the disc would be required to be physically present.
if (repo.baseUrlsBegin ()->schemeIsVolatile())
+ {
+ if (!poolIsClean)
+ sat::Pool::instance ().reposErase (repo.alias ());
continue;
+ }
try {
// Refreshing metadata