summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2009-09-14 22:44:51 -0500
committerDan McGee <dan@archlinux.org>2009-09-20 12:19:57 -0500
commit72883e3bcbc1ff2d46667fceb48c3c2c682cfe79 (patch)
tree46b4882f5375dd426c938f30968263f9e6af5355
parent6bfca2fd14d07a18d7000d1f9dd998428036656f (diff)
downloadpacman-72883e3bcbc1ff2d46667fceb48c3c2c682cfe79.tar.xz
Fully implement database lazy loading
Commit 34e1413d75 attempted to implement lazy loading of package databases. Although it took care of my main complaint (creating the database directory if it didn't exist), it didn't allow sync repos to be registered before alpm_option_set_dbpath() had been called. With this patch, we no longer compute the individual repository DB paths until necessary, allowing full lazy loading to work as intended, and allowing us to drop the extra setlibpath() calls from the frontend. This allows the changes introduced in a2cd48960 (but later reverted) to be added back in again. Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--lib/libalpm/add.c13
-rw-r--r--lib/libalpm/be_files.c39
-rw-r--r--lib/libalpm/db.c61
-rw-r--r--lib/libalpm/db.h8
-rw-r--r--lib/libalpm/remove.c4
-rw-r--r--src/pacman/pacman.c5
6 files changed, 75 insertions, 55 deletions
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index 70f8317b..c6751a49 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -132,13 +132,13 @@ static int extract_single_file(struct archive *archive,
if(strcmp(entryname, ".INSTALL") == 0) {
/* the install script goes inside the db */
- snprintf(filename, PATH_MAX, "%s%s-%s/install", db->path,
- newpkg->name, newpkg->version);
+ snprintf(filename, PATH_MAX, "%s%s-%s/install",
+ _alpm_db_path(db), newpkg->name, newpkg->version);
archive_entry_set_perm(entry, 0644);
} else if(strcmp(entryname, ".CHANGELOG") == 0) {
/* the changelog goes inside the db */
- snprintf(filename, PATH_MAX, "%s%s-%s/changelog", db->path,
- newpkg->name, newpkg->version);
+ snprintf(filename, PATH_MAX, "%s%s-%s/changelog",
+ _alpm_db_path(db), newpkg->name, newpkg->version);
archive_entry_set_perm(entry, 0644);
} else if(*entryname == '.') {
/* for now, ignore all files starting with '.' that haven't
@@ -483,8 +483,9 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
ALPM_LOG_FUNC;
- snprintf(scriptlet, PATH_MAX, "%s%s-%s/install", db->path,
- alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
+ snprintf(scriptlet, PATH_MAX, "%s%s-%s/install",
+ _alpm_db_path(db), alpm_pkg_get_name(newpkg),
+ alpm_pkg_get_version(newpkg));
/* see if this is an upgrade. if so, remove the old package first */
pmpkg_t *local = _alpm_db_get_pkgfromcache(db, newpkg->name);
diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index d698e018..21533ef2 100644
--- a/lib/libalpm/be_files.c
+++ b/lib/libalpm/be_files.c
@@ -51,10 +51,11 @@
* Return the last update time as number of seconds from the epoch.
* Returns 0 if the value is unknown or can't be read.
*/
-static time_t getlastupdate(const pmdb_t *db)
+static time_t getlastupdate(pmdb_t *db)
{
FILE *fp;
char *file;
+ const char *dbpath;
time_t ret = 0;
ALPM_LOG_FUNC;
@@ -63,9 +64,10 @@ static time_t getlastupdate(const pmdb_t *db)
return(ret);
}
- /* db->path + '.lastupdate' + NULL */
- MALLOC(file, strlen(db->path) + 12, RET_ERR(PM_ERR_MEMORY, ret));
- sprintf(file, "%s.lastupdate", db->path);
+ dbpath = _alpm_db_path(db);
+ /* dbpath + '.lastupdate' + NULL */
+ MALLOC(file, strlen(dbpath) + 12, RET_ERR(PM_ERR_MEMORY, ret));
+ sprintf(file, "%s.lastupdate", dbpath);
/* get the last update time, if it's there */
if((fp = fopen(file, "r")) == NULL) {
@@ -85,10 +87,11 @@ static time_t getlastupdate(const pmdb_t *db)
/*
* writes the dbpath/.lastupdate file with the value in time
*/
-static int setlastupdate(const pmdb_t *db, time_t time)
+static int setlastupdate(pmdb_t *db, time_t time)
{
FILE *fp;
char *file;
+ const char *dbpath;
int ret = 0;
ALPM_LOG_FUNC;
@@ -97,9 +100,10 @@ static int setlastupdate(const pmdb_t *db, time_t time)
return(-1);
}
- /* db->path + '.lastupdate' + NULL */
- MALLOC(file, strlen(db->path) + 12, RET_ERR(PM_ERR_MEMORY, ret));
- sprintf(file, "%s.lastupdate", db->path);
+ dbpath = _alpm_db_path(db);
+ /* dbpath + '.lastupdate' + NULL */
+ MALLOC(file, strlen(dbpath) + 12, RET_ERR(PM_ERR_MEMORY, ret));
+ sprintf(file, "%s.lastupdate", dbpath);
if((fp = fopen(file, "w")) == NULL) {
free(file);
@@ -116,7 +120,7 @@ static int setlastupdate(const pmdb_t *db, time_t time)
static int checkdbdir(pmdb_t *db)
{
struct stat buf;
- char *path = db->path;
+ const char *path = _alpm_db_path(db);
if(stat(path, &buf) != 0) {
_alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",
@@ -224,8 +228,9 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
_alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast());
return(-1);
} else {
+ const char *syncdbpath = _alpm_db_path(db);
/* remove the old dir */
- if(_alpm_rmrf(db->path) != 0) {
+ if(_alpm_rmrf(syncdbpath) != 0) {
_alpm_log(PM_LOG_ERROR, _("could not remove database %s\n"), db->treename);
RET_ERR(PM_ERR_DB_REMOVE, -1);
}
@@ -240,7 +245,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
/* uncompress the sync database */
checkdbdir(db);
- ret = _alpm_unpack(dbfilepath, db->path, NULL);
+ ret = _alpm_unpack(dbfilepath, syncdbpath, NULL);
if(ret) {
free(dbfilepath);
RET_ERR(PM_ERR_SYSTEM, -1);
@@ -305,13 +310,15 @@ int _alpm_db_populate(pmdb_t *db)
struct dirent *ent = NULL;
struct stat sbuf;
char path[PATH_MAX];
+ const char *dbpath;
DIR *dbdir;
ALPM_LOG_FUNC;
ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
- dbdir = opendir(db->path);
+ dbpath = _alpm_db_path(db);
+ dbdir = opendir(dbpath);
if(dbdir == NULL) {
return(0);
}
@@ -323,7 +330,7 @@ int _alpm_db_populate(pmdb_t *db)
continue;
}
/* stat the entry, make sure it's a directory */
- snprintf(path, PATH_MAX, "%s%s", db->path, name);
+ snprintf(path, PATH_MAX, "%s%s", dbpath, name);
if(stat(path, &sbuf) != 0 || !S_ISDIR(sbuf.st_mode)) {
continue;
}
@@ -366,10 +373,12 @@ static char *get_pkgpath(pmdb_t *db, pmpkg_t *info)
{
size_t len;
char *pkgpath;
+ const char *dbpath;
- len = strlen(db->path) + strlen(info->name) + strlen(info->version) + 3;
+ dbpath = _alpm_db_path(db);
+ len = strlen(dbpath) + strlen(info->name) + strlen(info->version) + 3;
MALLOC(pkgpath, len, RET_ERR(PM_ERR_MEMORY, NULL));
- sprintf(pkgpath, "%s%s-%s/", db->path, info->name, info->version);
+ sprintf(pkgpath, "%s%s-%s/", dbpath, info->name, info->version);
return(pkgpath);
}
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index 62c2e0a3..e57ff935 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -323,18 +323,15 @@ alpm_list_t SYMEXPORT *alpm_db_search(pmdb_t *db, const alpm_list_t* needles)
/** @} */
-pmdb_t *_alpm_db_new(const char *dbpath, const char *treename)
+static pmdb_t *_alpm_db_new(const char *treename, unsigned short is_local)
{
pmdb_t *db;
- const size_t pathsize = strlen(dbpath) + strlen(treename) + 2;
ALPM_LOG_FUNC;
CALLOC(db, 1, sizeof(pmdb_t), RET_ERR(PM_ERR_MEMORY, NULL));
- CALLOC(db->path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
-
- sprintf(db->path, "%s%s/", dbpath, treename);
STRDUP(db->treename, treename, RET_ERR(PM_ERR_MEMORY, NULL));
+ db->is_local = is_local;
return(db);
}
@@ -347,13 +344,44 @@ void _alpm_db_free(pmdb_t *db)
_alpm_db_free_pkgcache(db);
/* cleanup server list */
FREELIST(db->servers);
- FREE(db->path);
+ FREE(db->_path);
FREE(db->treename);
FREE(db);
return;
}
+const char *_alpm_db_path(pmdb_t *db)
+{
+ if(!db) {
+ return(NULL);
+ }
+ if(!db->_path) {
+ const char *dbpath;
+ size_t pathsize;
+
+ dbpath = alpm_option_get_dbpath();
+ if(!dbpath) {
+ _alpm_log(PM_LOG_ERROR, _("database path is undefined\n"));
+ RET_ERR(PM_ERR_DB_OPEN, NULL);
+ }
+
+ if(db->is_local) {
+ pathsize = strlen(dbpath) + strlen(db->treename) + 2;
+ CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
+ sprintf(db->_path, "%s%s/", dbpath, db->treename);
+ } else {
+ pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 2;
+ CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
+ /* all sync DBs now reside in the sync/ subdir of the dbpath */
+ sprintf(db->_path, "%ssync/%s/", dbpath, db->treename);
+ }
+ _alpm_log(PM_LOG_DEBUG, "database path for tree %s set to %s\n",
+ db->treename, db->_path);
+ }
+ return(db->_path);
+}
+
int _alpm_db_cmp(const void *d1, const void *d2)
{
pmdb_t *db1 = (pmdb_t *)d1;
@@ -440,7 +468,6 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
pmdb_t *_alpm_db_register_local(void)
{
pmdb_t *db;
- const char *dbpath;
ALPM_LOG_FUNC;
@@ -451,13 +478,7 @@ pmdb_t *_alpm_db_register_local(void)
_alpm_log(PM_LOG_DEBUG, "registering local database\n");
- dbpath = alpm_option_get_dbpath();
- if(!dbpath) {
- _alpm_log(PM_LOG_ERROR, _("database path is undefined\n"));
- RET_ERR(PM_ERR_DB_OPEN, NULL);
- }
-
- db = _alpm_db_new(dbpath, "local");
+ db = _alpm_db_new("local", 1);
if(db == NULL) {
RET_ERR(PM_ERR_DB_CREATE, NULL);
}
@@ -469,8 +490,6 @@ pmdb_t *_alpm_db_register_local(void)
pmdb_t *_alpm_db_register_sync(const char *treename)
{
pmdb_t *db;
- const char *dbpath;
- char path[PATH_MAX];
alpm_list_t *i;
ALPM_LOG_FUNC;
@@ -485,15 +504,7 @@ pmdb_t *_alpm_db_register_sync(const char *treename)
_alpm_log(PM_LOG_DEBUG, "registering sync database '%s'\n", treename);
- dbpath = alpm_option_get_dbpath();
- if(!dbpath) {
- _alpm_log(PM_LOG_ERROR, _("database path is undefined\n"));
- RET_ERR(PM_ERR_DB_OPEN, NULL);
- }
- /* all sync DBs now reside in the sync/ subdir of the dbpath */
- snprintf(path, PATH_MAX, "%ssync/", dbpath);
-
- db = _alpm_db_new(path, treename);
+ db = _alpm_db_new(treename, 0);
if(db == NULL) {
RET_ERR(PM_ERR_DB_CREATE, NULL);
}
diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h
index 950ace22..29816032 100644
--- a/lib/libalpm/db.h
+++ b/lib/libalpm/db.h
@@ -40,18 +40,20 @@ typedef enum _pmdbinfrq_t {
/* Database */
struct __pmdb_t {
- char *path;
char *treename;
+ /* do not access directly, use _alpm_db_path(db) for lazy access */
+ char *_path;
unsigned short pkgcache_loaded;
- alpm_list_t *pkgcache;
unsigned short grpcache_loaded;
+ unsigned short is_local;
+ alpm_list_t *pkgcache;
alpm_list_t *grpcache;
alpm_list_t *servers;
};
/* db.c, database general calls */
-pmdb_t *_alpm_db_new(const char *dbpath, const char *treename);
void _alpm_db_free(pmdb_t *db);
+const char *_alpm_db_path(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);
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 7bafaf1c..f31fbfb0 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -386,8 +386,8 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db)
/* get the name now so we can use it after package is removed */
pkgname = alpm_pkg_get_name(info);
- snprintf(scriptlet, PATH_MAX, "%s%s-%s/install", db->path,
- pkgname, alpm_pkg_get_version(info));
+ snprintf(scriptlet, PATH_MAX, "%s%s-%s/install",
+ _alpm_db_path(db), pkgname, alpm_pkg_get_version(info));
EVENT(trans, PM_TRANS_EVT_REMOVE_START, info, NULL);
_alpm_log(PM_LOG_DEBUG, "removing package %s-%s\n",
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 2a228ed9..ac515029 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -758,11 +758,8 @@ static int _parseconfig(const char *file, const char *givensection,
ret = 1;
goto cleanup;
}
- /* if we are not looking at the options section, register a db and also
- * ensure we have set all of our library paths as the library is too stupid
- * at the moment to do lazy opening of the databases */
+ /* if we are not looking at the options section, register a db */
if(strcmp(section, "options") != 0) {
- setlibpaths();
db = alpm_db_register_sync(section);
if(db == NULL) {
pm_printf(PM_LOG_ERROR, _("could not register '%s' database (%s)\n"),