Blame ndb_backport.diff

Bernhard M. Wiedemann 018f1b
--- ./lib/backend/ndb/glue.c.orig	2020-01-23 12:47:46.527816289 +0000
Bernhard M. Wiedemann 018f1b
+++ ./lib/backend/ndb/glue.c	2020-02-03 12:57:34.817304473 +0000
Bernhard M. Wiedemann 018f1b
@@ -52,8 +52,8 @@ static void closeEnv(rpmdb rdb)
Bernhard M. Wiedemann 018f1b
 	if (ndbenv->data)
Bernhard M. Wiedemann 018f1b
 	    free(ndbenv->data);
Bernhard M. Wiedemann 018f1b
 	free(ndbenv);
Bernhard M. Wiedemann 018f1b
+	rdb->db_dbenv = 0;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
-    rdb->db_dbenv = 0;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 static struct ndbEnv_s *openEnv(rpmdb rdb)
Bernhard M. Wiedemann 018f1b
@@ -80,6 +80,31 @@ static int ndb_Close(dbiIndex dbi, unsig
Bernhard M. Wiedemann 018f1b
     return 0;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
+static void ndb_CheckIndexSync(rpmpkgdb pkgdb, rpmxdb xdb)
Bernhard M. Wiedemann 018f1b
+{
Bernhard M. Wiedemann 018f1b
+    unsigned int generation, xdb_generation;
Bernhard M. Wiedemann 018f1b
+    if (!pkgdb || !xdb)
Bernhard M. Wiedemann 018f1b
+        return;
Bernhard M. Wiedemann 018f1b
+    if (rpmpkgLock(pkgdb, 0))
Bernhard M. Wiedemann 018f1b
+        return;
Bernhard M. Wiedemann 018f1b
+    if (rpmpkgGeneration(pkgdb, &generation)) {
Bernhard M. Wiedemann 018f1b
+        rpmpkgUnlock(pkgdb, 0);
Bernhard M. Wiedemann 018f1b
+        return;
Bernhard M. Wiedemann 018f1b
+    }
Bernhard M. Wiedemann 018f1b
+    if (!rpmxdbGetUserGeneration(xdb, &xdb_generation) && generation == xdb_generation) {
Bernhard M. Wiedemann 018f1b
+        rpmpkgUnlock(pkgdb, 0);
Bernhard M. Wiedemann 018f1b
+        return;
Bernhard M. Wiedemann 018f1b
+    }
Bernhard M. Wiedemann 018f1b
+    rpmpkgUnlock(pkgdb, 0);
Bernhard M. Wiedemann 018f1b
+    /* index corrupt or with different generation */
Bernhard M. Wiedemann 018f1b
+    if (rpmxdbIsRdonly(xdb)) {
Bernhard M. Wiedemann 018f1b
+	rpmlog(RPMLOG_WARNING, _("Detected outdated index databases\n"));
Bernhard M. Wiedemann 018f1b
+    } else {
Bernhard M. Wiedemann 018f1b
+	rpmlog(RPMLOG_WARNING, _("Rebuilding outdated index databases\n"));
Bernhard M. Wiedemann 018f1b
+	rpmxdbDelAllBlobs(xdb);
Bernhard M. Wiedemann 018f1b
+    }
Bernhard M. Wiedemann 018f1b
+}
Bernhard M. Wiedemann 018f1b
+
Bernhard M. Wiedemann 018f1b
 static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
     const char *dbhome = rpmdbHome(rdb);
Bernhard M. Wiedemann 018f1b
@@ -130,12 +155,13 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
Bernhard M. Wiedemann 018f1b
 	}
Bernhard M. Wiedemann 018f1b
 	if (!ndbenv->xdb) {
Bernhard M. Wiedemann 018f1b
 	    char *path = rstrscat(NULL, dbhome, "/Index.db", NULL);
Bernhard M. Wiedemann 018f1b
+	    int created = 0;
Bernhard M. Wiedemann 018f1b
 	    rpmlog(RPMLOG_DEBUG, "opening  db index       %s mode=0x%x\n", path, rdb->db_mode);
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 	    /* Open indexes readwrite if possible */
Bernhard M. Wiedemann 018f1b
 	    ioflags = O_RDWR;
Bernhard M. Wiedemann 018f1b
 	    rc = rpmxdbOpen(&ndbenv->xdb, rdb->db_pkgs->dbi_db, path, ioflags, 0666);
Bernhard M. Wiedemann 018f1b
-	    if (rc && errno == EACCES) {
Bernhard M. Wiedemann 018f1b
+	    if (rc && (errno == EACCES || errno == EROFS)) {
Bernhard M. Wiedemann 018f1b
 		/* If it is not asked for rw explicitly, try to open ro */
Bernhard M. Wiedemann 018f1b
 		if (!(oflags & O_RDWR)) {
Bernhard M. Wiedemann 018f1b
 		    ioflags = O_RDONLY;
Bernhard M. Wiedemann 018f1b
@@ -144,6 +170,7 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
Bernhard M. Wiedemann 018f1b
 	    } else if (rc && errno == ENOENT) {
Bernhard M. Wiedemann 018f1b
 		ioflags = O_CREAT|O_RDWR;
Bernhard M. Wiedemann 018f1b
 		rc = rpmxdbOpen(&ndbenv->xdb, rdb->db_pkgs->dbi_db, path, ioflags, 0666);
Bernhard M. Wiedemann 018f1b
+		created = 1;
Bernhard M. Wiedemann 018f1b
 	    }
Bernhard M. Wiedemann 018f1b
 	    if (rc) {
Bernhard M. Wiedemann 018f1b
 		perror("rpmxdbOpen");
Bernhard M. Wiedemann 018f1b
@@ -153,6 +180,8 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
Bernhard M. Wiedemann 018f1b
 	    }
Bernhard M. Wiedemann 018f1b
 	    free(path);
Bernhard M. Wiedemann 018f1b
 	    rpmxdbSetFsync(ndbenv->xdb, ndbenv->dofsync);
Bernhard M. Wiedemann 018f1b
+	    if (!created)
Bernhard M. Wiedemann 018f1b
+		ndb_CheckIndexSync(ndbenv->pkgdb, ndbenv->xdb);
Bernhard M. Wiedemann 018f1b
 	}
Bernhard M. Wiedemann 018f1b
 	if (rpmxdbLookupBlob(ndbenv->xdb, &id, rpmtag, 0, 0) == RPMRC_NOTFOUND) {
Bernhard M. Wiedemann 018f1b
 	    dbi->dbi_flags |= DBI_CREATED;
Bernhard M. Wiedemann 018f1b
@@ -179,7 +208,13 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 static int ndb_Verify(dbiIndex dbi, unsigned int flags)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
-    return 0;
Bernhard M. Wiedemann 018f1b
+    int rc;
Bernhard M. Wiedemann 018f1b
+    if (dbi->dbi_type == DBI_PRIMARY) {
Bernhard M. Wiedemann 018f1b
+	rc = rpmpkgVerify(dbi->dbi_db);
Bernhard M. Wiedemann 018f1b
+    } else {
Bernhard M. Wiedemann 018f1b
+	rc = 0;		/* cannot verify the index databases */
Bernhard M. Wiedemann 018f1b
+    }
Bernhard M. Wiedemann 018f1b
+    return rc;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 static void ndb_SetFSync(rpmdb rdb, int enable)
Bernhard M. Wiedemann 018f1b
@@ -396,15 +431,15 @@ static rpmRC ndb_idxdbIter(dbiIndex dbi,
Bernhard M. Wiedemann 018f1b
 	}
Bernhard M. Wiedemann 018f1b
 	k = dbc->listdata + dbc->list[dbc->ilist];
Bernhard M. Wiedemann 018f1b
 	kl = dbc->list[dbc->ilist + 1];
Bernhard M. Wiedemann 018f1b
-#if 0
Bernhard M. Wiedemann 018f1b
-	if (searchType == DBC_KEY_SEARCH) {
Bernhard M. Wiedemann 018f1b
+
Bernhard M. Wiedemann 018f1b
+	if (set == NULL) {
Bernhard M. Wiedemann 018f1b
 	    dbc->ilist += 2;
Bernhard M. Wiedemann 018f1b
 	    dbc->key = k;
Bernhard M. Wiedemann 018f1b
 	    dbc->keylen = kl;
Bernhard M. Wiedemann 018f1b
 	    rc = RPMRC_OK;
Bernhard M. Wiedemann 018f1b
 	    break;
Bernhard M. Wiedemann 018f1b
 	}
Bernhard M. Wiedemann 018f1b
-#endif
Bernhard M. Wiedemann 018f1b
+
Bernhard M. Wiedemann 018f1b
 	pkglist = 0;
Bernhard M. Wiedemann 018f1b
 	pkglistn = 0;
Bernhard M. Wiedemann 018f1b
 	rc = rpmidxGet(dbc->dbi->dbi_db, k, kl, &pkglist, &pkglistn);
Bernhard M. Wiedemann 018f1b
--- ./lib/backend/ndb/rpmpkg.c.orig	2019-11-13 09:19:29.306710577 +0000
Bernhard M. Wiedemann 018f1b
+++ ./lib/backend/ndb/rpmpkg.c	2020-01-23 12:48:59.739630414 +0000
Bernhard M. Wiedemann 018f1b
@@ -7,7 +7,6 @@
Bernhard M. Wiedemann 018f1b
 #include <sys/file.h>
Bernhard M. Wiedemann 018f1b
 #include <fcntl.h>
Bernhard M. Wiedemann 018f1b
 #include <stdio.h>
Bernhard M. Wiedemann 018f1b
-#include <time.h>
Bernhard M. Wiedemann 018f1b
 #include <unistd.h>
Bernhard M. Wiedemann 018f1b
 #include <string.h>
Bernhard M. Wiedemann 018f1b
 #include <stdlib.h>
Bernhard M. Wiedemann 018f1b
@@ -19,10 +18,6 @@
Bernhard M. Wiedemann 018f1b
 #define RPMRC_NOTFOUND 1
Bernhard M. Wiedemann 018f1b
 #define RPMRC_OK 0
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
-#ifdef RPMPKG_LZO
Bernhard M. Wiedemann 018f1b
-static int rpmpkgLZOCompress(unsigned char **blobp, unsigned int *bloblp);
Bernhard M. Wiedemann 018f1b
-static int rpmpkgLZODecompress(unsigned char **blobp, unsigned int *bloblp);
Bernhard M. Wiedemann 018f1b
-#endif
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 static int rpmpkgVerifyblob(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned int blkoff, unsigned int blkcnt);
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
@@ -49,23 +44,19 @@ typedef struct rpmpkgdb_s {
Bernhard M. Wiedemann 018f1b
     unsigned int nextpkgidx;
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
     struct pkgslot_s *slots;
Bernhard M. Wiedemann 018f1b
-    unsigned int aslots;	/* allocated slots */
Bernhard M. Wiedemann 018f1b
     unsigned int nslots;	/* used slots */
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
     unsigned int *slothash;
Bernhard M. Wiedemann 018f1b
     unsigned int nslothash;
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
     unsigned int freeslot;	/* first free slot */
Bernhard M. Wiedemann 018f1b
-    int slotorder;
Bernhard M. Wiedemann 018f1b
+    int ordered;		/* slots are ordered by the blk offsets */
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
     char *filename;
Bernhard M. Wiedemann 018f1b
     unsigned int fileblks;	/* file size in blks */
Bernhard M. Wiedemann 018f1b
     int dofsync;
Bernhard M. Wiedemann 018f1b
 } * rpmpkgdb;
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
-#define SLOTORDER_UNORDERED	0
Bernhard M. Wiedemann 018f1b
-#define SLOTORDER_BLKOFF	1
Bernhard M. Wiedemann 018f1b
-
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 static inline unsigned int le2h(unsigned char *p) 
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
@@ -144,10 +135,6 @@ static int rpmpkgReadHeader(rpmpkgdb pkg
Bernhard M. Wiedemann 018f1b
     if (pkgdb->slots && (pkgdb->generation != generation || pkgdb->slotnpages != slotnpages)) {
Bernhard M. Wiedemann 018f1b
 	free(pkgdb->slots);
Bernhard M. Wiedemann 018f1b
 	pkgdb->slots = 0;
Bernhard M. Wiedemann 018f1b
-	if (pkgdb->slothash) {
Bernhard M. Wiedemann 018f1b
-	    free(pkgdb->slothash);
Bernhard M. Wiedemann 018f1b
-	    pkgdb->slothash = 0;
Bernhard M. Wiedemann 018f1b
-	}
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
     pkgdb->generation = generation;
Bernhard M. Wiedemann 018f1b
     pkgdb->slotnpages = slotnpages;
Bernhard M. Wiedemann 018f1b
@@ -200,6 +187,7 @@ static inline unsigned int hashpkgidx(un
Bernhard M. Wiedemann 018f1b
     return h;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
+/* (re-)create a hash mapping pkgidx numbers to slots */
Bernhard M. Wiedemann 018f1b
 static int rpmpkgHashSlots(rpmpkgdb pkgdb)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
     unsigned int nslots, num;
Bernhard M. Wiedemann 018f1b
@@ -208,14 +196,14 @@ static int rpmpkgHashSlots(rpmpkgdb pkgd
Bernhard M. Wiedemann 018f1b
     int i;
Bernhard M. Wiedemann 018f1b
     pkgslot *slot;
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
-    pkgdb->nslothash = 0;
Bernhard M. Wiedemann 018f1b
-    num = pkgdb->nslots;
Bernhard M. Wiedemann 018f1b
+    num = pkgdb->nslots + 32;
Bernhard M. Wiedemann 018f1b
     while (num & (num - 1))
Bernhard M. Wiedemann 018f1b
 	num = num & (num - 1);
Bernhard M. Wiedemann 018f1b
     num *= 4;
Bernhard M. Wiedemann 018f1b
     hash = pkgdb->slothash;
Bernhard M. Wiedemann 018f1b
     if (!hash || pkgdb->nslothash != num) {
Bernhard M. Wiedemann 018f1b
-	free(pkgdb->slothash);
Bernhard M. Wiedemann 018f1b
+	if (hash)
Bernhard M. Wiedemann 018f1b
+	    free(hash);
Bernhard M. Wiedemann 018f1b
 	hash = pkgdb->slothash = xcalloc(num, sizeof(unsigned int));
Bernhard M. Wiedemann 018f1b
 	pkgdb->nslothash = num;
Bernhard M. Wiedemann 018f1b
     } else {
Bernhard M. Wiedemann 018f1b
@@ -228,8 +216,6 @@ static int rpmpkgHashSlots(rpmpkgdb pkgd
Bernhard M. Wiedemann 018f1b
 	    ;
Bernhard M. Wiedemann 018f1b
 	hash[h] = i + 1;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
-    pkgdb->slothash = hash;
Bernhard M. Wiedemann 018f1b
-    pkgdb->nslothash = num;
Bernhard M. Wiedemann 018f1b
     return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
@@ -247,10 +233,6 @@ static int rpmpkgReadSlots(rpmpkgdb pkgd
Bernhard M. Wiedemann 018f1b
 	free(pkgdb->slots);
Bernhard M. Wiedemann 018f1b
 	pkgdb->slots = 0;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
-    if (pkgdb->slothash) {
Bernhard M. Wiedemann 018f1b
-	free(pkgdb->slothash);
Bernhard M. Wiedemann 018f1b
-	pkgdb->slothash = 0;
Bernhard M. Wiedemann 018f1b
-    }
Bernhard M. Wiedemann 018f1b
     pkgdb->nslots = 0;
Bernhard M. Wiedemann 018f1b
     pkgdb->freeslot = 0;
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
@@ -262,8 +244,7 @@ static int rpmpkgReadSlots(rpmpkgdb pkgd
Bernhard M. Wiedemann 018f1b
     fileblks = stb.st_size / BLK_SIZE;
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
     /* read (and somewhat verify) all slots */
Bernhard M. Wiedemann 018f1b
-    pkgdb->aslots = slotnpages * (PAGE_SIZE / SLOT_SIZE);
Bernhard M. Wiedemann 018f1b
-    pkgdb->slots = xcalloc(pkgdb->aslots, sizeof(*pkgdb->slots));
Bernhard M. Wiedemann 018f1b
+    pkgdb->slots = xcalloc(slotnpages * (PAGE_SIZE / SLOT_SIZE), sizeof(*pkgdb->slots));
Bernhard M. Wiedemann 018f1b
     i = 0;
Bernhard M. Wiedemann 018f1b
     slot = pkgdb->slots;
Bernhard M. Wiedemann 018f1b
     minblkoff = slotnpages * (PAGE_SIZE / BLK_SIZE);
Bernhard M. Wiedemann 018f1b
@@ -299,7 +280,7 @@ static int rpmpkgReadSlots(rpmpkgdb pkgd
Bernhard M. Wiedemann 018f1b
 	}
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
     pkgdb->nslots = i;
Bernhard M. Wiedemann 018f1b
-    pkgdb->slotorder = SLOTORDER_UNORDERED;	/* XXX: always order? */
Bernhard M. Wiedemann 018f1b
+    pkgdb->ordered = 0;
Bernhard M. Wiedemann 018f1b
     pkgdb->fileblks = fileblks;
Bernhard M. Wiedemann 018f1b
     pkgdb->freeslot = freeslot;
Bernhard M. Wiedemann 018f1b
     if (rpmpkgHashSlots(pkgdb)) {
Bernhard M. Wiedemann 018f1b
@@ -317,15 +298,13 @@ static int orderslots_blkoff_cmp(const v
Bernhard M. Wiedemann 018f1b
     return blkoffa > blkoffb ? 1 : blkoffa < blkoffb ? -1 : 0;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
-static void rpmpkgOrderSlots(rpmpkgdb pkgdb, int slotorder)
Bernhard M. Wiedemann 018f1b
+static void rpmpkgOrderSlots(rpmpkgdb pkgdb)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
-    if (pkgdb->slotorder == slotorder)
Bernhard M. Wiedemann 018f1b
+    if (pkgdb->ordered)
Bernhard M. Wiedemann 018f1b
 	return;
Bernhard M. Wiedemann 018f1b
-    if (slotorder == SLOTORDER_BLKOFF) {
Bernhard M. Wiedemann 018f1b
-	if (pkgdb->nslots > 1)
Bernhard M. Wiedemann 018f1b
-	    qsort(pkgdb->slots, pkgdb->nslots, sizeof(*pkgdb->slots), orderslots_blkoff_cmp);
Bernhard M. Wiedemann 018f1b
-    }
Bernhard M. Wiedemann 018f1b
-    pkgdb->slotorder = slotorder;
Bernhard M. Wiedemann 018f1b
+    if (pkgdb->nslots > 1)
Bernhard M. Wiedemann 018f1b
+	qsort(pkgdb->slots, pkgdb->nslots, sizeof(*pkgdb->slots), orderslots_blkoff_cmp);
Bernhard M. Wiedemann 018f1b
+    pkgdb->ordered = 1;
Bernhard M. Wiedemann 018f1b
     rpmpkgHashSlots(pkgdb);
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
@@ -340,6 +319,8 @@ static inline pkgslot *rpmpkgFindSlot(rp
Bernhard M. Wiedemann 018f1b
     return 0;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
+/* Find an empty space for blkcnt blocks. If dontprepend is true, ignore
Bernhard M. Wiedemann 018f1b
+   the space between the slot area and the first blob */
Bernhard M. Wiedemann 018f1b
 static int rpmpkgFindEmptyOffset(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned int blkcnt, unsigned *blkoffp, pkgslot **oldslotp, int dontprepend)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
     unsigned int i, nslots = pkgdb->nslots;
Bernhard M. Wiedemann 018f1b
@@ -348,8 +329,8 @@ static int rpmpkgFindEmptyOffset(rpmpkgd
Bernhard M. Wiedemann 018f1b
     unsigned int lastblkend = pkgdb->slotnpages * (PAGE_SIZE / BLK_SIZE);
Bernhard M. Wiedemann 018f1b
     pkgslot *slot, *oldslot = 0;
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
-    if (pkgdb->slotorder != SLOTORDER_BLKOFF)
Bernhard M. Wiedemann 018f1b
-	rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
Bernhard M. Wiedemann 018f1b
+    if (!pkgdb->ordered)
Bernhard M. Wiedemann 018f1b
+	rpmpkgOrderSlots(pkgdb);
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
     if (dontprepend && nslots) {
Bernhard M. Wiedemann 018f1b
 	lastblkend = pkgdb->slots[0].blkoff;
Bernhard M. Wiedemann 018f1b
@@ -382,14 +363,15 @@ static int rpmpkgFindEmptyOffset(rpmpkgd
Bernhard M. Wiedemann 018f1b
     return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
+/* verify the blobs to the left and right of a free area */
Bernhard M. Wiedemann 018f1b
 static int rpmpkgNeighbourCheck(rpmpkgdb pkgdb, unsigned int blkoff, unsigned int blkcnt, unsigned int *newblkcnt)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
     unsigned int i, nslots = pkgdb->nslots;
Bernhard M. Wiedemann 018f1b
     unsigned int lastblkend = pkgdb->slotnpages * (PAGE_SIZE / BLK_SIZE);
Bernhard M. Wiedemann 018f1b
     pkgslot *slot, *left = 0, *right = 0;
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
-    if (pkgdb->slotorder != SLOTORDER_BLKOFF)
Bernhard M. Wiedemann 018f1b
-	rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
Bernhard M. Wiedemann 018f1b
+    if (!pkgdb->ordered)
Bernhard M. Wiedemann 018f1b
+	rpmpkgOrderSlots(pkgdb);
Bernhard M. Wiedemann 018f1b
     if (blkoff < lastblkend)
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     for (i = 0, slot = pkgdb->slots; i < nslots; i++, slot++) {
Bernhard M. Wiedemann 018f1b
@@ -413,7 +395,7 @@ static int rpmpkgNeighbourCheck(rpmpkgdb
Bernhard M. Wiedemann 018f1b
     if (right && rpmpkgVerifyblob(pkgdb, right->pkgidx, right->blkoff, right->blkcnt) != RPMRC_OK)
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     *newblkcnt = right ? right->blkoff - blkoff : blkcnt;
Bernhard M. Wiedemann 018f1b
-    /* bounds are intect. free area. */
Bernhard M. Wiedemann 018f1b
+    /* bounds are intact. ok to zero area. */
Bernhard M. Wiedemann 018f1b
     return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
@@ -433,6 +415,7 @@ static int rpmpkgWriteslot(rpmpkgdb pkgd
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
     pkgdb->generation++;
Bernhard M. Wiedemann 018f1b
+    /* rpmpkgFsync() is done by rpmpkgWriteHeader() */
Bernhard M. Wiedemann 018f1b
     if (rpmpkgWriteHeader(pkgdb)) {
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
@@ -527,7 +510,7 @@ static int rpmpkgValidateZero(rpmpkgdb p
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 /*** Blob primitives ***/
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
-/* head: magic + pkgidx + timestamp + bloblen */
Bernhard M. Wiedemann 018f1b
+/* head: magic + pkgidx + generation + bloblen */
Bernhard M. Wiedemann 018f1b
 /* tail: adler32 + bloblen + magic */
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 #define BLOBHEAD_MAGIC	('B' | 'l' << 8 | 'b' << 16 | 'S' << 24)
Bernhard M. Wiedemann 018f1b
@@ -536,10 +519,10 @@ static int rpmpkgValidateZero(rpmpkgdb p
Bernhard M. Wiedemann 018f1b
 #define BLOBHEAD_SIZE	(4 + 4 + 4 + 4)
Bernhard M. Wiedemann 018f1b
 #define BLOBTAIL_SIZE	(4 + 4 + 4)
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
-static int rpmpkgReadBlob(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned int blkoff, unsigned int blkcnt, unsigned char *blob, unsigned int *bloblp, unsigned int *tstampp)
Bernhard M. Wiedemann 018f1b
+static int rpmpkgReadBlob(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned int blkoff, unsigned int blkcnt, unsigned char *blob, unsigned int *bloblp, unsigned int *generationp)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
     unsigned char buf[BLOBHEAD_SIZE > BLOBTAIL_SIZE ? BLOBHEAD_SIZE : BLOBTAIL_SIZE];
Bernhard M. Wiedemann 018f1b
-    unsigned int bloblen, toread, tstamp;
Bernhard M. Wiedemann 018f1b
+    unsigned int bloblen, toread, generation;
Bernhard M. Wiedemann 018f1b
     off_t fileoff;
Bernhard M. Wiedemann 018f1b
     unsigned int adl;
Bernhard M. Wiedemann 018f1b
     int verifyadler = bloblp ? 0 : 1;
Bernhard M. Wiedemann 018f1b
@@ -555,7 +538,7 @@ static int rpmpkgReadBlob(rpmpkgdb pkgdb
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;	/* bad blob */
Bernhard M. Wiedemann 018f1b
     if (le2h(buf + 4) != pkgidx)
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;	/* bad blob */
Bernhard M. Wiedemann 018f1b
-    tstamp = le2h(buf + 8);
Bernhard M. Wiedemann 018f1b
+    generation = le2h(buf + 8);
Bernhard M. Wiedemann 018f1b
     bloblen = le2h(buf + 12);
Bernhard M. Wiedemann 018f1b
     if (blkcnt != (BLOBHEAD_SIZE + bloblen + BLOBTAIL_SIZE + BLK_SIZE - 1) / BLK_SIZE)
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;	/* bad blob */
Bernhard M. Wiedemann 018f1b
@@ -600,8 +583,8 @@ static int rpmpkgReadBlob(rpmpkgdb pkgdb
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
     if (bloblp)
Bernhard M. Wiedemann 018f1b
 	*bloblp = bloblen;
Bernhard M. Wiedemann 018f1b
-    if (tstampp)
Bernhard M. Wiedemann 018f1b
-	*tstampp = tstamp;
Bernhard M. Wiedemann 018f1b
+    if (generationp)
Bernhard M. Wiedemann 018f1b
+	*generationp = generation;
Bernhard M. Wiedemann 018f1b
     return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
@@ -684,14 +667,14 @@ static int rpmpkgMoveBlob(rpmpkgdb pkgdb
Bernhard M. Wiedemann 018f1b
     unsigned int blkoff = slot->blkoff;
Bernhard M. Wiedemann 018f1b
     unsigned int blkcnt = slot->blkcnt;
Bernhard M. Wiedemann 018f1b
     unsigned char *blob;
Bernhard M. Wiedemann 018f1b
-    unsigned int tstamp, blobl;
Bernhard M. Wiedemann 018f1b
+    unsigned int generation, blobl;
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
     blob = xmalloc((size_t)blkcnt * BLK_SIZE);
Bernhard M. Wiedemann 018f1b
-    if (rpmpkgReadBlob(pkgdb, pkgidx, blkoff, blkcnt, blob, &blobl, &tstamp)) {
Bernhard M. Wiedemann 018f1b
+    if (rpmpkgReadBlob(pkgdb, pkgidx, blkoff, blkcnt, blob, &blobl, &generation)) {
Bernhard M. Wiedemann 018f1b
 	free(blob);
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
-    if (rpmpkgWriteBlob(pkgdb, pkgidx, newblkoff, blkcnt, blob, blobl, tstamp)) {
Bernhard M. Wiedemann 018f1b
+    if (rpmpkgWriteBlob(pkgdb, pkgidx, newblkoff, blkcnt, blob, blobl, generation)) {
Bernhard M. Wiedemann 018f1b
 	free(blob);
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
@@ -703,15 +686,15 @@ static int rpmpkgMoveBlob(rpmpkgdb pkgdb
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
     slot->blkoff = newblkoff;
Bernhard M. Wiedemann 018f1b
-    pkgdb->slotorder = SLOTORDER_UNORDERED;
Bernhard M. Wiedemann 018f1b
+    pkgdb->ordered = 0;
Bernhard M. Wiedemann 018f1b
     return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 static int rpmpkgAddSlotPage(rpmpkgdb pkgdb)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
     unsigned int cutoff;
Bernhard M. Wiedemann 018f1b
-    if (pkgdb->slotorder != SLOTORDER_BLKOFF)
Bernhard M. Wiedemann 018f1b
-	rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
Bernhard M. Wiedemann 018f1b
+    if (!pkgdb->ordered)
Bernhard M. Wiedemann 018f1b
+	rpmpkgOrderSlots(pkgdb);
Bernhard M. Wiedemann 018f1b
     cutoff = (pkgdb->slotnpages + 1) * (PAGE_SIZE / BLK_SIZE);
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
     /* now move every blob before cutoff */
Bernhard M. Wiedemann 018f1b
@@ -729,7 +712,7 @@ static int rpmpkgAddSlotPage(rpmpkgdb pk
Bernhard M. Wiedemann 018f1b
 	if (rpmpkgMoveBlob(pkgdb, slot, newblkoff)) {
Bernhard M. Wiedemann 018f1b
 	    return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
 	}
Bernhard M. Wiedemann 018f1b
-	rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
Bernhard M. Wiedemann 018f1b
+	rpmpkgOrderSlots(pkgdb);
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
     /* make sure our new page is empty */
Bernhard M. Wiedemann 018f1b
@@ -958,6 +941,7 @@ static int rpmpkgPutInternal(rpmpkgdb pk
Bernhard M. Wiedemann 018f1b
     pkgslot *oldslot;
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
     /* we always read all slots when writing, just in case */
Bernhard M. Wiedemann 018f1b
+    /* this also will set pkgdb->freeslot */
Bernhard M. Wiedemann 018f1b
     if (rpmpkgReadSlots(pkgdb)) {
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
@@ -981,14 +965,15 @@ static int rpmpkgPutInternal(rpmpkgdb pk
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
     /* write new blob */
Bernhard M. Wiedemann 018f1b
-    if (rpmpkgWriteBlob(pkgdb, pkgidx, blkoff, blkcnt, blob, blobl, (unsigned int)time(0))) {
Bernhard M. Wiedemann 018f1b
+    if (rpmpkgWriteBlob(pkgdb, pkgidx, blkoff, blkcnt, blob, blobl, pkgdb->generation)) {
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
+    /* update nextpkgidx if needed */
Bernhard M. Wiedemann 018f1b
+    if (pkgidx >= pkgdb->nextpkgidx) {
Bernhard M. Wiedemann 018f1b
+	pkgdb->nextpkgidx = pkgidx + 1;
Bernhard M. Wiedemann 018f1b
+    }
Bernhard M. Wiedemann 018f1b
     /* write slot */
Bernhard M. Wiedemann 018f1b
     slotno = oldslot ? oldslot->slotno : pkgdb->freeslot;
Bernhard M. Wiedemann 018f1b
-    if (!slotno) {
Bernhard M. Wiedemann 018f1b
-	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    }
Bernhard M. Wiedemann 018f1b
     if (rpmpkgWriteslot(pkgdb, slotno, pkgidx, blkoff, blkcnt)) {
Bernhard M. Wiedemann 018f1b
 	free(pkgdb->slots);
Bernhard M. Wiedemann 018f1b
 	pkgdb->slots = 0;
Bernhard M. Wiedemann 018f1b
@@ -1006,7 +991,7 @@ static int rpmpkgPutInternal(rpmpkgdb pk
Bernhard M. Wiedemann 018f1b
 	/* just update the slot, no need to free the slot data */
Bernhard M. Wiedemann 018f1b
 	oldslot->blkoff = blkoff;
Bernhard M. Wiedemann 018f1b
 	oldslot->blkcnt = blkcnt;
Bernhard M. Wiedemann 018f1b
-	pkgdb->slotorder = SLOTORDER_UNORDERED;
Bernhard M. Wiedemann 018f1b
+	pkgdb->ordered = 0;
Bernhard M. Wiedemann 018f1b
     } else {
Bernhard M. Wiedemann 018f1b
 	free(pkgdb->slots);
Bernhard M. Wiedemann 018f1b
 	pkgdb->slots = 0;
Bernhard M. Wiedemann 018f1b
@@ -1023,7 +1008,7 @@ static int rpmpkgDelInternal(rpmpkgdb pk
Bernhard M. Wiedemann 018f1b
     if (rpmpkgReadSlots(pkgdb)) {
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
-    rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
Bernhard M. Wiedemann 018f1b
+    rpmpkgOrderSlots(pkgdb);
Bernhard M. Wiedemann 018f1b
     slot = rpmpkgFindSlot(pkgdb, pkgidx);
Bernhard M. Wiedemann 018f1b
     if (!slot) {
Bernhard M. Wiedemann 018f1b
 	return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
@@ -1049,9 +1034,10 @@ static int rpmpkgDelInternal(rpmpkgdb pk
Bernhard M. Wiedemann 018f1b
 	}
Bernhard M. Wiedemann 018f1b
 	slot->blkoff = 0;
Bernhard M. Wiedemann 018f1b
 	slot->blkcnt = 0;
Bernhard M. Wiedemann 018f1b
+	/* try to move the last two slots, the bigger one first */
Bernhard M. Wiedemann 018f1b
 	slot = pkgdb->slots + pkgdb->nslots - 2;
Bernhard M. Wiedemann 018f1b
 	if (slot->blkcnt < slot[1].blkcnt)
Bernhard M. Wiedemann 018f1b
-	  slot++;	/* bigger slot first */
Bernhard M. Wiedemann 018f1b
+	    slot++;	/* bigger slot first */
Bernhard M. Wiedemann 018f1b
 	for (i = 0; i < 2; i++, slot++) {
Bernhard M. Wiedemann 018f1b
 	    if (slot == pkgdb->slots + pkgdb->nslots)
Bernhard M. Wiedemann 018f1b
 		slot -= 2;
Bernhard M. Wiedemann 018f1b
@@ -1065,7 +1051,7 @@ static int rpmpkgDelInternal(rpmpkgdb pk
Bernhard M. Wiedemann 018f1b
 	    blkoff += slot->blkcnt;
Bernhard M. Wiedemann 018f1b
 	    blkcnt -= slot->blkcnt;
Bernhard M. Wiedemann 018f1b
 	}
Bernhard M. Wiedemann 018f1b
-	rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
Bernhard M. Wiedemann 018f1b
+	rpmpkgOrderSlots(pkgdb);
Bernhard M. Wiedemann 018f1b
     } else {
Bernhard M. Wiedemann 018f1b
 	slot->blkoff = 0;
Bernhard M. Wiedemann 018f1b
 	slot->blkcnt = 0;
Bernhard M. Wiedemann 018f1b
@@ -1104,7 +1090,7 @@ static int rpmpkgListInternal(rpmpkgdb p
Bernhard M. Wiedemann 018f1b
 	*npkgidxlistp = pkgdb->nslots;
Bernhard M. Wiedemann 018f1b
 	return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
-    rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
Bernhard M. Wiedemann 018f1b
+    rpmpkgOrderSlots(pkgdb);
Bernhard M. Wiedemann 018f1b
     nslots = pkgdb->nslots;
Bernhard M. Wiedemann 018f1b
     pkgidxlist = xcalloc(nslots + 1, sizeof(unsigned int));
Bernhard M. Wiedemann 018f1b
     for (i = 0, slot = pkgdb->slots; i < nslots; i++, slot++) {
Bernhard M. Wiedemann 018f1b
@@ -1115,6 +1101,22 @@ static int rpmpkgListInternal(rpmpkgdb p
Bernhard M. Wiedemann 018f1b
     return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
+static int rpmpkgVerifyInternal(rpmpkgdb pkgdb)
Bernhard M. Wiedemann 018f1b
+{
Bernhard M. Wiedemann 018f1b
+    unsigned int i, nslots;
Bernhard M. Wiedemann 018f1b
+    pkgslot *slot;
Bernhard M. Wiedemann 018f1b
+
Bernhard M. Wiedemann 018f1b
+    if (rpmpkgReadSlots(pkgdb))
Bernhard M. Wiedemann 018f1b
+	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
+    rpmpkgOrderSlots(pkgdb);
Bernhard M. Wiedemann 018f1b
+    nslots = pkgdb->nslots;
Bernhard M. Wiedemann 018f1b
+    for (i = 0, slot = pkgdb->slots; i < nslots; i++, slot++) {
Bernhard M. Wiedemann 018f1b
+	if (rpmpkgVerifyblob(pkgdb, slot->pkgidx, slot->blkoff, slot->blkcnt))
Bernhard M. Wiedemann 018f1b
+	    return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
+    }
Bernhard M. Wiedemann 018f1b
+    return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
+}
Bernhard M. Wiedemann 018f1b
+
Bernhard M. Wiedemann 018f1b
 int rpmpkgGet(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char **blobp, unsigned int *bloblp)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
     int rc;
Bernhard M. Wiedemann 018f1b
@@ -1127,10 +1129,6 @@ int rpmpkgGet(rpmpkgdb pkgdb, unsigned i
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     rc = rpmpkgGetInternal(pkgdb, pkgidx, blobp, bloblp);
Bernhard M. Wiedemann 018f1b
     rpmpkgUnlock(pkgdb, 0);
Bernhard M. Wiedemann 018f1b
-#ifdef RPMPKG_LZO
Bernhard M. Wiedemann 018f1b
-    if (!rc)
Bernhard M. Wiedemann 018f1b
-	rc = rpmpkgLZODecompress(blobp, bloblp);
Bernhard M. Wiedemann 018f1b
-#endif
Bernhard M. Wiedemann 018f1b
     return rc;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
@@ -1143,16 +1141,7 @@ int rpmpkgPut(rpmpkgdb pkgdb, unsigned i
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
     if (rpmpkgLockReadHeader(pkgdb, 1))
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-#ifdef RPMPKG_LZO
Bernhard M. Wiedemann 018f1b
-    if (rpmpkgLZOCompress(&blob, &blobl)) {
Bernhard M. Wiedemann 018f1b
-	rpmpkgUnlock(pkgdb, 1);
Bernhard M. Wiedemann 018f1b
-	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    }
Bernhard M. Wiedemann 018f1b
-#endif
Bernhard M. Wiedemann 018f1b
     rc = rpmpkgPutInternal(pkgdb, pkgidx, blob, blobl);
Bernhard M. Wiedemann 018f1b
-#ifdef RPMPKG_LZO
Bernhard M. Wiedemann 018f1b
-    free(blob);
Bernhard M. Wiedemann 018f1b
-#endif
Bernhard M. Wiedemann 018f1b
     rpmpkgUnlock(pkgdb, 1);
Bernhard M. Wiedemann 018f1b
     return rc;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
@@ -1184,6 +1173,16 @@ int rpmpkgList(rpmpkgdb pkgdb, unsigned
Bernhard M. Wiedemann 018f1b
     return rc;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
+int rpmpkgVerify(rpmpkgdb pkgdb)
Bernhard M. Wiedemann 018f1b
+{
Bernhard M. Wiedemann 018f1b
+    int rc;
Bernhard M. Wiedemann 018f1b
+    if (rpmpkgLockReadHeader(pkgdb, 0))
Bernhard M. Wiedemann 018f1b
+	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
+    rc = rpmpkgVerifyInternal(pkgdb);
Bernhard M. Wiedemann 018f1b
+    rpmpkgUnlock(pkgdb, 0);
Bernhard M. Wiedemann 018f1b
+    return rc;
Bernhard M. Wiedemann 018f1b
+}
Bernhard M. Wiedemann 018f1b
+
Bernhard M. Wiedemann 018f1b
 int rpmpkgNextPkgIdx(rpmpkgdb pkgdb, unsigned int *pkgidxp)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
     if (rpmpkgLockReadHeader(pkgdb, 1))
Bernhard M. Wiedemann 018f1b
@@ -1233,64 +1232,3 @@ int rpmpkgStats(rpmpkgdb pkgdb)
Bernhard M. Wiedemann 018f1b
     return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
-#ifdef RPMPKG_LZO
Bernhard M. Wiedemann 018f1b
-
Bernhard M. Wiedemann 018f1b
-#include "lzo/lzoconf.h"
Bernhard M. Wiedemann 018f1b
-#include "lzo/lzo1x.h"
Bernhard M. Wiedemann 018f1b
-
Bernhard M. Wiedemann 018f1b
-#define BLOBLZO_MAGIC	('L' | 'Z' << 8 | 'O' << 16 | 'B' << 24)
Bernhard M. Wiedemann 018f1b
-
Bernhard M. Wiedemann 018f1b
-static int rpmpkgLZOCompress(unsigned char **blobp, unsigned int *bloblp)
Bernhard M. Wiedemann 018f1b
-{
Bernhard M. Wiedemann 018f1b
-    unsigned char *blob = *blobp;
Bernhard M. Wiedemann 018f1b
-    unsigned int blobl = *bloblp;
Bernhard M. Wiedemann 018f1b
-    unsigned char *lzoblob, *workmem;
Bernhard M. Wiedemann 018f1b
-    unsigned int lzoblobl;
Bernhard M. Wiedemann 018f1b
-    lzo_uint blobl2;
Bernhard M. Wiedemann 018f1b
-
Bernhard M. Wiedemann 018f1b
-    if (lzo_init() != LZO_E_OK) {
Bernhard M. Wiedemann 018f1b
-	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    }
Bernhard M. Wiedemann 018f1b
-    workmem = xmalloc(LZO1X_1_MEM_COMPRESS);
Bernhard M. Wiedemann 018f1b
-    lzoblobl = 4 + 4 + blobl + blobl / 16 + 64 + 3;
Bernhard M. Wiedemann 018f1b
-    lzoblob = xmalloc(lzoblobl);
Bernhard M. Wiedemann 018f1b
-    h2le(BLOBLZO_MAGIC, lzoblob);
Bernhard M. Wiedemann 018f1b
-    h2le(blobl, lzoblob + 4);
Bernhard M. Wiedemann 018f1b
-    if (lzo1x_1_compress(blob, blobl, lzoblob + 8, &blobl2, workmem) != LZO_E_OK) {
Bernhard M. Wiedemann 018f1b
-	free(workmem);
Bernhard M. Wiedemann 018f1b
-	free(lzoblob);
Bernhard M. Wiedemann 018f1b
-	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    }
Bernhard M. Wiedemann 018f1b
-    free(workmem);
Bernhard M. Wiedemann 018f1b
-    *blobp = lzoblob;
Bernhard M. Wiedemann 018f1b
-    *bloblp = 8 + blobl2;
Bernhard M. Wiedemann 018f1b
-    return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
-}
Bernhard M. Wiedemann 018f1b
-
Bernhard M. Wiedemann 018f1b
-static int rpmpkgLZODecompress(unsigned char **blobp, unsigned int *bloblp)
Bernhard M. Wiedemann 018f1b
-{
Bernhard M. Wiedemann 018f1b
-    unsigned char *lzoblob = *blobp;
Bernhard M. Wiedemann 018f1b
-    unsigned int lzoblobl = *bloblp;
Bernhard M. Wiedemann 018f1b
-    unsigned char *blob;
Bernhard M. Wiedemann 018f1b
-    unsigned int blobl;
Bernhard M. Wiedemann 018f1b
-    lzo_uint blobl2;
Bernhard M. Wiedemann 018f1b
-
Bernhard M. Wiedemann 018f1b
-    if (!lzoblob || lzoblobl < 8)
Bernhard M. Wiedemann 018f1b
-	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    if (le2h(lzoblob) != BLOBLZO_MAGIC)
Bernhard M. Wiedemann 018f1b
-	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    if (lzo_init() != LZO_E_OK)
Bernhard M. Wiedemann 018f1b
-	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    blobl = le2h(lzoblob + 4);
Bernhard M. Wiedemann 018f1b
-    blob = xmalloc(blobl ? blobl : 1);
Bernhard M. Wiedemann 018f1b
-    if (lzo1x_decompress(lzoblob + 8, lzoblobl - 8, blob, &blobl2, 0) != LZO_E_OK || blobl2 != blobl) {
Bernhard M. Wiedemann 018f1b
-	free(blob);
Bernhard M. Wiedemann 018f1b
-	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    }
Bernhard M. Wiedemann 018f1b
-    free(lzoblob);
Bernhard M. Wiedemann 018f1b
-    *blobp = blob;
Bernhard M. Wiedemann 018f1b
-    *bloblp = blobl;
Bernhard M. Wiedemann 018f1b
-    return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
-}
Bernhard M. Wiedemann 018f1b
-
Bernhard M. Wiedemann 018f1b
-#endif
Bernhard M. Wiedemann 018f1b
--- ./lib/backend/ndb/rpmpkg.h.orig	2019-06-26 14:17:31.406985703 +0000
Bernhard M. Wiedemann 018f1b
+++ ./lib/backend/ndb/rpmpkg.h	2020-01-23 12:48:20.919728972 +0000
Bernhard M. Wiedemann 018f1b
@@ -12,6 +12,7 @@ int rpmpkgGet(rpmpkgdb pkgdb, unsigned i
Bernhard M. Wiedemann 018f1b
 int rpmpkgPut(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char *blob, unsigned int blobl);
Bernhard M. Wiedemann 018f1b
 int rpmpkgDel(rpmpkgdb pkgdb, unsigned int pkgidx);
Bernhard M. Wiedemann 018f1b
 int rpmpkgList(rpmpkgdb pkgdb, unsigned int **pkgidxlistp, unsigned int *npkgidxlistp);
Bernhard M. Wiedemann 018f1b
+int rpmpkgVerify(rpmpkgdb pkgdb);
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 int rpmpkgNextPkgIdx(rpmpkgdb pkgdb, unsigned int *pkgidxp);
Bernhard M. Wiedemann 018f1b
 int rpmpkgGeneration(rpmpkgdb pkgdb, unsigned int *generationp);
Bernhard M. Wiedemann 018f1b
--- ./lib/backend/ndb/rpmxdb.c.orig	2019-11-13 09:19:29.307710583 +0000
Bernhard M. Wiedemann 018f1b
+++ ./lib/backend/ndb/rpmxdb.c	2020-01-23 12:48:20.919728972 +0000
Bernhard M. Wiedemann 018f1b
@@ -224,11 +224,33 @@ static int usedslots_cmp(const void *a,
Bernhard M. Wiedemann 018f1b
     return sa->startpage > sb->startpage ? 1 : -1;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
+static int rpmxdbReadHeaderRaw(rpmxdb xdb, unsigned int *generationp, unsigned int *slotnpagesp, unsigned int *pagesizep, unsigned int *usergenerationp)
Bernhard M. Wiedemann 018f1b
+{
Bernhard M. Wiedemann 018f1b
+    unsigned int header[XDB_HEADER_SIZE / sizeof(unsigned int)];
Bernhard M. Wiedemann 018f1b
+    unsigned int version;
Bernhard M. Wiedemann 018f1b
+    if (pread(xdb->fd, header, sizeof(header), 0) != sizeof(header))
Bernhard M. Wiedemann 018f1b
+	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
+    if (le2ha((unsigned char *)header + XDB_OFFSET_MAGIC) != XDB_MAGIC)
Bernhard M. Wiedemann 018f1b
+	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
+    version = le2ha((unsigned char *)header + XDB_OFFSET_VERSION);
Bernhard M. Wiedemann 018f1b
+    if (version != XDB_VERSION) {
Bernhard M. Wiedemann 018f1b
+	rpmlog(RPMLOG_ERR, _("rpmxdb: Version mismatch. Expected version: %u. "
Bernhard M. Wiedemann 018f1b
+	    "Found version: %u\n"), XDB_VERSION, version);
Bernhard M. Wiedemann 018f1b
+	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
+    }
Bernhard M. Wiedemann 018f1b
+    *generationp = le2ha((unsigned char *)header + XDB_OFFSET_GENERATION);
Bernhard M. Wiedemann 018f1b
+    *slotnpagesp = le2ha((unsigned char *)header + XDB_OFFSET_SLOTNPAGES);
Bernhard M. Wiedemann 018f1b
+    *pagesizep = le2ha((unsigned char *)header + XDB_OFFSET_PAGESIZE);
Bernhard M. Wiedemann 018f1b
+    *usergenerationp = le2ha((unsigned char *)header + XDB_OFFSET_USERGENERATION);
Bernhard M. Wiedemann 018f1b
+    if (!*slotnpagesp || !*pagesizep)
Bernhard M. Wiedemann 018f1b
+	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
+    return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
+}
Bernhard M. Wiedemann 018f1b
+
Bernhard M. Wiedemann 018f1b
 static int rpmxdbReadHeader(rpmxdb xdb)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
     struct xdb_slot *slot;
Bernhard M. Wiedemann 018f1b
-    unsigned int header[XDB_HEADER_SIZE / sizeof(unsigned int)];
Bernhard M. Wiedemann 018f1b
-    unsigned int slotnpages, pagesize, generation, usergeneration, version;
Bernhard M. Wiedemann 018f1b
+    unsigned int slotnpages, pagesize, generation, usergeneration;
Bernhard M. Wiedemann 018f1b
     unsigned int page, *lastfreep;
Bernhard M. Wiedemann 018f1b
     unsigned char *pageptr;
Bernhard M. Wiedemann 018f1b
     struct xdb_slot *slots, **usedslots, *lastslot;
Bernhard M. Wiedemann 018f1b
@@ -246,23 +268,9 @@ static int rpmxdbReadHeader(rpmxdb xdb)
Bernhard M. Wiedemann 018f1b
     if (fstat(xdb->fd, &stb)) {
Bernhard M. Wiedemann 018f1b
         return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     }
Bernhard M. Wiedemann 018f1b
-    if (pread(xdb->fd, header, sizeof(header), 0) != sizeof(header)) {
Bernhard M. Wiedemann 018f1b
-	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    }
Bernhard M. Wiedemann 018f1b
-    if (le2ha((unsigned char *)header + XDB_OFFSET_MAGIC) != XDB_MAGIC)
Bernhard M. Wiedemann 018f1b
-	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    version = le2ha((unsigned char *)header + XDB_OFFSET_VERSION);
Bernhard M. Wiedemann 018f1b
-    if (version != XDB_VERSION) {
Bernhard M. Wiedemann 018f1b
-	rpmlog(RPMLOG_ERR, _("rpmxdb: Version mismatch. Expected version: %u. "
Bernhard M. Wiedemann 018f1b
-	    "Found version: %u\n"), XDB_VERSION, version);
Bernhard M. Wiedemann 018f1b
+    if (rpmxdbReadHeaderRaw(xdb, &generation, &slotnpages, &pagesize, &usergeneration))
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
-    }
Bernhard M. Wiedemann 018f1b
-
Bernhard M. Wiedemann 018f1b
-    generation = le2ha((unsigned char *)header + XDB_OFFSET_GENERATION);
Bernhard M. Wiedemann 018f1b
-    slotnpages = le2ha((unsigned char *)header + XDB_OFFSET_SLOTNPAGES);
Bernhard M. Wiedemann 018f1b
-    pagesize = le2ha((unsigned char *)header + XDB_OFFSET_PAGESIZE);
Bernhard M. Wiedemann 018f1b
-    usergeneration = le2ha((unsigned char *)header + XDB_OFFSET_USERGENERATION);
Bernhard M. Wiedemann 018f1b
-    if (!slotnpages || !pagesize || stb.st_size % pagesize != 0)
Bernhard M. Wiedemann 018f1b
+    if (stb.st_size % pagesize != 0)
Bernhard M. Wiedemann 018f1b
 	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
     xdb->pagesize = pagesize;
Bernhard M. Wiedemann 018f1b
     xdb->mapflags = xdb->rdonly ? PROT_READ : PROT_READ | PROT_WRITE;
Bernhard M. Wiedemann 018f1b
@@ -922,6 +930,43 @@ int rpmxdbDelBlob(rpmxdb xdb, unsigned i
Bernhard M. Wiedemann 018f1b
     rpmxdbUnlock(xdb, 1);
Bernhard M. Wiedemann 018f1b
     return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
 }
Bernhard M. Wiedemann 018f1b
+
Bernhard M. Wiedemann 018f1b
+int rpmxdbDelAllBlobs(rpmxdb xdb)
Bernhard M. Wiedemann 018f1b
+{
Bernhard M. Wiedemann 018f1b
+    unsigned int slotnpages, pagesize, generation, usergeneration;
Bernhard M. Wiedemann 018f1b
+    if (rpmxdbLockOnly(xdb, 1))
Bernhard M. Wiedemann 018f1b
+	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
+    /* unmap all blobs */
Bernhard M. Wiedemann 018f1b
+    if (xdb->slots) {
Bernhard M. Wiedemann 018f1b
+	int i;
Bernhard M. Wiedemann 018f1b
+	struct xdb_slot *slot;
Bernhard M. Wiedemann 018f1b
+	for (i = 1, slot = xdb->slots + i; i < xdb->nslots; i++, slot++) {
Bernhard M. Wiedemann 018f1b
+	    if (slot->startpage && slot->mapped) {
Bernhard M. Wiedemann 018f1b
+		unmapslot(xdb, slot);
Bernhard M. Wiedemann 018f1b
+		slot->mapcallback(xdb, slot->mapcallbackdata, 0, 0);
Bernhard M. Wiedemann 018f1b
+	    }
Bernhard M. Wiedemann 018f1b
+	}
Bernhard M. Wiedemann 018f1b
+	free(xdb->slots);
Bernhard M. Wiedemann 018f1b
+	xdb->slots = 0;
Bernhard M. Wiedemann 018f1b
+    }
Bernhard M. Wiedemann 018f1b
+    if (xdb->mapped)
Bernhard M. Wiedemann 018f1b
+	unmapheader(xdb);
Bernhard M. Wiedemann 018f1b
+    if (rpmxdbReadHeaderRaw(xdb, &generation, &slotnpages, &pagesize, &usergeneration)) {
Bernhard M. Wiedemann 018f1b
+	rpmxdbUnlock(xdb, 1);
Bernhard M. Wiedemann 018f1b
+	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
+    }
Bernhard M. Wiedemann 018f1b
+    xdb->generation = generation + 1;
Bernhard M. Wiedemann 018f1b
+    xdb->slotnpages = 1;
Bernhard M. Wiedemann 018f1b
+    xdb->pagesize = pagesize;
Bernhard M. Wiedemann 018f1b
+    xdb->usergeneration = usergeneration;
Bernhard M. Wiedemann 018f1b
+    if (rpmxdbWriteEmptySlotpage(xdb, 0)) {
Bernhard M. Wiedemann 018f1b
+	rpmxdbUnlock(xdb, 1);
Bernhard M. Wiedemann 018f1b
+	return RPMRC_FAIL;
Bernhard M. Wiedemann 018f1b
+    }
Bernhard M. Wiedemann 018f1b
+    ftruncate(xdb->fd, xdb->pagesize);
Bernhard M. Wiedemann 018f1b
+    rpmxdbUnlock(xdb, 1);
Bernhard M. Wiedemann 018f1b
+    return RPMRC_OK;
Bernhard M. Wiedemann 018f1b
+}
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 int rpmxdbResizeBlob(rpmxdb xdb, unsigned int id, size_t newsize)
Bernhard M. Wiedemann 018f1b
 {
Bernhard M. Wiedemann 018f1b
--- ./lib/backend/ndb/rpmxdb.h.orig	2019-11-13 09:19:29.307710583 +0000
Bernhard M. Wiedemann 018f1b
+++ ./lib/backend/ndb/rpmxdb.h	2020-01-23 12:48:20.919728972 +0000
Bernhard M. Wiedemann 018f1b
@@ -14,6 +14,7 @@ int rpmxdbUnlock(rpmxdb xdb, int excl);
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 int rpmxdbLookupBlob(rpmxdb xdb, unsigned int *idp, unsigned int blobtag, unsigned int subtag, int flags);
Bernhard M. Wiedemann 018f1b
 int rpmxdbDelBlob(rpmxdb xdb, unsigned int id) ;
Bernhard M. Wiedemann 018f1b
+int rpmxdbDelAllBlobs(rpmxdb xdb);
Bernhard M. Wiedemann 018f1b
 
Bernhard M. Wiedemann 018f1b
 int rpmxdbMapBlob(rpmxdb xdb, unsigned int id, int flags, void (*mapcallback)(rpmxdb xdb, void *data, void *newaddr, size_t newsize), void *mapcallbackdata);
Bernhard M. Wiedemann 018f1b
 int rpmxdbUnmapBlob(rpmxdb xdb, unsigned int id);