[pacman-dev] [PATCH] Keep pkgcaches and dbs in sync (resubmit)
Nagy Gabor
ngaba at bibl.u-szeged.hu
Thu Mar 27 14:51:14 EDT 2008
From 6631713f5bd54953ba60555b07b8e3ec5e4cfb81 Mon Sep 17 00:00:00 2001
From: Nagy Gabor <ngaba at bibl.u-szeged.hu>
Date: Thu, 27 Mar 2008 19:48:49 +0100
Subject: [PATCH] Keep pkgcaches and dbs in sync
Ref.: http://www.archlinux.org/pipermail/pacman-dev/2007-September/009429.html
http://bugs.frugalware.org/index.php?do=details&task_id=2533
This patch is based on the work of Vajna Miklos (vmiklos) from pacman-g2.
It's time to fix this issue, since we have upcoming GUIs.
Briefly, the problem is that pkgcache can become outdated.
The trivial fix would be: reload pkgcache immediately after db lock.
We follow a more sophisticated approach to minimize overhead:
1. Each dbs on HDD have a "fingerprint": .lastupdate (patch extends this to localdb too)
2. After pkgcache load this fingerprint is recorded to the new fingerprint field of pmdb_t
3. New _alpm_db_refrech_pkgcache was introduced to reload cache, if it is outdated.
(Note: fingerprint treats transaction atomic.)
[Resubmit: move fingerprint creation to the begining of load_pkgcache]
Signed-off-by: Nagy Gabor <ngaba at bibl.u-szeged.hu>
---
lib/libalpm/cache.c | 17 +++++++++++++++++
lib/libalpm/cache.h | 1 +
lib/libalpm/db.h | 1 +
lib/libalpm/trans.c | 11 +++++++++++
4 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/lib/libalpm/cache.c b/lib/libalpm/cache.c
index 7fa2405..8b5c335 100644
--- a/lib/libalpm/cache.c
+++ b/lib/libalpm/cache.c
@@ -54,6 +54,7 @@ int _alpm_db_load_pkgcache(pmdb_t *db)
_alpm_log(PM_LOG_DEBUG, "loading package cache for repository '%s'\n",
db->treename);
+ db->fingerprint = _alpm_db_getlastupdate(db);
_alpm_db_rewind(db);
while((info = _alpm_db_scan(db, NULL)) != NULL) {
@@ -90,6 +91,22 @@ void _alpm_db_free_pkgcache(pmdb_t *db)
}
}
+/* Reload pkgcache if it is outdated
+ */
+int _alpm_db_refresh_pkgcache(pmdb_t *db) {
+ ALPM_LOG_FUNC;
+
+ if(db == NULL) {
+ return(-1);
+ }
+
+ if(!db->pkgcache || (db->fingerprint != _alpm_db_getlastupdate(db))) {
+ return(_alpm_db_load_pkgcache(db));
+ }
+
+ return(0);
+}
+
alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db)
{
ALPM_LOG_FUNC;
diff --git a/lib/libalpm/cache.h b/lib/libalpm/cache.h
index 915896e..4569b70 100644
--- a/lib/libalpm/cache.h
+++ b/lib/libalpm/cache.h
@@ -27,6 +27,7 @@
/* packages */
int _alpm_db_load_pkgcache(pmdb_t *db);
void _alpm_db_free_pkgcache(pmdb_t *db);
+int _alpm_db_refresh_pkgcache(pmdb_t *db);
int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg);
int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg);
alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db);
diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h
index 8c8c9bd..cd362d5 100644
--- a/lib/libalpm/db.h
+++ b/lib/libalpm/db.h
@@ -45,6 +45,7 @@ struct __pmdb_t {
alpm_list_t *pkgcache;
alpm_list_t *grpcache;
alpm_list_t *servers;
+ time_t fingerprint; /* of pkgcache */
};
/* db.c, database general calls */
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index 3edbbac..f425147 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -65,6 +65,7 @@ int SYMEXPORT alpm_trans_init(pmtranstype_t type, pmtransflag_t flags,
alpm_trans_cb_progress progress)
{
ALPM_LOG_FUNC;
+ alpm_list_t *i;
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
@@ -77,6 +78,12 @@ int SYMEXPORT alpm_trans_init(pmtranstype_t type, pmtransflag_t flags,
RET_ERR(PM_ERR_HANDLE_LOCK, -1);
}
+ /* ensure dbs and pkgcaches are in sync */
+ _alpm_db_refresh_pkgcache(handle->db_local);
+ for(i = handle->dbs_sync; i; i = i->next) {
+ _alpm_db_refresh_pkgcache(i->data);
+ }
+
handle->trans = _alpm_trans_new();
if(handle->trans == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
@@ -203,6 +210,10 @@ int SYMEXPORT alpm_trans_release()
_alpm_trans_free(trans);
handle->trans = NULL;
+ time_t fingerprint = time(NULL);
+ _alpm_db_setlastupdate(handle->db_local, fingerprint);
+ handle->db_local->fingerprint = fingerprint;
+
/* unlock db */
if(handle->lckfd != -1) {
close(handle->lckfd);
--
1.5.3.8
More information about the pacman-dev
mailing list