--- ./lib/backend/db3.c.orig 2020-01-17 11:50:39.048477444 +0000 +++ ./lib/backend/db3.c 2020-01-17 11:58:15.351365745 +0000 @@ -421,10 +421,6 @@ static int db_init(rpmdb rdb, const char if (rdb->db_dbenv != NULL) { rdb->db_opens++; return 0; - } else { - /* On first call, set backend description to something... */ - free(rdb->db_descr); - rasprintf(&rdb->db_descr, "db%u", DB_VERSION_MAJOR); } /* @@ -1426,6 +1422,9 @@ static rpmRC db3_pkgdbNew(dbiIndex dbi, } struct rpmdbOps_s db3_dbops = { + .name = "bdb", + .path = "Packages", + .open = db3_dbiOpen, .close = db3_dbiClose, .verify = db3_dbiVerify, --- ./lib/backend/dbi.c.orig 2020-01-17 11:54:38.207894769 +0000 +++ ./lib/backend/dbi.c 2020-01-17 11:56:45.555584517 +0000 @@ -12,6 +12,19 @@ #include "lib/rpmdb_internal.h" #include "debug.h" +const struct rpmdbOps_s *backends[] = { +#if defined(WITH_LMDB) + &lmdb_dbops, +#endif +#ifdef ENABLE_NDB + &ndb_dbops, +#endif +#if defined(WITH_BDB) + &db3_dbops, +#endif + &dummydb_dbops, + NULL +}; dbiIndex dbiFree(dbiIndex dbi) { @@ -38,59 +51,58 @@ dbDetectBackend(rpmdb rdb) const char *dbhome = rpmdbHome(rdb); char *db_backend = rpmExpand("%{?_db_backend}", NULL); char *path = NULL; + const struct rpmdbOps_s **ops, *ops_config; -#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 -#endif -#if defined(WITH_BDB) - { - rdb->db_ops = &db3_dbops; - if (*db_backend == '\0') { - free(db_backend); - db_backend = xstrdup("bdb"); + rdb->db_ops = NULL; + + ops_config = NULL; + for (ops = backends; *ops; ops++) { + if (rstreq(db_backend, (*ops)->name)) { + ops_config = *ops; + break; } } -#endif -#if defined(WITH_LMDB) - path = rstrscat(NULL, dbhome, "/data.mdb", NULL); - if (access(path, F_OK) == 0 && rdb->db_ops != &lmdb_dbops) { - rdb->db_ops = &lmdb_dbops; - rpmlog(RPMLOG_WARNING, _("Found LMDB data.mdb database while attempting %s backend: using lmdb backend.\n"), db_backend); + /* if we have a configured backend, check it first */ + if (ops_config && ops_config->path) { + path = rstrscat(NULL, dbhome, "/", ops_config->path, NULL); + if (access(path, F_OK) == 0) + rdb->db_ops = ops_config; + free(path); } - 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, _("Found NDB Packages.db database while attempting %s backend: using ndb backend.\n"), db_backend); - } - free(path); -#endif + /* if it did not match, check all available backends */ + if (rdb->db_ops == NULL) { + for (ops = backends; *ops; ops++) { + if ((*ops)->path == NULL || *ops == ops_config) + continue; -#if defined(WITH_BDB) - 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); + path = rstrscat(NULL, dbhome, "/", (*ops)->path, NULL); + if (access(path, F_OK) == 0) { + rpmlog(RPMLOG_DEBUG, + _("Found %s %s database while attempting %s backend: " + "using %s backend.\n"), + (*ops)->name, (*ops)->path, db_backend, (*ops)->name); + rdb->db_ops = *ops; + } + free(path); + if (rdb->db_ops != NULL) + break; + } } - free(path); -#endif + /* if we did not find a match, use the configured backend */ + if (rdb->db_ops == NULL && ops_config) + rdb->db_ops = ops_config; + + /* if everything failed fall back to dummydb */ if (rdb->db_ops == NULL) { rdb->db_ops = &dummydb_dbops; - rpmlog(RPMLOG_DEBUG, "using dummy database, installs not possible\n"); + rpmlog(RPMLOG_WARNING, "using dummy database, installs not possible\n"); } + rdb->db_descr = rdb->db_ops->name; + if (db_backend) free(db_backend); } --- ./lib/backend/dbi.h.orig 2020-01-17 11:52:17.960236465 +0000 +++ ./lib/backend/dbi.h 2020-01-17 11:57:36.907459407 +0000 @@ -51,7 +51,7 @@ struct rpmdb_s { int db_flags; int db_mode; /*!< open mode */ int db_perms; /*!< open permissions */ - char * db_descr; /*!< db backend description (for error msgs) */ + const char * db_descr; /*!< db backend description (for error msgs) */ struct dbChk_s * db_checked;/*!< headerCheck()'ed package instances */ rpmdb db_next; int db_opens; @@ -61,7 +61,7 @@ struct rpmdb_s { dbiIndex * db_indexes; /*!< Tag indices. */ int db_buildindex; /*!< Index rebuild indicator */ - struct rpmdbOps_s * db_ops; /*!< backend ops */ + const struct rpmdbOps_s * db_ops; /*!< backend ops */ /* dbenv and related parameters */ void * db_dbenv; /*!< Backend private handle */ @@ -244,6 +244,9 @@ RPM_GNUC_INTERNAL const void * idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen); struct rpmdbOps_s { + const char *name; /* backend name */ + const char *path; /* main database name */ + int (*open)(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags); int (*close)(dbiIndex dbi, unsigned int flags); int (*verify)(dbiIndex dbi, unsigned int flags); --- ./lib/backend/dummydb.c.orig 2020-01-17 11:50:49.472452046 +0000 +++ ./lib/backend/dummydb.c 2020-01-17 11:52:08.048260613 +0000 @@ -93,6 +93,9 @@ static const void * dummydb_idxdbKey(dbi struct rpmdbOps_s dummydb_dbops = { + .name = "dummy", + .path = NULL, + .open = dummydb_Open, .close = dummydb_Close, .verify = dummydb_Verify, --- ./lib/backend/lmdb.c.orig 2020-01-17 11:50:45.808460969 +0000 +++ ./lib/backend/lmdb.c 2020-01-17 11:58:30.247329459 +0000 @@ -137,10 +137,6 @@ static int db_init(rpmdb rdb, const char if (rdb->db_dbenv != NULL) { rdb->db_opens++; return 0; - } else { - /* On first call, set backend description to something... */ - free(rdb->db_descr); - rdb->db_descr = xstrdup("lmdb"); } MDB_dbi maxdbs = 32; @@ -916,6 +912,9 @@ exit: } struct rpmdbOps_s lmdb_dbops = { + .name = "lmdb", + .path = "data.mdb", + .open = lmdb_dbiOpen, .close = lmdb_dbiClose, .verify = lmdb_dbiVerify, --- ./lib/backend/ndb/glue.c.orig 2020-01-17 11:51:09.708402746 +0000 +++ ./lib/backend/ndb/glue.c 2020-01-17 11:51:56.272289298 +0000 @@ -482,6 +482,9 @@ static const void * ndb_idxdbKey(dbiInde struct rpmdbOps_s ndb_dbops = { + .name = "ndb", + .path = "Packages.db", + .open = ndb_Open, .close = ndb_Close, .verify = ndb_Verify, --- ./lib/rpmdb.c.orig 2020-01-17 11:59:15.279219743 +0000 +++ ./lib/rpmdb.c 2020-01-17 12:00:36.495021876 +0000 @@ -417,7 +417,6 @@ int rpmdbClose(rpmdb db) db->db_fullpath = _free(db->db_fullpath); db->db_checked = dbChkFree(db->db_checked); db->db_indexes = _free(db->db_indexes); - db->db_descr = _free(db->db_descr); if (next) { *prev = next->db_next; @@ -482,7 +481,6 @@ static rpmdb newRpmdb(const char * root, db->db_tags = dbiTags; db->db_ndbi = sizeof(dbiTags) / sizeof(rpmDbiTag); db->db_indexes = xcalloc(db->db_ndbi, sizeof(*db->db_indexes)); - db->db_descr = xstrdup("unknown db"); db->nrefs = 0; return rpmdbLink(db); } @@ -517,6 +515,8 @@ static int openDatabase(const char * pre /* Just the primary Packages database opened here */ rc = pkgdbOpen(db, db->db_flags, NULL); + if (!db->db_descr) + db->db_descr = "unknown db"; } if (rc || justCheck || dbp == NULL)