Dominique Leuenberger
522b94c796
- 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
121 lines
3.6 KiB
Diff
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
|