--- ./lib/backend/bdb_ro.c.orig 2020-01-17 12:42:10.916701298 +0000 +++ ./lib/backend/bdb_ro.c 2020-01-17 12:42:50.924603470 +0000 @@ -790,6 +790,7 @@ static unsigned int bdbro_pkgdbKey(dbiIn struct rpmdbOps_s bdbro_dbops = { .name = "bdb_ro", .path = "Packages", + .readonly = 1, .open = bdbro_Open, .close = bdbro_Close, --- ./lib/backend/dbi.c.orig 2020-01-17 12:42:10.916701298 +0000 +++ ./lib/backend/dbi.c 2020-01-17 12:42:50.924603470 +0000 @@ -105,11 +105,20 @@ dbDetectBackend(rpmdb rdb) } rdb->db_descr = rdb->db_ops->name; + rdb->db_ops_config = ops_config; if (db_backend) free(db_backend); } +int dbiNeedConversion(rpmdb rdb) +{ + if (!rdb->db_ops) + dbDetectBackend(rdb); + return rdb->db_ops->readonly && rdb->db_ops_config + && rdb->db_ops_config->path && !rdb->db_ops_config->readonly; +} + const char * dbiName(dbiIndex dbi) { return dbi->dbi_file; --- ./lib/backend/dbi.h.orig 2020-01-17 12:42:10.916701298 +0000 +++ ./lib/backend/dbi.h 2020-01-17 12:42:50.924603470 +0000 @@ -62,6 +62,7 @@ struct rpmdb_s { int db_buildindex; /*!< Index rebuild indicator */ const struct rpmdbOps_s * db_ops; /*!< backend ops */ + const struct rpmdbOps_s * db_ops_config; /*!< configured backend ops */ /* dbenv and related parameters */ void * db_dbenv; /*!< Backend private handle */ @@ -201,6 +202,14 @@ RPM_GNUC_INTERNAL const char * dbiName(dbiIndex dbi); /** \ingroup dbi + * Check if the database needs to be converted to a different format + * @param db rpm database + * @return boolean + */ +RPM_GNUC_INTERNAL +int dbiNeedConversion(rpmdb rdb); + +/** \ingroup dbi * Open a database cursor. * @param dbi index database handle * @param flags DBC_WRITE if writing, or 0 (DBC_READ) for reading @@ -246,6 +255,7 @@ const void * idxdbKey(dbiIndex dbi, dbiC struct rpmdbOps_s { const char *name; /* backend name */ const char *path; /* main database name */ + int readonly; /* cannot modify database */ int (*open)(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags); int (*close)(dbiIndex dbi, unsigned int flags); --- ./lib/rpmdb.c.orig 2020-01-17 12:42:10.916701298 +0000 +++ ./lib/rpmdb.c 2020-01-17 12:42:50.924603470 +0000 @@ -513,8 +513,16 @@ static int openDatabase(const char * pre rpmsqActivate(1); } + /* Convert the database if needed */ + if (!db->db_pkgs && !justCheck && (mode & O_ACCMODE) == O_RDWR && dbiNeedConversion(db)) { + rpmlog(RPMLOG_WARNING, _("Converting database from %s to %s format\n"), db->db_ops->name, db->db_ops_config->name); + rc = rpmdbRebuild(prefix, NULL, NULL); + db->db_ops = NULL; /* force re-detection of backend */ + } + /* Just the primary Packages database opened here */ - rc = pkgdbOpen(db, db->db_flags, NULL); + if (!rc) + rc = pkgdbOpen(db, db->db_flags, NULL); if (!db->db_descr) db->db_descr = "unknown db"; }