[pacman-dev] [PATCH] WIP: check local DB version
Dan McGee
dan at archlinux.org
Sun Feb 27 14:55:13 EST 2011
---
Any feedback on this going in? One of the checklist items on my 3.5.0 release
list.
-Dan
lib/libalpm/alpm.c | 2 +
lib/libalpm/alpm.h | 1 +
lib/libalpm/be_local.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
lib/libalpm/be_sync.c | 6 +++++
lib/libalpm/db.c | 8 +++++++
lib/libalpm/db.h | 4 ++-
lib/libalpm/error.c | 2 +
lib/libalpm/trans.c | 15 +++++++++++-
src/pacman/util.c | 4 +++
9 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c
index 7c3bfc2..4f95832 100644
--- a/lib/libalpm/alpm.c
+++ b/lib/libalpm/alpm.c
@@ -56,6 +56,8 @@ int SYMEXPORT alpm_initialize(void)
}
if(_alpm_db_register_local() == NULL) {
/* error code should be set */
+ _alpm_handle_free(handle);
+ handle = NULL;
return(-1);
}
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index cf3a913..0f3b716 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -497,6 +497,7 @@ enum _pmerrno_t {
PM_ERR_DB_NULL,
PM_ERR_DB_NOT_NULL,
PM_ERR_DB_NOT_FOUND,
+ PM_ERR_DB_VERSION,
PM_ERR_DB_WRITE,
PM_ERR_DB_REMOVE,
/* Servers */
diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
index c1e86a6..a0d8b73 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -924,9 +924,63 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info)
return(ret);
}
+static int local_db_version(pmdb_t *db)
+{
+ struct dirent *ent = NULL;
+ const char *dbpath;
+ DIR *dbdir;
+ int version;
+
+ dbpath = _alpm_db_path(db);
+ if(dbpath == NULL) {
+ RET_ERR(PM_ERR_DB_OPEN, -1);
+ }
+ dbdir = opendir(dbpath);
+ if(dbdir == NULL) {
+ if(errno == ENOENT) {
+ /* database dir doesn't exist yet */
+ version = 2;
+ goto done;
+ } else {
+ RET_ERR(PM_ERR_DB_OPEN, -1);
+ }
+ }
+
+ while((ent = readdir(dbdir)) != NULL) {
+ const char *name = ent->d_name;
+ char path[PATH_MAX];
+
+ if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
+ continue;
+ }
+ if(!is_dir(dbpath, ent)) {
+ continue;
+ }
+
+ snprintf(path, PATH_MAX, "%s%s/depends", dbpath, name);
+ if(access(path, F_OK) == 0) {
+ printf("found %s\n", path);
+ /* we found a depends file- bail */
+ version = 1;
+ goto done;
+ }
+ }
+ /* we found no depends file after full scan */
+ version = 2;
+
+done:
+ if(dbdir) {
+ closedir(dbdir);
+ }
+
+ _alpm_log(PM_LOG_DEBUG, "local database version %d\n", version);
+ return(version);
+}
+
struct db_operations local_db_ops = {
.populate = local_db_populate,
.unregister = _alpm_db_unregister,
+ .version = local_db_version,
};
pmdb_t *_alpm_db_register_local(void)
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index 69f7663..2191494 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -443,9 +443,15 @@ error:
return(0);
}
+static int sync_db_version(pmdb_t *db)
+{
+ return(2);
+}
+
struct db_operations sync_db_ops = {
.populate = sync_db_populate,
.unregister = _alpm_db_unregister,
+ .version = sync_db_version,
};
pmdb_t *_alpm_db_register_sync(const char *treename)
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index 2a8db8e..fb64fae 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -405,6 +405,14 @@ const char *_alpm_db_path(pmdb_t *db)
return(db->_path);
}
+int _alpm_db_version(pmdb_t *db)
+{
+ if(!db) {
+ return(-1);
+ }
+ return(db->ops->version(db));
+}
+
int _alpm_db_cmp(const void *d1, const void *d2)
{
pmdb_t *db1 = (pmdb_t *)d1;
diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h
index a530a2e..75776d7 100644
--- a/lib/libalpm/db.h
+++ b/lib/libalpm/db.h
@@ -45,6 +45,7 @@ typedef enum _pmdbinfrq_t {
struct db_operations {
int (*populate) (pmdb_t *);
void (*unregister) (pmdb_t *);
+ int (*version) (pmdb_t *);
};
/* Database */
@@ -65,14 +66,15 @@ struct __pmdb_t {
/* db.c, database general calls */
+pmdb_t *_alpm_db_new(const char *treename, int is_local);
void _alpm_db_free(pmdb_t *db);
const char *_alpm_db_path(pmdb_t *db);
+int _alpm_db_version(pmdb_t *db);
int _alpm_db_cmp(const void *d1, const void *d2);
alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles);
pmdb_t *_alpm_db_register_local(void);
pmdb_t *_alpm_db_register_sync(const char *treename);
void _alpm_db_unregister(pmdb_t *db);
-pmdb_t *_alpm_db_new(const char *treename, int is_local);
/* be_*.c, backend specific calls */
int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c
index 2cc6685..21fbb48 100644
--- a/lib/libalpm/error.c
+++ b/lib/libalpm/error.c
@@ -77,6 +77,8 @@ const char SYMEXPORT *alpm_strerror(int err)
return _("database already registered");
case PM_ERR_DB_NOT_FOUND:
return _("could not find database");
+ case PM_ERR_DB_VERSION:
+ return _("database is incorrect version");
case PM_ERR_DB_WRITE:
return _("could not update database");
case PM_ERR_DB_REMOVE:
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index 9f61796..7a3ee83 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -59,10 +59,11 @@
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
int SYMEXPORT alpm_trans_init(pmtransflag_t flags,
- alpm_trans_cb_event event, alpm_trans_cb_conv conv,
- alpm_trans_cb_progress progress)
+ alpm_trans_cb_event event, alpm_trans_cb_conv conv,
+ alpm_trans_cb_progress progress)
{
pmtrans_t *trans;
+ const int localdb_version = 2;
ALPM_LOG_FUNC;
@@ -79,6 +80,16 @@ int SYMEXPORT alpm_trans_init(pmtransflag_t flags,
}
}
+ /* check database version */
+ if(_alpm_db_version(handle->db_local) < localdb_version) {
+ _alpm_log(PM_LOG_ERROR,
+ _("%s database version %d is too old, version %d required\n"),
+ handle->db_local->treename, _alpm_db_version(handle->db_local),
+ localdb_version);
+ _alpm_lckrm();
+ RET_ERR(PM_ERR_DB_VERSION, -1);
+ }
+
trans = _alpm_trans_new();
if(trans == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
diff --git a/src/pacman/util.c b/src/pacman/util.c
index c08ebb1..9d50afb 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -63,6 +63,10 @@ int trans_init(pmtransflag_t flags)
fprintf(stderr, _(" if you're sure a package manager is not already\n"
" running, you can remove %s\n"), alpm_option_get_lockfile());
}
+ else if(pm_errno == PM_ERR_DB_VERSION) {
+ fprintf(stderr, _(" try running pacman-db-upgrade\n"));
+ }
+
return(-1);
}
return(0);
--
1.7.4.1
More information about the pacman-dev
mailing list