File ndb-backport.diff of Package rpm-ndb.21495
--- ./lib/backend/ndb/glue.c.orig 2020-01-16 15:11:26.181880288 +0000
+++ ./lib/backend/ndb/glue.c 2020-01-16 15:11:26.181880288 +0000
@@ -30,6 +30,7 @@ struct ndbEnv_s {
rpmpkgdb pkgdb;
rpmxdb xdb;
int refs;
+ int dofsync;
unsigned int hdrNum;
void *data;
@@ -58,8 +59,10 @@ static void closeEnv(rpmdb rdb)
static struct ndbEnv_s *openEnv(rpmdb rdb)
{
struct ndbEnv_s *ndbenv = rdb->db_dbenv;
- if (!ndbenv)
+ if (!ndbenv) {
rdb->db_dbenv = ndbenv = xcalloc(1, sizeof(struct ndbEnv_s));
+ ndbenv->dofsync = 1;
+ }
ndbenv->refs++;
return ndbenv;
}
@@ -77,6 +80,31 @@ static int ndb_Close(dbiIndex dbi, unsig
return 0;
}
+static void ndb_CheckIndexSync(rpmpkgdb pkgdb, rpmxdb xdb)
+{
+ unsigned int generation, xdb_generation;
+ if (!pkgdb || !xdb)
+ return;
+ if (rpmpkgLock(pkgdb, 0))
+ return;
+ if (rpmpkgGeneration(pkgdb, &generation)) {
+ rpmpkgUnlock(pkgdb, 0);
+ return;
+ }
+ if (!rpmxdbGetUserGeneration(xdb, &xdb_generation) && generation == xdb_generation) {
+ rpmpkgUnlock(pkgdb, 0);
+ return;
+ }
+ rpmpkgUnlock(pkgdb, 0);
+ /* index corrupt or with different generation */
+ if (rpmxdbIsRdonly(xdb)) {
+ rpmlog(RPMLOG_WARNING, _("Detected outdated index databases\n"));
+ } else {
+ rpmlog(RPMLOG_WARNING, _("Rebuilding outdated index databases\n"));
+ rpmxdbDelAllBlobs(xdb);
+ }
+}
+
static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
{
const char *dbhome = rpmdbHome(rdb);
@@ -114,6 +142,7 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
}
free(path);
dbi->dbi_db = ndbenv->pkgdb = pkgdb;
+ rpmpkgSetFsync(pkgdb, ndbenv->dofsync);
if ((oflags & (O_RDWR | O_RDONLY)) == O_RDONLY)
dbi->dbi_flags |= DBI_RDONLY;
@@ -126,6 +155,7 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
}
if (!ndbenv->xdb) {
char *path = rstrscat(NULL, dbhome, "/Index.db", NULL);
+ int created = 0;
rpmlog(RPMLOG_DEBUG, "opening db index %s mode=0x%x\n", path, rdb->db_mode);
/* Open indexes readwrite if possible */
@@ -140,6 +170,7 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
} else if (rc && errno == ENOENT) {
ioflags = O_CREAT|O_RDWR;
rc = rpmxdbOpen(&ndbenv->xdb, rdb->db_pkgs->dbi_db, path, ioflags, 0666);
+ created = 1;
}
if (rc) {
perror("rpmxdbOpen");
@@ -148,6 +179,9 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
return 1;
}
free(path);
+ rpmxdbSetFsync(ndbenv->xdb, ndbenv->dofsync);
+ if (!created)
+ ndb_CheckIndexSync(ndbenv->pkgdb, ndbenv->xdb);
}
if (rpmxdbLookupBlob(ndbenv->xdb, &id, rpmtag, 0, 0) == RPMRC_NOTFOUND) {
dbi->dbi_flags |= DBI_CREATED;
@@ -174,11 +208,25 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
static int ndb_Verify(dbiIndex dbi, unsigned int flags)
{
- return 1;
+ int rc;
+ if (dbi->dbi_type == DBI_PRIMARY) {
+ rc = rpmpkgVerify(dbi->dbi_db);
+ } else {
+ rc = 0; /* cannot verify the index databases */
+ }
+ return rc;
}
static void ndb_SetFSync(rpmdb rdb, int enable)
{
+ struct ndbEnv_s *ndbenv = rdb->db_dbenv;
+ if (ndbenv) {
+ ndbenv->dofsync = enable;
+ if (ndbenv->pkgdb)
+ rpmpkgSetFsync(ndbenv->pkgdb, enable);
+ if (ndbenv->xdb)
+ rpmxdbSetFsync(ndbenv->xdb, enable);
+ }
}
static int indexSync(rpmpkgdb pkgdb, rpmxdb xdb)
@@ -383,15 +431,15 @@ static rpmRC ndb_idxdbIter(dbiIndex dbi,
}
k = dbc->listdata + dbc->list[dbc->ilist];
kl = dbc->list[dbc->ilist + 1];
-#if 0
- if (searchType == DBC_KEY_SEARCH) {
+
+ if (set == NULL) {
dbc->ilist += 2;
dbc->key = k;
dbc->keylen = kl;
rc = RPMRC_OK;
break;
}
-#endif
+
pkglist = 0;
pkglistn = 0;
rc = rpmidxGet(dbc->dbi->dbi_db, k, kl, &pkglist, &pkglistn);
--- ./lib/backend/ndb/rpmidx.c.orig 2020-01-16 15:11:26.181880288 +0000
+++ ./lib/backend/ndb/rpmidx.c 2020-01-16 15:11:26.181880288 +0000
@@ -66,8 +66,6 @@
typedef struct rpmidxdb_s {
rpmpkgdb pkgdb; /* master database */
- char *filename;
- int fd; /* our file descriptor */
int flags;
int mode;
@@ -166,36 +164,13 @@ static void mapcb(rpmxdb xdb, void *data
set_mapped((rpmidxdb)data, newaddr, (unsigned int)newsize);
}
-static int rpmidxReadHeader(rpmidxdb idxdb);
-
static int rpmidxMap(rpmidxdb idxdb)
{
- if (idxdb->xdb) {
- if (rpmxdbMapBlob(idxdb->xdb, idxdb->xdbid, idxdb->rdonly ? O_RDONLY : O_RDWR, mapcb, idxdb))
- return RPMRC_FAIL;
- if (idxdb->file_size < 4096) {
- rpmxdbUnmapBlob(idxdb->xdb, idxdb->xdbid);
- return RPMRC_FAIL;
- }
- } else {
-#ifdef IDXDB_FILESUPPORT
- struct stat stb;
- size_t size;
- void *mapped;
- if (fstat(idxdb->fd, &stb))
- return RPMRC_FAIL;
- size = stb.st_size;
- if (size < 4096)
- return RPMRC_FAIL;
- /* round up for mmap */
- size = (size + idxdb->pagesize - 1) & ~(idxdb->pagesize - 1);
- mapped = mmap(0, size, idxdb->rdonly ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED, idxdb->fd, 0);
- if (mapped == MAP_FAILED)
- return RPMRC_FAIL;
- set_mapped(idxdb, mapped, (unsigned int)stb.st_size);
-#else
+ if (rpmxdbMapBlob(idxdb->xdb, idxdb->xdbid, idxdb->rdonly ? O_RDONLY : O_RDWR, mapcb, idxdb))
+ return RPMRC_FAIL;
+ if (idxdb->file_size < 4096) {
+ rpmxdbUnmapBlob(idxdb->xdb, idxdb->xdbid);
return RPMRC_FAIL;
-#endif
}
return RPMRC_OK;
}
@@ -204,47 +179,8 @@ static void rpmidxUnmap(rpmidxdb idxdb)
{
if (!idxdb->head_mapped)
return;
- if (idxdb->xdb) {
- rpmxdbUnmapBlob(idxdb->xdb, idxdb->xdbid);
- } else {
-#ifdef IDXDB_FILESUPPORT
- size_t size = idxdb->file_size;
- /* round up for munmap */
- size = (size + idxdb->pagesize - 1) & ~(idxdb->pagesize - 1);
- munmap(idxdb->head_mapped, size);
- set_mapped(idxdb, 0, 0);
-#else
- return;
-#endif
- }
-}
-
-#ifdef IDXDB_FILESUPPORT
-static int rpmidxReadHeader(rpmidxdb idxdb);
-
-/* re-open file to get the new version */
-static int rpmidxHandleObsolete(rpmidxdb idxdb)
-{
- int nfd;
- struct stat stb1, stb2;
-
- if (fstat(idxdb->fd, &stb1))
- return RPMRC_FAIL;
- nfd = open(idxdb->filename, idxdb->rdonly ? O_RDONLY : O_RDWR, 0);
- if (nfd == -1)
- return RPMRC_FAIL;
- if (fstat(nfd, &stb2)) {
- close(nfd);
- return RPMRC_FAIL;
- }
- if (stb1.st_dev == stb2.st_dev && stb1.st_ino == stb2.st_ino)
- return RPMRC_FAIL; /* openend the same obsolete file */
- rpmidxUnmap(idxdb);
- close(idxdb->fd);
- idxdb->fd = nfd;
- return rpmidxReadHeader(idxdb); /* re-try with new file */
+ rpmxdbUnmapBlob(idxdb->xdb, idxdb->xdbid);
}
-#endif
static int rpmidxReadHeader(rpmidxdb idxdb)
{
@@ -270,10 +206,6 @@ static int rpmidxReadHeader(rpmidxdb idx
rpmidxUnmap(idxdb);
return RPMRC_FAIL;
}
-#ifdef IDXDB_FILESUPPORT
- if (!idxdb->xdb && le2ha(idxdb->head_mapped + IDXDB_OFFSET_OBSOLETE))
- return rpmidxHandleObsolete(idxdb);
-#endif
idxdb->generation = le2ha(idxdb->head_mapped + IDXDB_OFFSET_GENERATION);
idxdb->nslots = le2ha(idxdb->head_mapped + IDXDB_OFFSET_NSLOTS);
idxdb->usedslots = le2ha(idxdb->head_mapped + IDXDB_OFFSET_USEDSLOTS);
@@ -336,23 +268,6 @@ static inline void bumpGeneration(rpmidx
h2lea(idxdb->generation, idxdb->head_mapped + IDXDB_OFFSET_GENERATION);
}
-#ifdef IDXDB_FILESUPPORT
-static int createempty(rpmidxdb idxdb, off_t off, size_t size)
-{
- char buf[4096];
- memset(buf, 0, sizeof(buf));
- while (size >= 4096) {
- if (pwrite(idxdb->fd, buf, 4096, off) != 4096)
- return RPMRC_FAIL;
- off += 4096;
- size -= 4096;
- }
- if (size > 0 && pwrite(idxdb->fd, buf, size , off) != size)
- return RPMRC_FAIL;
- return RPMRC_OK;
-}
-#endif
-
/*** Key management ***/
#define MURMUR_M 0x5bd1e995
@@ -452,29 +367,8 @@ static inline int equalkey(rpmidxdb idxd
static int addkeypage(rpmidxdb idxdb) {
unsigned int addsize = idxdb->pagesize > IDXDB_KEY_CHUNKSIZE ? idxdb->pagesize : IDXDB_KEY_CHUNKSIZE;
- if (idxdb->xdb) {
- if (rpmxdbResizeBlob(idxdb->xdb, idxdb->xdbid, idxdb->file_size + addsize))
- return RPMRC_FAIL;
- } else {
-#ifdef IDXDB_FILESUPPORT
- /* don't use ftruncate because we want to create a "backed" page */
- void *newaddr;
- size_t oldsize, newsize;
- if (createempty(idxdb, idxdb->file_size, addsize))
- return RPMRC_FAIL;
- oldsize = idxdb->file_size;
- newsize = idxdb->file_size + addsize;
- /* round up for mremap */
- oldsize = (oldsize + idxdb->pagesize - 1) & ~(idxdb->pagesize - 1);
- newsize = (newsize + idxdb->pagesize - 1) & ~(idxdb->pagesize - 1);
- newaddr = mremap(idxdb->head_mapped, oldsize, newsize, MREMAP_MAYMOVE);
- if (newaddr == MAP_FAILED)
- return RPMRC_FAIL;
- set_mapped(idxdb, newaddr, idxdb->file_size + addsize);
-#else
+ if (rpmxdbResizeBlob(idxdb->xdb, idxdb->xdbid, idxdb->file_size + addsize))
return RPMRC_FAIL;
-#endif
- }
return RPMRC_OK;
}
@@ -589,7 +483,7 @@ static int rpmidxRebuildInternal(rpmidxd
nidxdb = &nidxdb_s;
memset(nidxdb, 0, sizeof(*nidxdb));
- nidxdb->pagesize = sysconf(_SC_PAGE_SIZE);
+ nidxdb->pagesize = rpmxdbPagesize(idxdb->xdb);
/* calculate nslots the hard way, don't trust usedslots */
nslots = 0;
@@ -627,60 +521,20 @@ static int rpmidxRebuildInternal(rpmidxd
nidxdb->xmask = xmask;
/* create new database */
- if (idxdb->xdb) {
- nidxdb->xdb = idxdb->xdb;
- nidxdb->xdbtag = idxdb->xdbtag;
- if (rpmxdbLookupBlob(nidxdb->xdb, &nidxdb->xdbid, idxdb->xdbtag, IDXDB_XDB_SUBTAG_REBUILD, O_CREAT|O_TRUNC)) {
- return RPMRC_FAIL;
- }
- if (rpmxdbResizeBlob(nidxdb->xdb, nidxdb->xdbid, file_size)) {
- return RPMRC_FAIL;
- }
- if (rpmidxMap(nidxdb)) {
- return RPMRC_FAIL;
- }
- } else {
-#ifdef IDXDB_FILESUPPORT
- void *mapped;
- nidxdb->filename = malloc(strlen(idxdb->filename) + 8);
- if (!nidxdb->filename)
- return RPMRC_FAIL;
- sprintf(nidxdb->filename, "%s-XXXXXX", idxdb->filename);
- nidxdb->fd = mkstemp(nidxdb->filename);
- if (nidxdb->fd == -1) {
- free(nidxdb->filename);
- return RPMRC_FAIL;
- }
- if (createempty(nidxdb, 0, file_size)) {
- close(nidxdb->fd);
- unlink(nidxdb->filename);
- free(nidxdb->filename);
- return RPMRC_FAIL;
- }
- mapped = mmap(0, file_size, idxdb->rdonly ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED, nidxdb->fd, 0);
- if (mapped == MAP_FAILED) {
- close(nidxdb->fd);
- unlink(nidxdb->filename);
- free(nidxdb->filename);
- return RPMRC_FAIL;
- }
- set_mapped(nidxdb, mapped, file_size);
-#else
+ nidxdb->xdb = idxdb->xdb;
+ nidxdb->xdbtag = idxdb->xdbtag;
+ if (rpmxdbLookupBlob(nidxdb->xdb, &nidxdb->xdbid, idxdb->xdbtag, IDXDB_XDB_SUBTAG_REBUILD, O_CREAT|O_TRUNC)) {
return RPMRC_FAIL;
-#endif
}
-
- /* copy all entries */
- done = calloc(idxdb->nslots / 8 + 1, 1);
- if (!done) {
- rpmidxUnmap(nidxdb);
- if (!idxdb->xdb) {
- close(nidxdb->fd);
- unlink(nidxdb->filename);
- free(nidxdb->filename);
- }
+ if (rpmxdbResizeBlob(nidxdb->xdb, nidxdb->xdbid, file_size)) {
return RPMRC_FAIL;
}
+ if (rpmidxMap(nidxdb)) {
+ return RPMRC_FAIL;
+ }
+
+ /* copy all entries */
+ done = xcalloc(idxdb->nslots / 8 + 1, 1);
keyend = 1;
for (i = 0, ent = idxdb->slot_mapped; i < idxdb->nslots; i++, ent += 8) {
unsigned int x = le2ha(ent);
@@ -709,42 +563,14 @@ static int rpmidxRebuildInternal(rpmidxd
/* shrink if we have allocated excessive key space */
xfile_size = file_size - key_size + keyend + IDXDB_KEY_CHUNKSIZE;
xfile_size = (xfile_size + nidxdb->pagesize - 1) & ~(nidxdb->pagesize - 1);
- if (xfile_size < file_size) {
- if (nidxdb->xdb) {
- rpmxdbResizeBlob(nidxdb->xdb, nidxdb->xdbid, xfile_size);
- } else {
- if (ftruncate(nidxdb->fd, xfile_size)) {
- rpmlog(RPMLOG_WARNING, _("truncate failed: %s\n"), strerror(errno));
- }
- }
- }
+ if (xfile_size < file_size)
+ rpmxdbResizeBlob(nidxdb->xdb, nidxdb->xdbid, xfile_size);
/* now switch over to new database */
- if (idxdb->xdb) {
- rpmidxUnmap(idxdb);
- if (rpmxdbRenameBlob(nidxdb->xdb, &nidxdb->xdbid, idxdb->xdbtag, IDXDB_XDB_SUBTAG))
- return RPMRC_FAIL;
- idxdb->xdbid = nidxdb->xdbid;
- } else {
-#ifdef IDXDB_FILESUPPORT
- if (rename(nidxdb->filename, idxdb->filename)) {
- close(nidxdb->fd);
- unlink(nidxdb->filename);
- free(nidxdb->filename);
- return RPMRC_FAIL;
- }
- if (idxdb->head_mapped) {
- h2lea(1, idxdb->head_mapped + IDXDB_OFFSET_OBSOLETE);
- bumpGeneration(idxdb);
- rpmidxUnmap(idxdb);
- }
- free(nidxdb->filename);
- close(idxdb->fd);
- idxdb->fd = nidxdb->fd;
-#else
+ rpmidxUnmap(idxdb);
+ if (rpmxdbRenameBlob(nidxdb->xdb, &nidxdb->xdbid, idxdb->xdbtag, IDXDB_XDB_SUBTAG))
return RPMRC_FAIL;
-#endif
- }
+ idxdb->xdbid = nidxdb->xdbid;
if (rpmidxReadHeader(idxdb))
return RPMRC_FAIL;
return RPMRC_OK;
@@ -929,12 +755,10 @@ static int rpmidxGetInternal(rpmidxdb id
continue;
if ((nhits & 15) == 0) {
if (!hits) {
- hits = malloc(16 * sizeof(unsigned int));
+ hits = xmalloc(16 * sizeof(unsigned int));
} else {
- hits = realloc(hits, (nhits + 16) * sizeof(unsigned int));
+ hits = xrealloc(hits, (nhits + 16) * sizeof(unsigned int));
}
- if (!hits)
- return RPMRC_FAIL;
}
data = le2ha(ent + 4);
ovldata = (data & 0x80000000) ? le2ha(idxdb->slot_mapped + idxdb->nslots * 8 + 4 * h) : 0;
@@ -957,9 +781,7 @@ static void rpmidxListSort(rpmidxdb idxd
unsigned int i, *arr;
if (nkeylist < 2 * 2)
return;
- arr = malloc(nkeylist * sizeof(unsigned int));
- if (!arr)
- return;
+ arr = xmalloc(nkeylist * sizeof(unsigned int));
for (i = 0; i < nkeylist; i += 2) {
arr[i] = i;
arr[i + 1] = murmurhash(data + keylist[i], keylist[i + 1]) & idxdb->hmask;
@@ -980,15 +802,9 @@ static int rpmidxListInternal(rpmidxdb i
unsigned int nkeylist = 0;
unsigned char *data, *terminate, *key, *keyendp;
- data = malloc(idxdb->keyend + 1); /* +1 so we can terminate the last key */
- if (!data)
- return RPMRC_FAIL;
+ data = xmalloc(idxdb->keyend + 1); /* +1 so we can terminate the last key */
memcpy(data, idxdb->key_mapped, idxdb->keyend);
- keylist = malloc(16 * sizeof(*keylist));
- if (!keylist) {
- free(data);
- return RPMRC_FAIL;
- }
+ keylist = xmalloc(16 * sizeof(*keylist));
terminate = 0;
for (key = data + 1, keyendp = data + idxdb->keyend; key < keyendp; ) {
unsigned int hl, keyl;
@@ -997,12 +813,7 @@ static int rpmidxListInternal(rpmidxdb i
continue;
}
if ((nkeylist & 15) == 0) {
- unsigned int *kl = realloc(keylist, (nkeylist + 16) * sizeof(*keylist));
- if (!kl) {
- free(keylist);
- free(data);
- return RPMRC_FAIL;
- }
+ unsigned int *kl = xrealloc(keylist, (nkeylist + 16) * sizeof(*keylist));
keylist = kl;
}
keyl = decodekeyl(key, &hl);
@@ -1025,26 +836,14 @@ static int rpmidxListInternal(rpmidxdb i
static int rpmidxInitInternal(rpmidxdb idxdb)
{
- if (idxdb->xdb) {
- unsigned int id;
- int rc = rpmxdbLookupBlob(idxdb->xdb, &id, idxdb->xdbtag, IDXDB_XDB_SUBTAG, 0);
- if (rc == RPMRC_OK && id) {
- idxdb->xdbid = id;
- return RPMRC_OK; /* somebody else was faster */
- }
- if (rc && rc != RPMRC_NOTFOUND)
- return rc;
- } else {
-#ifdef IDXDB_FILESUPPORT
- struct stat stb;
- if (stat(idxdb->filename, &stb))
- return RPMRC_FAIL;
- if (stb.st_size) /* somebody else was faster */
- return rpmidxHandleObsolete(idxdb);
-#else
- return RPMRC_FAIL;
-#endif
+ unsigned int id;
+ int rc = rpmxdbLookupBlob(idxdb->xdb, &id, idxdb->xdbtag, IDXDB_XDB_SUBTAG, 0);
+ if (rc == RPMRC_OK && id) {
+ idxdb->xdbid = id;
+ return RPMRC_OK; /* somebody else was faster */
}
+ if (rc && rc != RPMRC_NOTFOUND)
+ return rc;
return rpmidxRebuildInternal(idxdb);
}
@@ -1052,18 +851,12 @@ static int rpmidxLock(rpmidxdb idxdb, in
{
if (excl && idxdb->rdonly)
return RPMRC_FAIL;
- if (idxdb->xdb)
- return rpmxdbLock(idxdb->xdb, excl);
- else
- return rpmpkgLock(idxdb->pkgdb, excl);
+ return rpmxdbLock(idxdb->xdb, excl);
}
static int rpmidxUnlock(rpmidxdb idxdb, int excl)
{
- if (idxdb->xdb)
- return rpmxdbUnlock(idxdb->xdb, excl);
- else
- return rpmpkgUnlock(idxdb->pkgdb, excl);
+ return rpmxdbUnlock(idxdb->xdb, excl);
}
static int rpmidxLockReadHeader(rpmidxdb idxdb, int excl)
@@ -1089,49 +882,7 @@ static int rpmidxInit(rpmidxdb idxdb)
int rpmidxOpen(rpmidxdb *idxdbp, rpmpkgdb pkgdb, const char *filename, int flags, int mode)
{
-#ifdef IDXDB_FILESUPPORT
- struct stat stb;
- rpmidxdb idxdb;
-
- *idxdbp = 0;
- idxdb = calloc(1, sizeof(*idxdb));
- if (!idxdb)
- return RPMRC_FAIL;
- idxdb->filename = strdup(filename);
- if (!idxdb->filename) {
- free(idxdb);
- return RPMRC_FAIL;
- }
- if ((flags & (O_RDONLY|O_RDWR)) == O_RDONLY)
- idxdb->rdonly = 1;
- if ((idxdb->fd = open(filename, flags, mode)) == -1) {
- free(idxdb->filename);
- free(idxdb);
- return RPMRC_FAIL;
- }
- if (fstat(idxdb->fd, &stb)) {
- close(idxdb->fd);
- free(idxdb->filename);
- free(idxdb);
- return RPMRC_FAIL;
- }
- idxdb->pkgdb = pkgdb;
- idxdb->flags = flags;
- idxdb->mode = mode;
- idxdb->pagesize = sysconf(_SC_PAGE_SIZE);
- if (stb.st_size == 0) {
- if (rpmidxInit(idxdb)) {
- close(idxdb->fd);
- free(idxdb->filename);
- free(idxdb);
- return RPMRC_FAIL;
- }
- }
- *idxdbp = idxdb;
- return RPMRC_OK;
-#else
return RPMRC_FAIL;
-#endif
}
int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag)
@@ -1150,19 +901,13 @@ int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmp
rpmxdbUnlock(xdb, 0);
return RPMRC_FAIL;
}
- idxdb = calloc(1, sizeof(*idxdb));
- if (!idxdb) {
- rpmxdbUnlock(xdb, 0);
- return RPMRC_FAIL;
- }
- idxdb->fd = -1;
+ idxdb = xcalloc(1, sizeof(*idxdb));
idxdb->xdb = xdb;
idxdb->xdbtag = xdbtag;
idxdb->xdbid = id;
idxdb->pkgdb = pkgdb;
- idxdb->pagesize = sysconf(_SC_PAGE_SIZE);
- if (rpmxdbIsRdonly(xdb))
- idxdb->rdonly = 1;
+ idxdb->pagesize = rpmxdbPagesize(xdb);
+ idxdb->rdonly = rpmxdbIsRdonly(xdb) ? 1 : 0;
if (!id) {
if (rpmidxInit(idxdb)) {
free(idxdb);
@@ -1199,12 +944,6 @@ int rpmidxDelXdb(rpmpkgdb pkgdb, rpmxdb
void rpmidxClose(rpmidxdb idxdb)
{
rpmidxUnmap(idxdb);
- if (idxdb->fd >= 0) {
- close(idxdb->fd);
- idxdb->fd = -1;
- }
- if (idxdb->filename)
- free(idxdb->filename);
free(idxdb);
}
@@ -1263,11 +1002,7 @@ int rpmidxStats(rpmidxdb idxdb)
if (rpmidxLockReadHeader(idxdb, 0))
return RPMRC_FAIL;
printf("--- IndexDB Stats\n");
- if (idxdb->xdb) {
- printf("Xdb tag: %d, id: %d\n", idxdb->xdbtag, idxdb->xdbid);
- } else {
- printf("Filename: %s\n", idxdb->filename);
- }
+ printf("Xdb tag: %d, id: %d\n", idxdb->xdbtag, idxdb->xdbid);
printf("Generation: %u\n", idxdb->generation);
printf("Slots: %u\n", idxdb->nslots);
printf("Used slots: %u\n", idxdb->usedslots);
--- ./lib/backend/ndb/rpmpkg.c.orig 2020-01-16 15:11:26.181880288 +0000
+++ ./lib/backend/ndb/rpmpkg.c 2020-01-16 15:11:26.181880288 +0000
@@ -7,7 +7,6 @@
#include <sys/file.h>
#include <fcntl.h>
#include <stdio.h>
-#include <time.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
@@ -19,10 +18,6 @@
#define RPMRC_NOTFOUND 1
#define RPMRC_OK 0
-#ifdef RPMPKG_LZO
-static int rpmpkgLZOCompress(unsigned char **blobp, unsigned int *bloblp);
-static int rpmpkgLZODecompress(unsigned char **blobp, unsigned int *bloblp);
-#endif
static int rpmpkgVerifyblob(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned int blkoff, unsigned int blkcnt);
@@ -49,23 +44,19 @@ typedef struct rpmpkgdb_s {
unsigned int nextpkgidx;
struct pkgslot_s *slots;
- unsigned int aslots; /* allocated slots */
unsigned int nslots; /* used slots */
unsigned int *slothash;
unsigned int nslothash;
unsigned int freeslot; /* first free slot */
- int slotorder;
+ int ordered; /* slots are ordered by the blk offsets */
char *filename;
unsigned int fileblks; /* file size in blks */
int dofsync;
} * rpmpkgdb;
-#define SLOTORDER_UNORDERED 0
-#define SLOTORDER_BLKOFF 1
-
static inline unsigned int le2h(unsigned char *p)
{
@@ -144,10 +135,6 @@ static int rpmpkgReadHeader(rpmpkgdb pkg
if (pkgdb->slots && (pkgdb->generation != generation || pkgdb->slotnpages != slotnpages)) {
free(pkgdb->slots);
pkgdb->slots = 0;
- if (pkgdb->slothash) {
- free(pkgdb->slothash);
- pkgdb->slothash = 0;
- }
}
pkgdb->generation = generation;
pkgdb->slotnpages = slotnpages;
@@ -156,6 +143,15 @@ static int rpmpkgReadHeader(rpmpkgdb pkg
return RPMRC_OK;
}
+static int rpmpkgFsync(rpmpkgdb pkgdb)
+{
+#ifdef HAVE_FDATASYNC
+ return fdatasync(pkgdb->fd);
+#else
+ return fsync(pkgdb->fd);
+#endif
+}
+
static int rpmpkgWriteHeader(rpmpkgdb pkgdb)
{
unsigned char header[PKGDB_HEADER_SIZE];
@@ -168,7 +164,7 @@ static int rpmpkgWriteHeader(rpmpkgdb pk
if (pwrite(pkgdb->fd, header, sizeof(header), 0) != sizeof(header)) {
return RPMRC_FAIL;
}
- if (pkgdb->dofsync && fsync(pkgdb->fd))
+ if (pkgdb->dofsync && rpmpkgFsync(pkgdb))
return RPMRC_FAIL; /* write error */
return RPMRC_OK;
}
@@ -191,6 +187,7 @@ static inline unsigned int hashpkgidx(un
return h;
}
+/* (re-)create a hash mapping pkgidx numbers to slots */
static int rpmpkgHashSlots(rpmpkgdb pkgdb)
{
unsigned int nslots, num;
@@ -199,17 +196,15 @@ static int rpmpkgHashSlots(rpmpkgdb pkgd
int i;
pkgslot *slot;
- pkgdb->nslothash = 0;
- num = pkgdb->nslots;
+ num = pkgdb->nslots + 32;
while (num & (num - 1))
num = num & (num - 1);
num *= 4;
hash = pkgdb->slothash;
if (!hash || pkgdb->nslothash != num) {
- free(pkgdb->slothash);
- hash = pkgdb->slothash = calloc(num, sizeof(unsigned int));
- if (!hash)
- return RPMRC_FAIL;
+ if (hash)
+ free(hash);
+ hash = pkgdb->slothash = xcalloc(num, sizeof(unsigned int));
pkgdb->nslothash = num;
} else {
memset(hash, 0, num * sizeof(unsigned int));
@@ -221,8 +216,6 @@ static int rpmpkgHashSlots(rpmpkgdb pkgd
;
hash[h] = i + 1;
}
- pkgdb->slothash = hash;
- pkgdb->nslothash = num;
return RPMRC_OK;
}
@@ -240,10 +233,6 @@ static int rpmpkgReadSlots(rpmpkgdb pkgd
free(pkgdb->slots);
pkgdb->slots = 0;
}
- if (pkgdb->slothash) {
- free(pkgdb->slothash);
- pkgdb->slothash = 0;
- }
pkgdb->nslots = 0;
pkgdb->freeslot = 0;
@@ -255,11 +244,7 @@ static int rpmpkgReadSlots(rpmpkgdb pkgd
fileblks = stb.st_size / BLK_SIZE;
/* read (and somewhat verify) all slots */
- pkgdb->aslots = slotnpages * (PAGE_SIZE / SLOT_SIZE);
- pkgdb->slots = calloc(pkgdb->aslots, sizeof(*pkgdb->slots));
- if (!pkgdb->slots) {
- return RPMRC_FAIL;
- }
+ pkgdb->slots = xcalloc(slotnpages * (PAGE_SIZE / SLOT_SIZE), sizeof(*pkgdb->slots));
i = 0;
slot = pkgdb->slots;
minblkoff = slotnpages * (PAGE_SIZE / BLK_SIZE);
@@ -295,7 +280,7 @@ static int rpmpkgReadSlots(rpmpkgdb pkgd
}
}
pkgdb->nslots = i;
- pkgdb->slotorder = SLOTORDER_UNORDERED; /* XXX: always order? */
+ pkgdb->ordered = 0;
pkgdb->fileblks = fileblks;
pkgdb->freeslot = freeslot;
if (rpmpkgHashSlots(pkgdb)) {
@@ -313,15 +298,13 @@ static int orderslots_blkoff_cmp(const v
return blkoffa > blkoffb ? 1 : blkoffa < blkoffb ? -1 : 0;
}
-static void rpmpkgOrderSlots(rpmpkgdb pkgdb, int slotorder)
+static void rpmpkgOrderSlots(rpmpkgdb pkgdb)
{
- if (pkgdb->slotorder == slotorder)
+ if (pkgdb->ordered)
return;
- if (slotorder == SLOTORDER_BLKOFF) {
- if (pkgdb->nslots > 1)
- qsort(pkgdb->slots, pkgdb->nslots, sizeof(*pkgdb->slots), orderslots_blkoff_cmp);
- }
- pkgdb->slotorder = slotorder;
+ if (pkgdb->nslots > 1)
+ qsort(pkgdb->slots, pkgdb->nslots, sizeof(*pkgdb->slots), orderslots_blkoff_cmp);
+ pkgdb->ordered = 1;
rpmpkgHashSlots(pkgdb);
}
@@ -336,6 +319,8 @@ static inline pkgslot *rpmpkgFindSlot(rp
return 0;
}
+/* Find an empty space for blkcnt blocks. If dontprepend is true, ignore
+ the space between the slot area and the first blob */
static int rpmpkgFindEmptyOffset(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned int blkcnt, unsigned *blkoffp, pkgslot **oldslotp, int dontprepend)
{
unsigned int i, nslots = pkgdb->nslots;
@@ -344,8 +329,8 @@ static int rpmpkgFindEmptyOffset(rpmpkgd
unsigned int lastblkend = pkgdb->slotnpages * (PAGE_SIZE / BLK_SIZE);
pkgslot *slot, *oldslot = 0;
- if (pkgdb->slotorder != SLOTORDER_BLKOFF)
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
+ if (!pkgdb->ordered)
+ rpmpkgOrderSlots(pkgdb);
if (dontprepend && nslots) {
lastblkend = pkgdb->slots[0].blkoff;
@@ -378,14 +363,15 @@ static int rpmpkgFindEmptyOffset(rpmpkgd
return RPMRC_OK;
}
+/* verify the blobs to the left and right of a free area */
static int rpmpkgNeighbourCheck(rpmpkgdb pkgdb, unsigned int blkoff, unsigned int blkcnt, unsigned int *newblkcnt)
{
unsigned int i, nslots = pkgdb->nslots;
unsigned int lastblkend = pkgdb->slotnpages * (PAGE_SIZE / BLK_SIZE);
pkgslot *slot, *left = 0, *right = 0;
- if (pkgdb->slotorder != SLOTORDER_BLKOFF)
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
+ if (!pkgdb->ordered)
+ rpmpkgOrderSlots(pkgdb);
if (blkoff < lastblkend)
return RPMRC_FAIL;
for (i = 0, slot = pkgdb->slots; i < nslots; i++, slot++) {
@@ -409,7 +395,7 @@ static int rpmpkgNeighbourCheck(rpmpkgdb
if (right && rpmpkgVerifyblob(pkgdb, right->pkgidx, right->blkoff, right->blkcnt) != RPMRC_OK)
return RPMRC_FAIL;
*newblkcnt = right ? right->blkoff - blkoff : blkcnt;
- /* bounds are intect. free area. */
+ /* bounds are intact. ok to zero area. */
return RPMRC_OK;
}
@@ -429,6 +415,7 @@ static int rpmpkgWriteslot(rpmpkgdb pkgd
return RPMRC_FAIL;
}
pkgdb->generation++;
+ /* rpmpkgFsync() is done by rpmpkgWriteHeader() */
if (rpmpkgWriteHeader(pkgdb)) {
return RPMRC_FAIL;
}
@@ -445,7 +432,7 @@ static int rpmpkgWriteEmptySlotpage(rpmp
if (pwrite(pkgdb->fd, page, PAGE_SIZE - off, pageno * PAGE_SIZE + off) != PAGE_SIZE - off) {
return RPMRC_FAIL;
}
- if (pkgdb->dofsync && fsync(pkgdb->fd)) {
+ if (pkgdb->dofsync && rpmpkgFsync(pkgdb)) {
return RPMRC_FAIL; /* write error */
}
return RPMRC_OK;
@@ -523,7 +510,7 @@ static int rpmpkgValidateZero(rpmpkgdb p
/*** Blob primitives ***/
-/* head: magic + pkgidx + timestamp + bloblen */
+/* head: magic + pkgidx + generation + bloblen */
/* tail: adler32 + bloblen + magic */
#define BLOBHEAD_MAGIC ('B' | 'l' << 8 | 'b' << 16 | 'S' << 24)
@@ -532,10 +519,10 @@ static int rpmpkgValidateZero(rpmpkgdb p
#define BLOBHEAD_SIZE (4 + 4 + 4 + 4)
#define BLOBTAIL_SIZE (4 + 4 + 4)
-static int rpmpkgReadBlob(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned int blkoff, unsigned int blkcnt, unsigned char *blob, unsigned int *bloblp, unsigned int *tstampp)
+static int rpmpkgReadBlob(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned int blkoff, unsigned int blkcnt, unsigned char *blob, unsigned int *bloblp, unsigned int *generationp)
{
unsigned char buf[BLOBHEAD_SIZE > BLOBTAIL_SIZE ? BLOBHEAD_SIZE : BLOBTAIL_SIZE];
- unsigned int bloblen, toread, tstamp;
+ unsigned int bloblen, toread, generation;
off_t fileoff;
unsigned int adl;
int verifyadler = bloblp ? 0 : 1;
@@ -551,7 +538,7 @@ static int rpmpkgReadBlob(rpmpkgdb pkgdb
return RPMRC_FAIL; /* bad blob */
if (le2h(buf + 4) != pkgidx)
return RPMRC_FAIL; /* bad blob */
- tstamp = le2h(buf + 8);
+ generation = le2h(buf + 8);
bloblen = le2h(buf + 12);
if (blkcnt != (BLOBHEAD_SIZE + bloblen + BLOBTAIL_SIZE + BLK_SIZE - 1) / BLK_SIZE)
return RPMRC_FAIL; /* bad blob */
@@ -596,8 +583,8 @@ static int rpmpkgReadBlob(rpmpkgdb pkgdb
}
if (bloblp)
*bloblp = bloblen;
- if (tstampp)
- *tstampp = tstamp;
+ if (generationp)
+ *generationp = generation;
return RPMRC_OK;
}
@@ -656,7 +643,7 @@ static int rpmpkgWriteBlob(rpmpkgdb pkgd
/* update file length */
if (blkoff + blkcnt > pkgdb->fileblks)
pkgdb->fileblks = blkoff + blkcnt;
- if (pkgdb->dofsync && fsync(pkgdb->fd)) {
+ if (pkgdb->dofsync && rpmpkgFsync(pkgdb)) {
return RPMRC_FAIL; /* write error */
}
return RPMRC_OK;
@@ -668,7 +655,7 @@ static int rpmpkgDelBlob(rpmpkgdb pkgdb,
return RPMRC_FAIL;
if (rpmpkgZeroBlks(pkgdb, blkoff, blkcnt))
return RPMRC_FAIL;
- if (pkgdb->dofsync && fsync(pkgdb->fd))
+ if (pkgdb->dofsync && rpmpkgFsync(pkgdb))
return RPMRC_FAIL; /* write error */
return RPMRC_OK;
}
@@ -680,14 +667,14 @@ static int rpmpkgMoveBlob(rpmpkgdb pkgdb
unsigned int blkoff = slot->blkoff;
unsigned int blkcnt = slot->blkcnt;
unsigned char *blob;
- unsigned int tstamp, blobl;
+ unsigned int generation, blobl;
- blob = malloc((size_t)blkcnt * BLK_SIZE);
- if (rpmpkgReadBlob(pkgdb, pkgidx, blkoff, blkcnt, blob, &blobl, &tstamp)) {
+ blob = xmalloc((size_t)blkcnt * BLK_SIZE);
+ if (rpmpkgReadBlob(pkgdb, pkgidx, blkoff, blkcnt, blob, &blobl, &generation)) {
free(blob);
return RPMRC_FAIL;
}
- if (rpmpkgWriteBlob(pkgdb, pkgidx, newblkoff, blkcnt, blob, blobl, tstamp)) {
+ if (rpmpkgWriteBlob(pkgdb, pkgidx, newblkoff, blkcnt, blob, blobl, generation)) {
free(blob);
return RPMRC_FAIL;
}
@@ -699,15 +686,15 @@ static int rpmpkgMoveBlob(rpmpkgdb pkgdb
return RPMRC_FAIL;
}
slot->blkoff = newblkoff;
- pkgdb->slotorder = SLOTORDER_UNORDERED;
+ pkgdb->ordered = 0;
return RPMRC_OK;
}
static int rpmpkgAddSlotPage(rpmpkgdb pkgdb)
{
unsigned int cutoff;
- if (pkgdb->slotorder != SLOTORDER_BLKOFF)
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
+ if (!pkgdb->ordered)
+ rpmpkgOrderSlots(pkgdb);
cutoff = (pkgdb->slotnpages + 1) * (PAGE_SIZE / BLK_SIZE);
/* now move every blob before cutoff */
@@ -725,7 +712,7 @@ static int rpmpkgAddSlotPage(rpmpkgdb pk
if (rpmpkgMoveBlob(pkgdb, slot, newblkoff)) {
return RPMRC_FAIL;
}
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
+ rpmpkgOrderSlots(pkgdb);
}
/* make sure our new page is empty */
@@ -845,18 +832,31 @@ static int rpmpkgInit(rpmpkgdb pkgdb)
return rc;
}
+static int rpmpkgFsyncDir(const char *filename)
+{
+ int rc = RPMRC_OK;
+ DIR *pdir;
+ char *filenameCopy = xstrdup(filename);
+
+ if ((pdir = opendir(dirname(filenameCopy))) == NULL) {
+ free(filenameCopy);
+ return RPMRC_FAIL;
+ }
+ if (fsync(dirfd(pdir)) == -1)
+ rc = RPMRC_FAIL;
+ closedir(pdir);
+ free(filenameCopy);
+ return rc;
+}
+
int rpmpkgOpen(rpmpkgdb *pkgdbp, const char *filename, int flags, int mode)
{
struct stat stb;
rpmpkgdb pkgdb;
*pkgdbp = 0;
- pkgdb = calloc(1, sizeof(*pkgdb));
- pkgdb->filename = strdup(filename);
- if (!pkgdb->filename) {
- free(pkgdb);
- return RPMRC_FAIL;
- }
+ pkgdb = xcalloc(1, sizeof(*pkgdb));
+ pkgdb->filename = xstrdup(filename);
if ((flags & (O_RDONLY|O_RDWR)) == O_RDONLY)
pkgdb->rdonly = 1;
if ((pkgdb->fd = open(filename, flags, mode)) == -1) {
@@ -864,37 +864,6 @@ int rpmpkgOpen(rpmpkgdb *pkgdbp, const c
free(pkgdb);
return RPMRC_FAIL;
}
- if (flags & O_CREAT) {
- char *filenameCopy;
- DIR *pdir;
-
- if ((filenameCopy = strdup(pkgdb->filename)) == NULL) {
- close(pkgdb->fd);
- free(pkgdb->filename);
- free(pkgdb);
- return RPMRC_FAIL;
- }
-
- if ((pdir = opendir(dirname(filenameCopy))) == NULL) {
- free(filenameCopy);
- close(pkgdb->fd);
- free(pkgdb->filename);
- free(pkgdb);
- return RPMRC_FAIL;
- }
-
- if (fsync(dirfd(pdir)) == -1) {
- closedir(pdir);
- free(filenameCopy);
- close(pkgdb->fd);
- free(pkgdb->filename);
- free(pkgdb);
- return RPMRC_FAIL;
- }
- closedir(pdir);
- free(filenameCopy);
-
- }
if (fstat(pkgdb->fd, &stb)) {
close(pkgdb->fd);
free(pkgdb->filename);
@@ -902,6 +871,13 @@ int rpmpkgOpen(rpmpkgdb *pkgdbp, const c
return RPMRC_FAIL;
}
if (stb.st_size == 0) {
+ /* created new database */
+ if (rpmpkgFsyncDir(pkgdb->filename)) {
+ close(pkgdb->fd);
+ free(pkgdb->filename);
+ free(pkgdb);
+ return RPMRC_FAIL;
+ }
if (rpmpkgInit(pkgdb)) {
close(pkgdb->fd);
free(pkgdb->filename);
@@ -950,7 +926,7 @@ static int rpmpkgGetInternal(rpmpkgdb pk
if (!slot) {
return RPMRC_NOTFOUND;
}
- blob = malloc((size_t)slot->blkcnt * BLK_SIZE);
+ blob = xmalloc((size_t)slot->blkcnt * BLK_SIZE);
if (rpmpkgReadBlob(pkgdb, pkgidx, slot->blkoff, slot->blkcnt, blob, bloblp, (unsigned int *)0)) {
free(blob);
return RPMRC_FAIL;
@@ -965,6 +941,7 @@ static int rpmpkgPutInternal(rpmpkgdb pk
pkgslot *oldslot;
/* we always read all slots when writing, just in case */
+ /* this also will set pkgdb->freeslot */
if (rpmpkgReadSlots(pkgdb)) {
return RPMRC_FAIL;
}
@@ -988,7 +965,7 @@ static int rpmpkgPutInternal(rpmpkgdb pk
return RPMRC_FAIL;
}
/* write new blob */
- if (rpmpkgWriteBlob(pkgdb, pkgidx, blkoff, blkcnt, blob, blobl, (unsigned int)time(0))) {
+ if (rpmpkgWriteBlob(pkgdb, pkgidx, blkoff, blkcnt, blob, blobl, pkgdb->generation)) {
return RPMRC_FAIL;
}
/* write slot */
@@ -1013,7 +990,7 @@ static int rpmpkgPutInternal(rpmpkgdb pk
/* just update the slot, no need to free the slot data */
oldslot->blkoff = blkoff;
oldslot->blkcnt = blkcnt;
- pkgdb->slotorder = SLOTORDER_UNORDERED;
+ pkgdb->ordered = 0;
} else {
free(pkgdb->slots);
pkgdb->slots = 0;
@@ -1030,7 +1007,7 @@ static int rpmpkgDelInternal(rpmpkgdb pk
if (rpmpkgReadSlots(pkgdb)) {
return RPMRC_FAIL;
}
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
+ rpmpkgOrderSlots(pkgdb);
slot = rpmpkgFindSlot(pkgdb, pkgidx);
if (!slot) {
return RPMRC_OK;
@@ -1056,9 +1033,10 @@ static int rpmpkgDelInternal(rpmpkgdb pk
}
slot->blkoff = 0;
slot->blkcnt = 0;
+ /* try to move the last two slots, the bigger one first */
slot = pkgdb->slots + pkgdb->nslots - 2;
if (slot->blkcnt < slot[1].blkcnt)
- slot++; /* bigger slot first */
+ slot++; /* bigger slot first */
for (i = 0; i < 2; i++, slot++) {
if (slot == pkgdb->slots + pkgdb->nslots)
slot -= 2;
@@ -1072,7 +1050,7 @@ static int rpmpkgDelInternal(rpmpkgdb pk
blkoff += slot->blkcnt;
blkcnt -= slot->blkcnt;
}
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
+ rpmpkgOrderSlots(pkgdb);
} else {
slot->blkoff = 0;
slot->blkcnt = 0;
@@ -1111,9 +1089,9 @@ static int rpmpkgListInternal(rpmpkgdb p
*npkgidxlistp = pkgdb->nslots;
return RPMRC_OK;
}
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
+ rpmpkgOrderSlots(pkgdb);
nslots = pkgdb->nslots;
- pkgidxlist = calloc(nslots + 1, sizeof(unsigned int));
+ pkgidxlist = xcalloc(nslots + 1, sizeof(unsigned int));
for (i = 0, slot = pkgdb->slots; i < nslots; i++, slot++) {
pkgidxlist[i] = slot->pkgidx;
}
@@ -1122,6 +1100,22 @@ static int rpmpkgListInternal(rpmpkgdb p
return RPMRC_OK;
}
+static int rpmpkgVerifyInternal(rpmpkgdb pkgdb)
+{
+ unsigned int i, nslots;
+ pkgslot *slot;
+
+ if (rpmpkgReadSlots(pkgdb))
+ return RPMRC_FAIL;
+ rpmpkgOrderSlots(pkgdb);
+ nslots = pkgdb->nslots;
+ for (i = 0, slot = pkgdb->slots; i < nslots; i++, slot++) {
+ if (rpmpkgVerifyblob(pkgdb, slot->pkgidx, slot->blkoff, slot->blkcnt))
+ return RPMRC_FAIL;
+ }
+ return RPMRC_OK;
+}
+
int rpmpkgGet(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char **blobp, unsigned int *bloblp)
{
int rc;
@@ -1134,10 +1128,6 @@ int rpmpkgGet(rpmpkgdb pkgdb, unsigned i
return RPMRC_FAIL;
rc = rpmpkgGetInternal(pkgdb, pkgidx, blobp, bloblp);
rpmpkgUnlock(pkgdb, 0);
-#ifdef RPMPKG_LZO
- if (!rc)
- rc = rpmpkgLZODecompress(blobp, bloblp);
-#endif
return rc;
}
@@ -1150,16 +1140,7 @@ int rpmpkgPut(rpmpkgdb pkgdb, unsigned i
}
if (rpmpkgLockReadHeader(pkgdb, 1))
return RPMRC_FAIL;
-#ifdef RPMPKG_LZO
- if (rpmpkgLZOCompress(&blob, &blobl)) {
- rpmpkgUnlock(pkgdb, 1);
- return RPMRC_FAIL;
- }
-#endif
rc = rpmpkgPutInternal(pkgdb, pkgidx, blob, blobl);
-#ifdef RPMPKG_LZO
- free(blob);
-#endif
rpmpkgUnlock(pkgdb, 1);
return rc;
}
@@ -1191,6 +1172,16 @@ int rpmpkgList(rpmpkgdb pkgdb, unsigned
return rc;
}
+int rpmpkgVerify(rpmpkgdb pkgdb)
+{
+ int rc;
+ if (rpmpkgLockReadHeader(pkgdb, 0))
+ return RPMRC_FAIL;
+ rc = rpmpkgVerifyInternal(pkgdb);
+ rpmpkgUnlock(pkgdb, 0);
+ return rc;
+}
+
int rpmpkgNextPkgIdx(rpmpkgdb pkgdb, unsigned int *pkgidxp)
{
if (rpmpkgLockReadHeader(pkgdb, 1))
@@ -1240,73 +1231,3 @@ int rpmpkgStats(rpmpkgdb pkgdb)
return RPMRC_OK;
}
-#ifdef RPMPKG_LZO
-
-#include "lzo/lzoconf.h"
-#include "lzo/lzo1x.h"
-
-#define BLOBLZO_MAGIC ('L' | 'Z' << 8 | 'O' << 16 | 'B' << 24)
-
-static int rpmpkgLZOCompress(unsigned char **blobp, unsigned int *bloblp)
-{
- unsigned char *blob = *blobp;
- unsigned int blobl = *bloblp;
- unsigned char *lzoblob, *workmem;
- unsigned int lzoblobl;
- lzo_uint blobl2;
-
- if (lzo_init() != LZO_E_OK) {
- return RPMRC_FAIL;
- }
- workmem = malloc(LZO1X_1_MEM_COMPRESS);
- if (!workmem) {
- return RPMRC_FAIL;
- }
- lzoblobl = 4 + 4 + blobl + blobl / 16 + 64 + 3;
- lzoblob = malloc(lzoblobl);
- if (!lzoblob) {
- free(workmem);
- return RPMRC_FAIL;
- }
- h2le(BLOBLZO_MAGIC, lzoblob);
- h2le(blobl, lzoblob + 4);
- if (lzo1x_1_compress(blob, blobl, lzoblob + 8, &blobl2, workmem) != LZO_E_OK) {
- free(workmem);
- free(lzoblob);
- return RPMRC_FAIL;
- }
- free(workmem);
- *blobp = lzoblob;
- *bloblp = 8 + blobl2;
- return RPMRC_OK;
-}
-
-static int rpmpkgLZODecompress(unsigned char **blobp, unsigned int *bloblp)
-{
- unsigned char *lzoblob = *blobp;
- unsigned int lzoblobl = *bloblp;
- unsigned char *blob;
- unsigned int blobl;
- lzo_uint blobl2;
-
- if (!lzoblob || lzoblobl < 8)
- return RPMRC_FAIL;
- if (le2h(lzoblob) != BLOBLZO_MAGIC)
- return RPMRC_FAIL;
- if (lzo_init() != LZO_E_OK)
- return RPMRC_FAIL;
- blobl = le2h(lzoblob + 4);
- blob = malloc(blobl ? blobl : 1);
- if (!blob)
- return RPMRC_FAIL;
- if (lzo1x_decompress(lzoblob + 8, lzoblobl - 8, blob, &blobl2, 0) != LZO_E_OK || blobl2 != blobl) {
- free(blob);
- return RPMRC_FAIL;
- }
- free(lzoblob);
- *blobp = blob;
- *bloblp = blobl;
- return RPMRC_OK;
-}
-
-#endif
--- ./lib/backend/ndb/rpmpkg.h.orig 2020-01-28 10:57:30.224197080 +0000
+++ ./lib/backend/ndb/rpmpkg.h 2020-01-16 15:11:26.181880288 +0000
@@ -12,6 +12,7 @@ int rpmpkgGet(rpmpkgdb pkgdb, unsigned i
int rpmpkgPut(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char *blob, unsigned int blobl);
int rpmpkgDel(rpmpkgdb pkgdb, unsigned int pkgidx);
int rpmpkgList(rpmpkgdb pkgdb, unsigned int **pkgidxlistp, unsigned int *npkgidxlistp);
+int rpmpkgVerify(rpmpkgdb pkgdb);
int rpmpkgNextPkgIdx(rpmpkgdb pkgdb, unsigned int *pkgidxp);
int rpmpkgGeneration(rpmpkgdb pkgdb, unsigned int *generationp);
--- ./lib/backend/ndb/rpmxdb.c.orig 2020-01-16 15:11:26.181880288 +0000
+++ ./lib/backend/ndb/rpmxdb.c 2020-01-28 12:08:26.097237489 +0000
@@ -36,6 +36,7 @@ typedef struct rpmxdb_s {
unsigned int usergeneration;
unsigned char *mapped;
+ int mapflags;
unsigned int mappedlen;
struct xdb_slot {
@@ -95,12 +96,52 @@ static inline void h2lea(unsigned int x,
#define SLOT_MAGIC ('S' | 'l' << 8 | 'o' << 16)
-#define SLOT_SIZE 16
+#define SLOT_SIZE 16
#define SLOT_START (XDB_HEADER_SIZE / SLOT_SIZE)
-static void rpmxdbUnmap(rpmxdb xdb)
+
+/* low level map/remap a file into memory */
+static void *mapmem(void *oldaddr, size_t oldsize, size_t newsize, int prot, int fd, off_t offset)
{
- munmap(xdb->mapped, xdb->mappedlen);
+ if (oldaddr) {
+#if HAVE_MREMAP
+ return mremap(oldaddr, oldsize, newsize, MREMAP_MAYMOVE);
+#else
+ void *mapped = mmap(0, newsize, prot, MAP_SHARED, fd, offset);
+ if (mapped != MAP_FAILED)
+ munmap(oldaddr, oldsize);
+ return mapped;
+#endif
+ }
+ return mmap(0, newsize, prot, MAP_SHARED, fd, offset);
+}
+
+/* unmap a mapped region */
+static void unmapmem(void *addr, size_t size)
+{
+ munmap(addr, size);
+}
+
+#define ROUNDTOSYSTEMPAGE(xdb, size) (((size) + (xdb->systempagesize - 1)) & ~(xdb->systempagesize - 1))
+
+/* xdb header mapping functions */
+static int mapheader(rpmxdb xdb, unsigned int slotnpages)
+{
+ unsigned char *mapped;
+ size_t mappedlen = slotnpages * xdb->pagesize;
+
+ mappedlen = ROUNDTOSYSTEMPAGE(xdb, mappedlen);
+ mapped = mapmem(xdb->mapped, xdb->mappedlen, mappedlen, xdb->mapflags, xdb->fd, 0);
+ if ((void *)mapped == MAP_FAILED)
+ return RPMRC_FAIL;
+ xdb->mapped = mapped;
+ xdb->mappedlen = mappedlen;
+ return RPMRC_OK;
+}
+
+static void unmapheader(rpmxdb xdb)
+{
+ unmapmem(xdb->mapped, xdb->mappedlen);
xdb->mapped = 0;
xdb->mappedlen = 0;
}
@@ -120,9 +161,9 @@ static int mapslot(rpmxdb xdb, struct xd
shift = off & (xdb->systempagesize - 1);
off -= shift;
size += shift;
- size = (size + xdb->systempagesize - 1) & ~(xdb->systempagesize - 1);
+ size = ROUNDTOSYSTEMPAGE(xdb, size);
}
- mapped = mmap(0, size, slot->mapflags, MAP_SHARED, xdb->fd, off);
+ mapped = mapmem(0, 0, size, slot->mapflags, xdb->fd, off);
if (mapped == MAP_FAILED)
return RPMRC_FAIL;
slot->mapped = (unsigned char *)mapped + shift;
@@ -131,44 +172,41 @@ static int mapslot(rpmxdb xdb, struct xd
static void unmapslot(rpmxdb xdb, struct xdb_slot *slot)
{
- size_t size;
unsigned char *mapped = slot->mapped;
+ size_t size;
if (!mapped)
return;
size = slot->pagecnt * xdb->pagesize;
if (xdb->pagesize != xdb->systempagesize) {
size_t off = slot->startpage * xdb->pagesize;
size_t shift = off & (xdb->systempagesize - 1);
- mapped -= shift;
size += shift;
- size = (size + xdb->systempagesize - 1) & ~(xdb->systempagesize - 1);
+ size = ROUNDTOSYSTEMPAGE(xdb, size);
+ mapped -= shift;
}
- munmap(mapped, size);
+ unmapmem(mapped, size);
slot->mapped = 0;
}
static int remapslot(rpmxdb xdb, struct xdb_slot *slot, unsigned int newpagecnt)
{
- void *mapped;
+ unsigned char *mapped = slot->mapped;
size_t off, oldsize, newsize, shift;
+
oldsize = slot->pagecnt * xdb->pagesize;
newsize = newpagecnt * xdb->pagesize;
off = slot->startpage * xdb->pagesize;
shift = 0;
if (xdb->pagesize != xdb->systempagesize) {
- off = slot->startpage * xdb->pagesize;
shift = off & (xdb->systempagesize - 1);
off -= shift;
oldsize += shift;
- oldsize = (oldsize + xdb->systempagesize - 1) & ~(xdb->systempagesize - 1);
newsize += shift;
- newsize = (newsize + xdb->systempagesize - 1) & ~(xdb->systempagesize - 1);
+ oldsize = ROUNDTOSYSTEMPAGE(xdb, oldsize);
+ newsize = ROUNDTOSYSTEMPAGE(xdb, newsize);
}
- if (slot->mapped)
- mapped = mremap(slot->mapped - shift, oldsize, newsize, MREMAP_MAYMOVE);
- else
- mapped = mmap(0, newsize, slot->mapflags, MAP_SHARED, xdb->fd, off);
- if (mapped == MAP_FAILED)
+ mapped = mapmem(mapped ? mapped - shift : 0, oldsize, newsize, slot->mapflags, xdb->fd, off);
+ if ((void *)mapped == MAP_FAILED)
return RPMRC_FAIL;
slot->mapped = (unsigned char *)mapped + shift;
slot->pagecnt = newpagecnt;
@@ -186,11 +224,33 @@ static int usedslots_cmp(const void *a,
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;
@@ -198,61 +258,31 @@ static int rpmxdbReadHeader(rpmxdb xdb)
unsigned int usedblobpages;
int i, nused, slotno;
struct stat stb;
- size_t mapsize;
if (xdb->mapped) {
if (le2ha(xdb->mapped + XDB_OFFSET_GENERATION) == xdb->generation) {
return RPMRC_OK;
}
- rpmxdbUnmap(xdb);
+ unmapheader(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)
- 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);
+ if (rpmxdbReadHeaderRaw(xdb, &generation, &slotnpages, &pagesize, &usergeneration))
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;
- /* round up */
- mapsize = slotnpages * pagesize;
- mapsize = (mapsize + xdb->systempagesize - 1) & ~(xdb->systempagesize - 1);
- xdb->mapped = mmap(0, mapsize, xdb->rdonly ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED, xdb->fd, 0);
- if ((void *)xdb->mapped == MAP_FAILED) {
- xdb->mapped = 0;
+ if (mapheader(xdb, slotnpages))
return RPMRC_FAIL;
- }
- xdb->mappedlen = mapsize;
/* read in all slots */
xdb->firstfree = 0;
nslots = slotnpages * (pagesize / SLOT_SIZE) - SLOT_START + 1;
- slots = calloc(nslots + 1, sizeof(struct xdb_slot));
- if (!slots) {
- rpmxdbUnmap(xdb);
- return RPMRC_FAIL;
- }
- usedslots = calloc(nslots + 1, sizeof(int));
- if (!usedslots) {
- rpmxdbUnmap(xdb);
- free(slots);
- return RPMRC_FAIL;
- }
+ slots = xcalloc(nslots + 1, sizeof(struct xdb_slot));
+ usedslots = xcalloc(nslots + 1, sizeof(struct xdb_slot *));
nused = 0;
slotno = 1;
slot = slots + 1;
@@ -267,7 +297,7 @@ static int rpmxdbReadHeader(rpmxdb xdb)
if ((slot->subtag & 0x00ffffff) != SLOT_MAGIC) {
free(slots);
free(usedslots);
- rpmxdbUnmap(xdb);
+ unmapheader(xdb);
return RPMRC_FAIL;
}
slot->subtag = (slot->subtag >> 24) & 255;
@@ -296,7 +326,7 @@ static int rpmxdbReadHeader(rpmxdb xdb)
if (lastslot->startpage + lastslot->pagecnt > slot->startpage) {
free(slots);
free(usedslots);
- rpmxdbUnmap(xdb);
+ unmapheader(xdb);
return RPMRC_FAIL;
}
lastslot->next = slot->slotno;
@@ -384,9 +414,7 @@ static int rpmxdbWriteEmptyPages(rpmxdb
unsigned char *page;
if (!count)
return RPMRC_OK;
- page = malloc(xdb->pagesize);
- if (!page)
- return RPMRC_FAIL;
+ page = xmalloc(xdb->pagesize);
memset(page, 0, xdb->pagesize);
for (; count; count--, pageno++) {
if (pwrite(xdb->fd, page, xdb->pagesize, pageno * xdb->pagesize) != xdb->pagesize) {
@@ -402,9 +430,7 @@ static int rpmxdbWriteEmptySlotpage(rpmx
{
unsigned char *page;
int i, spp;
- page = malloc(xdb->pagesize);
- if (!page)
- return RPMRC_FAIL;
+ page = xmalloc(xdb->pagesize);
memset(page, 0, xdb->pagesize);
spp = xdb->pagesize / SLOT_SIZE; /* slots per page */
for (i = pageno ? 0 : SLOT_START; i < spp; i++)
@@ -493,20 +519,33 @@ static int rpmxdbInit(rpmxdb xdb)
return rc;
}
+static int rpmxdbFsyncDir(const char *filename)
+{
+ int rc = RPMRC_OK;
+ DIR *pdir;
+ char *filenameCopy = xstrdup(filename);
+
+ if ((pdir = opendir(dirname(filenameCopy))) == NULL) {
+ free(filenameCopy);
+ return RPMRC_FAIL;
+ }
+ if (fsync(dirfd(pdir)) == -1)
+ rc = RPMRC_FAIL;
+ closedir(pdir);
+ free(filenameCopy);
+ return rc;
+}
+
int rpmxdbOpen(rpmxdb *xdbp, rpmpkgdb pkgdb, const char *filename, int flags, int mode)
{
struct stat stb;
rpmxdb xdb;
*xdbp = 0;
- xdb = calloc(1, sizeof(*xdb));
+ xdb = xcalloc(1, sizeof(*xdb));
xdb->pkgdb = pkgdb;
- xdb->filename = strdup(filename);
+ xdb->filename = xstrdup(filename);
xdb->systempagesize = sysconf(_SC_PAGE_SIZE);
- if (!xdb->filename) {
- free(xdb);
- return RPMRC_FAIL;
- }
if ((flags & (O_RDONLY|O_RDWR)) == O_RDONLY)
xdb->rdonly = 1;
if ((xdb->fd = open(filename, flags, mode)) == -1) {
@@ -514,36 +553,6 @@ int rpmxdbOpen(rpmxdb *xdbp, rpmpkgdb pk
free(xdb);
return RPMRC_FAIL;
}
- if (flags & O_CREAT) {
- char *filenameCopy;
- DIR *pdir;
-
- if ((filenameCopy = strdup(xdb->filename)) == NULL) {
- close(xdb->fd);
- free(xdb->filename);
- free(xdb);
- return RPMRC_FAIL;
- }
-
- if ((pdir = opendir(dirname(filenameCopy))) == NULL) {
- free(filenameCopy);
- close(xdb->fd);
- free(xdb->filename);
- free(xdb);
- return RPMRC_FAIL;
- }
-
- if (fsync(dirfd(pdir)) == -1) {
- closedir(pdir);
- free(filenameCopy);
- close(xdb->fd);
- free(xdb->filename);
- free(xdb);
- return RPMRC_FAIL;
- }
- closedir(pdir);
- free(filenameCopy);
- }
if (fstat(xdb->fd, &stb)) {
close(xdb->fd);
free(xdb->filename);
@@ -551,6 +560,13 @@ int rpmxdbOpen(rpmxdb *xdbp, rpmpkgdb pk
return RPMRC_FAIL;
}
if (stb.st_size == 0) {
+ /* created new database */
+ if (rpmxdbFsyncDir(xdb->filename)) {
+ close(xdb->fd);
+ free(xdb->filename);
+ free(xdb);
+ return RPMRC_FAIL;
+ }
if (rpmxdbInit(xdb)) {
close(xdb->fd);
free(xdb->filename);
@@ -607,6 +623,7 @@ static int moveblobto(rpmxdb xdb, struct
didmap = 0;
oldpagecnt = oldslot->pagecnt;
if (!oldslot->mapped && oldpagecnt) {
+ oldslot->mapflags = PROT_READ;
if (mapslot(xdb, oldslot))
return RPMRC_FAIL;
didmap = 1;
@@ -728,10 +745,8 @@ static int moveblobstofront(rpmxdb xdb,
/* add a single page containing empty slots */
static int addslotpage(rpmxdb xdb)
{
- unsigned char *newaddr;
struct xdb_slot *slot;
int i, spp, nslots;
- size_t newmappedlen;
if (xdb->firstfree)
return RPMRC_FAIL;
@@ -750,22 +765,15 @@ static int addslotpage(rpmxdb xdb)
}
spp = xdb->pagesize / SLOT_SIZE; /* slots per page */
- slot = realloc(xdb->slots, (nslots + 1 + spp) * sizeof(*slot));
- if (!slot)
- return RPMRC_FAIL;
+ slot = xrealloc(xdb->slots, (nslots + 1 + spp) * sizeof(*slot));
xdb->slots = slot;
- if (rpmxdbWriteEmptySlotpage(xdb, xdb->slotnpages)) {
+ if (rpmxdbWriteEmptySlotpage(xdb, xdb->slotnpages))
return RPMRC_FAIL;
- }
- /* remap slots */
- newmappedlen = xdb->slotnpages * xdb->pagesize + xdb->pagesize;
- newmappedlen = (newmappedlen + xdb->systempagesize - 1) & ~(xdb->systempagesize - 1);
- newaddr = mremap(xdb->mapped, xdb->mappedlen, newmappedlen, MREMAP_MAYMOVE);
- if (newaddr == MAP_FAILED)
+
+ /* remap the header */
+ if (mapheader(xdb, xdb->slotnpages + 1))
return RPMRC_FAIL;
- xdb->mapped = newaddr;
- xdb->mappedlen = newmappedlen;
/* update the header */
xdb->slotnpages++;
@@ -787,13 +795,16 @@ static int addslotpage(rpmxdb xdb)
*slot = xdb->slots[nslots];
slot->slotno = nslots + spp;
xdb->slots[slot->prev].next = slot->slotno;
+
+ /* we have a new slotpage */
xdb->nslots += spp;
+ xdb->slots[0].pagecnt++;
/* add new free slots to the firstfree chain */
memset(xdb->slots + nslots, 0, sizeof(*slot) * spp);
for (i = 0; i < spp - 1; i++) {
xdb->slots[nslots + i].slotno = nslots + i;
- xdb->slots[nslots + i].next = i + 1;
+ xdb->slots[nslots + i].next = nslots + i + 1;
}
xdb->slots[nslots + i].slotno = nslots + i;
xdb->firstfree = nslots;
@@ -920,6 +931,45 @@ int rpmxdbDelBlob(rpmxdb xdb, unsigned i
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;
+ }
+ if (ftruncate(xdb->fd, xdb->pagesize)) {
+ /* ftruncate failed, but that is not a problem */
+ }
+ rpmxdbUnlock(xdb, 1);
+ return RPMRC_OK;
+}
+
int rpmxdbResizeBlob(rpmxdb xdb, unsigned int id, size_t newsize)
{
struct xdb_slot *slot;
@@ -946,11 +996,7 @@ int rpmxdbResizeBlob(rpmxdb xdb, unsigne
if (slot->mapped) {
memset(slot->mapped + pg, 0, xdb->pagesize - pg);
} else {
- char *empty = calloc(1, xdb->pagesize - pg);
- if (!empty) {
- rpmxdbUnlock(xdb, 1);
- return RPMRC_FAIL;
- }
+ char *empty = xcalloc(1, xdb->pagesize - pg);
if (pwrite(xdb->fd, empty, xdb->pagesize - pg, (slot->startpage + newpagecnt - 1) * xdb->pagesize + pg ) != xdb->pagesize - pg) {
free(empty);
rpmxdbUnlock(xdb, 1);
@@ -1156,12 +1202,26 @@ int rpmxdbIsRdonly(rpmxdb xdb)
return xdb->rdonly;
}
+unsigned int rpmxdbPagesize(rpmxdb xdb)
+{
+ return xdb->pagesize;
+}
+
+static int rpmxdbFsync(rpmxdb xdb)
+{
+#ifdef HAVE_FDATASYNC
+ return fdatasync(xdb->fd);
+#else
+ return fsync(xdb->fd);
+#endif
+}
+
int rpmxdbSetUserGeneration(rpmxdb xdb, unsigned int usergeneration)
{
if (rpmxdbLockReadHeader(xdb, 1))
return RPMRC_FAIL;
/* sync before the update */
- if (xdb->dofsync && fsync(xdb->fd)) {
+ if (xdb->dofsync && rpmxdbFsync(xdb)) {
rpmxdbUnlock(xdb, 1);
return RPMRC_FAIL;
}
--- ./lib/backend/ndb/rpmxdb.h.orig 2020-01-16 15:11:26.181880288 +0000
+++ ./lib/backend/ndb/rpmxdb.h 2020-01-16 15:11:26.181880288 +0000
@@ -7,12 +7,14 @@ int rpmxdbOpen(rpmxdb *xdbp, rpmpkgdb pk
void rpmxdbClose(rpmxdb xdb);
void rpmxdbSetFsync(rpmxdb xdb, int dofsync);
int rpmxdbIsRdonly(rpmxdb xdb);
+unsigned int rpmxdbPagesize(rpmxdb xdb);
int rpmxdbLock(rpmxdb xdb, int excl);
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);