Move database 'version' check to registration time
This is another step toward doing both local database validation (ensuring we don't have depends files) and sync database validation (via signatures if present) when the database is registered. Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
db3b86e7f3
commit
1150d9e15a
8 changed files with 62 additions and 89 deletions
|
@ -70,7 +70,7 @@ pmhandle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath,
|
||||||
snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf);
|
snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf);
|
||||||
|
|
||||||
if(_alpm_db_register_local(myhandle) == NULL) {
|
if(_alpm_db_register_local(myhandle) == NULL) {
|
||||||
myerr = PM_ERR_DB_CREATE;
|
myerr = myhandle->pm_errno;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -314,6 +314,56 @@ static int is_dir(const char *path, struct dirent *entry)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int local_db_validate(pmdb_t *db)
|
||||||
|
{
|
||||||
|
struct dirent *ent = NULL;
|
||||||
|
const char *dbpath;
|
||||||
|
DIR *dbdir;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
dbpath = _alpm_db_path(db);
|
||||||
|
if(dbpath == NULL) {
|
||||||
|
RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);
|
||||||
|
}
|
||||||
|
dbdir = opendir(dbpath);
|
||||||
|
if(dbdir == NULL) {
|
||||||
|
if(errno == ENOENT) {
|
||||||
|
/* database dir doesn't exist yet */
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
RET_ERR(db->handle, 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 */
|
||||||
|
db->handle->pm_errno = PM_ERR_DB_VERSION;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* we found no depends file after full scan */
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if(dbdir) {
|
||||||
|
closedir(dbdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int local_db_populate(pmdb_t *db)
|
static int local_db_populate(pmdb_t *db)
|
||||||
{
|
{
|
||||||
size_t est_count;
|
size_t est_count;
|
||||||
|
@ -328,6 +378,7 @@ static int local_db_populate(pmdb_t *db)
|
||||||
/* pm_errno set in _alpm_db_path() */
|
/* pm_errno set in _alpm_db_path() */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbdir = opendir(dbpath);
|
dbdir = opendir(dbpath);
|
||||||
if(dbdir == NULL) {
|
if(dbdir == NULL) {
|
||||||
if(errno == ENOENT) {
|
if(errno == ENOENT) {
|
||||||
|
@ -867,62 +918,9 @@ 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(db->handle, 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(db->handle, 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(db->handle, 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(pmhandle_t *handle)
|
pmdb_t *_alpm_db_register_local(pmhandle_t *handle)
|
||||||
|
@ -933,11 +931,18 @@ pmdb_t *_alpm_db_register_local(pmhandle_t *handle)
|
||||||
|
|
||||||
db = _alpm_db_new("local", 1);
|
db = _alpm_db_new("local", 1);
|
||||||
if(db == NULL) {
|
if(db == NULL) {
|
||||||
|
handle->pm_errno = PM_ERR_DB_CREATE;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
db->ops = &local_db_ops;
|
db->ops = &local_db_ops;
|
||||||
db->handle = handle;
|
db->handle = handle;
|
||||||
|
|
||||||
|
if(local_db_validate(db)) {
|
||||||
|
/* pm_errno set in local_db_validate() */
|
||||||
|
_alpm_db_free(db);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
handle->db_local = db;
|
handle->db_local = db;
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
|
@ -559,15 +559,9 @@ error:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sync_db_version(pmdb_t UNUSED *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(pmhandle_t *handle, const char *treename,
|
pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename,
|
||||||
|
|
|
@ -370,14 +370,6 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *_alpm_db_sig_path(pmdb_t *db)
|
char *_alpm_db_sig_path(pmdb_t *db)
|
||||||
{
|
{
|
||||||
char *sigpath;
|
char *sigpath;
|
||||||
|
@ -522,11 +514,6 @@ pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db)
|
||||||
_alpm_db_load_pkgcache(db);
|
_alpm_db_load_pkgcache(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hmmm, still NULL ?*/
|
|
||||||
if(!db->pkgcache) {
|
|
||||||
_alpm_log(db->handle, PM_LOG_DEBUG, "warning: pkgcache is NULL for db '%s'\n", db->treename);
|
|
||||||
}
|
|
||||||
|
|
||||||
return db->pkgcache;
|
return db->pkgcache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ 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 */
|
||||||
|
|
|
@ -101,8 +101,6 @@ int SYMEXPORT alpm_trans_init(pmhandle_t *handle, pmtransflag_t flags,
|
||||||
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;
|
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
CHECK_HANDLE(handle, return -1);
|
CHECK_HANDLE(handle, return -1);
|
||||||
|
@ -122,16 +120,6 @@ int SYMEXPORT alpm_trans_init(pmhandle_t *handle, pmtransflag_t flags,
|
||||||
trans->cb_progress = progress;
|
trans->cb_progress = progress;
|
||||||
trans->state = STATE_INITIALIZED;
|
trans->state = STATE_INITIALIZED;
|
||||||
|
|
||||||
/* check database version */
|
|
||||||
db_version = _alpm_db_version(handle->db_local);
|
|
||||||
if(db_version < required_db_version) {
|
|
||||||
_alpm_log(handle, PM_LOG_ERROR,
|
|
||||||
_("%s database version is too old\n"), handle->db_local->treename);
|
|
||||||
remove_lock(handle);
|
|
||||||
_alpm_trans_free(trans);
|
|
||||||
RET_ERR(handle, PM_ERR_DB_VERSION, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
handle->trans = trans;
|
handle->trans = trans;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -449,6 +449,9 @@ static int setup_libalpm(void)
|
||||||
if(!handle) {
|
if(!handle) {
|
||||||
pm_printf(PM_LOG_ERROR, _("failed to initialize alpm library (%s)\n"),
|
pm_printf(PM_LOG_ERROR, _("failed to initialize alpm library (%s)\n"),
|
||||||
alpm_strerror(err));
|
alpm_strerror(err));
|
||||||
|
if(err == PM_ERR_DB_VERSION) {
|
||||||
|
fprintf(stderr, _(" try running pacman-db-upgrade\n"));
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
config->handle = handle;
|
config->handle = handle;
|
||||||
|
|
|
@ -68,9 +68,6 @@ int trans_init(pmtransflag_t flags)
|
||||||
" running, you can remove %s\n"),
|
" running, you can remove %s\n"),
|
||||||
alpm_option_get_lockfile(config->handle));
|
alpm_option_get_lockfile(config->handle));
|
||||||
}
|
}
|
||||||
else if(err == PM_ERR_DB_VERSION) {
|
|
||||||
fprintf(stderr, _(" try running pacman-db-upgrade\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue