From: Michael Tremer Date: Tue, 19 Jan 2021 19:59:57 +0000 (+0000) Subject: libpakfire: Add lmdb database environment X-Git-Tag: 0.9.28~1285^2~842 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=33d55ab4ed2d0d00eefa1d9e4ecafb87f38c38d7;p=pakfire.git libpakfire: Add lmdb database environment Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 64b998fbf..a48d9a10d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -269,6 +269,7 @@ lib_LTLIBRARIES += \ libpakfire_la_SOURCES = \ src/libpakfire/arch.c \ src/libpakfire/archive.c \ + src/libpakfire/db.c \ src/libpakfire/errno.c \ src/libpakfire/execute.c \ src/libpakfire/file.c \ @@ -294,6 +295,7 @@ pkginclude_HEADERS += \ src/libpakfire/include/pakfire/arch.h \ src/libpakfire/include/pakfire/archive.h \ src/libpakfire/include/pakfire/constants.h \ + src/libpakfire/include/pakfire/db.h \ src/libpakfire/include/pakfire/errno.h \ src/libpakfire/include/pakfire/execute.h \ src/libpakfire/include/pakfire/file.h \ diff --git a/src/libpakfire/db.c b/src/libpakfire/db.c new file mode 100644 index 000000000..865ef6463 --- /dev/null +++ b/src/libpakfire/db.c @@ -0,0 +1,130 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2021 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#include +#include + +#include + +#include +#include +#include +#include +#include + +struct pakfire_db { + Pakfire pakfire; + int nrefs; +}; + +/* + This function initialises the database environment, but stores it in the main pakfire + object so that we do not have to create a circle-reference between pakfire and the + database object. +*/ +int pakfire_db_env_init(Pakfire pakfire, MDB_env** env) { + DEBUG(pakfire, "Initialising database environment\n"); + + // Allocate database environment + int r = mdb_env_create(env); + if (r) { + ERROR(pakfire, "Could not allocate database environment\n"); + return r; + } + + const char* root = pakfire_get_path(pakfire); + char* path = pakfire_path_join(root, "var/lib/pakfire/database.db"); + + // Ensure the directory exists + pakfire_mkdir(pakfire, path, 0); + + // Open the database environment + r = mdb_env_open(*env, path, 0, 0660); + if (r) { + switch (r) { + case MDB_VERSION_MISMATCH: + ERROR(pakfire, "The database is of an incompatible version\n"); + errno = EINVAL; + break; + + case MDB_INVALID: + errno = EINVAL; + break; + + default: + ERROR(pakfire, "Could not open database %s: %s\n", path, strerror(errno)); + errno = r; + } + + // Reset r to non-zero + r = 1; + goto ERROR; + } + +ERROR: + free(path); + + return r; +} + +void pakfire_db_env_free(Pakfire pakfire, MDB_env* env) { + DEBUG(pakfire, "Freeing database environment\n"); + + if (env) + mdb_env_close(env); +} + +int pakfire_db_open(struct pakfire_db** db, Pakfire pakfire) { + struct pakfire_db* o = pakfire_calloc(1, sizeof(*o)); + if (!o) + return -ENOMEM; + + DEBUG(pakfire, "Allocated database at %p\n", o); + + o->pakfire = pakfire_ref(pakfire); + o->nrefs = 1; + + *db = o; + + return 0; +} + +struct pakfire_db* pakfire_db_ref(struct pakfire_db* db) { + db->nrefs++; + + return db; +} + +static void pakfire_db_free(struct pakfire_db* db) { + DEBUG(db->pakfire, "Releasing database at %p\n", db); + + pakfire_unref(db->pakfire); + + pakfire_free(db); +} + +struct pakfire_db* pakfire_db_unref(struct pakfire_db* db) { + if (--db->nrefs > 0) + return db; + + pakfire_db_free(db); + + return NULL; +} diff --git a/src/libpakfire/include/pakfire/db.h b/src/libpakfire/include/pakfire/db.h new file mode 100644 index 000000000..79f505d1e --- /dev/null +++ b/src/libpakfire/include/pakfire/db.h @@ -0,0 +1,42 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2021 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef PAKFIRE_DB_H +#define PAKFIRE_DB_H + +#ifdef PAKFIRE_PRIVATE + +#include + +#include + +struct pakfire_db; + +int pakfire_db_env_init(Pakfire pakfire, MDB_env** env); +void pakfire_db_env_free(Pakfire pakfire, MDB_env* env); + +int pakfire_db_open(struct pakfire_db** db, Pakfire pakfire); + +struct pakfire_db* pakfire_db_ref(struct pakfire_db* db); +struct pakfire_db* pakfire_db_unref(struct pakfire_db* db); + +#endif + +#endif /* PAKFIRE_DB_H */ diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index a05dbecb3..d15837218 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -36,6 +38,7 @@ #include #include +#include #include #include #include @@ -50,6 +53,9 @@ struct _Pakfire { char* cache_path; char* arch; + // Database Environment + MDB_env* mdb_env; + // Pool stuff Pool* pool; int pool_ready; @@ -81,6 +87,32 @@ static int log_priority(const char* priority) { return 0; } +// A utility function is already called pakfire_free +static void _pakfire_free(Pakfire pakfire) { + DEBUG(pakfire, "Releasing Pakfire at %p\n", pakfire); + + pakfire_repo_free_all(pakfire); + + if (pakfire->mdb_env) + pakfire_db_env_free(pakfire, pakfire->mdb_env); + + if (pakfire->pool) + pool_free(pakfire->pool); + + queue_free(&pakfire->installonly); + + if (pakfire->arch) + pakfire_free(pakfire->arch); + + if (pakfire->path) + pakfire_free(pakfire->path); + + if (pakfire->cache_path) + pakfire_free(pakfire->cache_path); + + pakfire_free(pakfire); +} + PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char* arch) { // Default to the native architecture if (!arch) @@ -123,6 +155,14 @@ PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char DEBUG(p, " arch = %s\n", pakfire_get_arch(p)); DEBUG(p, " path = %s\n", pakfire_get_path(p)); + // Initialise the database environment + int r = pakfire_db_env_init(p, &p->mdb_env); + if (r) { + _pakfire_free(p); + + return r; + } + // Initialize the pool p->pool = pool_create(); pool_setdisttype(p->pool, DISTTYPE_RPM); @@ -149,23 +189,10 @@ PAKFIRE_EXPORT Pakfire pakfire_ref(Pakfire pakfire) { } PAKFIRE_EXPORT Pakfire pakfire_unref(Pakfire pakfire) { - if (!pakfire) - return NULL; - if (--pakfire->nrefs > 0) return pakfire; - DEBUG(pakfire, "Releasing Pakfire at %p\n", pakfire); - - pakfire_repo_free_all(pakfire); - pool_free(pakfire->pool); - queue_free(&pakfire->installonly); - - pakfire_free(pakfire->path); - pakfire_free(pakfire->cache_path); - pakfire_free(pakfire->arch); - - pakfire_free(pakfire); + _pakfire_free(pakfire); return NULL; }