Check local DB version before continuing transaction
Ensure we have a local DB version that is up to par with what we expect before we go down any road that might modify it. This should prevent stupid mistakes with the 3.5.X upgrade and people not running pacman-db-upgrade after the transaction as they will need to. Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
5ea4706f57
commit
f45369800a
9 changed files with 92 additions and 3 deletions
|
@ -56,6 +56,8 @@ int SYMEXPORT alpm_initialize(void)
|
||||||
}
|
}
|
||||||
if(_alpm_db_register_local() == NULL) {
|
if(_alpm_db_register_local() == NULL) {
|
||||||
/* error code should be set */
|
/* error code should be set */
|
||||||
|
_alpm_handle_free(handle);
|
||||||
|
handle = NULL;
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -497,6 +497,7 @@ enum _pmerrno_t {
|
||||||
PM_ERR_DB_NULL,
|
PM_ERR_DB_NULL,
|
||||||
PM_ERR_DB_NOT_NULL,
|
PM_ERR_DB_NOT_NULL,
|
||||||
PM_ERR_DB_NOT_FOUND,
|
PM_ERR_DB_NOT_FOUND,
|
||||||
|
PM_ERR_DB_VERSION,
|
||||||
PM_ERR_DB_WRITE,
|
PM_ERR_DB_WRITE,
|
||||||
PM_ERR_DB_REMOVE,
|
PM_ERR_DB_REMOVE,
|
||||||
/* Servers */
|
/* Servers */
|
||||||
|
|
|
@ -924,9 +924,62 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info)
|
||||||
return(ret);
|
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) {
|
||||||
|
/* 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 = {
|
struct db_operations local_db_ops = {
|
||||||
.populate = local_db_populate,
|
.populate = local_db_populate,
|
||||||
.unregister = _alpm_db_unregister,
|
.unregister = _alpm_db_unregister,
|
||||||
|
.version = local_db_version,
|
||||||
};
|
};
|
||||||
|
|
||||||
pmdb_t *_alpm_db_register_local(void)
|
pmdb_t *_alpm_db_register_local(void)
|
||||||
|
|
|
@ -443,9 +443,15 @@ error:
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sync_db_version(pmdb_t *db)
|
||||||
|
{
|
||||||
|
return(2);
|
||||||
|
}
|
||||||
|
|
||||||
struct db_operations sync_db_ops = {
|
struct db_operations sync_db_ops = {
|
||||||
.populate = sync_db_populate,
|
.populate = sync_db_populate,
|
||||||
.unregister = _alpm_db_unregister,
|
.unregister = _alpm_db_unregister,
|
||||||
|
.version = sync_db_version,
|
||||||
};
|
};
|
||||||
|
|
||||||
pmdb_t *_alpm_db_register_sync(const char *treename)
|
pmdb_t *_alpm_db_register_sync(const char *treename)
|
||||||
|
|
|
@ -405,6 +405,14 @@ const char *_alpm_db_path(pmdb_t *db)
|
||||||
return(db->_path);
|
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)
|
int _alpm_db_cmp(const void *d1, const void *d2)
|
||||||
{
|
{
|
||||||
pmdb_t *db1 = (pmdb_t *)d1;
|
pmdb_t *db1 = (pmdb_t *)d1;
|
||||||
|
|
|
@ -45,6 +45,7 @@ typedef enum _pmdbinfrq_t {
|
||||||
struct db_operations {
|
struct db_operations {
|
||||||
int (*populate) (pmdb_t *);
|
int (*populate) (pmdb_t *);
|
||||||
void (*unregister) (pmdb_t *);
|
void (*unregister) (pmdb_t *);
|
||||||
|
int (*version) (pmdb_t *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Database */
|
/* Database */
|
||||||
|
@ -65,14 +66,15 @@ struct __pmdb_t {
|
||||||
|
|
||||||
|
|
||||||
/* db.c, database general calls */
|
/* db.c, database general calls */
|
||||||
|
pmdb_t *_alpm_db_new(const char *treename, int is_local);
|
||||||
void _alpm_db_free(pmdb_t *db);
|
void _alpm_db_free(pmdb_t *db);
|
||||||
const char *_alpm_db_path(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);
|
int _alpm_db_cmp(const void *d1, const void *d2);
|
||||||
alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles);
|
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_local(void);
|
||||||
pmdb_t *_alpm_db_register_sync(const char *treename);
|
pmdb_t *_alpm_db_register_sync(const char *treename);
|
||||||
void _alpm_db_unregister(pmdb_t *db);
|
void _alpm_db_unregister(pmdb_t *db);
|
||||||
pmdb_t *_alpm_db_new(const char *treename, int is_local);
|
|
||||||
|
|
||||||
/* be_*.c, backend specific calls */
|
/* be_*.c, backend specific calls */
|
||||||
int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
|
int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
|
||||||
|
|
|
@ -77,6 +77,8 @@ const char SYMEXPORT *alpm_strerror(int err)
|
||||||
return _("database already registered");
|
return _("database already registered");
|
||||||
case PM_ERR_DB_NOT_FOUND:
|
case PM_ERR_DB_NOT_FOUND:
|
||||||
return _("could not find database");
|
return _("could not find database");
|
||||||
|
case PM_ERR_DB_VERSION:
|
||||||
|
return _("database is incorrect version");
|
||||||
case PM_ERR_DB_WRITE:
|
case PM_ERR_DB_WRITE:
|
||||||
return _("could not update database");
|
return _("could not update database");
|
||||||
case PM_ERR_DB_REMOVE:
|
case PM_ERR_DB_REMOVE:
|
||||||
|
|
|
@ -105,10 +105,12 @@ static int remove_lock(pmhandle_t *handle)
|
||||||
* @return 0 on success, -1 on error (pm_errno is set accordingly)
|
* @return 0 on success, -1 on error (pm_errno is set accordingly)
|
||||||
*/
|
*/
|
||||||
int SYMEXPORT alpm_trans_init(pmtransflag_t flags,
|
int SYMEXPORT alpm_trans_init(pmtransflag_t flags,
|
||||||
alpm_trans_cb_event event, alpm_trans_cb_conv conv,
|
alpm_trans_cb_event event, alpm_trans_cb_conv conv,
|
||||||
alpm_trans_cb_progress progress)
|
alpm_trans_cb_progress progress)
|
||||||
{
|
{
|
||||||
pmtrans_t *trans;
|
pmtrans_t *trans;
|
||||||
|
const int required_db_version = 2;
|
||||||
|
int db_version;
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
@ -124,6 +126,15 @@ int SYMEXPORT alpm_trans_init(pmtransflag_t flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check database version */
|
||||||
|
db_version = _alpm_db_version(handle->db_local);
|
||||||
|
if(db_version < required_db_version) {
|
||||||
|
_alpm_log(PM_LOG_ERROR,
|
||||||
|
_("%s database version is too old\n"), handle->db_local->treename);
|
||||||
|
remove_lock(handle);
|
||||||
|
RET_ERR(PM_ERR_DB_VERSION, -1);
|
||||||
|
}
|
||||||
|
|
||||||
trans = _alpm_trans_new();
|
trans = _alpm_trans_new();
|
||||||
if(trans == NULL) {
|
if(trans == NULL) {
|
||||||
RET_ERR(PM_ERR_MEMORY, -1);
|
RET_ERR(PM_ERR_MEMORY, -1);
|
||||||
|
|
|
@ -63,6 +63,10 @@ int trans_init(pmtransflag_t flags)
|
||||||
fprintf(stderr, _(" if you're sure a package manager is not already\n"
|
fprintf(stderr, _(" if you're sure a package manager is not already\n"
|
||||||
" running, you can remove %s\n"), alpm_option_get_lockfile());
|
" 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(-1);
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
|
|
Loading…
Add table
Reference in a new issue