Add a 'valid' flag to the database object

Start by converting all of our flags to a 'status' bitmask (pkgcache
status, grpcache status). Add a new 'valid' flag as well. This will let
us keep track if the database itself has been marked valid in whatever
fashion.

For local databases at the moment we ensure there are no depends files;
for sync databases we ensure the PGP signature is valid if
required/requested. The loading of the pkgcache is prohibited if the
database is invalid.

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2011-06-07 20:42:15 -05:00
parent 1150d9e15a
commit 79e98316ea
9 changed files with 65 additions and 31 deletions

View file

@ -1002,6 +1002,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_INVALID,
PM_ERR_DB_VERSION, PM_ERR_DB_VERSION,
PM_ERR_DB_WRITE, PM_ERR_DB_WRITE,
PM_ERR_DB_REMOVE, PM_ERR_DB_REMOVE,

View file

@ -321,6 +321,10 @@ static int local_db_validate(pmdb_t *db)
DIR *dbdir; DIR *dbdir;
int ret = -1; int ret = -1;
if(db->status & DB_STATUS_VALID) {
return 0;
}
dbpath = _alpm_db_path(db); dbpath = _alpm_db_path(db);
if(dbpath == NULL) { if(dbpath == NULL) {
RET_ERR(db->handle, PM_ERR_DB_OPEN, -1); RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);
@ -329,6 +333,7 @@ static int local_db_validate(pmdb_t *db)
if(dbdir == NULL) { if(dbdir == NULL) {
if(errno == ENOENT) { if(errno == ENOENT) {
/* database dir doesn't exist yet */ /* database dir doesn't exist yet */
db->status |= DB_STATUS_VALID;
return 0; return 0;
} else { } else {
RET_ERR(db->handle, PM_ERR_DB_OPEN, -1); RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);
@ -354,6 +359,7 @@ static int local_db_validate(pmdb_t *db)
} }
} }
/* we found no depends file after full scan */ /* we found no depends file after full scan */
db->status |= DB_STATUS_VALID;
ret = 0; ret = 0;
done: done:

View file

@ -69,9 +69,15 @@ static char *get_sync_dir(pmhandle_t *handle)
static int sync_db_validate(pmdb_t *db) static int sync_db_validate(pmdb_t *db)
{ {
pgp_verify_t check_sig;
if(db->status & DB_STATUS_VALID) {
return 0;
}
/* this takes into account the default verification level if UNKNOWN /* this takes into account the default verification level if UNKNOWN
* was assigned to this db */ * was assigned to this db */
pgp_verify_t check_sig = _alpm_db_get_sigverify_level(db); check_sig = _alpm_db_get_sigverify_level(db);
if(check_sig != PM_PGP_VERIFY_NEVER) { if(check_sig != PM_PGP_VERIFY_NEVER) {
int ret; int ret;
@ -83,6 +89,7 @@ static int sync_db_validate(pmdb_t *db)
/* we can skip any validation if the database doesn't exist */ /* we can skip any validation if the database doesn't exist */
if(access(dbpath, R_OK) != 0 && errno == ENOENT) { if(access(dbpath, R_OK) != 0 && errno == ENOENT) {
goto valid;
return 0; return 0;
} }
@ -95,6 +102,8 @@ static int sync_db_validate(pmdb_t *db)
} }
} }
valid:
db->status |= DB_STATUS_VALID;
return 0; return 0;
} }
@ -215,6 +224,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
/* Cache needs to be rebuilt */ /* Cache needs to be rebuilt */
_alpm_db_free_pkgcache(db); _alpm_db_free_pkgcache(db);
db->status &= ~DB_STATUS_VALID;
if(sync_db_validate(db)) { if(sync_db_validate(db)) {
/* pm_errno should be set */ /* pm_errno should be set */
ret = -1; ret = -1;

View file

@ -468,11 +468,8 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
/* Returns a new package cache from db. /* Returns a new package cache from db.
* It frees the cache if it already exists. * It frees the cache if it already exists.
*/ */
int _alpm_db_load_pkgcache(pmdb_t *db) static int load_pkgcache(pmdb_t *db)
{ {
if(db == NULL) {
return -1;
}
_alpm_db_free_pkgcache(db); _alpm_db_free_pkgcache(db);
_alpm_log(db->handle, PM_LOG_DEBUG, "loading package cache for repository '%s'\n", _alpm_log(db->handle, PM_LOG_DEBUG, "loading package cache for repository '%s'\n",
@ -483,23 +480,23 @@ int _alpm_db_load_pkgcache(pmdb_t *db)
return -1; return -1;
} }
db->pkgcache_loaded = 1; db->status |= DB_STATUS_PKGCACHE;
return 0; return 0;
} }
void _alpm_db_free_pkgcache(pmdb_t *db) void _alpm_db_free_pkgcache(pmdb_t *db)
{ {
if(db == NULL || !db->pkgcache_loaded) { if(db == NULL || !(db->status & DB_STATUS_PKGCACHE)) {
return; return;
} }
_alpm_log(db->handle, PM_LOG_DEBUG, "freeing package cache for repository '%s'\n", _alpm_log(db->handle, PM_LOG_DEBUG,
db->treename); "freeing package cache for repository '%s'\n", db->treename);
alpm_list_free_inner(_alpm_db_get_pkgcache(db), alpm_list_free_inner(_alpm_db_get_pkgcache(db),
(alpm_list_fn_free)_alpm_pkg_free); (alpm_list_fn_free)_alpm_pkg_free);
_alpm_pkghash_free(db->pkgcache); _alpm_pkghash_free(db->pkgcache);
db->pkgcache_loaded = 0; db->status &= ~DB_STATUS_PKGCACHE;
_alpm_db_free_grpcache(db); _alpm_db_free_grpcache(db);
} }
@ -510,8 +507,12 @@ pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db)
return NULL; return NULL;
} }
if(!db->pkgcache_loaded) { if(!(db->status & DB_STATUS_VALID)) {
_alpm_db_load_pkgcache(db); RET_ERR(db->handle, PM_ERR_DB_INVALID, NULL);
}
if(!(db->status & DB_STATUS_PKGCACHE)) {
load_pkgcache(db);
} }
return db->pkgcache; return db->pkgcache;
@ -533,7 +534,7 @@ int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg)
{ {
pmpkg_t *newpkg; pmpkg_t *newpkg;
if(db == NULL || !db->pkgcache_loaded || pkg == NULL) { if(db == NULL || pkg == NULL || !(db->status & DB_STATUS_PKGCACHE)) {
return -1; return -1;
} }
@ -555,7 +556,7 @@ int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg)
{ {
pmpkg_t *data = NULL; pmpkg_t *data = NULL;
if(db == NULL || !db->pkgcache_loaded || pkg == NULL) { if(db == NULL || pkg == NULL || !(db->status & DB_STATUS_PKGCACHE)) {
return -1; return -1;
} }
@ -585,8 +586,6 @@ pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target)
pmpkghash_t *pkgcache = _alpm_db_get_pkgcache_hash(db); pmpkghash_t *pkgcache = _alpm_db_get_pkgcache_hash(db);
if(!pkgcache) { if(!pkgcache) {
_alpm_log(db->handle, PM_LOG_DEBUG, "warning: failed to get '%s' from NULL pkgcache\n",
target);
return NULL; return NULL;
} }
@ -595,7 +594,7 @@ pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target)
/* Returns a new group cache from db. /* Returns a new group cache from db.
*/ */
int _alpm_db_load_grpcache(pmdb_t *db) static int load_grpcache(pmdb_t *db)
{ {
alpm_list_t *lp; alpm_list_t *lp;
@ -641,7 +640,7 @@ int _alpm_db_load_grpcache(pmdb_t *db)
} }
} }
db->grpcache_loaded = 1; db->status |= DB_STATUS_GRPCACHE;
return 0; return 0;
} }
@ -649,19 +648,19 @@ void _alpm_db_free_grpcache(pmdb_t *db)
{ {
alpm_list_t *lg; alpm_list_t *lg;
if(db == NULL || !db->grpcache_loaded) { if(db == NULL || !(db->status & DB_STATUS_GRPCACHE)) {
return; return;
} }
_alpm_log(db->handle, PM_LOG_DEBUG, "freeing group cache for repository '%s'\n", _alpm_log(db->handle, PM_LOG_DEBUG,
db->treename); "freeing group cache for repository '%s'\n", db->treename);
for(lg = db->grpcache; lg; lg = lg->next) { for(lg = db->grpcache; lg; lg = lg->next) {
_alpm_grp_free(lg->data); _alpm_grp_free(lg->data);
lg->data = NULL; lg->data = NULL;
} }
FREELIST(db->grpcache); FREELIST(db->grpcache);
db->grpcache_loaded = 0; db->status &= ~DB_STATUS_GRPCACHE;
} }
alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db) alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db)
@ -670,8 +669,12 @@ alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db)
return NULL; return NULL;
} }
if(!db->grpcache_loaded) { if(!(db->status & DB_STATUS_VALID)) {
_alpm_db_load_grpcache(db); RET_ERR(db->handle, PM_ERR_DB_INVALID, NULL);
}
if(!(db->status & DB_STATUS_GRPCACHE)) {
load_grpcache(db);
} }
return db->grpcache; return db->grpcache;

View file

@ -43,6 +43,13 @@ typedef enum _pmdbinfrq_t {
INFRQ_ALL = 0x1F INFRQ_ALL = 0x1F
} pmdbinfrq_t; } pmdbinfrq_t;
/** Database status. Bitflags. */
enum _pmdbstatus_t {
DB_STATUS_VALID = (1 << 0),
DB_STATUS_PKGCACHE = (1 << 1),
DB_STATUS_GRPCACHE = (1 << 2)
};
struct db_operations { struct db_operations {
int (*populate) (pmdb_t *); int (*populate) (pmdb_t *);
void (*unregister) (pmdb_t *); void (*unregister) (pmdb_t *);
@ -54,10 +61,10 @@ struct __pmdb_t {
char *treename; char *treename;
/* do not access directly, use _alpm_db_path(db) for lazy access */ /* do not access directly, use _alpm_db_path(db) for lazy access */
char *_path; char *_path;
int pkgcache_loaded;
int grpcache_loaded;
/* also indicates whether we are RO or RW */ /* also indicates whether we are RO or RW */
int is_local; int is_local;
/* flags determining validity, loaded caches, etc. */
enum _pmdbstatus_t status;
pmpkghash_t *pkgcache; pmpkghash_t *pkgcache;
alpm_list_t *grpcache; alpm_list_t *grpcache;
alpm_list_t *servers; alpm_list_t *servers;
@ -72,7 +79,6 @@ 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);
char *_alpm_db_sig_path(pmdb_t *db); char *_alpm_db_sig_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(pmhandle_t *handle); pmdb_t *_alpm_db_register_local(pmhandle_t *handle);
@ -88,7 +94,6 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info);
/* cache bullshit */ /* cache bullshit */
/* packages */ /* packages */
int _alpm_db_load_pkgcache(pmdb_t *db);
void _alpm_db_free_pkgcache(pmdb_t *db); void _alpm_db_free_pkgcache(pmdb_t *db);
int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg); int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg);
int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg); int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg);
@ -97,7 +102,6 @@ alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db);
int _alpm_db_ensure_pkgcache(pmdb_t *db, pmdbinfrq_t infolevel); int _alpm_db_ensure_pkgcache(pmdb_t *db, pmdbinfrq_t infolevel);
pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target); pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target);
/* groups */ /* groups */
int _alpm_db_load_grpcache(pmdb_t *db);
void _alpm_db_free_grpcache(pmdb_t *db); void _alpm_db_free_grpcache(pmdb_t *db);
alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db); alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db);
pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target); pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target);

View file

@ -70,6 +70,8 @@ const char SYMEXPORT *alpm_strerror(enum _pmerrno_t 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_INVALID:
return _("invalid or corrupted database");
case PM_ERR_DB_VERSION: case PM_ERR_DB_VERSION:
return _("database is incorrect version"); return _("database is incorrect version");
case PM_ERR_DB_WRITE: case PM_ERR_DB_WRITE:

View file

@ -101,11 +101,19 @@ 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;
alpm_list_t *i;
/* Sanity checks */ /* Sanity checks */
CHECK_HANDLE(handle, return -1); CHECK_HANDLE(handle, return -1);
ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, -1)); ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, -1));
for(i = handle->dbs_sync; i; i = i->next) {
const pmdb_t *db = i->data;
if(!(db->status & DB_STATUS_VALID)) {
RET_ERR(handle, PM_ERR_DB_INVALID, -1);
}
}
/* lock db */ /* lock db */
if(!(flags & PM_TRANS_FLAG_NOLOCK)) { if(!(flags & PM_TRANS_FLAG_NOLOCK)) {
if(make_lock(handle)) { if(make_lock(handle)) {

View file

@ -450,7 +450,7 @@ static int setup_libalpm(void)
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) { if(err == PM_ERR_DB_VERSION) {
fprintf(stderr, _(" try running pacman-db-upgrade\n")); pm_printf(PM_LOG_ERROR, _(" try running pacman-db-upgrade\n"));
} }
return -1; return -1;
} }

View file

@ -18,4 +18,4 @@ self.args = "--ask=1 -S grp"
self.addrule("PACMAN_RETCODE=0") self.addrule("PACMAN_RETCODE=0")
self.addrule("!PKG_EXIST=%s" % pkg1.name) self.addrule("!PKG_EXIST=%s" % pkg1.name)
self.addrule("PKG_EXIST=%s" % pkg2.name) self.addrule("PKG_EXIST=%s" % pkg2.name)
self.addrule("PACMAN_OUTPUT=is in IgnorePkg") self.addrule("PKG_EXIST=%s" % pkg3.name)