rpm/db_conversion.diff

170 lines
5.6 KiB
Diff

--- lib/backend/bdb_ro.c.orig 2022-04-07 11:13:18.994517848 +0000
+++ lib/backend/bdb_ro.c 2022-12-02 13:22:16.726408071 +0000
@@ -793,6 +793,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 2022-04-07 11:13:18.994517848 +0000
+++ lib/backend/dbi.c 2022-12-02 13:22:16.726408071 +0000
@@ -138,11 +138,20 @@ exit:
}
rdb->db_descr = rdb->db_ops->name;
+ rdb->db_ops_config = cfg;
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 2022-04-07 11:13:18.994517848 +0000
+++ lib/backend/dbi.h 2022-12-02 13:22:16.726408071 +0000
@@ -13,6 +13,7 @@ enum rpmdbFlags {
RPMDB_FLAG_REBUILD = (1 << 1),
RPMDB_FLAG_VERIFYONLY = (1 << 2),
RPMDB_FLAG_SALVAGE = (1 << 3),
+ RPMDB_FLAG_CONVERT = (1 << 4),
};
typedef enum dbCtrlOp_e {
@@ -53,6 +54,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 */
@@ -197,6 +199,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
@@ -240,6 +250,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/backend/ndb/rpmpkg.c.orig 2022-04-07 11:13:18.997517869 +0000
+++ lib/backend/ndb/rpmpkg.c 2022-12-02 13:22:16.726408071 +0000
@@ -1116,11 +1116,12 @@ static int rpmpkgPutInternal(rpmpkgdb pk
if (rpmpkgWriteBlob(pkgdb, pkgidx, blkoff, blkcnt, blob, blobl, pkgdb->generation)) {
return RPMRC_FAIL;
}
+ /* update nextpkgidx if needed */
+ if (pkgidx >= pkgdb->nextpkgidx) {
+ pkgdb->nextpkgidx = pkgidx + 1;
+ }
/* write slot */
slotno = oldslot ? oldslot->slotno : pkgdb->freeslot;
- if (!slotno) {
- return RPMRC_FAIL;
- }
if (rpmpkgWriteslot(pkgdb, slotno, pkgidx, blkoff, blkcnt)) {
free(pkgdb->slots);
pkgdb->slots = 0;
--- lib/rpmdb.c.orig 2022-09-20 12:08:27.197920294 +0000
+++ lib/rpmdb.c 2022-12-02 13:24:02.830159868 +0000
@@ -469,7 +469,12 @@ static int openDatabase(const char * pre
/* Open just bare minimum when rebuilding a potentially damaged db */
int justPkgs = (db->db_flags & RPMDB_FLAG_REBUILD) &&
((db->db_mode & O_ACCMODE) == O_RDONLY);
- rc = doOpen(db, justPkgs);
+ if (!db->db_pkgs && !justCheck && (mode & O_ACCMODE) == O_RDWR && dbiNeedConversion(db)) {
+ rc = rpmdbRebuild(prefix, NULL, NULL, RPMDB_REBUILD_FLAG_CONVERT);
+ db->db_ops = NULL; /* force re-detection of backend */
+ }
+ if (!rc)
+ rc = doOpen(db, justPkgs);
if (!db->db_descr)
db->db_descr = "unknown db";
@@ -2228,6 +2233,15 @@ int rpmdbAdd(rpmdb db, Header h)
if (db == NULL)
return 0;
+ if ((db->db_flags & RPMDB_FLAG_CONVERT) != 0) {
+ /* keep old instance numbers when converting */
+ hdrNum = headerGetInstance(h);
+ if (hdrNum == 0) {
+ ret = -1;
+ goto exit;
+ }
+ }
+
hdrBlob = headerExport(h, &hdrLen);
if (hdrBlob == NULL || hdrLen == 0) {
ret = -1;
@@ -2423,7 +2437,22 @@ int rpmdbRebuild(const char * prefix, rp
}
rootdbpath = rpmGetPath(prefix, dbpath, NULL);
- newdbpath = rpmGetPath("%{?_dbpath_rebuild}", NULL);
+ if ((rebuildflags & RPMDB_REBUILD_FLAG_CONVERT) != 0) {
+ char lbuf[PATH_MAX];
+ ssize_t s = readlink(rootdbpath, lbuf, PATH_MAX);
+ if (s > 0 && s < PATH_MAX) {
+ lbuf[s] = 0;
+ free(dbpath);
+ if (lbuf[0] == '/')
+ dbpath = strdup(lbuf);
+ else
+ dbpath = rpmGetPath("%{?_dbpath}", "/../", lbuf, NULL);
+ free(rootdbpath);
+ rootdbpath = rpmGetPath(prefix, dbpath, NULL);
+ }
+ newdbpath = strdup("");
+ } else
+ newdbpath = rpmGetPath("%{?_dbpath_rebuild}", NULL);
if (rstreq(newdbpath, "") || rstreq(newdbpath, dbpath)) {
newdbpath = _free(newdbpath);
rasprintf(&newdbpath, "%srebuilddb.%d", dbpath, (int) getpid());
@@ -2449,7 +2478,9 @@ int rpmdbRebuild(const char * prefix, rp
goto exit;
}
if (openDatabase(prefix, newdbpath, &newdb,
- (O_RDWR | O_CREAT), 0644, RPMDB_FLAG_REBUILD)) {
+ (O_RDWR | O_CREAT), 0644, RPMDB_FLAG_REBUILD |
+ (rebuildflags & RPMDB_REBUILD_FLAG_CONVERT ?
+ RPMDB_FLAG_CONVERT : 0))) {
rc = 1;
goto exit;
}
--- lib/rpmdb_internal.h.orig 2022-04-07 11:13:19.014517984 +0000
+++ lib/rpmdb_internal.h 2022-12-02 13:22:16.726408071 +0000
@@ -25,6 +25,7 @@ extern "C" {
enum rpmdbRebuildFlags_e {
RPMDB_REBUILD_FLAG_SALVAGE = (1 << 0),
+ RPMDB_REBUILD_FLAG_CONVERT = (1 << 1),
};
/** \ingroup rpmdb