144 lines
5.5 KiB
Diff
144 lines
5.5 KiB
Diff
From 49d43a334572199088ecc24ce6fc0e86c8699d2e Mon Sep 17 00:00:00 2001
|
|
From: Michael Schroeder <mls@suse.de>
|
|
Date: Fri, 10 Jan 2020 15:49:16 +0100
|
|
Subject: [PATCH] ndb: add a rpmxdbDelAllBlobs method
|
|
|
|
This will delete all blobs (i.e. index databases) from the
|
|
ndb master index database. We do this kind of low-level on purpose,
|
|
so that it even works if the index database is corrupt.
|
|
|
|
This will be used in the next commit which implements automatic
|
|
index regeneration if the index is out of sync.
|
|
|
|
URL:https://github.com/rpm-software-management/rpm/commit/49d43a334572199088ecc24ce6fc0e86c8699d2e
|
|
---
|
|
lib/backend/ndb/rpmxdb.c | 81 +++++++++++++++++++++++++++++++++++++-----------
|
|
lib/backend/ndb/rpmxdb.h | 1 +
|
|
2 files changed, 64 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/lib/backend/ndb/rpmxdb.c b/lib/backend/ndb/rpmxdb.c
|
|
index 2f94491..3baafa6 100644
|
|
--- a/lib/backend/ndb/rpmxdb.c
|
|
+++ b/lib/backend/ndb/rpmxdb.c
|
|
@@ -224,11 +224,33 @@ static int usedslots_cmp(const void *a, const void *b)
|
|
return sa->startpage > sb->startpage ? 1 : -1;
|
|
}
|
|
|
|
+static int rpmxdbReadHeaderRaw(rpmxdb xdb, unsigned int *generationp, unsigned int *slotnpagesp, unsigned int *pagesizep, unsigned int *usergenerationp)
|
|
+{
|
|
+ unsigned int header[XDB_HEADER_SIZE / sizeof(unsigned int)];
|
|
+ unsigned int version;
|
|
+ if (pread(xdb->fd, header, sizeof(header), 0) != sizeof(header))
|
|
+ return RPMRC_FAIL;
|
|
+ if (le2ha((unsigned char *)header + XDB_OFFSET_MAGIC) != XDB_MAGIC)
|
|
+ return RPMRC_FAIL;
|
|
+ version = le2ha((unsigned char *)header + XDB_OFFSET_VERSION);
|
|
+ if (version != XDB_VERSION) {
|
|
+ rpmlog(RPMLOG_ERR, _("rpmxdb: Version mismatch. Expected version: %u. "
|
|
+ "Found version: %u\n"), XDB_VERSION, version);
|
|
+ return RPMRC_FAIL;
|
|
+ }
|
|
+ *generationp = le2ha((unsigned char *)header + XDB_OFFSET_GENERATION);
|
|
+ *slotnpagesp = le2ha((unsigned char *)header + XDB_OFFSET_SLOTNPAGES);
|
|
+ *pagesizep = le2ha((unsigned char *)header + XDB_OFFSET_PAGESIZE);
|
|
+ *usergenerationp = le2ha((unsigned char *)header + XDB_OFFSET_USERGENERATION);
|
|
+ if (!*slotnpagesp || !*pagesizep)
|
|
+ return RPMRC_FAIL;
|
|
+ return RPMRC_OK;
|
|
+}
|
|
+
|
|
static int rpmxdbReadHeader(rpmxdb xdb)
|
|
{
|
|
struct xdb_slot *slot;
|
|
- unsigned int header[XDB_HEADER_SIZE / sizeof(unsigned int)];
|
|
- unsigned int slotnpages, pagesize, generation, usergeneration, version;
|
|
+ unsigned int slotnpages, pagesize, generation, usergeneration;
|
|
unsigned int page, *lastfreep;
|
|
unsigned char *pageptr;
|
|
struct xdb_slot *slots, **usedslots, *lastslot;
|
|
@@ -246,23 +268,9 @@ static int rpmxdbReadHeader(rpmxdb xdb)
|
|
if (fstat(xdb->fd, &stb)) {
|
|
return RPMRC_FAIL;
|
|
}
|
|
- if (pread(xdb->fd, header, sizeof(header), 0) != sizeof(header)) {
|
|
- return RPMRC_FAIL;
|
|
- }
|
|
- if (le2ha((unsigned char *)header + XDB_OFFSET_MAGIC) != XDB_MAGIC)
|
|
+ if (rpmxdbReadHeaderRaw(xdb, &generation, &slotnpages, &pagesize, &usergeneration))
|
|
return RPMRC_FAIL;
|
|
- version = le2ha((unsigned char *)header + XDB_OFFSET_VERSION);
|
|
- if (version != XDB_VERSION) {
|
|
- rpmlog(RPMLOG_ERR, _("rpmxdb: Version mismatch. Expected version: %u. "
|
|
- "Found version: %u\n"), XDB_VERSION, version);
|
|
- return RPMRC_FAIL;
|
|
- }
|
|
-
|
|
- generation = le2ha((unsigned char *)header + XDB_OFFSET_GENERATION);
|
|
- slotnpages = le2ha((unsigned char *)header + XDB_OFFSET_SLOTNPAGES);
|
|
- pagesize = le2ha((unsigned char *)header + XDB_OFFSET_PAGESIZE);
|
|
- usergeneration = le2ha((unsigned char *)header + XDB_OFFSET_USERGENERATION);
|
|
- if (!slotnpages || !pagesize || stb.st_size % pagesize != 0)
|
|
+ if (stb.st_size % pagesize != 0)
|
|
return RPMRC_FAIL;
|
|
xdb->pagesize = pagesize;
|
|
xdb->mapflags = xdb->rdonly ? PROT_READ : PROT_READ | PROT_WRITE;
|
|
@@ -923,6 +931,43 @@ int rpmxdbDelBlob(rpmxdb xdb, unsigned int id)
|
|
return RPMRC_OK;
|
|
}
|
|
|
|
+int rpmxdbDelAllBlobs(rpmxdb xdb)
|
|
+{
|
|
+ unsigned int slotnpages, pagesize, generation, usergeneration;
|
|
+ if (rpmxdbLockOnly(xdb, 1))
|
|
+ return RPMRC_FAIL;
|
|
+ /* unmap all blobs */
|
|
+ if (xdb->slots) {
|
|
+ int i;
|
|
+ struct xdb_slot *slot;
|
|
+ for (i = 1, slot = xdb->slots + i; i < xdb->nslots; i++, slot++) {
|
|
+ if (slot->startpage && slot->mapped) {
|
|
+ unmapslot(xdb, slot);
|
|
+ slot->mapcallback(xdb, slot->mapcallbackdata, 0, 0);
|
|
+ }
|
|
+ }
|
|
+ free(xdb->slots);
|
|
+ xdb->slots = 0;
|
|
+ }
|
|
+ if (xdb->mapped)
|
|
+ unmapheader(xdb);
|
|
+ if (rpmxdbReadHeaderRaw(xdb, &generation, &slotnpages, &pagesize, &usergeneration)) {
|
|
+ rpmxdbUnlock(xdb, 1);
|
|
+ return RPMRC_FAIL;
|
|
+ }
|
|
+ xdb->generation = generation + 1;
|
|
+ xdb->slotnpages = 1;
|
|
+ xdb->pagesize = pagesize;
|
|
+ xdb->usergeneration = usergeneration;
|
|
+ if (rpmxdbWriteEmptySlotpage(xdb, 0)) {
|
|
+ rpmxdbUnlock(xdb, 1);
|
|
+ return RPMRC_FAIL;
|
|
+ }
|
|
+ ftruncate(xdb->fd, xdb->pagesize);
|
|
+ rpmxdbUnlock(xdb, 1);
|
|
+ return RPMRC_OK;
|
|
+}
|
|
+
|
|
int rpmxdbResizeBlob(rpmxdb xdb, unsigned int id, size_t newsize)
|
|
{
|
|
struct xdb_slot *slot;
|
|
diff --git a/lib/backend/ndb/rpmxdb.h b/lib/backend/ndb/rpmxdb.h
|
|
index 88a3e61..ddf02c1 100644
|
|
--- a/lib/backend/ndb/rpmxdb.h
|
|
+++ b/lib/backend/ndb/rpmxdb.h
|
|
@@ -14,6 +14,7 @@ int rpmxdbUnlock(rpmxdb xdb, int excl);
|
|
|
|
int rpmxdbLookupBlob(rpmxdb xdb, unsigned int *idp, unsigned int blobtag, unsigned int subtag, int flags);
|
|
int rpmxdbDelBlob(rpmxdb xdb, unsigned int id) ;
|
|
+int rpmxdbDelAllBlobs(rpmxdb xdb);
|
|
|
|
int rpmxdbMapBlob(rpmxdb xdb, unsigned int id, int flags, void (*mapcallback)(rpmxdb xdb, void *data, void *newaddr, size_t newsize), void *mapcallbackdata);
|
|
int rpmxdbUnmapBlob(rpmxdb xdb, unsigned int id);
|
|
--
|
|
1.8.3.1
|
|
|