Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LMDB backend for RPMDB to RPM (from @n3npq in #281) #291

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/Dockerfile
Expand Up @@ -24,6 +24,7 @@ RUN dnf -y install \
popt-devel \
libarchive-devel \
libdb-devel \
lmdb-devel \
libselinux-devel \
ima-evm-utils \
libcap-devel \
Expand Down
24 changes: 24 additions & 0 deletions configure.ac
Expand Up @@ -581,6 +581,30 @@ AS_IF([test "$enable_ndb" = yes],[
])
AM_CONDITIONAL([NDB], [test "$enable_ndb" = yes])

#=================
# Check for LMDB support
AC_ARG_ENABLE([lmdb],
[AS_HELP_STRING([--enable-lmdb=@<:@yes/no/auto@:>@],
[build with LMDB rpm database format support (default=auto)])],
[enable_lmdb="$enableval"],
[enable_lmdb=auto])

AS_IF([test "x$enable_lmdb" != "xno"], [
PKG_CHECK_MODULES([LMDB], [lmdb], [have_lmdb=yes], [have_lmdb=no])
AS_IF([test "$enable_lmdb" = "yes"], [
if test "$have_lmdb" = "no"; then
AC_MSG_ERROR([--enable-lmdb specified, but not available])
fi
])
])

if test "x$have_lmdb" = "xyes"; then
AC_DEFINE([WITH_LMDB], [1], [Define if LMDB is available])
LMDB_REQUIRES=lmdb
AC_SUBST(LMDB_REQUIRES)
fi
AM_CONDITIONAL([LMDB], [test "x$have_lmdb" = "xyes"])

AM_GNU_GETTEXT_VERSION([0.16.1])
AM_GNU_GETTEXT([external])
AM_ICONV
Expand Down
8 changes: 8 additions & 0 deletions lib/Makefile.am
Expand Up @@ -7,6 +7,7 @@ AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I$(top_builddir)/include/
AM_CPPFLAGS += @WITH_BEECRYPT_INCLUDE@
AM_CPPFLAGS += @WITH_NSS_INCLUDE@
AM_CPPFLAGS += @WITH_POPT_INCLUDE@
AM_CPPFLAGS += $(LMDB_CFLAGS)
AM_CPPFLAGS += -I$(top_srcdir)/misc
AM_CPPFLAGS += -DLOCALEDIR="\"$(localedir)\""
AM_CPPFLAGS += -DSYSCONFDIR="\"$(sysconfdir)\""
Expand Down Expand Up @@ -75,6 +76,13 @@ librpm_la_SOURCES += \
backend/ndb/rpmxdb.h
endif

if LMDB
AM_CPPFLAGS += $(LMDB_CFLAGS)
librpm_la_LIBADD += $(LMDB_LIBS)
librpm_la_SOURCES += \
backend/lmdb.c
endif

tagtbl.C: Makefile.am $(srcdir)/rpmtag.h gentagtbl.sh
@AWK=${AWK} ${SHELL} $(srcdir)/gentagtbl.sh \
$(srcdir)/rpmtag.h > $@.new && \
Expand Down
44 changes: 34 additions & 10 deletions lib/backend/dbi.c
Expand Up @@ -35,31 +35,55 @@ dbiIndex dbiNew(rpmdb rdb, rpmDbiTagVal rpmtag)
static void
dbDetectBackend(rpmdb rdb)
{
#ifdef ENABLE_NDB
const char *dbhome = rpmdbHome(rdb);
char *db_backend = rpmExpand("%{?_db_backend}", NULL);
char *path = NULL;

#if defined(WITH_LMDB)
if (!strcmp(db_backend, "lmdb")) {
rdb->db_ops = &lmdb_dbops;
} else
#endif
#ifdef ENABLE_NDB
if (!strcmp(db_backend, "ndb")) {
rdb->db_ops = &ndb_dbops;
} else {
} else
#endif
{
rdb->db_ops = &db3_dbops;
if (*db_backend == '\0') {
free(db_backend);
db_backend = xstrdup("bdb");
}
}
free(db_backend);

char *path = rstrscat(NULL, dbhome, "/Packages", NULL);
if (access(path, F_OK) == 0 && rdb->db_ops != &db3_dbops) {
rdb->db_ops = &db3_dbops;
rpmlog(RPMLOG_WARNING, _("Unexpected database format\n"));
#if defined(WITH_LMDB)
path = rstrscat(NULL, dbhome, "/Packages.mdb", NULL);
if (access(path, F_OK) == 0 && rdb->db_ops != &lmdb_dbops) {
rdb->db_ops = &lmdb_dbops;
rpmlog(RPMLOG_WARNING, _("Found LMDB Packages.mdb database while attempting %s backend: using lmdb backend.\n"), db_backend);
}
free(path);
#endif

#ifdef ENABLE_NDB
path = rstrscat(NULL, dbhome, "/Packages.db", NULL);
if (access(path, F_OK) == 0 && rdb->db_ops != &ndb_dbops) {
rdb->db_ops = &ndb_dbops;
rpmlog(RPMLOG_WARNING, _("Unexpected database format\n"));
rpmlog(RPMLOG_WARNING, _("Found NDB Packages.db database while attempting %s backend: using ndb backend.\n"), db_backend);
}
free(path);
#else
rdb->db_ops = &db3_dbops;
#endif

path = rstrscat(NULL, dbhome, "/Packages", NULL);
if (access(path, F_OK) == 0 && rdb->db_ops != &db3_dbops) {
rdb->db_ops = &db3_dbops;
rpmlog(RPMLOG_WARNING, _("Found BDB Packages database while attempting %s backend: using bdb backend.\n"), db_backend);
}
free(path);

if (db_backend)
free(db_backend);
}

const char * dbiName(dbiIndex dbi)
Expand Down
5 changes: 5 additions & 0 deletions lib/backend/dbi.h
Expand Up @@ -257,6 +257,11 @@ RPM_GNUC_INTERNAL
extern struct rpmdbOps_s ndb_dbops;
#endif

#if defined(WITH_LMDB)
RPM_GNUC_INTERNAL
extern struct rpmdbOps_s lmdb_dbops;
#endif

#ifdef __cplusplus
}
#endif
Expand Down