Deprecate Berkeley DB
This commit is contained in:
parent
6560e2761e
commit
9aabff85da
164
backport-Add-a-salvagedb-option-to-the-rpmdb-tool.patch
Normal file
164
backport-Add-a-salvagedb-option-to-the-rpmdb-tool.patch
Normal file
@ -0,0 +1,164 @@
|
||||
From 243041f5fb68b68102243d713a1c5a3dc52698a2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Mon, 3 Feb 2020 14:20:19 +0100
|
||||
Subject: [PATCH] Add a --salvagedb option to the rpmdb tool
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/243041f5fb68b68102243d713a1c5a3dc52698a2
|
||||
---
|
||||
lib/backend/dbi.h | 1 +
|
||||
lib/backend/ndb/glue.c | 7 +++++--
|
||||
lib/rpmdb.c | 7 +++++--
|
||||
lib/rpmdb_internal.h | 8 +++++++-
|
||||
lib/rpmts.c | 8 ++++++--
|
||||
rpmdb.c | 6 ++++++
|
||||
6 files changed, 30 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/dbi.h b/lib/backend/dbi.h
|
||||
index c4bf387..f70eb33 100644
|
||||
--- a/lib/backend/dbi.h
|
||||
+++ b/lib/backend/dbi.h
|
||||
@@ -10,6 +10,7 @@ enum rpmdbFlags {
|
||||
RPMDB_FLAG_JUSTCHECK = (1 << 0),
|
||||
RPMDB_FLAG_REBUILD = (1 << 1),
|
||||
RPMDB_FLAG_VERIFYONLY = (1 << 2),
|
||||
+ RPMDB_FLAG_SALVAGE = (1 << 3),
|
||||
};
|
||||
|
||||
typedef enum dbCtrlOp_e {
|
||||
diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c
|
||||
index d19da7c..ae30ceb 100644
|
||||
--- a/lib/backend/ndb/glue.c
|
||||
+++ b/lib/backend/ndb/glue.c
|
||||
@@ -128,8 +128,11 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
|
||||
rpmpkgdb pkgdb = 0;
|
||||
char *path = rstrscat(NULL, dbhome, "/", rdb->db_ops->path, NULL);
|
||||
rpmlog(RPMLOG_DEBUG, "opening db index %s mode=0x%x\n", path, rdb->db_mode);
|
||||
- rc = rpmpkgOpen(&pkgdb, path, oflags, 0666);
|
||||
- if (rc && errno == ENOENT) {
|
||||
+ if ((rdb->db_flags & RPMDB_FLAG_SALVAGE) == 0)
|
||||
+ rc = rpmpkgOpen(&pkgdb, path, oflags, 0666);
|
||||
+ else
|
||||
+ rc = rpmpkgSalvage(&pkgdb, path);
|
||||
+ if (rc && errno == ENOENT && (rdb->db_flags & RPMDB_FLAG_SALVAGE) == 0) {
|
||||
oflags = O_RDWR|O_CREAT;
|
||||
dbi->dbi_flags |= DBI_CREATED;
|
||||
rc = rpmpkgOpen(&pkgdb, path, oflags, 0666);
|
||||
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
|
||||
index 91543eb..a072813 100644
|
||||
--- a/lib/rpmdb.c
|
||||
+++ b/lib/rpmdb.c
|
||||
@@ -2479,7 +2479,8 @@ static int rpmdbSetPermissions(char * src, char * dest)
|
||||
}
|
||||
|
||||
int rpmdbRebuild(const char * prefix, rpmts ts,
|
||||
- rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg))
|
||||
+ rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg),
|
||||
+ int rebuildflags)
|
||||
{
|
||||
rpmdb olddb;
|
||||
char * dbpath = NULL;
|
||||
@@ -2519,7 +2520,9 @@ int rpmdbRebuild(const char * prefix, rpmts ts,
|
||||
}
|
||||
|
||||
if (openDatabase(prefix, dbpath, &olddb,
|
||||
- O_RDONLY, 0644, RPMDB_FLAG_REBUILD)) {
|
||||
+ O_RDONLY, 0644, RPMDB_FLAG_REBUILD |
|
||||
+ (rebuildflags & RPMDB_REBUILD_FLAG_SALVAGE ?
|
||||
+ RPMDB_FLAG_SALVAGE : 0))) {
|
||||
rc = 1;
|
||||
goto exit;
|
||||
}
|
||||
diff --git a/lib/rpmdb_internal.h b/lib/rpmdb_internal.h
|
||||
index 5ad844c..d7446e5 100644
|
||||
--- a/lib/rpmdb_internal.h
|
||||
+++ b/lib/rpmdb_internal.h
|
||||
@@ -23,6 +23,10 @@ extern "C" {
|
||||
#undef HTKEYTYPE
|
||||
#undef HTDATATYPE
|
||||
|
||||
+enum rpmdbRebuildFlags_e {
|
||||
+ RPMDB_REBUILD_FLAG_SALVAGE = (1 << 0),
|
||||
+};
|
||||
+
|
||||
/** \ingroup rpmdb
|
||||
* Reference a database instance.
|
||||
* @param db rpm database
|
||||
@@ -63,11 +67,13 @@ int rpmdbClose (rpmdb db);
|
||||
* @param prefix path to top of install tree
|
||||
* @param ts transaction set (or NULL)
|
||||
* @param (*hdrchk) headerCheck() vector (or NULL)
|
||||
+ * @param rebuildflags flags
|
||||
* @return 0 on success
|
||||
*/
|
||||
RPM_GNUC_INTERNAL
|
||||
int rpmdbRebuild(const char * prefix, rpmts ts,
|
||||
- rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg));
|
||||
+ rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg),
|
||||
+ int rebuildflags);
|
||||
|
||||
/** \ingroup rpmdb
|
||||
* Verify database components.
|
||||
diff --git a/lib/rpmts.c b/lib/rpmts.c
|
||||
index d0fdfbe..eb98da7 100644
|
||||
--- a/lib/rpmts.c
|
||||
+++ b/lib/rpmts.c
|
||||
@@ -135,17 +135,21 @@ int rpmtsRebuildDB(rpmts ts)
|
||||
{
|
||||
int rc = -1;
|
||||
rpmtxn txn = NULL;
|
||||
+ int rebuildflags = 0;
|
||||
|
||||
/* Cannot do this on a populated transaction set */
|
||||
if (rpmtsNElements(ts) > 0)
|
||||
return -1;
|
||||
|
||||
+ if (rpmExpandNumeric("%{?_rebuilddb_salvage}"))
|
||||
+ rebuildflags |= RPMDB_REBUILD_FLAG_SALVAGE;
|
||||
+
|
||||
txn = rpmtxnBegin(ts, RPMTXN_WRITE);
|
||||
if (txn) {
|
||||
if (!(ts->vsflags & RPMVSF_NOHDRCHK))
|
||||
- rc = rpmdbRebuild(ts->rootDir, ts, headerCheck);
|
||||
+ rc = rpmdbRebuild(ts->rootDir, ts, headerCheck, rebuildflags);
|
||||
else
|
||||
- rc = rpmdbRebuild(ts->rootDir, NULL, NULL);
|
||||
+ rc = rpmdbRebuild(ts->rootDir, NULL, NULL, rebuildflags);
|
||||
rpmtxnEnd(txn);
|
||||
}
|
||||
return rc;
|
||||
diff --git a/rpmdb.c b/rpmdb.c
|
||||
index 25c088d..b72f0a5 100644
|
||||
--- a/rpmdb.c
|
||||
+++ b/rpmdb.c
|
||||
@@ -12,6 +12,7 @@ enum modes {
|
||||
MODE_VERIFYDB = (1 << 2),
|
||||
MODE_EXPORTDB = (1 << 3),
|
||||
MODE_IMPORTDB = (1 << 4),
|
||||
+ MODE_SALVAGEDB = (1 << 5),
|
||||
};
|
||||
|
||||
static int mode = 0;
|
||||
@@ -24,6 +25,8 @@ static struct poptOption dbOptsTable[] = {
|
||||
NULL},
|
||||
{ "verifydb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR|POPT_ARGFLAG_DOC_HIDDEN),
|
||||
&mode, MODE_VERIFYDB, N_("verify database files"), NULL},
|
||||
+ { "salvagedb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR|POPT_ARGFLAG_DOC_HIDDEN),
|
||||
+ &mode, MODE_SALVAGEDB, N_("salvage database"), NULL},
|
||||
{ "exportdb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_EXPORTDB,
|
||||
N_("export database to stdout header list"),
|
||||
NULL},
|
||||
@@ -108,8 +111,11 @@ int main(int argc, char *argv[])
|
||||
ec = rpmtsInitDB(ts, 0644);
|
||||
break;
|
||||
case MODE_REBUILDDB:
|
||||
+ case MODE_SALVAGEDB:
|
||||
{ rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}");
|
||||
rpmVSFlags ovsflags = rpmtsSetVSFlags(ts, vsflags);
|
||||
+ if (mode == MODE_SALVAGEDB)
|
||||
+ rpmDefineMacro(NULL, "_rebuilddb_salvage 1", 0);
|
||||
ec = rpmtsRebuildDB(ts);
|
||||
rpmtsSetVSFlags(ts, ovsflags);
|
||||
} break;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
From de3f36acc91bf13e694bb479e8dbe0502a4cc4e1 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Tue, 14 Apr 2020 11:09:29 +0200
|
||||
Subject: [PATCH] Add an index sync call at the end of a database rebuild
|
||||
|
||||
This is normally unneeded because an index sync is already done
|
||||
after each package is added to the database. But rebuilding an
|
||||
empty database lead to no index sync being done and a mismatch
|
||||
between the generation count. This in turn will trigger a
|
||||
index regeneration.
|
||||
|
||||
Found by using ndb when running the test suite.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/de3f36acc91bf13e694bb479e8dbe0502a4cc4e1
|
||||
---
|
||||
lib/rpmdb.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
|
||||
index 57a3c3d..4c10156 100644
|
||||
--- a/lib/rpmdb.c
|
||||
+++ b/lib/rpmdb.c
|
||||
@@ -2578,6 +2578,7 @@ int rpmdbRebuild(const char * prefix, rpmts ts,
|
||||
}
|
||||
|
||||
rpmdbClose(olddb);
|
||||
+ dbCtrl(newdb, DB_CTRL_INDEXSYNC);
|
||||
rpmdbClose(newdb);
|
||||
|
||||
if (failed) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,98 @@
|
||||
From bc00f99cb0c6bc367bd198b3b0fdc7cd445737c5 Mon Sep 17 00:00:00 2001
|
||||
From: Panu Matilainen <pmatilai@redhat.com>
|
||||
Date: Mon, 21 Oct 2019 13:37:22 +0300
|
||||
Subject: [PATCH] Add backend name and path of main database file to db_ops
|
||||
struct
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/bc00f99cb0c6bc367bd198b3b0fdc7cd445737c5
|
||||
Conflict:delete the contents of lib/backend/sqlite.c, because we have no sqlite database.
|
||||
---
|
||||
lib/backend/db3.c | 3 +++
|
||||
lib/backend/dbi.h | 5 ++++-
|
||||
lib/backend/dummydb.c | 3 +++
|
||||
lib/backend/lmdb.c | 3 +++
|
||||
lib/backend/ndb/glue.c | 3 +++
|
||||
5 files changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/backend/db3.c b/lib/backend/db3.c
|
||||
index ff1fc26..ab2f11f 100644
|
||||
--- a/lib/backend/db3.c
|
||||
+++ b/lib/backend/db3.c
|
||||
@@ -1365,6 +1365,9 @@ static unsigned int db3_pkgdbKey(dbiIndex dbi, dbiCursor dbc)
|
||||
}
|
||||
|
||||
struct rpmdbOps_s db3_dbops = {
|
||||
+ .name = "bdb",
|
||||
+ .path = "Packages",
|
||||
+
|
||||
.open = db3_dbiOpen,
|
||||
.close = db3_dbiClose,
|
||||
.verify = db3_dbiVerify,
|
||||
diff --git a/lib/backend/dbi.h b/lib/backend/dbi.h
|
||||
index e9e42d8..a618ea2 100644
|
||||
--- a/lib/backend/dbi.h
|
||||
+++ b/lib/backend/dbi.h
|
||||
@@ -59,7 +59,7 @@ struct rpmdb_s {
|
||||
dbiIndex * db_indexes; /*!< Tag indices. */
|
||||
int db_buildindex; /*!< Index rebuild indicator */
|
||||
|
||||
- struct rpmdbOps_s * db_ops; /*!< backend ops */
|
||||
+ const struct rpmdbOps_s * db_ops; /*!< backend ops */
|
||||
|
||||
/* dbenv and related parameters */
|
||||
void * db_dbenv; /*!< Backend private handle */
|
||||
@@ -245,6 +245,9 @@ RPM_GNUC_INTERNAL
|
||||
const void * idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen);
|
||||
|
||||
struct rpmdbOps_s {
|
||||
+ const char *name; /* backend name */
|
||||
+ const char *path; /* main database name */
|
||||
+
|
||||
int (*open)(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags);
|
||||
int (*close)(dbiIndex dbi, unsigned int flags);
|
||||
int (*verify)(dbiIndex dbi, unsigned int flags);
|
||||
diff --git a/lib/backend/dummydb.c b/lib/backend/dummydb.c
|
||||
index 6137675..631b635 100644
|
||||
--- a/lib/backend/dummydb.c
|
||||
+++ b/lib/backend/dummydb.c
|
||||
@@ -88,6 +88,9 @@ static const void * dummydb_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *
|
||||
|
||||
|
||||
struct rpmdbOps_s dummydb_dbops = {
|
||||
+ .name = "dummy",
|
||||
+ .path = NULL,
|
||||
+
|
||||
.open = dummydb_Open,
|
||||
.close = dummydb_Close,
|
||||
.verify = dummydb_Verify,
|
||||
diff --git a/lib/backend/lmdb.c b/lib/backend/lmdb.c
|
||||
index f63fcb7..801f50e 100644
|
||||
--- a/lib/backend/lmdb.c
|
||||
+++ b/lib/backend/lmdb.c
|
||||
@@ -922,6 +922,9 @@ static unsigned int lmdb_pkgdbKey(dbiIndex dbi, dbiCursor dbc)
|
||||
}
|
||||
|
||||
struct rpmdbOps_s lmdb_dbops = {
|
||||
+ .name = "lmdb",
|
||||
+ .path = "data.mdb",
|
||||
+
|
||||
.open = lmdb_dbiOpen,
|
||||
.close = lmdb_dbiClose,
|
||||
.verify = lmdb_dbiVerify,
|
||||
diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c
|
||||
index b088a0b..d679ed1 100644
|
||||
--- a/lib/backend/ndb/glue.c
|
||||
+++ b/lib/backend/ndb/glue.c
|
||||
@@ -496,6 +496,9 @@ static const void * ndb_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keyl
|
||||
|
||||
|
||||
struct rpmdbOps_s ndb_dbops = {
|
||||
+ .name = "ndb",
|
||||
+ .path = "Packages.db",
|
||||
+
|
||||
.open = ndb_Open,
|
||||
.close = ndb_Close,
|
||||
.verify = ndb_Verify,
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
924
backport-Add-support-for-reading-BDB-without-the-library.patch
Normal file
924
backport-Add-support-for-reading-BDB-without-the-library.patch
Normal file
@ -0,0 +1,924 @@
|
||||
From 7cc9eb84a3b2baa0109be599572d78870e0dd3fe Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Thu, 19 Dec 2019 14:08:50 +0100
|
||||
Subject: [PATCH] Add support for reading BDB without the library
|
||||
|
||||
This commit implements a read-only backend that allows accessing
|
||||
of BerkeleyDB databases without using the BerkeleyDB library.
|
||||
The code supports btree version 9-10 and hash version 8-10.
|
||||
|
||||
There are two use cases for this:
|
||||
|
||||
1) Conversion of an existing BerkeleyDB to a different
|
||||
backend.
|
||||
|
||||
2) Allowing package scriptlets to do database queries while
|
||||
in a transaction that replaced rpm with a version that
|
||||
no longer links against BerkeleyDB.
|
||||
|
||||
If both BerkeleyDB and the read-only backend are enabled, rpm will
|
||||
default to BerkeleyDB.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/7cc9eb84a3b2baa0109be599572d78870e0dd3fe
|
||||
Conflict:delete the contents of ci/Dockerfile
|
||||
---
|
||||
configure.ac | 14 +
|
||||
lib/Makefile.am | 4 +
|
||||
lib/backend/bdb_ro.c | 813 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
lib/backend/dbi.c | 3 +
|
||||
lib/backend/dbi.h | 5 +
|
||||
5 files changed, 839 insertions(+)
|
||||
create mode 100644 lib/backend/bdb_ro.c
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 2801b13..0257dde 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -595,6 +595,20 @@ AS_IF([test "$enable_ndb" = yes],[
|
||||
AM_CONDITIONAL([NDB], [test "$enable_ndb" = yes])
|
||||
|
||||
#=================
|
||||
+# Process --enable-bdb-ro
|
||||
+AC_ARG_ENABLE([bdb-ro], [AS_HELP_STRING([--enable-bdb-ro (EXPERIMENTAL)],[enable the read-only Berkeley DB code])],
|
||||
+[case "$enable_bdb_ro" in
|
||||
+yes|no) ;;
|
||||
+*) AC_MSG_ERROR([invalid argument to --enable-bdb-ro])
|
||||
+ ;;
|
||||
+esac],
|
||||
+[enable_bdb_ro=no])
|
||||
+AS_IF([test "$enable_bdb_ro" = yes],[
|
||||
+ AC_DEFINE(WITH_BDB_RO, 1, [Build with read-only Berkeley DB])
|
||||
+])
|
||||
+AM_CONDITIONAL([BDB_RO], [test "$enable_bdb_ro" = yes])
|
||||
+
|
||||
+#=================
|
||||
# Check for LMDB support
|
||||
AC_ARG_ENABLE([lmdb],
|
||||
[AS_HELP_STRING([--enable-lmdb=@<:@yes/no/auto@:>@ (EXPERIMENTAL)],
|
||||
diff --git a/lib/Makefile.am b/lib/Makefile.am
|
||||
index 349b5ca..2006d70 100644
|
||||
--- a/lib/Makefile.am
|
||||
+++ b/lib/Makefile.am
|
||||
@@ -68,6 +68,10 @@ librpm_la_LIBADD += @WITH_DB_LIB@
|
||||
endif
|
||||
endif
|
||||
|
||||
+if BDB_RO
|
||||
+librpm_la_SOURCES += backend/bdb_ro.c
|
||||
+endif
|
||||
+
|
||||
if NDB
|
||||
librpm_la_SOURCES += \
|
||||
backend/ndb/glue.c \
|
||||
diff --git a/lib/backend/bdb_ro.c b/lib/backend/bdb_ro.c
|
||||
new file mode 100644
|
||||
index 0000000..74569cb
|
||||
--- /dev/null
|
||||
+++ b/lib/backend/bdb_ro.c
|
||||
@@ -0,0 +1,813 @@
|
||||
+#include "system.h"
|
||||
+
|
||||
+#include <sys/types.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdint.h>
|
||||
+#include <unistd.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include "lib/rpmdb_internal.h"
|
||||
+#include <rpm/rpmstring.h>
|
||||
+#include <rpm/rpmlog.h>
|
||||
+
|
||||
+#define BDB_HASH 0
|
||||
+#define BDB_BTREE 1
|
||||
+
|
||||
+struct dbiCursor_s;
|
||||
+
|
||||
+struct bdb_kv {
|
||||
+ unsigned char *kv;
|
||||
+ unsigned int len;
|
||||
+};
|
||||
+
|
||||
+struct bdb_db {
|
||||
+ int fd; /* file descriptor of database */
|
||||
+ int type; /* BDB_HASH / BDB_BTREE */
|
||||
+ unsigned int pagesize;
|
||||
+ unsigned int lastpage;
|
||||
+ int swapped; /* different endianess? */
|
||||
+ /* btree */
|
||||
+ unsigned int root; /* root page of the b-tree */
|
||||
+ /* hash */
|
||||
+ unsigned int maxbucket;
|
||||
+ unsigned int highmask;
|
||||
+ unsigned int lowmask;
|
||||
+ unsigned int spares[32]; /* spare pages for each splitpoint */
|
||||
+};
|
||||
+
|
||||
+struct bdb_cur {
|
||||
+ struct bdb_db *db;
|
||||
+
|
||||
+ struct bdb_kv key; /* key and value from the db entry */
|
||||
+ struct bdb_kv val;
|
||||
+
|
||||
+ unsigned char *page; /* the page we're looking at */
|
||||
+
|
||||
+ unsigned char *ovpage;
|
||||
+ struct bdb_kv keyov; /* space to store oversized keys/values */
|
||||
+ struct bdb_kv valov;
|
||||
+
|
||||
+ int state; /* 1: onpage, -1: error */
|
||||
+ int idx; /* entry index */
|
||||
+ int numidx; /* number of entries on the page */
|
||||
+ int islookup; /* we're doing a lookup operation */
|
||||
+
|
||||
+ /* hash */
|
||||
+ unsigned int bucket; /* current bucket */
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static void swap16(unsigned char *p)
|
||||
+{
|
||||
+ int a = p[0];
|
||||
+ p[0] = p[1];
|
||||
+ p[1] = a;
|
||||
+}
|
||||
+
|
||||
+static void swap32(unsigned char *p)
|
||||
+{
|
||||
+ int a = p[0];
|
||||
+ p[0] = p[3];
|
||||
+ p[3] = a;
|
||||
+ a = p[1];
|
||||
+ p[1] = p[2];
|
||||
+ p[2] = a;
|
||||
+}
|
||||
+
|
||||
+static void swap32_2(unsigned char *p)
|
||||
+{
|
||||
+ swap32(p);
|
||||
+ swap32(p + 4);
|
||||
+}
|
||||
+
|
||||
+static void bdb_swapmetapage(struct bdb_db *db, unsigned char *page)
|
||||
+{
|
||||
+ int i, maxi = db->type == BDB_HASH ? 224 : 92;
|
||||
+ for (i = 8; i < maxi; i += 4)
|
||||
+ swap32((unsigned char *)(page + i));
|
||||
+ swap32((unsigned char *)(page + 24));
|
||||
+}
|
||||
+
|
||||
+static void bdb_swappage(struct bdb_db *db, unsigned char *page)
|
||||
+{
|
||||
+ unsigned int pagesize = db->pagesize;
|
||||
+ int type, i, nent, off;
|
||||
+ swap32(page + 8); /* page number */
|
||||
+ swap32_2(page + 12); /* prev/next page */
|
||||
+ swap16(page + 20); /* nitems */
|
||||
+ swap16(page + 22); /* highfree */
|
||||
+
|
||||
+ type = page[25];
|
||||
+ if (type != 2 && type != 13 && type != 3 && type != 5)
|
||||
+ return;
|
||||
+ nent = *(uint16_t *)(page + 20);
|
||||
+ if (nent > (pagesize - 26) / 2)
|
||||
+ nent = (pagesize - 26) / 2;
|
||||
+ for (i = 0; i < nent; i++) {
|
||||
+ int minoff = 26 + nent * 2;
|
||||
+ swap16(page + 26 + i * 2); /* offset */
|
||||
+ off = *(uint16_t *)(page + 26 + i * 2);
|
||||
+ if (off < minoff || off >= pagesize)
|
||||
+ continue;
|
||||
+ if (type == 2 || type == 13) { /* hash */
|
||||
+ if (page[off] == 3 && off + 12 <= pagesize)
|
||||
+ swap32_2(page + off + 4); /* page no/length */
|
||||
+ } else if (type == 3) { /* btree internal */
|
||||
+ if (off + 12 > pagesize)
|
||||
+ continue;
|
||||
+ swap16(page + off); /* length */
|
||||
+ swap32_2(page + off + 4); /* page no/num recs */
|
||||
+ if (page[off + 2] == 3 && off + 24 <= pagesize)
|
||||
+ swap32_2(page + off + 16); /* with overflow page/length */
|
||||
+ } else if (type == 5) { /* btree leaf */
|
||||
+ if (off + 3 <= pagesize && page[off + 2] == 1)
|
||||
+ swap16(page + off); /* length */
|
||||
+ else if (off + 12 <= pagesize && page[off + 2] == 3)
|
||||
+ swap32_2(page + off + 4); /* overflow page/length */
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int bdb_getpage(struct bdb_db *db, unsigned char *page, unsigned int pageno)
|
||||
+{
|
||||
+ if (!pageno || pageno > db->lastpage)
|
||||
+ return -1;
|
||||
+ if (pread(db->fd, page, db->pagesize, (off_t)pageno * db->pagesize) != db->pagesize) {
|
||||
+ rpmlog(RPMLOG_ERR, "pread: %s\n", strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (db->swapped)
|
||||
+ bdb_swappage(db, page);
|
||||
+ if (pageno != *(uint32_t *)(page + 8))
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void bdb_close(struct bdb_db *db)
|
||||
+{
|
||||
+ if (db->fd >= 0)
|
||||
+ close(db->fd);
|
||||
+ free(db);
|
||||
+}
|
||||
+
|
||||
+static struct bdb_db *bdb_open(const char *name)
|
||||
+{
|
||||
+ uint32_t meta[512 / 4];
|
||||
+ int i, fd;
|
||||
+ struct bdb_db *db;
|
||||
+
|
||||
+ fd = open(name, O_RDONLY);
|
||||
+ if (!fd) {
|
||||
+ rpmlog(RPMLOG_ERR, "%s: %s\n", name, strerror(errno));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ db = xcalloc(1, sizeof(*db));
|
||||
+ db->fd = fd;
|
||||
+ if (pread(fd, meta, 512, 0) != 512) {
|
||||
+ rpmlog(RPMLOG_ERR, "%s: pread: %s\n", name, strerror(errno));
|
||||
+ bdb_close(db);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (meta[3] == 0x00061561 || meta[3] == 0x61150600) {
|
||||
+ db->type = BDB_HASH;
|
||||
+ db->swapped = meta[3] == 0x61150600;
|
||||
+ } else if (meta[3] == 0x00053162 || meta[3] == 0x62310500) {
|
||||
+ db->type = BDB_BTREE;
|
||||
+ db->swapped = meta[3] == 0x62310500;
|
||||
+ } else {
|
||||
+ rpmlog(RPMLOG_ERR, "%s: not a berkeley db hash/btree database\n", name);
|
||||
+ bdb_close(db);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (db->swapped)
|
||||
+ bdb_swapmetapage(db, (unsigned char *)meta);
|
||||
+ db->pagesize = meta[5];
|
||||
+ db->lastpage = meta[8];
|
||||
+ if (db->type == BDB_HASH) {
|
||||
+ if (meta[4] < 8 || meta[4] > 10) {
|
||||
+ rpmlog(RPMLOG_ERR, "%s: unsupported hash version %d\n", name, meta[4]);
|
||||
+ bdb_close(db);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ db->maxbucket = meta[18];
|
||||
+ db->highmask = meta[19];
|
||||
+ db->lowmask = meta[20];
|
||||
+ for (i = 0; i < 32; i++)
|
||||
+ db->spares[i] = meta[24 + i];
|
||||
+ }
|
||||
+ if (db->type == BDB_BTREE) {
|
||||
+ if (meta[4] < 9 || meta[4] > 10) {
|
||||
+ rpmlog(RPMLOG_ERR, "%s: unsupported btree version %d\n", name, meta[4]);
|
||||
+ bdb_close(db);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ db->root = meta[22];
|
||||
+ }
|
||||
+ return db;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/****** overflow handling ******/
|
||||
+
|
||||
+static int ovfl_get(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, uint32_t *pagenolen)
|
||||
+{
|
||||
+ unsigned int pageno = pagenolen[0];
|
||||
+ unsigned int len = pagenolen[1];
|
||||
+ unsigned int plen;
|
||||
+ unsigned char *p;
|
||||
+
|
||||
+ if (len == 0)
|
||||
+ return -1;
|
||||
+ if (len > ov->len) {
|
||||
+ if (ov->kv)
|
||||
+ ov->kv = xrealloc(ov->kv, len);
|
||||
+ else
|
||||
+ ov->kv = xmalloc(len);
|
||||
+ ov->len = len;
|
||||
+ }
|
||||
+ if (!cur->ovpage)
|
||||
+ cur->ovpage = xmalloc(cur->db->pagesize);
|
||||
+ p = ov->kv;
|
||||
+ while (len > 0) {
|
||||
+ if (bdb_getpage(cur->db, cur->ovpage, pageno))
|
||||
+ return -1;
|
||||
+ if (cur->ovpage[25] != 7)
|
||||
+ return -1;
|
||||
+ plen = *(uint16_t *)(cur->ovpage + 22);
|
||||
+ if (plen + 26 > cur->db->pagesize || plen > len)
|
||||
+ return -1;
|
||||
+ memcpy(p, cur->ovpage + 26, plen);
|
||||
+ p += plen;
|
||||
+ len -= plen;
|
||||
+ pageno = *(uint32_t *)(cur->ovpage + 16);
|
||||
+ }
|
||||
+ if (kv) {
|
||||
+ kv->kv = ov->kv;
|
||||
+ kv->len = pagenolen[1];
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/****** hash implementation ******/
|
||||
+
|
||||
+static int hash_bucket_to_page(struct bdb_db *db, unsigned int bucket)
|
||||
+{
|
||||
+ unsigned int b;
|
||||
+ int i = 0;
|
||||
+ for (b = bucket; b; b >>= 1)
|
||||
+ i++;
|
||||
+ return bucket + db->spares[i];
|
||||
+}
|
||||
+
|
||||
+static int hash_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl)
|
||||
+{
|
||||
+ uint32_t bucket;
|
||||
+ unsigned int pg, i;
|
||||
+ cur->state = -1;
|
||||
+ for (bucket = 0, i = 0; i < keyl; i++)
|
||||
+ bucket = (bucket * 16777619) ^ key[i];
|
||||
+ bucket &= cur->db->highmask;
|
||||
+ if (bucket > cur->db->maxbucket)
|
||||
+ bucket &= cur->db->lowmask;
|
||||
+ cur->bucket = bucket;
|
||||
+ pg = hash_bucket_to_page(cur->db, bucket);
|
||||
+ if (bdb_getpage(cur->db, cur->page, pg))
|
||||
+ return -1;
|
||||
+ if (cur->page[25] != 8 && cur->page[25] != 13)
|
||||
+ return -1;
|
||||
+ cur->idx = (unsigned int)-2;
|
||||
+ cur->numidx = *(uint16_t *)(cur->page + 20);
|
||||
+ cur->state = 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int hash_getkv(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, int off, int len)
|
||||
+{
|
||||
+ if (len <= 0 || off + len > cur->db->pagesize)
|
||||
+ return -1;
|
||||
+ if (cur->page[off] == 1) {
|
||||
+ kv->kv = cur->page + off + 1;
|
||||
+ kv->len = len - 1;
|
||||
+ } else if (cur->page[off] == 3) {
|
||||
+ uint32_t ovlpage[2];
|
||||
+ if (len != 12)
|
||||
+ return -1;
|
||||
+ memcpy(ovlpage, cur->page + off + 4, 8); /* off is unaligned */
|
||||
+ if (ovfl_get(cur, kv, ov, ovlpage))
|
||||
+ return -1;
|
||||
+ } else {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int hash_next(struct bdb_cur *cur)
|
||||
+{
|
||||
+ int pagesize = cur->db->pagesize;
|
||||
+ int koff, klen, voff, vlen;
|
||||
+ if (!cur->state && hash_lookup(cur, 0, 0))
|
||||
+ return -1;
|
||||
+ cur->idx += 2;
|
||||
+ for (;;) {
|
||||
+ if (cur->idx + 1 >= cur->numidx) {
|
||||
+ unsigned int pg;
|
||||
+ cur->idx = cur->numidx = 0;
|
||||
+ pg = *(uint32_t *)(cur->page + 16);
|
||||
+ if (!pg) {
|
||||
+ if (cur->islookup || cur->bucket >= cur->db->maxbucket)
|
||||
+ return 1;
|
||||
+ pg = hash_bucket_to_page(cur->db, ++cur->bucket);
|
||||
+ }
|
||||
+ if (bdb_getpage(cur->db, cur->page, pg))
|
||||
+ return -1;
|
||||
+ if (cur->page[25] != 8 && cur->page[25] != 13)
|
||||
+ return -1;
|
||||
+ cur->numidx = *(uint16_t *)(cur->page + 20);
|
||||
+ continue;
|
||||
+ }
|
||||
+ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx);
|
||||
+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx);
|
||||
+ if (koff >= pagesize || voff >= pagesize)
|
||||
+ return -1;
|
||||
+ if (cur->idx == 0)
|
||||
+ klen = pagesize - koff;
|
||||
+ else
|
||||
+ klen = *(uint16_t *)(cur->page + 24 + 2 * cur->idx) - koff;
|
||||
+ vlen = koff - voff;
|
||||
+ if (hash_getkv(cur, &cur->key, &cur->keyov, koff, klen))
|
||||
+ return -1;
|
||||
+ if (!cur->islookup && hash_getkv(cur, &cur->val, &cur->valov, voff, vlen))
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int hash_getval(struct bdb_cur *cur)
|
||||
+{
|
||||
+ int koff, voff;
|
||||
+ if (cur->state != 1 || cur->idx + 1 >= cur->numidx)
|
||||
+ return -1;
|
||||
+ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx);
|
||||
+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx);
|
||||
+ return hash_getkv(cur, &cur->val, &cur->valov, voff, koff - voff);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/****** btree implementation ******/
|
||||
+
|
||||
+static int btree_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keylen)
|
||||
+{
|
||||
+ int pagesize = cur->db->pagesize;
|
||||
+ int off, lastoff, idx, numidx;
|
||||
+ unsigned int pg;
|
||||
+ unsigned char *ekey;
|
||||
+ unsigned int ekeylen;
|
||||
+ int cmp;
|
||||
+
|
||||
+ cur->state = -1;
|
||||
+ pg = cur->db->root;
|
||||
+ for (;;) {
|
||||
+ if (bdb_getpage(cur->db, cur->page, pg))
|
||||
+ return -1;
|
||||
+ if (cur->page[25] == 5)
|
||||
+ break; /* found leaf page */
|
||||
+ if (cur->page[25] != 3)
|
||||
+ return -1;
|
||||
+ numidx = *(uint16_t *)(cur->page + 20);
|
||||
+ if (!numidx)
|
||||
+ return -1;
|
||||
+ for (lastoff = 0, idx = 0; idx < numidx; idx++, lastoff = off) {
|
||||
+ off = *(uint16_t *)(cur->page + 26 + 2 * idx);
|
||||
+ if ((off & 3) != 0 || off + 3 > pagesize)
|
||||
+ return -1;
|
||||
+ ekeylen = *(uint16_t *)(cur->page + off);
|
||||
+ if (off + 12 + ekeylen > pagesize)
|
||||
+ return -1;
|
||||
+ if (!keylen) {
|
||||
+ lastoff = off;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (idx == 0)
|
||||
+ continue;
|
||||
+ ekey = cur->page + off + 12;
|
||||
+ if ((cur->page[off + 2] & 0x7f) == 3) {
|
||||
+ if (ekeylen != 12)
|
||||
+ return -1;
|
||||
+ if (ovfl_get(cur, 0, &cur->keyov, (uint32_t *)(ekey + 4)))
|
||||
+ return -1;
|
||||
+ ekeylen = *(uint32_t *)(ekey + 8);
|
||||
+ ekey = cur->keyov.kv;
|
||||
+ } else if ((cur->page[off + 2] & 0x7f) != 1) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ cmp = memcmp(ekey, key, keylen < ekeylen ? keylen : ekeylen);
|
||||
+ if (cmp > 0 || (cmp == 0 && ekeylen > keylen))
|
||||
+ break;
|
||||
+ }
|
||||
+ pg = *(uint32_t *)(cur->page + lastoff + 4);
|
||||
+ }
|
||||
+ cur->idx = (unsigned int)-2;
|
||||
+ cur->numidx = *(uint16_t *)(cur->page + 20);
|
||||
+ cur->state = 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int btree_getkv(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, int off)
|
||||
+{
|
||||
+ if ((off & 3) != 0)
|
||||
+ return -1;
|
||||
+ if (cur->page[off + 2] == 1) {
|
||||
+ int len = *(uint16_t *)(cur->page + off);
|
||||
+ if (off + 3 + len > cur->db->pagesize)
|
||||
+ return -1;
|
||||
+ kv->kv = cur->page + off + 3;
|
||||
+ kv->len = len;
|
||||
+ } else if (cur->page[off + 2] == 3) {
|
||||
+ if (off + 12 > cur->db->pagesize)
|
||||
+ return -1;
|
||||
+ if (ovfl_get(cur, kv, ov, (uint32_t *)(cur->page + off + 4)))
|
||||
+ return -1;
|
||||
+ } else {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int btree_next(struct bdb_cur *cur)
|
||||
+{
|
||||
+ int pagesize = cur->db->pagesize;
|
||||
+ int koff, voff;
|
||||
+ if (!cur->state && btree_lookup(cur, 0, 0))
|
||||
+ return -1;
|
||||
+ cur->idx += 2;
|
||||
+ for (;;) {
|
||||
+ if (cur->idx + 1 >= cur->numidx) {
|
||||
+ unsigned int pg;
|
||||
+ cur->idx = cur->numidx = 0;
|
||||
+ pg = *(uint32_t *)(cur->page + 16);
|
||||
+ if (cur->islookup || !pg)
|
||||
+ return 1;
|
||||
+ if (bdb_getpage(cur->db, cur->page, pg))
|
||||
+ return -1;
|
||||
+ if (cur->page[25] != 5)
|
||||
+ return -1;
|
||||
+ cur->numidx = *(uint16_t *)(cur->page + 20);
|
||||
+ continue;
|
||||
+ }
|
||||
+ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx);
|
||||
+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx);
|
||||
+ if (koff + 3 > pagesize || voff + 3 > pagesize)
|
||||
+ return -1;
|
||||
+ if ((cur->page[koff + 2] & 0x80) != 0 || (cur->page[voff + 2] & 0x80) != 0)
|
||||
+ continue; /* ignore deleted */
|
||||
+ if (btree_getkv(cur, &cur->key, &cur->keyov, koff))
|
||||
+ return -1;
|
||||
+ if (!cur->islookup && btree_getkv(cur, &cur->val, &cur->valov, voff))
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int btree_getval(struct bdb_cur *cur)
|
||||
+{
|
||||
+ int voff;
|
||||
+ if (cur->state != 1 || cur->idx + 1 >= cur->numidx)
|
||||
+ return -1;
|
||||
+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx);
|
||||
+ return btree_getkv(cur, &cur->val, &cur->valov, voff);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/****** cursor functions ******/
|
||||
+
|
||||
+static struct bdb_cur *cur_open(struct bdb_db *db)
|
||||
+{
|
||||
+ struct bdb_cur *cur = xcalloc(1, sizeof(*cur));
|
||||
+ cur->db = db;
|
||||
+ cur->page = xmalloc(db->pagesize);
|
||||
+ return cur;
|
||||
+}
|
||||
+
|
||||
+static void cur_close(struct bdb_cur *cur)
|
||||
+{
|
||||
+ if (cur->page)
|
||||
+ free(cur->page);
|
||||
+ if (cur->ovpage)
|
||||
+ free(cur->ovpage);
|
||||
+ if (cur->keyov.kv)
|
||||
+ free(cur->keyov.kv);
|
||||
+ if (cur->valov.kv)
|
||||
+ free(cur->valov.kv);
|
||||
+ free(cur);
|
||||
+}
|
||||
+
|
||||
+static int cur_next(struct bdb_cur *cur)
|
||||
+{
|
||||
+ if (cur->state < 0)
|
||||
+ return -1;
|
||||
+ if (cur->db->type == BDB_HASH)
|
||||
+ return hash_next(cur);
|
||||
+ if (cur->db->type == BDB_BTREE)
|
||||
+ return btree_next(cur);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static int cur_getval(struct bdb_cur *cur)
|
||||
+{
|
||||
+ if (cur->state < 0)
|
||||
+ return -1;
|
||||
+ if (cur->db->type == BDB_HASH)
|
||||
+ return hash_getval(cur);
|
||||
+ if (cur->db->type == BDB_BTREE)
|
||||
+ return btree_getval(cur);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static int cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl)
|
||||
+{
|
||||
+ int r = -1;
|
||||
+ if (cur->db->type == BDB_HASH)
|
||||
+ r = hash_lookup(cur, key, keyl);
|
||||
+ if (cur->db->type == BDB_BTREE)
|
||||
+ r = btree_lookup(cur, key, keyl);
|
||||
+ if (r != 0)
|
||||
+ return r;
|
||||
+ cur->islookup = 1;
|
||||
+ while ((r = cur_next(cur)) == 0)
|
||||
+ if (keyl == cur->key.len && !memcmp(key, cur->key.kv, keyl))
|
||||
+ break;
|
||||
+ cur->islookup = 0;
|
||||
+ if (r == 0)
|
||||
+ r = cur_getval(cur);
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static int cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl)
|
||||
+{
|
||||
+ int r = -1;
|
||||
+ if (cur->db->type == BDB_BTREE)
|
||||
+ r = btree_lookup(cur, key, keyl);
|
||||
+ if (r != 0)
|
||||
+ return r;
|
||||
+ cur->islookup = 1;
|
||||
+ while ((r = cur_next(cur)) == 0) {
|
||||
+ unsigned int ekeyl = cur->key.len;
|
||||
+ int cmp = memcmp(cur->key.kv, key, keyl < ekeyl ? keyl : ekeyl);
|
||||
+ if (cmp > 0 || (cmp == 0 && ekeyl >= keyl))
|
||||
+ break;
|
||||
+ }
|
||||
+ cur->islookup = 0;
|
||||
+ if (r == 0)
|
||||
+ r = cur_getval(cur);
|
||||
+ else if (r == 1)
|
||||
+ r = cur_next(cur);
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+/****** glue code ******/
|
||||
+
|
||||
+static unsigned int getui32(unsigned char *x, int swapped)
|
||||
+{
|
||||
+ union _dbswap bs;
|
||||
+ memcpy(bs.uc, x, 4);
|
||||
+ if (swapped)
|
||||
+ _DBSWAP(bs);
|
||||
+ return bs.ui;
|
||||
+}
|
||||
+
|
||||
+static void setui32(unsigned char *x, uint32_t v, int swapped)
|
||||
+{
|
||||
+ union _dbswap bs;
|
||||
+ bs.ui = v;
|
||||
+ if (swapped)
|
||||
+ _DBSWAP(bs);
|
||||
+ memcpy(x, bs.uc, 4);
|
||||
+}
|
||||
+
|
||||
+static void log_error(dbiIndex dbi)
|
||||
+{
|
||||
+ rpmlog(RPMLOG_ERR, "bdb_ro error reading %s database\n", dbi->dbi_file);
|
||||
+}
|
||||
+
|
||||
+static int bdbro_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
|
||||
+{
|
||||
+ const char *dbhome = rpmdbHome(rdb);
|
||||
+ dbiIndex dbi = NULL;
|
||||
+ char *path;
|
||||
+
|
||||
+ if (dbip)
|
||||
+ *dbip = NULL;
|
||||
+ if ((rdb->db_mode & O_ACCMODE) != O_RDONLY)
|
||||
+ return EPERM;
|
||||
+ if ((dbi = dbiNew(rdb, rpmtag)) == NULL)
|
||||
+ return 1;
|
||||
+ path = rstrscat(NULL, dbhome, "/", dbi->dbi_file, NULL);
|
||||
+ rpmlog(RPMLOG_DEBUG, "opening db index %s\n", path);
|
||||
+ dbi->dbi_db = bdb_open(path);
|
||||
+ if (!dbi->dbi_db) {
|
||||
+ rpmlog(RPMLOG_ERR, "could not open %s: %s\n", path, strerror(errno));
|
||||
+ free(path);
|
||||
+ dbiFree(dbi);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ free(path);
|
||||
+ dbi->dbi_flags |= DBI_RDONLY;
|
||||
+ if (dbip)
|
||||
+ *dbip = dbi;
|
||||
+ else
|
||||
+ (void) dbiClose(dbi, 0);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int bdbro_Close(dbiIndex dbi, unsigned int flags)
|
||||
+{
|
||||
+ if (dbi->dbi_db)
|
||||
+ bdb_close(dbi->dbi_db);
|
||||
+ dbiFree(dbi);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int bdbro_Verify(dbiIndex dbi, unsigned int flags)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void bdbro_SetFSync(rpmdb rdb, int enable)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static int bdbro_Ctrl(rpmdb rdb, dbCtrlOp ctrl)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static dbiCursor bdbro_CursorInit(dbiIndex dbi, unsigned int flags)
|
||||
+{
|
||||
+ return dbi ? (void *)cur_open(dbi->dbi_db) : NULL;
|
||||
+}
|
||||
+
|
||||
+static dbiCursor bdbro_CursorFree(dbiIndex dbi, dbiCursor dbc)
|
||||
+{
|
||||
+ if (dbc)
|
||||
+ cur_close((void *)dbc);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void appenddbt(dbiCursor dbc, unsigned char *val, unsigned int vallen, dbiIndexSet *setp)
|
||||
+{
|
||||
+ struct bdb_cur *cur = (void *)dbc;
|
||||
+ dbiIndexSet set;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ set = dbiIndexSetNew(vallen / (2 * sizeof(uint32_t)));
|
||||
+ set->count = vallen / (2 * sizeof(uint32_t));
|
||||
+
|
||||
+ for (i = 0; i < set->count; i++, val += 8) {
|
||||
+ set->recs[i].hdrNum = getui32(val, cur->db->swapped);
|
||||
+ set->recs[i].tagNum = getui32(val + 4, cur->db->swapped);
|
||||
+ }
|
||||
+ if (*setp == NULL) {
|
||||
+ *setp = set;
|
||||
+ } else {
|
||||
+ dbiIndexSetAppendSet(*setp, set, 0);
|
||||
+ dbiIndexSetFree(set);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static rpmRC bdbro_idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h)
|
||||
+{
|
||||
+ return RPMRC_FAIL;
|
||||
+}
|
||||
+
|
||||
+static rpmRC bdbro_idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h)
|
||||
+{
|
||||
+ return RPMRC_FAIL;
|
||||
+}
|
||||
+
|
||||
+static rpmRC bdbro_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen,
|
||||
+ dbiIndexSet *set, int searchType)
|
||||
+{
|
||||
+ struct bdb_cur *cur = (void *)dbc;
|
||||
+ int r;
|
||||
+
|
||||
+ if (!cur)
|
||||
+ return RPMRC_FAIL;
|
||||
+ if (searchType == DBC_PREFIX_SEARCH) {
|
||||
+ rpmRC rc = RPMRC_NOTFOUND;
|
||||
+ if (!keyp)
|
||||
+ return RPMRC_FAIL;
|
||||
+ r = cur_lookup_ge(cur, (const unsigned char *)keyp, keylen);
|
||||
+ for (; r == 0; r = cur_next(cur)) {
|
||||
+ if (cur->key.len < keylen || memcmp(cur->key.kv, keyp, keylen) != 0)
|
||||
+ break;
|
||||
+ if (set)
|
||||
+ appenddbt(dbc, cur->val.kv, cur->val.len, set);
|
||||
+ rc = RPMRC_OK;
|
||||
+ }
|
||||
+ if (r == -1)
|
||||
+ log_error(dbi);
|
||||
+ cur->key.kv = 0;
|
||||
+ return r == -1 ? RPMRC_FAIL : rc;
|
||||
+ }
|
||||
+ if (keyp) {
|
||||
+ if (keylen == 0) {
|
||||
+ keyp = "";
|
||||
+ keylen = 1;
|
||||
+ }
|
||||
+ r = cur_lookup(cur, (const unsigned char *)keyp, keylen);
|
||||
+ } else {
|
||||
+ r = cur_next(cur);
|
||||
+ }
|
||||
+ if (r == 0) {
|
||||
+ if (set)
|
||||
+ appenddbt(dbc, cur->val.kv, cur->val.len, set);
|
||||
+ return RPMRC_OK;
|
||||
+ }
|
||||
+ if (r == -1)
|
||||
+ log_error(dbi);
|
||||
+ cur->key.kv = 0;
|
||||
+ return r == 1 ? RPMRC_NOTFOUND : RPMRC_FAIL;
|
||||
+}
|
||||
+
|
||||
+static const void *bdbro_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen)
|
||||
+{
|
||||
+ struct bdb_cur *cur = (void *)dbc;
|
||||
+ if (!cur || !cur->key.kv)
|
||||
+ return 0;
|
||||
+ if (keylen)
|
||||
+ *keylen = cur->key.len;
|
||||
+ return cur->key.kv;
|
||||
+}
|
||||
+
|
||||
+static rpmRC bdbro_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum,
|
||||
+ unsigned char *hdrBlob, unsigned int hdrLen)
|
||||
+{
|
||||
+ return RPMRC_FAIL;
|
||||
+}
|
||||
+
|
||||
+static rpmRC bdbro_pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum)
|
||||
+{
|
||||
+ return RPMRC_FAIL;
|
||||
+}
|
||||
+
|
||||
+static rpmRC bdbro_pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum,
|
||||
+ unsigned char **hdrBlob, unsigned int *hdrLen)
|
||||
+{
|
||||
+ struct bdb_cur *cur = (void *)dbc;
|
||||
+ int r;
|
||||
+ if (hdrNum) {
|
||||
+ unsigned char hdrkey[4];
|
||||
+ setui32(hdrkey, hdrNum, cur->db->swapped);
|
||||
+ r = cur_lookup(cur, hdrkey, 4);
|
||||
+ } else {
|
||||
+ r = cur_next(cur);
|
||||
+ }
|
||||
+ if (r == 0) {
|
||||
+ if (hdrBlob)
|
||||
+ *hdrBlob = cur->val.kv;
|
||||
+ if (hdrLen)
|
||||
+ *hdrLen = cur->val.len;
|
||||
+ return RPMRC_OK;
|
||||
+ }
|
||||
+ if (r == -1)
|
||||
+ log_error(dbi);
|
||||
+ cur->key.kv = 0;
|
||||
+ return r == 1 ? RPMRC_NOTFOUND : RPMRC_FAIL;
|
||||
+}
|
||||
+
|
||||
+static unsigned int bdbro_pkgdbKey(dbiIndex dbi, dbiCursor dbc)
|
||||
+{
|
||||
+ struct bdb_cur *cur = (void *)dbc;
|
||||
+ if (!cur || !cur->key.kv || cur->key.len != 4)
|
||||
+ return 0;
|
||||
+ return getui32(cur->key.kv, cur->db->swapped);
|
||||
+}
|
||||
+
|
||||
+struct rpmdbOps_s bdbro_dbops = {
|
||||
+ .name = "bdb_ro",
|
||||
+ .path = "Packages",
|
||||
+
|
||||
+ .open = bdbro_Open,
|
||||
+ .close = bdbro_Close,
|
||||
+ .verify = bdbro_Verify,
|
||||
+ .setFSync = bdbro_SetFSync,
|
||||
+ .ctrl = bdbro_Ctrl,
|
||||
+
|
||||
+ .cursorInit = bdbro_CursorInit,
|
||||
+ .cursorFree = bdbro_CursorFree,
|
||||
+
|
||||
+ .pkgdbPut = bdbro_pkgdbPut,
|
||||
+ .pkgdbDel = bdbro_pkgdbDel,
|
||||
+ .pkgdbGet = bdbro_pkgdbGet,
|
||||
+ .pkgdbKey = bdbro_pkgdbKey,
|
||||
+
|
||||
+ .idxdbGet = bdbro_idxdbGet,
|
||||
+ .idxdbPut = bdbro_idxdbPut,
|
||||
+ .idxdbDel = bdbro_idxdbDel,
|
||||
+ .idxdbKey = bdbro_idxdbKey
|
||||
+};
|
||||
+
|
||||
diff --git a/lib/backend/dbi.c b/lib/backend/dbi.c
|
||||
index 9b6c0a9..7841440 100644
|
||||
--- a/lib/backend/dbi.c
|
||||
+++ b/lib/backend/dbi.c
|
||||
@@ -25,6 +25,9 @@ const struct rpmdbOps_s *backends[] = {
|
||||
#if defined(WITH_BDB)
|
||||
&db3_dbops,
|
||||
#endif
|
||||
+#if defined(WITH_BDB_RO)
|
||||
+ &bdbro_dbops,
|
||||
+#endif
|
||||
&dummydb_dbops,
|
||||
NULL
|
||||
};
|
||||
diff --git a/lib/backend/dbi.h b/lib/backend/dbi.h
|
||||
index b2b9717..c4bf387 100644
|
||||
--- a/lib/backend/dbi.h
|
||||
+++ b/lib/backend/dbi.h
|
||||
@@ -274,6 +274,11 @@ RPM_GNUC_INTERNAL
|
||||
extern struct rpmdbOps_s db3_dbops;
|
||||
#endif
|
||||
|
||||
+#if defined(WITH_BDB_RO)
|
||||
+RPM_GNUC_INTERNAL
|
||||
+extern struct rpmdbOps_s bdbro_dbops;
|
||||
+#endif
|
||||
+
|
||||
#ifdef ENABLE_NDB
|
||||
RPM_GNUC_INTERNAL
|
||||
extern struct rpmdbOps_s ndb_dbops;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
From 8cd161b5bb9b639f5b729063272115436caab545 Mon Sep 17 00:00:00 2001
|
||||
From: Panu Matilainen <pmatilai@redhat.com>
|
||||
Date: Thu, 12 Mar 2020 11:42:15 +0200
|
||||
Subject: [PATCH] Always open (and initialize) the entire database at once
|
||||
|
||||
In some scenarios we previously only created some of the indexes only
|
||||
lazy db init through query. Partially initialized databases don't make
|
||||
sense and are only asking for trouble, in particular this was causing
|
||||
issues with sqlite backend which is stricter about readonly-mode.
|
||||
|
||||
Except for the special case of reading a potentially damaged database
|
||||
for rebuilding, always open all the indexes from openDatabase().
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/8cd161b5bb9b639f5b729063272115436caab545
|
||||
Conflict:context adaptation about openDatabase
|
||||
---
|
||||
lib/rpmdb.c | 37 ++++++++++++++++++-------------------
|
||||
1 file changed, 18 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
|
||||
index c5d8f49..073800b 100644
|
||||
--- a/lib/rpmdb.c
|
||||
+++ b/lib/rpmdb.c
|
||||
@@ -357,17 +357,22 @@ const char *rpmdbHome(rpmdb db)
|
||||
return dbdir;
|
||||
}
|
||||
|
||||
-int rpmdbOpenAll(rpmdb db)
|
||||
+static int doOpen(rpmdb db, int justPkgs)
|
||||
{
|
||||
- int rc = 0;
|
||||
+ int rc = pkgdbOpen(db, db->db_flags, NULL);
|
||||
+ if (!justPkgs) {
|
||||
+ for (int dbix = 0; dbix < db->db_ndbi; dbix++) {
|
||||
+ rc += indexOpen(db, db->db_tags[dbix], db->db_flags, NULL);
|
||||
+ }
|
||||
+ }
|
||||
+ return rc;
|
||||
+}
|
||||
|
||||
+int rpmdbOpenAll(rpmdb db)
|
||||
+{
|
||||
if (db == NULL) return -2;
|
||||
|
||||
- rc = pkgdbOpen(db, db->db_flags, NULL);
|
||||
- for (int dbix = 0; dbix < db->db_ndbi; dbix++) {
|
||||
- rc += indexOpen(db, db->db_tags[dbix], db->db_flags, NULL);
|
||||
- }
|
||||
- return rc;
|
||||
+ return doOpen(db, 0);
|
||||
}
|
||||
|
||||
static int dbiForeach(dbiIndex *dbis, int ndbi,
|
||||
@@ -510,13 +515,16 @@ static int openDatabase(const char * prefix,
|
||||
/* Try to ensure db home exists, error out if we can't even create */
|
||||
rc = rpmioMkpath(rpmdbHome(db), 0755, getuid(), getgid());
|
||||
if (rc == 0) {
|
||||
+ /* Open just bare minimum when rebuilding a potentially damaged db */
|
||||
+ int justPkgs = (db->db_flags & RPMDB_FLAG_REBUILD) &&
|
||||
+ ((db->db_mode & O_ACCMODE) == O_RDONLY);
|
||||
/* Enable signal queue on the first db open */
|
||||
if (db->db_next == NULL) {
|
||||
rpmsqActivate(1);
|
||||
}
|
||||
|
||||
- /* Just the primary Packages database opened here */
|
||||
- rc = pkgdbOpen(db, db->db_flags, NULL);
|
||||
+ rc = doOpen(db, justPkgs);
|
||||
+
|
||||
}
|
||||
|
||||
if (rc || justCheck || dbp == NULL)
|
||||
@@ -554,10 +562,7 @@ int rpmdbInit (const char * prefix, int perms)
|
||||
|
||||
rc = openDatabase(prefix, NULL, &db, (O_CREAT | O_RDWR), perms, 0);
|
||||
if (db != NULL) {
|
||||
- int xx;
|
||||
- xx = rpmdbOpenAll(db);
|
||||
- if (xx && rc == 0) rc = xx;
|
||||
- xx = rpmdbClose(db);
|
||||
+ int xx = rpmdbClose(db);
|
||||
if (xx && rc == 0) rc = xx;
|
||||
db = NULL;
|
||||
}
|
||||
@@ -573,8 +578,6 @@ int rpmdbVerify(const char * prefix)
|
||||
|
||||
if (db != NULL) {
|
||||
int xx;
|
||||
- rc = rpmdbOpenAll(db);
|
||||
-
|
||||
|
||||
if (db->db_pkgs)
|
||||
rc += dbiVerify(db->db_pkgs, 0);
|
||||
@@ -2551,10 +2554,6 @@ int rpmdbRebuild(const char * prefix, rpmts ts,
|
||||
rc = 1;
|
||||
goto exit;
|
||||
}
|
||||
- if (rpmdbOpenAll(newdb)) {
|
||||
- rc = 1;
|
||||
- goto exit;
|
||||
- }
|
||||
|
||||
{ Header h = NULL;
|
||||
rpmdbMatchIterator mi;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
30
backport-Deprecate-Berkeley-DB-database-backend.patch
Normal file
30
backport-Deprecate-Berkeley-DB-database-backend.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From fc0169eb03c893d63dc44f2ada954d42e0e759ed Mon Sep 17 00:00:00 2001
|
||||
From: Panu Matilainen <pmatilai@redhat.com>
|
||||
Date: Mon, 23 Mar 2020 11:22:31 +0200
|
||||
Subject: [PATCH] Deprecate Berkeley DB database backend
|
||||
|
||||
Berkeley DB 5.x is dead upstream ever since the license change some
|
||||
seven years ago. Mark as deprecated for later removal now that we're
|
||||
starting to have viable alternatives.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/fc0169eb03c893d63dc44f2ada954d42e0e759ed
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index d5ce5ef..bdfe2c6 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -533,7 +533,7 @@ AM_CONDITIONAL(HAVE_LIBDW_STRTAB,[test "$HAVE_LIBDW_STRTAB" = yes])
|
||||
#=================
|
||||
# Check for BDB support
|
||||
AC_ARG_ENABLE([bdb],
|
||||
- [AS_HELP_STRING([--enable-bdb=@<:@yes/no/auto@:>@],
|
||||
+ [AS_HELP_STRING([--enable-bdb=@<:@yes/no/auto@:>@ (DEPRECATED)],
|
||||
[build with Berkeley DB rpm database format support (default=yes)])],
|
||||
[enable_bdb="$enableval"],
|
||||
[enable_bdb=yes])
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
33
backport-Fix-building-with-no-BerkeleyDB-support.patch
Normal file
33
backport-Fix-building-with-no-BerkeleyDB-support.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 4c7323f69b4fddf928245e9db2d1c9ca9b277ef2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Wed, 18 Dec 2019 17:42:31 +0100
|
||||
Subject: [PATCH] Fix building with no BerkeleyDB support
|
||||
|
||||
The configure script used to define BDB even if BerkeleyDB has
|
||||
been disabled.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/4c7323f69b4fddf928245e9db2d1c9ca9b277ef2
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index de6034c..7a90b2f 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -544,11 +544,11 @@ AC_ARG_ENABLE([bdb],
|
||||
[enable_bdb="$enableval"],
|
||||
[enable_bdb=yes])
|
||||
|
||||
+have_bdb="no"
|
||||
AS_IF([test "x$enable_bdb" != "xno"], [
|
||||
if [ test -x db/dist/configure ]; then
|
||||
have_bdb="internal"
|
||||
else
|
||||
- have_bdb="no"
|
||||
AC_CHECK_HEADERS([db.h],[
|
||||
AC_PREPROC_IFELSE([
|
||||
AC_LANG_SOURCE([
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,143 @@
|
||||
From 7630389dcd3494c13b74b119cca37f97d2d8445a Mon Sep 17 00:00:00 2001
|
||||
From: Panu Matilainen <pmatilai@redhat.com>
|
||||
Date: Mon, 30 Mar 2020 11:29:19 +0300
|
||||
Subject: [PATCH] Flush 1998 vintage dirent.h compatibility mess from system.h
|
||||
|
||||
dirent.h and struct dirent are actually standard on this millenium, the
|
||||
only thing that isn't is d_type member for which we have and retain
|
||||
a specific test in configure.ac. Include <dirent.h> where needed,
|
||||
relatively few places do which makes it even a bigger insult to have
|
||||
this included from system.h.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/7630389dcd3494c13b74b119cca37f97d2d8445a
|
||||
---
|
||||
lib/backend/ndb/rpmpkg.c | 1 +
|
||||
lib/backend/ndb/rpmxdb.c | 1 +
|
||||
lib/rpmdb.c | 1 +
|
||||
misc/fts.c | 1 +
|
||||
rpmio/rpmglob.c | 5 ++---
|
||||
rpmio/rpmio.c | 1 +
|
||||
system.h | 17 -----------------
|
||||
7 files changed, 7 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmpkg.c b/lib/backend/ndb/rpmpkg.c
|
||||
index b9cd67c..64d0493 100644
|
||||
--- a/lib/backend/ndb/rpmpkg.c
|
||||
+++ b/lib/backend/ndb/rpmpkg.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <libgen.h>
|
||||
+#include <dirent.h>
|
||||
|
||||
#include "rpmpkg.h"
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmxdb.c b/lib/backend/ndb/rpmxdb.c
|
||||
index dbd4942..5136fbc 100644
|
||||
--- a/lib/backend/ndb/rpmxdb.c
|
||||
+++ b/lib/backend/ndb/rpmxdb.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <endian.h>
|
||||
#include <libgen.h>
|
||||
+#include <dirent.h>
|
||||
|
||||
#include "rpmxdb.h"
|
||||
|
||||
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
|
||||
index 3035e63..57a3c3d 100644
|
||||
--- a/lib/rpmdb.c
|
||||
+++ b/lib/rpmdb.c
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <sys/file.h>
|
||||
#include <utime.h>
|
||||
#include <errno.h>
|
||||
+#include <dirent.h>
|
||||
|
||||
#ifndef DYING /* XXX already in "system.h" */
|
||||
#include <fnmatch.h>
|
||||
diff --git a/misc/fts.c b/misc/fts.c
|
||||
index 5c6f53d..b43f261 100644
|
||||
--- a/misc/fts.c
|
||||
+++ b/misc/fts.c
|
||||
@@ -68,6 +68,7 @@ static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
|
||||
#include "system.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include "misc/rpmfts.h"
|
||||
# define __set_errno(val) (*__errno_location ()) = (val)
|
||||
diff --git a/rpmio/rpmglob.c b/rpmio/rpmglob.c
|
||||
index 3c497cb..93f7fa5 100644
|
||||
--- a/rpmio/rpmglob.c
|
||||
+++ b/rpmio/rpmglob.c
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#include <dirent.h>
|
||||
#include <pwd.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h> /* S_ISDIR */
|
||||
@@ -75,8 +76,6 @@ typedef struct {
|
||||
int (*gl_stat)(const char *, struct stat *);
|
||||
} glob_t;
|
||||
|
||||
-#define NAMLEN(_d) NLENGTH(_d)
|
||||
-
|
||||
#include <errno.h>
|
||||
#ifndef __set_errno
|
||||
#define __set_errno(val) errno = (val)
|
||||
@@ -746,7 +745,7 @@ glob_in_dir(const char *pattern, const char *directory, int flags,
|
||||
if (fnmatch(pattern, name, fnm_flags) == 0) {
|
||||
struct globlink *new = (struct globlink *)
|
||||
alloca(sizeof(struct globlink));
|
||||
- len = NAMLEN(d);
|
||||
+ len = strlen(d->d_name);
|
||||
new->name = (char *) xmalloc(len + 1);
|
||||
*((char *) mempcpy(new->name, name, len))
|
||||
= '\0';
|
||||
diff --git a/rpmio/rpmio.c b/rpmio/rpmio.c
|
||||
index 82c3302..aa1357c 100644
|
||||
--- a/rpmio/rpmio.c
|
||||
+++ b/rpmio/rpmio.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
+#include <dirent.h>
|
||||
#if defined(__linux__)
|
||||
#include <sys/personality.h>
|
||||
#endif
|
||||
diff --git a/system.h b/system.h
|
||||
index 8854d70..f0122cb 100644
|
||||
--- a/system.h
|
||||
+++ b/system.h
|
||||
@@ -49,23 +49,6 @@ char * stpncpy(char * dest, const char * src, size_t n);
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
-#ifdef HAVE_DIRENT_H
|
||||
-# include <dirent.h>
|
||||
-# define NLENGTH(direct) (strlen((direct)->d_name))
|
||||
-#else /* not HAVE_DIRENT_H */
|
||||
-# define dirent direct
|
||||
-# define NLENGTH(direct) ((direct)->d_namlen)
|
||||
-# ifdef HAVE_SYS_NDIR_H
|
||||
-# include <sys/ndir.h>
|
||||
-# endif /* HAVE_SYS_NDIR_H */
|
||||
-# ifdef HAVE_SYS_DIR_H
|
||||
-# include <sys/dir.h>
|
||||
-# endif /* HAVE_SYS_DIR_H */
|
||||
-# ifdef HAVE_NDIR_H
|
||||
-# include <ndir.h>
|
||||
-# endif /* HAVE_NDIR_H */
|
||||
-#endif /* HAVE_DIRENT_H */
|
||||
-
|
||||
#if HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
27
backport-Handle-XZ-in-uncompress-macro.patch
Normal file
27
backport-Handle-XZ-in-uncompress-macro.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 3d63df622037796279514a4da3ddc6807a102c1d Mon Sep 17 00:00:00 2001
|
||||
From: Panu Matilainen <pmatilai@redhat.com>
|
||||
Date: Fri, 27 Mar 2009 14:11:43 +0200
|
||||
Subject: [PATCH] Handle XZ in %uncompress macro - should've been in commit
|
||||
8078d0ba24662308b10d9eb0f0da978584b7e757
|
||||
|
||||
---
|
||||
rpmio/macro.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/rpmio/macro.c b/rpmio/macro.c
|
||||
index c55b9e2..32eb6ec 100644
|
||||
--- a/rpmio/macro.c
|
||||
+++ b/rpmio/macro.c
|
||||
@@ -981,6 +981,9 @@ doFoo(MacroBuf mb, int negate, const char * f, size_t fn,
|
||||
case COMPRESSED_LZMA:
|
||||
sprintf(be, "%%__lzma -dc %s", b);
|
||||
break;
|
||||
+ case COMPRESSED_XZ:
|
||||
+ sprintf(be, "%%__xz -dc %s", b);
|
||||
+ break;
|
||||
}
|
||||
b = be;
|
||||
} else if (STREQ("getenv", f, fn)) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
191
backport-Implement-a-key-only-rpmdb-index-iterator.patch
Normal file
191
backport-Implement-a-key-only-rpmdb-index-iterator.patch
Normal file
@ -0,0 +1,191 @@
|
||||
From 4eb7900d54609738d0d562ba7ac5f0d0f2ebf7e0 Mon Sep 17 00:00:00 2001
|
||||
From: Panu Matilainen <pmatilai@redhat.com>
|
||||
Date: Thu, 5 Dec 2019 14:22:08 +0200
|
||||
Subject: [PATCH] Implement a key-only rpmdb index iterator
|
||||
|
||||
The regular index iterator grabs the associated data too, which we
|
||||
don't always need. The data associated with indexes is relatively
|
||||
lightweight, but as with everything, it adds up if in the millions scale.
|
||||
|
||||
Update all backends to allow for NULL set in the index retrieve to
|
||||
signal key-only retrieval. Ndb actually had an earlier, abandoned
|
||||
implementation of the same idea under slightly different API, lets
|
||||
reuse the code-block.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/4eb7900d54609738d0d562ba7ac5f0d0f2ebf7e0
|
||||
Conflict: delete the contents of lib/backend/sqlite.c, because we have no sqlite database.
|
||||
---
|
||||
lib/backend/db3.c | 18 ++++++++++--------
|
||||
lib/backend/lmdb.c | 18 ++++++++++--------
|
||||
lib/backend/ndb/glue.c | 6 +++---
|
||||
lib/rpmdb.c | 11 ++++++++++-
|
||||
lib/rpmdb.h | 8 ++++++++
|
||||
5 files changed, 41 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/db3.c b/lib/backend/db3.c
|
||||
index ff0fe43..3e6d198 100644
|
||||
--- a/lib/backend/db3.c
|
||||
+++ b/lib/backend/db3.c
|
||||
@@ -1008,7 +1008,7 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
|
||||
dbiIndexSet *set, int searchType)
|
||||
{
|
||||
rpmRC rc = RPMRC_FAIL; /* assume failure */
|
||||
- if (dbi != NULL && dbc != NULL && set != NULL) {
|
||||
+ if (dbi != NULL && dbc != NULL) {
|
||||
int cflags = DB_NEXT;
|
||||
int dbrc;
|
||||
DBT data, key;
|
||||
@@ -1033,12 +1033,14 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
|
||||
if (searchType == DBC_PREFIX_SEARCH &&
|
||||
(key.size < keylen || memcmp(key.data, keyp, keylen) != 0))
|
||||
break;
|
||||
- dbt2set(dbi, &data, &newset);
|
||||
- if (*set == NULL) {
|
||||
- *set = newset;
|
||||
- } else {
|
||||
- dbiIndexSetAppendSet(*set, newset, 0);
|
||||
- dbiIndexSetFree(newset);
|
||||
+ if (set) {
|
||||
+ dbt2set(dbi, &data, &newset);
|
||||
+ if (*set == NULL) {
|
||||
+ *set = newset;
|
||||
+ } else {
|
||||
+ dbiIndexSetAppendSet(*set, newset, 0);
|
||||
+ dbiIndexSetFree(newset);
|
||||
+ }
|
||||
}
|
||||
if (searchType != DBC_PREFIX_SEARCH)
|
||||
break;
|
||||
@@ -1048,7 +1050,7 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
|
||||
}
|
||||
|
||||
/* fixup result status for prefix search */
|
||||
- if (searchType == DBC_PREFIX_SEARCH) {
|
||||
+ if (searchType == DBC_PREFIX_SEARCH && set) {
|
||||
if (dbrc == DB_NOTFOUND && *set != NULL && (*set)->count > 0)
|
||||
dbrc = 0;
|
||||
else if (dbrc == 0 && (*set == NULL || (*set)->count == 0))
|
||||
diff --git a/lib/backend/lmdb.c b/lib/backend/lmdb.c
|
||||
index badd317..f5b94ce 100644
|
||||
--- a/lib/backend/lmdb.c
|
||||
+++ b/lib/backend/lmdb.c
|
||||
@@ -574,7 +574,7 @@ static rpmRC lmdb_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
|
||||
dbiIndexSet *set, int searchType)
|
||||
{
|
||||
rpmRC rc = RPMRC_FAIL; /* assume failure */
|
||||
- if (dbi != NULL && dbc != NULL && set != NULL) {
|
||||
+ if (dbi != NULL && dbc != NULL) {
|
||||
int cflags = MDB_NEXT;
|
||||
int dbrc;
|
||||
MDB_val key = { 0, NULL };
|
||||
@@ -598,12 +598,14 @@ static rpmRC lmdb_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
|
||||
if (searchType == DBC_PREFIX_SEARCH &&
|
||||
(key.mv_size < keylen || memcmp(key.mv_data, keyp, keylen) != 0))
|
||||
break;
|
||||
- dbt2set(dbi, &data, &newset);
|
||||
- if (*set == NULL) {
|
||||
- *set = newset;
|
||||
- } else {
|
||||
- dbiIndexSetAppendSet(*set, newset, 0);
|
||||
- dbiIndexSetFree(newset);
|
||||
+ if (set) {
|
||||
+ dbt2set(dbi, &data, &newset);
|
||||
+ if (*set == NULL) {
|
||||
+ *set = newset;
|
||||
+ } else {
|
||||
+ dbiIndexSetAppendSet(*set, newset, 0);
|
||||
+ dbiIndexSetFree(newset);
|
||||
+ }
|
||||
}
|
||||
if (searchType != DBC_PREFIX_SEARCH)
|
||||
break;
|
||||
@@ -613,7 +615,7 @@ static rpmRC lmdb_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
|
||||
}
|
||||
|
||||
/* fixup result status for prefix search */
|
||||
- if (searchType == DBC_PREFIX_SEARCH) {
|
||||
+ if (searchType == DBC_PREFIX_SEARCH && set) {
|
||||
if (dbrc == MDB_NOTFOUND && *set != NULL && (*set)->count > 0)
|
||||
dbrc = 0;
|
||||
else if (dbrc == 0 && (*set == NULL || (*set)->count == 0))
|
||||
diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c
|
||||
index 03aaaa8..07ddb0a 100644
|
||||
--- a/lib/backend/ndb/glue.c
|
||||
+++ b/lib/backend/ndb/glue.c
|
||||
@@ -400,15 +400,15 @@ static rpmRC ndb_idxdbIter(dbiIndex dbi, dbiCursor dbc, dbiIndexSet *set)
|
||||
}
|
||||
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);
|
||||
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
|
||||
index 9cd50e7..6317dd0 100644
|
||||
--- a/lib/rpmdb.c
|
||||
+++ b/lib/rpmdb.c
|
||||
@@ -298,6 +298,7 @@ struct rpmdbIndexIterator_s {
|
||||
dbiCursor ii_dbc;
|
||||
dbiIndexSet ii_set;
|
||||
unsigned int *ii_hdrNums;
|
||||
+ int ii_skipdata;
|
||||
};
|
||||
|
||||
static rpmdb rpmdbRock;
|
||||
@@ -1885,6 +1886,13 @@ rpmdbIndexIterator rpmdbIndexIteratorInit(rpmdb db, rpmDbiTag rpmtag)
|
||||
return ii;
|
||||
}
|
||||
|
||||
+rpmdbIndexIterator rpmdbIndexKeyIteratorInit(rpmdb db, rpmDbiTag rpmtag)
|
||||
+{
|
||||
+ rpmdbIndexIterator ki = rpmdbIndexIteratorInit(db, rpmtag);
|
||||
+ ki->ii_skipdata = 1;
|
||||
+ return ki;
|
||||
+}
|
||||
+
|
||||
int rpmdbIndexIteratorNext(rpmdbIndexIterator ii, const void ** key, size_t * keylen)
|
||||
{
|
||||
int rc;
|
||||
@@ -1899,7 +1907,8 @@ int rpmdbIndexIteratorNext(rpmdbIndexIterator ii, const void ** key, size_t * ke
|
||||
/* free old data */
|
||||
ii->ii_set = dbiIndexSetFree(ii->ii_set);
|
||||
|
||||
- rc = idxdbGet(ii->ii_dbi, ii->ii_dbc, NULL, 0, &ii->ii_set, DBC_NORMAL_SEARCH);
|
||||
+ rc = idxdbGet(ii->ii_dbi, ii->ii_dbc, NULL, 0,
|
||||
+ ii->ii_skipdata ? NULL : &ii->ii_set, DBC_NORMAL_SEARCH);
|
||||
|
||||
*key = idxdbKey(ii->ii_dbi, ii->ii_dbc, &iikeylen);
|
||||
*keylen = iikeylen;
|
||||
diff --git a/lib/rpmdb.h b/lib/rpmdb.h
|
||||
index 75a722e..8e3ab5a 100644
|
||||
--- a/lib/rpmdb.h
|
||||
+++ b/lib/rpmdb.h
|
||||
@@ -154,6 +154,14 @@ Header rpmdbNextIterator(rpmdbMatchIterator mi);
|
||||
rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi);
|
||||
|
||||
/** \ingroup rpmdb
|
||||
+ * Get an iterator for index keys
|
||||
+ * @param db rpm database
|
||||
+ * @param rpmtag the index to iterate over
|
||||
+ * @return the index iterator
|
||||
+ */
|
||||
+rpmdbIndexIterator rpmdbIndexKeyIteratorInit(rpmdb db, rpmDbiTag rpmtag);
|
||||
+
|
||||
+/** \ingroup rpmdb
|
||||
* Get an iterator for an index
|
||||
* @param db rpm database
|
||||
* @param rpmtag the index to iterate over
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
From 3cb955b77f07c70ba01d765aa6377908847608f5 Mon Sep 17 00:00:00 2001
|
||||
From: Panu Matilainen <pmatilai@redhat.com>
|
||||
Date: Mon, 23 Nov 2020 13:46:14 +0200
|
||||
Subject: [PATCH] Only attempt loading the keyring once the rpmdb is open
|
||||
|
||||
When we do lazy rpmdb open in rpmtsInitIterator(), we also do a lazy
|
||||
keyring open. Except that since the keyring typically lives in the rpmdb,
|
||||
we PROBABLY should try open the database first. One of those "WTF I've
|
||||
been smoking" moments, lol.
|
||||
|
||||
Prevents an ugly if mostly harmless double error anything we can't open
|
||||
the database for one reason or another.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/3cb955b77f07c70ba01d765aa6377908847608f5
|
||||
---
|
||||
lib/rpmts.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/rpmts.c b/lib/rpmts.c
|
||||
index 9fa9cb0..8c8ae42 100644
|
||||
--- a/lib/rpmts.c
|
||||
+++ b/lib/rpmts.c
|
||||
@@ -177,12 +177,12 @@ rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag,
|
||||
if (ts == NULL)
|
||||
return NULL;
|
||||
|
||||
- if (ts && ts->keyring == NULL)
|
||||
- loadKeyring(ts);
|
||||
-
|
||||
if (ts->rdb == NULL && rpmtsOpenDB(ts, ts->dbmode))
|
||||
return NULL;
|
||||
|
||||
+ if (ts->keyring == NULL)
|
||||
+ loadKeyring(ts);
|
||||
+
|
||||
/* Parse out "N(EVR)" tokens from a label key if present */
|
||||
if (rpmtag == RPMDBI_LABEL && keyp != NULL && strchr(keyp, '(')) {
|
||||
const char *se, *s = keyp;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
From 2d63d5ee78963a8f90dcdf93c461f89d326a5a18 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Mon, 3 Feb 2020 11:37:30 +0100
|
||||
Subject: [PATCH] Permit ndb database queries on read-only media
|
||||
|
||||
See also commit a429c99e13fbe9926243f29b78df8d64222c4469 for db3.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/2d63d5ee78963a8f90dcdf93c461f89d326a5a18
|
||||
---
|
||||
lib/backend/ndb/glue.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c
|
||||
index 90c10f8..d19da7c 100644
|
||||
--- a/lib/backend/ndb/glue.c
|
||||
+++ b/lib/backend/ndb/glue.c
|
||||
@@ -161,7 +161,7 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
|
||||
/* Open indexes readwrite if possible */
|
||||
ioflags = O_RDWR;
|
||||
rc = rpmxdbOpen(&ndbenv->xdb, rdb->db_pkgs->dbi_db, path, ioflags, 0666);
|
||||
- if (rc && errno == EACCES) {
|
||||
+ if (rc && (errno == EACCES || errno == EROFS)) {
|
||||
/* If it is not asked for rw explicitly, try to open ro */
|
||||
if (!(oflags & O_RDWR)) {
|
||||
ioflags = O_RDONLY;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
From 7949d290b80aaebf7213e0b70a614d0d00585577 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Fri, 10 Jan 2020 15:56:59 +0100
|
||||
Subject: [PATCH] Remove the experimental status from the ndb database
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/7949d290b80aaebf7213e0b70a614d0d00585577
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 7a90b2f..2801b13 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -581,7 +581,7 @@ fi
|
||||
|
||||
#=================
|
||||
# Process --enable-ndb
|
||||
-AC_ARG_ENABLE([ndb], [AS_HELP_STRING([--enable-ndb (EXPERIMENTAL)],[enable the new rpm database format])],
|
||||
+AC_ARG_ENABLE([ndb], [AS_HELP_STRING([--enable-ndb],[enable the new rpm database format])],
|
||||
[case "$enable_ndb" in
|
||||
yes|no) ;;
|
||||
*) AC_MSG_ERROR([invalid argument to --enable-ndb])
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
From fd054a40b2ba005571455d749de0423975e77651 Mon Sep 17 00:00:00 2001
|
||||
From: Panu Matilainen <pmatilai@redhat.com>
|
||||
Date: Wed, 18 Nov 2020 13:56:14 +0200
|
||||
Subject: [PATCH] Stop on first failure when trying to open a database
|
||||
(RhBug:1898301)
|
||||
|
||||
If an index open fails there's no point trying to go on, things are
|
||||
not going to work and at least BDB will segfault in some cases...
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/fd054a40b2ba005571455d749de0423975e77651
|
||||
---
|
||||
lib/rpmdb.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
|
||||
index 874f079..41da9da 100644
|
||||
--- a/lib/rpmdb.c
|
||||
+++ b/lib/rpmdb.c
|
||||
@@ -355,7 +355,7 @@ static int doOpen(rpmdb db, int justPkgs)
|
||||
{
|
||||
int rc = pkgdbOpen(db, db->db_flags, NULL);
|
||||
if (!justPkgs) {
|
||||
- for (int dbix = 0; dbix < db->db_ndbi; dbix++) {
|
||||
+ for (int dbix = 0; rc == 0 && dbix < db->db_ndbi; dbix++) {
|
||||
rc += indexOpen(db, db->db_tags[dbix], db->db_flags, NULL);
|
||||
}
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
From 108adfc4d10b2158d38d599430275b149ad236c5 Mon Sep 17 00:00:00 2001
|
||||
From: Panu Matilainen <pmatilai@redhat.com>
|
||||
Date: Mon, 21 Oct 2019 14:50:22 +0300
|
||||
Subject: [PATCH] Use paths from db_ops in the backends too where possible
|
||||
|
||||
ndb and sqlite have control of their own paths, BDB and LMDB do things
|
||||
differently and dummydb doesn't have a path at all.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/108adfc4d10b2158d38d599430275b149ad236c5
|
||||
Conflict: delete the contents of lib/backend/sqlite.c, because we have no sqlite database.
|
||||
---
|
||||
lib/backend/ndb/glue.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c
|
||||
index d679ed1..03aaaa8 100644
|
||||
--- a/lib/backend/ndb/glue.c
|
||||
+++ b/lib/backend/ndb/glue.c
|
||||
@@ -101,7 +101,7 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
|
||||
|
||||
if (dbi->dbi_type == DBI_PRIMARY) {
|
||||
rpmpkgdb pkgdb = 0;
|
||||
- char *path = rstrscat(NULL, dbhome, "/Packages.db", NULL);
|
||||
+ char *path = rstrscat(NULL, dbhome, "/", rdb->db_ops->path, NULL);
|
||||
rpmlog(RPMLOG_DEBUG, "opening db index %s mode=0x%x\n", path, rdb->db_mode);
|
||||
rc = rpmpkgOpen(&pkgdb, path, oflags, 0666);
|
||||
if (rc && errno == ENOENT) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,118 @@
|
||||
From bc236cc369b8af9995dd50ba5263d354f47421ce Mon Sep 17 00:00:00 2001
|
||||
From: Panu Matilainen <pmatilai@redhat.com>
|
||||
Date: Mon, 21 Oct 2019 14:39:50 +0300
|
||||
Subject: [PATCH] Use the new backend struct data for backend configuration and
|
||||
detection
|
||||
|
||||
Refactor the hand-written separate tests into an array walk now that we can.
|
||||
No functional changes, except that there's no more special fallback for BDB.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/bc236cc369b8af9995dd50ba5263d354f47421ce
|
||||
Conflict:delete the contents of sqlite, because we have no sqlite database.
|
||||
---
|
||||
lib/backend/dbi.c | 77 +++++++++++++++++++++++++------------------------------
|
||||
1 file changed, 35 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/dbi.c b/lib/backend/dbi.c
|
||||
index 5e00310..a4a40a8 100644
|
||||
--- a/lib/backend/dbi.c
|
||||
+++ b/lib/backend/dbi.c
|
||||
@@ -12,6 +12,19 @@
|
||||
#include "lib/rpmdb_internal.h"
|
||||
#include "debug.h"
|
||||
|
||||
+const struct rpmdbOps_s *backends[] = {
|
||||
+#if defined(WITH_LMDB)
|
||||
+ &lmdb_dbops,
|
||||
+#endif
|
||||
+#ifdef ENABLE_NDB
|
||||
+ &ndb_dbops,
|
||||
+#endif
|
||||
+#if defined(WITH_BDB)
|
||||
+ &db3_dbops,
|
||||
+#endif
|
||||
+ &dummydb_dbops,
|
||||
+ NULL
|
||||
+};
|
||||
|
||||
dbiIndex dbiFree(dbiIndex dbi)
|
||||
{
|
||||
@@ -38,53 +51,33 @@ dbDetectBackend(rpmdb rdb)
|
||||
const char *dbhome = rpmdbHome(rdb);
|
||||
char *db_backend = rpmExpand("%{?_db_backend}", NULL);
|
||||
char *path = NULL;
|
||||
+ const struct rpmdbOps_s **ops;
|
||||
|
||||
-#if defined(WITH_LMDB)
|
||||
- if (!strcmp(db_backend, "lmdb")) {
|
||||
- rdb->db_ops = &lmdb_dbops;
|
||||
- } else
|
||||
-#endif
|
||||
-#ifdef ENABLE_NDB
|
||||
- if (!strcmp(db_backend, "ndb")) {
|
||||
- rdb->db_ops = &ndb_dbops;
|
||||
- } else
|
||||
-#endif
|
||||
-#if defined(WITH_BDB)
|
||||
- {
|
||||
- rdb->db_ops = &db3_dbops;
|
||||
- if (*db_backend == '\0') {
|
||||
- free(db_backend);
|
||||
- db_backend = xstrdup("bdb");
|
||||
+ for (ops = backends; ops && *ops; ops++) {
|
||||
+ if (rstreq(db_backend, (*ops)->name)) {
|
||||
+ rdb->db_ops = *ops;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
-#endif
|
||||
|
||||
-#if defined(WITH_LMDB)
|
||||
- path = rstrscat(NULL, dbhome, "/data.mdb", NULL);
|
||||
- if (access(path, F_OK) == 0 && rdb->db_ops != &lmdb_dbops) {
|
||||
- rdb->db_ops = &lmdb_dbops;
|
||||
- rpmlog(RPMLOG_WARNING, _("Found LMDB data.mdb database while attempting %s backend: using lmdb backend.\n"), db_backend);
|
||||
- }
|
||||
- free(path);
|
||||
-#endif
|
||||
-
|
||||
-#ifdef ENABLE_NDB
|
||||
- path = rstrscat(NULL, dbhome, "/Packages.db", NULL);
|
||||
- if (access(path, F_OK) == 0 && rdb->db_ops != &ndb_dbops) {
|
||||
- rdb->db_ops = &ndb_dbops;
|
||||
- rpmlog(RPMLOG_WARNING, _("Found NDB Packages.db database while attempting %s backend: using ndb backend.\n"), db_backend);
|
||||
- }
|
||||
- free(path);
|
||||
-#endif
|
||||
-
|
||||
-#if defined(WITH_BDB)
|
||||
- path = rstrscat(NULL, dbhome, "/Packages", NULL);
|
||||
- if (access(path, F_OK) == 0 && rdb->db_ops != &db3_dbops) {
|
||||
- rdb->db_ops = &db3_dbops;
|
||||
- rpmlog(RPMLOG_WARNING, _("Found BDB Packages database while attempting %s backend: using bdb backend.\n"), db_backend);
|
||||
+ for (ops = backends; ops && *ops; ops++) {
|
||||
+ int stop = 0;
|
||||
+ if ((*ops)->path == NULL)
|
||||
+ continue;
|
||||
+
|
||||
+ path = rstrscat(NULL, dbhome, "/", (*ops)->path, NULL);
|
||||
+ if (access(path, F_OK) == 0 && rdb->db_ops != *ops) {
|
||||
+ rpmlog(RPMLOG_WARNING,
|
||||
+ _("Found %s %s database while attempting %s backend: "
|
||||
+ "using %s backend.\n"),
|
||||
+ (*ops)->name, (*ops)->path, db_backend, (*ops)->name);
|
||||
+ rdb->db_ops = *ops;
|
||||
+ stop = 1;
|
||||
+ }
|
||||
+ free(path);
|
||||
+ if (stop)
|
||||
+ break;
|
||||
}
|
||||
- free(path);
|
||||
-#endif
|
||||
|
||||
if (rdb->db_ops == NULL) {
|
||||
rdb->db_ops = &dummydb_dbops;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
219
backport-ndb-add-a-rpmpkgSalvage-method.patch
Normal file
219
backport-ndb-add-a-rpmpkgSalvage-method.patch
Normal file
@ -0,0 +1,219 @@
|
||||
From 6489957449fec63ddf330330e9435b4ee0c388b0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Mon, 3 Feb 2020 14:18:23 +0100
|
||||
Subject: [PATCH] ndb: add a rpmpkgSalvage() method
|
||||
|
||||
This can be used to recover as much data as possibly from a
|
||||
terminally broken database. It works by scanning the database
|
||||
file for entries that are not corrupt.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/6489957449fec63ddf330330e9435b4ee0c388b0
|
||||
---
|
||||
lib/backend/ndb/rpmpkg.c | 157 +++++++++++++++++++++++++++++++++++++++++++++--
|
||||
lib/backend/ndb/rpmpkg.h | 1 +
|
||||
2 files changed, 153 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmpkg.c b/lib/backend/ndb/rpmpkg.c
|
||||
index 922ae11..b9cd67c 100644
|
||||
--- a/lib/backend/ndb/rpmpkg.c
|
||||
+++ b/lib/backend/ndb/rpmpkg.c
|
||||
@@ -30,8 +30,6 @@ typedef struct pkgslot_s {
|
||||
|
||||
typedef struct rpmpkgdb_s {
|
||||
int fd; /* our file descriptor */
|
||||
- int flags;
|
||||
- int mode;
|
||||
|
||||
int rdonly;
|
||||
|
||||
@@ -885,8 +883,6 @@ int rpmpkgOpen(rpmpkgdb *pkgdbp, const char *filename, int flags, int mode)
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
}
|
||||
- pkgdb->flags = flags;
|
||||
- pkgdb->mode = mode;
|
||||
pkgdb->dofsync = 1;
|
||||
*pkgdbp = pkgdb;
|
||||
return RPMRC_OK;
|
||||
@@ -908,6 +904,157 @@ void rpmpkgClose(rpmpkgdb pkgdb)
|
||||
free(pkgdb);
|
||||
}
|
||||
|
||||
+
|
||||
+static unsigned int salvage_latest_blob(unsigned int *salvaged, unsigned int cnt)
|
||||
+{
|
||||
+ unsigned int i, max = 0, maxi = 0;
|
||||
+ for (i = 0; i < cnt - 1; i++) {
|
||||
+ if (salvaged[i * 4 + 7] - salvaged[i * 4 + 3] > max) {
|
||||
+ max = salvaged[i * 4 + 7] - salvaged[i * 4 + 3];
|
||||
+ maxi = i;
|
||||
+ }
|
||||
+ }
|
||||
+ if ((unsigned int)(salvaged[3] - salvaged[i * 4 + 3]) > max)
|
||||
+ maxi = cnt - 1;
|
||||
+ return maxi;
|
||||
+}
|
||||
+
|
||||
+static int salvage_cmp(const void *av, const void *bv)
|
||||
+{
|
||||
+ const unsigned int *a = av, *b = bv;
|
||||
+ if (a[0] != b[0])
|
||||
+ return a[0] > b[0] ? 1 : -1;
|
||||
+ if (a[3] != b[3])
|
||||
+ return a[3] > b[3] ? 1 : -1;
|
||||
+ if (a[1] != b[1])
|
||||
+ return a[1] > b[1] ? 1 : -1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define SALVAGE_PAGESIZE 4096
|
||||
+#define SALVAGE_BLKCHUNK (SALVAGE_PAGESIZE / BLK_SIZE)
|
||||
+
|
||||
+int rpmpkgSalvage(rpmpkgdb *pkgdbp, const char *filename)
|
||||
+{
|
||||
+ struct stat stb;
|
||||
+ rpmpkgdb pkgdb;
|
||||
+ unsigned int blk, iblk, blkskip;
|
||||
+ unsigned int blkoff, blkcnt, pkgidx, generation, bloblen;
|
||||
+ unsigned int nfound, nslots, i, j;
|
||||
+ unsigned char page[SALVAGE_PAGESIZE];
|
||||
+ unsigned int *salvaged;
|
||||
+
|
||||
+ *pkgdbp = 0;
|
||||
+ pkgdb = xcalloc(1, sizeof(*pkgdb));
|
||||
+ pkgdb->filename = xstrdup(filename);
|
||||
+ pkgdb->rdonly = 1;
|
||||
+ if ((pkgdb->fd = open(filename, O_RDONLY)) == -1) {
|
||||
+ rpmpkgClose(pkgdb);
|
||||
+ return RPMRC_FAIL;
|
||||
+ }
|
||||
+ if (rpmpkgGetLock(pkgdb, LOCK_SH)) {
|
||||
+ rpmpkgClose(pkgdb);
|
||||
+ return RPMRC_FAIL;
|
||||
+ }
|
||||
+ pkgdb->locked_shared++;
|
||||
+ if (fstat(pkgdb->fd, &stb)) {
|
||||
+ rpmpkgClose(pkgdb);
|
||||
+ return RPMRC_FAIL;
|
||||
+ }
|
||||
+ if (stb.st_size < BLK_SIZE) {
|
||||
+ rpmpkgClose(pkgdb);
|
||||
+ return RPMRC_FAIL;
|
||||
+ }
|
||||
+ pkgdb->fileblks = stb.st_size / BLK_SIZE;
|
||||
+ blkskip = 1;
|
||||
+ nfound = 0;
|
||||
+ salvaged = xmalloc(64 * (4 * sizeof(unsigned int)));
|
||||
+ for (blk = 0; blk < pkgdb->fileblks; blk += SALVAGE_BLKCHUNK) {
|
||||
+ unsigned int size;
|
||||
+ unsigned char *bp = page;
|
||||
+ if (pkgdb->fileblks - blk > SALVAGE_BLKCHUNK)
|
||||
+ size = SALVAGE_PAGESIZE;
|
||||
+ else
|
||||
+ size = (pkgdb->fileblks - blk) * BLK_SIZE;
|
||||
+ if (pread(pkgdb->fd, page, size, (off_t)blk * BLK_SIZE) != size)
|
||||
+ continue;
|
||||
+ if (size != SALVAGE_PAGESIZE)
|
||||
+ memset(page + size, 0, SALVAGE_PAGESIZE - size);
|
||||
+ if (blkskip) {
|
||||
+ memset(page, 0, blkskip * BLK_SIZE);
|
||||
+ blkskip = 0;
|
||||
+ }
|
||||
+ for (iblk = 0; iblk < SALVAGE_BLKCHUNK; iblk++, bp += BLK_SIZE) {
|
||||
+ if (le2h(bp) != BLOBHEAD_MAGIC)
|
||||
+ continue;
|
||||
+ pkgidx = le2h(bp + 4);
|
||||
+ if (!pkgidx)
|
||||
+ continue;
|
||||
+ generation = le2h(bp + 8);
|
||||
+ bloblen = le2h(bp + 12);
|
||||
+ blkoff = blk + iblk;
|
||||
+ blkcnt = (BLOBHEAD_SIZE + bloblen + BLOBTAIL_SIZE + BLK_SIZE - 1) / BLK_SIZE;
|
||||
+ if (blkoff + blkcnt > pkgdb->fileblks)
|
||||
+ continue;
|
||||
+ if (rpmpkgVerifyblob(pkgdb, pkgidx, blkoff, blkcnt))
|
||||
+ continue;
|
||||
+ /* found a valid blob, add to salvaged list */
|
||||
+ if (nfound && (nfound & 63) == 0)
|
||||
+ salvaged = xrealloc(salvaged, (nfound + 64) * (4 * sizeof(unsigned int)));
|
||||
+ salvaged[nfound * 4 + 0] = pkgidx;
|
||||
+ salvaged[nfound * 4 + 1] = blkoff;
|
||||
+ salvaged[nfound * 4 + 2] = blkcnt;
|
||||
+ salvaged[nfound * 4 + 3] = generation;
|
||||
+ nfound++;
|
||||
+ /* advance to after the blob! */
|
||||
+ blkoff += blkcnt;
|
||||
+ if (blkoff >= blk + SALVAGE_BLKCHUNK) {
|
||||
+ blkskip = blkoff % SALVAGE_BLKCHUNK;
|
||||
+ blk = blkoff - blkskip - SALVAGE_BLKCHUNK;
|
||||
+ break;
|
||||
+ } else {
|
||||
+ iblk = blkoff - blk - 1;
|
||||
+ bp = page + iblk * BLK_SIZE;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ /* now strip duplicate entries */
|
||||
+ nslots = 0;
|
||||
+ if (nfound > 1) {
|
||||
+ qsort(salvaged, nfound, sizeof(unsigned int) * 4, salvage_cmp);
|
||||
+ for (i = 0; i < nfound; i++) {
|
||||
+ pkgidx = salvaged[i * 4];
|
||||
+ for (j = i + 1; j < nfound; j++)
|
||||
+ if (salvaged[j * 4] != pkgidx)
|
||||
+ break;
|
||||
+ if (j != i + 1)
|
||||
+ i += salvage_latest_blob(salvaged + i * 4, j - i);
|
||||
+ if (i != nslots)
|
||||
+ memcpy(salvaged + nslots * 4, salvaged + i * 4, sizeof(unsigned int) * 4);
|
||||
+ nslots++;
|
||||
+ i = j - 1;
|
||||
+ }
|
||||
+ }
|
||||
+ pkgdb->slots = xcalloc(nslots + 1, sizeof(*pkgdb->slots));
|
||||
+ for (i = 0; i < nslots; i++) {
|
||||
+ pkgdb->slots[i].pkgidx = salvaged[i * 4 + 0];
|
||||
+ pkgdb->slots[i].blkoff = salvaged[i * 4 + 1];
|
||||
+ pkgdb->slots[i].blkcnt = salvaged[i * 4 + 2];
|
||||
+ pkgdb->slots[i].slotno = 0;
|
||||
+ }
|
||||
+ free(salvaged);
|
||||
+ pkgdb->header_ok = 1;
|
||||
+ pkgdb->nslots = nslots;
|
||||
+ pkgdb->ordered = 0;
|
||||
+ rpmpkgOrderSlots(pkgdb);
|
||||
+ if (rpmpkgHashSlots(pkgdb)) {
|
||||
+ rpmpkgClose(pkgdb);
|
||||
+ return RPMRC_FAIL;
|
||||
+ }
|
||||
+ *pkgdbp = pkgdb;
|
||||
+ return RPMRC_OK;
|
||||
+}
|
||||
+
|
||||
void rpmpkgSetFsync(rpmpkgdb pkgdb, int dofsync)
|
||||
{
|
||||
pkgdb->dofsync = dofsync;
|
||||
@@ -1184,7 +1331,7 @@ int rpmpkgVerify(rpmpkgdb pkgdb)
|
||||
|
||||
int rpmpkgNextPkgIdx(rpmpkgdb pkgdb, unsigned int *pkgidxp)
|
||||
{
|
||||
- if (rpmpkgLockReadHeader(pkgdb, 1))
|
||||
+ if (rpmpkgLockReadHeader(pkgdb, 1) || !pkgdb->nextpkgidx)
|
||||
return RPMRC_FAIL;
|
||||
*pkgidxp = pkgdb->nextpkgidx++;
|
||||
if (rpmpkgWriteHeader(pkgdb)) {
|
||||
diff --git a/lib/backend/ndb/rpmpkg.h b/lib/backend/ndb/rpmpkg.h
|
||||
index 72d05c4..6466818 100644
|
||||
--- a/lib/backend/ndb/rpmpkg.h
|
||||
+++ b/lib/backend/ndb/rpmpkg.h
|
||||
@@ -2,6 +2,7 @@ struct rpmpkgdb_s;
|
||||
typedef struct rpmpkgdb_s *rpmpkgdb;
|
||||
|
||||
int rpmpkgOpen(rpmpkgdb *pkgdbp, const char *filename, int flags, int mode);
|
||||
+int rpmpkgSalvage(rpmpkgdb *pkgdbp, const char *filename);
|
||||
void rpmpkgClose(rpmpkgdb pkgdbp);
|
||||
void rpmpkgSetFsync(rpmpkgdb pkgdbp, int dofsync);
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
143
backport-ndb-add-a-rpmxdbDelAllBlobs-method.patch
Normal file
143
backport-ndb-add-a-rpmxdbDelAllBlobs-method.patch
Normal file
@ -0,0 +1,143 @@
|
||||
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
|
||||
|
||||
93
backport-ndb-add-a-verify-method.patch
Normal file
93
backport-ndb-add-a-verify-method.patch
Normal file
@ -0,0 +1,93 @@
|
||||
From 3feb7993a800525395dca5a173ade5f8e4fbd8d5 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Fri, 10 Jan 2020 11:55:32 +0100
|
||||
Subject: [PATCH] ndb: add a verify method
|
||||
|
||||
This adds a verify method for ndb's Packages.db database. The
|
||||
Index.db database is currently not verified.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/3feb7993a800525395dca5a173ade5f8e4fbd8d5
|
||||
---
|
||||
lib/backend/ndb/glue.c | 8 +++++++-
|
||||
lib/backend/ndb/rpmpkg.c | 26 ++++++++++++++++++++++++++
|
||||
lib/backend/ndb/rpmpkg.h | 1 +
|
||||
3 files changed, 34 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c
|
||||
index 07ddb0a..376e360 100644
|
||||
--- a/lib/backend/ndb/glue.c
|
||||
+++ b/lib/backend/ndb/glue.c
|
||||
@@ -179,7 +179,13 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
|
||||
|
||||
static int ndb_Verify(dbiIndex dbi, unsigned int flags)
|
||||
{
|
||||
- return 0;
|
||||
+ 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)
|
||||
diff --git a/lib/backend/ndb/rpmpkg.c b/lib/backend/ndb/rpmpkg.c
|
||||
index b95f29f..2213872 100644
|
||||
--- a/lib/backend/ndb/rpmpkg.c
|
||||
+++ b/lib/backend/ndb/rpmpkg.c
|
||||
@@ -1101,6 +1101,22 @@ static int rpmpkgListInternal(rpmpkgdb pkgdb, unsigned int **pkgidxlistp, unsign
|
||||
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;
|
||||
@@ -1157,6 +1173,16 @@ int rpmpkgList(rpmpkgdb pkgdb, unsigned int **pkgidxlistp, unsigned int *npkgidx
|
||||
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))
|
||||
diff --git a/lib/backend/ndb/rpmpkg.h b/lib/backend/ndb/rpmpkg.h
|
||||
index 7e5d0c6..72d05c4 100644
|
||||
--- a/lib/backend/ndb/rpmpkg.h
|
||||
+++ b/lib/backend/ndb/rpmpkg.h
|
||||
@@ -12,6 +12,7 @@ int rpmpkgGet(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char **blobp, unsign
|
||||
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);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
From 85b51e2dcf2a0a6393d2fbc51b78d5398e5ffeed Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Tue, 14 Apr 2020 10:44:11 +0200
|
||||
Subject: [PATCH] ndb: also copy the mapped pointer when keeping a slot
|
||||
|
||||
We forgot to copy the mapped pointer if a slot was kept when
|
||||
re-syncing after a generation mismatch. This led to the mapped
|
||||
pointer being zero even if the map callback was set.
|
||||
Also add an extra test for the map callback before setting the
|
||||
protection flag to PROT_READ.
|
||||
|
||||
Found by testing the code with different mapping protection flags.
|
||||
See the next commits.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/85b51e2dcf2a0a6393d2fbc51b78d5398e5ffeed
|
||||
---
|
||||
lib/backend/ndb/rpmxdb.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmxdb.c b/lib/backend/ndb/rpmxdb.c
|
||||
index 5136fbc..354a098 100644
|
||||
--- a/lib/backend/ndb/rpmxdb.c
|
||||
+++ b/lib/backend/ndb/rpmxdb.c
|
||||
@@ -369,6 +369,8 @@ static int rpmxdbReadHeader(rpmxdb xdb)
|
||||
nslot->mapcallback(xdb, nslot->mapcallbackdata, 0, 0);
|
||||
}
|
||||
}
|
||||
+ } else {
|
||||
+ nslot->mapped = slot->mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -624,7 +626,8 @@ static int moveblobto(rpmxdb xdb, struct xdb_slot *oldslot, struct xdb_slot *aft
|
||||
didmap = 0;
|
||||
oldpagecnt = oldslot->pagecnt;
|
||||
if (!oldslot->mapped && oldpagecnt) {
|
||||
- oldslot->mapflags = PROT_READ;
|
||||
+ if (!oldslot->mapcallback)
|
||||
+ oldslot->mapflags = PROT_READ;
|
||||
if (mapslot(xdb, oldslot))
|
||||
return RPMRC_FAIL;
|
||||
didmap = 1;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,106 @@
|
||||
From 3cfd298e9d03a7867118326fc60cc86fd7ea9b73 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Tue, 14 Apr 2020 10:58:34 +0200
|
||||
Subject: [PATCH] ndb: do not map the index databases read-write all the time
|
||||
|
||||
Pass the flags to rpmidxOpenXdb and use read only mode if the
|
||||
user specified O_RDONLY. We already did that for rpmidxOpen in
|
||||
the past but we always used read-write mode when using the Xdb.
|
||||
|
||||
We still open the Xdb itself in read-write mode so that we can
|
||||
regenerate missing index databases.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/3cfd298e9d03a7867118326fc60cc86fd7ea9b73
|
||||
---
|
||||
lib/backend/ndb/glue.c | 11 ++++-------
|
||||
lib/backend/ndb/rpmidx.c | 8 ++++++--
|
||||
lib/backend/ndb/rpmidx.h | 2 +-
|
||||
3 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c
|
||||
index f69a46e..2bdfecc 100644
|
||||
--- a/lib/backend/ndb/glue.c
|
||||
+++ b/lib/backend/ndb/glue.c
|
||||
@@ -147,9 +147,6 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
|
||||
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;
|
||||
} else {
|
||||
unsigned int id;
|
||||
rpmidxdb idxdb = 0;
|
||||
@@ -188,20 +185,20 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
|
||||
ndb_CheckIndexSync(ndbenv->pkgdb, ndbenv->xdb);
|
||||
}
|
||||
if (rpmxdbLookupBlob(ndbenv->xdb, &id, rpmtag, 0, 0) == RPMRC_NOTFOUND) {
|
||||
+ oflags = O_RDWR|O_CREAT;
|
||||
dbi->dbi_flags |= DBI_CREATED;
|
||||
}
|
||||
rpmlog(RPMLOG_DEBUG, "opening db index %s tag=%d\n", dbiName(dbi), rpmtag);
|
||||
- if (rpmidxOpenXdb(&idxdb, rdb->db_pkgs->dbi_db, ndbenv->xdb, rpmtag)) {
|
||||
+ if (rpmidxOpenXdb(&idxdb, rdb->db_pkgs->dbi_db, ndbenv->xdb, rpmtag, oflags)) {
|
||||
perror("rpmidxOpenXdb");
|
||||
ndb_Close(dbi, 0);
|
||||
return 1;
|
||||
}
|
||||
dbi->dbi_db = idxdb;
|
||||
-
|
||||
- if (rpmxdbIsRdonly(ndbenv->xdb))
|
||||
- dbi->dbi_flags |= DBI_RDONLY;
|
||||
}
|
||||
|
||||
+ if ((oflags & (O_RDWR | O_RDONLY)) == O_RDONLY)
|
||||
+ dbi->dbi_flags |= DBI_RDONLY;
|
||||
|
||||
if (dbip != NULL)
|
||||
*dbip = dbi;
|
||||
diff --git a/lib/backend/ndb/rpmidx.c b/lib/backend/ndb/rpmidx.c
|
||||
index 0ec8c8d..90b22d5 100644
|
||||
--- a/lib/backend/ndb/rpmidx.c
|
||||
+++ b/lib/backend/ndb/rpmidx.c
|
||||
@@ -885,13 +885,17 @@ int rpmidxOpen(rpmidxdb *idxdbp, rpmpkgdb pkgdb, const char *filename, int flags
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
|
||||
-int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag)
|
||||
+int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag, int flags)
|
||||
{
|
||||
rpmidxdb idxdb;
|
||||
unsigned int id;
|
||||
*idxdbp = 0;
|
||||
int rc;
|
||||
|
||||
+ if (rpmxdbIsRdonly(xdb) && (flags & (O_RDONLY|O_RDWR)) != O_RDONLY) {
|
||||
+ errno = EACCES;
|
||||
+ return RPMRC_FAIL;
|
||||
+ }
|
||||
if (rpmxdbLock(xdb, 0))
|
||||
return RPMRC_FAIL;
|
||||
rc = rpmxdbLookupBlob(xdb, &id, xdbtag, IDXDB_XDB_SUBTAG, 0);
|
||||
@@ -907,7 +911,7 @@ int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdb
|
||||
idxdb->xdbid = id;
|
||||
idxdb->pkgdb = pkgdb;
|
||||
idxdb->pagesize = rpmxdbPagesize(xdb);
|
||||
- idxdb->rdonly = rpmxdbIsRdonly(xdb) ? 1 : 0;
|
||||
+ idxdb->rdonly = (flags & (O_RDONLY|O_RDWR)) == O_RDONLY ? 1 : 0;
|
||||
if (!id) {
|
||||
if (rpmidxInit(idxdb)) {
|
||||
free(idxdb);
|
||||
diff --git a/lib/backend/ndb/rpmidx.h b/lib/backend/ndb/rpmidx.h
|
||||
index e89bd82..9b01fb9 100644
|
||||
--- a/lib/backend/ndb/rpmidx.h
|
||||
+++ b/lib/backend/ndb/rpmidx.h
|
||||
@@ -5,7 +5,7 @@ struct rpmidxdb_s;
|
||||
typedef struct rpmidxdb_s *rpmidxdb;
|
||||
|
||||
int rpmidxOpen(rpmidxdb *idxdbp, rpmpkgdb pkgdb, const char *filename, int flags, int mode);
|
||||
-int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag);
|
||||
+int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag, int flags);
|
||||
int rpmidxDelXdb(rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag);
|
||||
void rpmidxClose(rpmidxdb idxdbp);
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,190 @@
|
||||
From aea8c86ec8a73d34f26c77ad40179df92970260f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Tue, 14 Apr 2020 11:07:31 +0200
|
||||
Subject: [PATCH] ndb: do not map xdb's header read-write all the time
|
||||
|
||||
Instead just map it read-write if one of the functions request
|
||||
exclusive access. We keep track of the number of exclusive
|
||||
locks and fall back to read-only mapping if the count reaches
|
||||
zero again.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/aea8c86ec8a73d34f26c77ad40179df92970260f
|
||||
---
|
||||
lib/backend/ndb/rpmxdb.c | 55 +++++++++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 40 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmxdb.c b/lib/backend/ndb/rpmxdb.c
|
||||
index 354a098..ec408f8 100644
|
||||
--- a/lib/backend/ndb/rpmxdb.c
|
||||
+++ b/lib/backend/ndb/rpmxdb.c
|
||||
@@ -37,7 +37,7 @@ typedef struct rpmxdb_s {
|
||||
unsigned int usergeneration;
|
||||
|
||||
unsigned char *mapped;
|
||||
- int mapflags;
|
||||
+ int mappedrw;
|
||||
unsigned int mappedlen;
|
||||
|
||||
struct xdb_slot {
|
||||
@@ -58,6 +58,7 @@ typedef struct rpmxdb_s {
|
||||
unsigned int usedblobpages;
|
||||
unsigned int systempagesize;
|
||||
int dofsync;
|
||||
+ unsigned int locked_excl;
|
||||
} *rpmxdb;
|
||||
|
||||
|
||||
@@ -126,17 +127,19 @@ static void unmapmem(void *addr, size_t size)
|
||||
#define ROUNDTOSYSTEMPAGE(xdb, size) (((size) + (xdb->systempagesize - 1)) & ~(xdb->systempagesize - 1))
|
||||
|
||||
/* xdb header mapping functions */
|
||||
-static int mapheader(rpmxdb xdb, unsigned int slotnpages)
|
||||
+static int mapheader(rpmxdb xdb, unsigned int slotnpages, int rw)
|
||||
{
|
||||
unsigned char *mapped;
|
||||
size_t mappedlen = slotnpages * xdb->pagesize;
|
||||
+ int mapflags = rw ? PROT_READ | PROT_WRITE : PROT_READ;
|
||||
|
||||
mappedlen = ROUNDTOSYSTEMPAGE(xdb, mappedlen);
|
||||
- mapped = mapmem(xdb->mapped, xdb->mappedlen, mappedlen, xdb->mapflags, xdb->fd, 0);
|
||||
+ mapped = mapmem(xdb->mapped, xdb->mappedlen, mappedlen, mapflags, xdb->fd, 0);
|
||||
if ((void *)mapped == MAP_FAILED)
|
||||
return RPMRC_FAIL;
|
||||
xdb->mapped = mapped;
|
||||
xdb->mappedlen = mappedlen;
|
||||
+ xdb->mappedrw = rw;
|
||||
return RPMRC_OK;
|
||||
}
|
||||
|
||||
@@ -248,7 +251,7 @@ static int rpmxdbReadHeaderRaw(rpmxdb xdb, unsigned int *generationp, unsigned i
|
||||
return RPMRC_OK;
|
||||
}
|
||||
|
||||
-static int rpmxdbReadHeader(rpmxdb xdb)
|
||||
+static int rpmxdbReadHeader(rpmxdb xdb, int rw)
|
||||
{
|
||||
struct xdb_slot *slot;
|
||||
unsigned int slotnpages, pagesize, generation, usergeneration;
|
||||
@@ -262,6 +265,11 @@ static int rpmxdbReadHeader(rpmxdb xdb)
|
||||
|
||||
if (xdb->mapped) {
|
||||
if (le2ha(xdb->mapped + XDB_OFFSET_GENERATION) == xdb->generation) {
|
||||
+ if (rw && !xdb->mappedrw) {
|
||||
+ unmapheader(xdb);
|
||||
+ if (mapheader(xdb, xdb->slotnpages, rw))
|
||||
+ return RPMRC_FAIL;
|
||||
+ }
|
||||
return RPMRC_OK;
|
||||
}
|
||||
unmapheader(xdb);
|
||||
@@ -274,9 +282,8 @@ static int rpmxdbReadHeader(rpmxdb xdb)
|
||||
if (stb.st_size % pagesize != 0)
|
||||
return RPMRC_FAIL;
|
||||
xdb->pagesize = pagesize;
|
||||
- xdb->mapflags = xdb->rdonly ? PROT_READ : PROT_READ | PROT_WRITE;
|
||||
|
||||
- if (mapheader(xdb, slotnpages))
|
||||
+ if (mapheader(xdb, slotnpages, rw))
|
||||
return RPMRC_FAIL;
|
||||
|
||||
/* read in all slots */
|
||||
@@ -476,19 +483,25 @@ static int rpmxdbInitInternal(rpmxdb xdb)
|
||||
/* we use the master pdb for locking */
|
||||
static int rpmxdbLockOnly(rpmxdb xdb, int excl)
|
||||
{
|
||||
+ int rc;
|
||||
if (excl && xdb->rdonly)
|
||||
return RPMRC_FAIL;
|
||||
- return rpmpkgLock(xdb->pkgdb, excl);
|
||||
+ rc = rpmpkgLock(xdb->pkgdb, excl);
|
||||
+ if (!rc && excl)
|
||||
+ xdb->locked_excl++;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
-/* this is the same as rpmxdbLockReadHeader. It does the
|
||||
+/* This is similar to rpmxdbLockReadHeader. It does the
|
||||
* ReadHeader to sync the mappings if xdb moved some blobs.
|
||||
+ * Note that we just ask for rad-only access in the
|
||||
+ * rpmxdbReadHeader call.
|
||||
*/
|
||||
int rpmxdbLock(rpmxdb xdb, int excl)
|
||||
{
|
||||
if (rpmxdbLockOnly(xdb, excl))
|
||||
return RPMRC_FAIL;
|
||||
- if (rpmxdbReadHeader(xdb)) {
|
||||
+ if (rpmxdbReadHeader(xdb, 0)) {
|
||||
rpmxdbUnlock(xdb, excl);
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
@@ -497,14 +510,25 @@ int rpmxdbLock(rpmxdb xdb, int excl)
|
||||
|
||||
int rpmxdbUnlock(rpmxdb xdb, int excl)
|
||||
{
|
||||
+ if (excl && xdb->locked_excl) {
|
||||
+ xdb->locked_excl--;
|
||||
+ if (!xdb->locked_excl && xdb->mapped && xdb->mappedrw) {
|
||||
+ unmapheader(xdb);
|
||||
+ mapheader(xdb, xdb->slotnpages, 0);
|
||||
+ }
|
||||
+ }
|
||||
return rpmpkgUnlock(xdb->pkgdb, excl);
|
||||
}
|
||||
|
||||
+/* Like rpmxdbLock, but map the header rw if excl is set.
|
||||
+ * This is what the functions in this module use, whereas
|
||||
+ * rpmidx uses rpmxdbLock.
|
||||
+ */
|
||||
static int rpmxdbLockReadHeader(rpmxdb xdb, int excl)
|
||||
{
|
||||
if (rpmxdbLockOnly(xdb, excl))
|
||||
return RPMRC_FAIL;
|
||||
- if (rpmxdbReadHeader(xdb)) {
|
||||
+ if (rpmxdbReadHeader(xdb, excl)) {
|
||||
rpmxdbUnlock(xdb, excl);
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
@@ -776,7 +800,7 @@ static int addslotpage(rpmxdb xdb)
|
||||
return RPMRC_FAIL;
|
||||
|
||||
/* remap the header */
|
||||
- if (mapheader(xdb, xdb->slotnpages + 1))
|
||||
+ if (mapheader(xdb, xdb->slotnpages + 1, xdb->mappedrw))
|
||||
return RPMRC_FAIL;
|
||||
|
||||
/* update the header */
|
||||
@@ -856,7 +880,8 @@ int rpmxdbLookupBlob(rpmxdb xdb, unsigned int *idp, unsigned int blobtag, unsign
|
||||
{
|
||||
struct xdb_slot *slot;
|
||||
unsigned int i, nslots;
|
||||
- if (rpmxdbLockReadHeader(xdb, flags ? 1 : 0))
|
||||
+ int excl = flags ? 1 : 0;
|
||||
+ if (rpmxdbLockReadHeader(xdb, excl))
|
||||
return RPMRC_FAIL;
|
||||
nslots = xdb->nslots;
|
||||
slot = 0;
|
||||
@@ -869,18 +894,18 @@ int rpmxdbLookupBlob(rpmxdb xdb, unsigned int *idp, unsigned int blobtag, unsign
|
||||
i = 0;
|
||||
if (i && (flags & O_TRUNC) != 0) {
|
||||
if (rpmxdbResizeBlob(xdb, i, 0)) {
|
||||
- rpmxdbUnlock(xdb, flags ? 1 : 0);
|
||||
+ rpmxdbUnlock(xdb, excl);
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
}
|
||||
if (!i && (flags & O_CREAT) != 0) {
|
||||
if (createblob(xdb, &i, blobtag, subtag)) {
|
||||
- rpmxdbUnlock(xdb, flags ? 1 : 0);
|
||||
+ rpmxdbUnlock(xdb, excl);
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
}
|
||||
*idp = i;
|
||||
- rpmxdbUnlock(xdb, flags ? 1 : 0);
|
||||
+ rpmxdbUnlock(xdb, excl);
|
||||
return i ? RPMRC_OK : RPMRC_NOTFOUND;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
38
backport-ndb-drop-unused-number-of-allocated-slots.patch
Normal file
38
backport-ndb-drop-unused-number-of-allocated-slots.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From 8e39098fa991b097ec0c746f0b4e3d8ab19a69ee Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Fri, 10 Jan 2020 11:45:52 +0100
|
||||
Subject: [PATCH] ndb: drop unused number of allocated slots
|
||||
|
||||
This is not used as we re-read all slots everytime a package
|
||||
is added or deleted.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/8e39098fa991b097ec0c746f0b4e3d8ab19a69ee
|
||||
---
|
||||
lib/backend/ndb/rpmpkg.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmpkg.c b/lib/backend/ndb/rpmpkg.c
|
||||
index eb65049..b613fa5 100644
|
||||
--- a/lib/backend/ndb/rpmpkg.c
|
||||
+++ b/lib/backend/ndb/rpmpkg.c
|
||||
@@ -45,7 +45,6 @@ typedef struct rpmpkgdb_s {
|
||||
unsigned int nextpkgidx;
|
||||
|
||||
struct pkgslot_s *slots;
|
||||
- unsigned int aslots; /* allocated slots */
|
||||
unsigned int nslots; /* used slots */
|
||||
|
||||
unsigned int *slothash;
|
||||
@@ -256,8 +255,7 @@ static int rpmpkgReadSlots(rpmpkgdb pkgdb)
|
||||
fileblks = stb.st_size / BLK_SIZE;
|
||||
|
||||
/* read (and somewhat verify) all slots */
|
||||
- pkgdb->aslots = slotnpages * (PAGE_SIZE / SLOT_SIZE);
|
||||
- pkgdb->slots = xcalloc(pkgdb->aslots, sizeof(*pkgdb->slots));
|
||||
+ pkgdb->slots = xcalloc(slotnpages * (PAGE_SIZE / SLOT_SIZE), sizeof(*pkgdb->slots));
|
||||
i = 0;
|
||||
slot = pkgdb->slots;
|
||||
minblkoff = slotnpages * (PAGE_SIZE / BLK_SIZE);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
28
backport-ndb-fix-ftruncate-return-value-warning.patch
Normal file
28
backport-ndb-fix-ftruncate-return-value-warning.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From bc13afbbfdfa33b10bb87e9503b3b06a0d65bfd2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Tue, 14 Jan 2020 17:05:27 +0100
|
||||
Subject: [PATCH] ndb: fix ftruncate return value warning
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/bc13afbbfdfa33b10bb87e9503b3b06a0d65bfd2
|
||||
---
|
||||
lib/backend/ndb/rpmxdb.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmxdb.c b/lib/backend/ndb/rpmxdb.c
|
||||
index 3baafa6..dbd4942 100644
|
||||
--- a/lib/backend/ndb/rpmxdb.c
|
||||
+++ b/lib/backend/ndb/rpmxdb.c
|
||||
@@ -963,7 +963,9 @@ int rpmxdbDelAllBlobs(rpmxdb xdb)
|
||||
rpmxdbUnlock(xdb, 1);
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
- ftruncate(xdb->fd, xdb->pagesize);
|
||||
+ if (ftruncate(xdb->fd, xdb->pagesize)) {
|
||||
+ /* ftruncate failed, but that is not a problem */
|
||||
+ }
|
||||
rpmxdbUnlock(xdb, 1);
|
||||
return RPMRC_OK;
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
From 40269d4b3f960e6cb73db1cea0bcc5973f9ce72c Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Fri, 10 Jan 2020 15:51:38 +0100
|
||||
Subject: [PATCH] ndb: implement index regeneration if the index is out of sync
|
||||
|
||||
We compare the user generation stored in the index database with
|
||||
the generation count from the package database. In case there
|
||||
is a mismatch, we delete all the index databases and rely on the
|
||||
already existing missing index creation code to rebuild the
|
||||
database.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/40269d4b3f960e6cb73db1cea0bcc5973f9ce72c
|
||||
---
|
||||
lib/backend/ndb/glue.c | 29 +++++++++++++++++++++++++++++
|
||||
1 file changed, 29 insertions(+)
|
||||
|
||||
diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c
|
||||
index 841c2fe..90c10f8 100644
|
||||
--- a/lib/backend/ndb/glue.c
|
||||
+++ b/lib/backend/ndb/glue.c
|
||||
@@ -80,6 +80,31 @@ static int ndb_Close(dbiIndex dbi, unsigned int flags)
|
||||
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);
|
||||
@@ -130,6 +155,7 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
|
||||
}
|
||||
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 */
|
||||
@@ -144,6 +170,7 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
|
||||
} 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");
|
||||
@@ -153,6 +180,8 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
|
||||
}
|
||||
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;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
154
backport-ndb-make-ordered-slots-flag-a-boolean.patch
Normal file
154
backport-ndb-make-ordered-slots-flag-a-boolean.patch
Normal file
@ -0,0 +1,154 @@
|
||||
From cbe9bcf954b2043dcefabbda6722ee3e149d8a8b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Fri, 10 Jan 2020 11:44:01 +0100
|
||||
Subject: [PATCH] ndb: make "ordered slots" flag a boolean
|
||||
|
||||
We never needed to order by pkgid or slot number, so simplify
|
||||
the code.
|
||||
|
||||
https://github.com/rpm-software-management/rpm/commit/cbe9bcf954b2043dcefabbda6722ee3e149d8a8b
|
||||
---
|
||||
lib/backend/ndb/rpmpkg.c | 43 +++++++++++++++++++------------------------
|
||||
1 file changed, 19 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmpkg.c b/lib/backend/ndb/rpmpkg.c
|
||||
index b8e33bf..eb65049 100644
|
||||
--- a/lib/backend/ndb/rpmpkg.c
|
||||
+++ b/lib/backend/ndb/rpmpkg.c
|
||||
@@ -52,16 +52,13 @@ typedef struct rpmpkgdb_s {
|
||||
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)
|
||||
{
|
||||
@@ -296,7 +293,7 @@ static int rpmpkgReadSlots(rpmpkgdb pkgdb)
|
||||
}
|
||||
}
|
||||
pkgdb->nslots = i;
|
||||
- pkgdb->slotorder = SLOTORDER_UNORDERED; /* XXX: always order? */
|
||||
+ pkgdb->ordered = 0;
|
||||
pkgdb->fileblks = fileblks;
|
||||
pkgdb->freeslot = freeslot;
|
||||
if (rpmpkgHashSlots(pkgdb)) {
|
||||
@@ -314,15 +311,13 @@ static int orderslots_blkoff_cmp(const void *a, const void *b)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -347,8 +342,8 @@ static int rpmpkgFindEmptyOffset(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned i
|
||||
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;
|
||||
@@ -388,8 +383,8 @@ static int rpmpkgNeighbourCheck(rpmpkgdb pkgdb, unsigned int blkoff, unsigned in
|
||||
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++) {
|
||||
@@ -704,15 +699,15 @@ static int rpmpkgMoveBlob(rpmpkgdb pkgdb, pkgslot *slot, unsigned int newblkoff)
|
||||
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 */
|
||||
@@ -730,7 +725,7 @@ static int rpmpkgAddSlotPage(rpmpkgdb pkgdb)
|
||||
if (rpmpkgMoveBlob(pkgdb, slot, newblkoff)) {
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
|
||||
+ rpmpkgOrderSlots(pkgdb);
|
||||
}
|
||||
|
||||
/* make sure our new page is empty */
|
||||
@@ -1008,7 +1003,7 @@ static int rpmpkgPutInternal(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char
|
||||
/* 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;
|
||||
@@ -1025,7 +1020,7 @@ static int rpmpkgDelInternal(rpmpkgdb pkgdb, unsigned int pkgidx)
|
||||
if (rpmpkgReadSlots(pkgdb)) {
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
|
||||
+ rpmpkgOrderSlots(pkgdb);
|
||||
slot = rpmpkgFindSlot(pkgdb, pkgidx);
|
||||
if (!slot) {
|
||||
return RPMRC_OK;
|
||||
@@ -1068,7 +1063,7 @@ static int rpmpkgDelInternal(rpmpkgdb pkgdb, unsigned int pkgidx)
|
||||
blkoff += slot->blkcnt;
|
||||
blkcnt -= slot->blkcnt;
|
||||
}
|
||||
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
|
||||
+ rpmpkgOrderSlots(pkgdb);
|
||||
} else {
|
||||
slot->blkoff = 0;
|
||||
slot->blkcnt = 0;
|
||||
@@ -1107,7 +1102,7 @@ static int rpmpkgListInternal(rpmpkgdb pkgdb, unsigned int **pkgidxlistp, unsign
|
||||
*npkgidxlistp = pkgdb->nslots;
|
||||
return RPMRC_OK;
|
||||
}
|
||||
- rpmpkgOrderSlots(pkgdb, SLOTORDER_BLKOFF);
|
||||
+ rpmpkgOrderSlots(pkgdb);
|
||||
nslots = pkgdb->nslots;
|
||||
pkgidxlist = xcalloc(nslots + 1, sizeof(unsigned int));
|
||||
for (i = 0, slot = pkgdb->slots; i < nslots; i++, slot++) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
39
backport-ndb-make-rpmxdbWriteHeader-a-void-function.patch
Normal file
39
backport-ndb-make-rpmxdbWriteHeader-a-void-function.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 6511823c97c6f40b8d99961767537f4f3bebc16e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Tue, 14 Apr 2020 11:27:46 +0200
|
||||
Subject: [PATCH] ndb: make rpmxdbWriteHeader a void function
|
||||
|
||||
It's a static function and nobody tests the return code. It just
|
||||
writes into mapped memory like rpmxdbUpdateSlot, which is also void.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/6511823c97c6f40b8d99961767537f4f3bebc16e
|
||||
---
|
||||
lib/backend/ndb/rpmxdb.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmxdb.c b/lib/backend/ndb/rpmxdb.c
|
||||
index ab22746..be85fdc 100644
|
||||
--- a/lib/backend/ndb/rpmxdb.c
|
||||
+++ b/lib/backend/ndb/rpmxdb.c
|
||||
@@ -392,17 +392,14 @@ static int rpmxdbReadHeader(rpmxdb xdb, int rw)
|
||||
return RPMRC_OK;
|
||||
}
|
||||
|
||||
-static int rpmxdbWriteHeader(rpmxdb xdb)
|
||||
+static void rpmxdbWriteHeader(rpmxdb xdb)
|
||||
{
|
||||
- if (!xdb->mapped)
|
||||
- return RPMRC_FAIL;
|
||||
h2lea(XDB_MAGIC, xdb->mapped + XDB_OFFSET_MAGIC);
|
||||
h2lea(XDB_VERSION, xdb->mapped + XDB_OFFSET_VERSION);
|
||||
h2lea(xdb->generation, xdb->mapped + XDB_OFFSET_GENERATION);
|
||||
h2lea(xdb->slotnpages, xdb->mapped + XDB_OFFSET_SLOTNPAGES);
|
||||
h2lea(xdb->pagesize, xdb->mapped + XDB_OFFSET_PAGESIZE);
|
||||
h2lea(xdb->usergeneration, xdb->mapped + XDB_OFFSET_USERGENERATION);
|
||||
- return RPMRC_OK;
|
||||
}
|
||||
|
||||
static void rpmxdbUpdateSlot(rpmxdb xdb, struct xdb_slot *slot)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From d435beb937ca38a3d3f1c6acb1b3ca06dcb3544d Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Fri, 10 Jan 2020 11:51:07 +0100
|
||||
Subject: [PATCH] ndb: no longer free the pkgid hash all the time
|
||||
|
||||
Reuse the hash if the size matches. This was actually the original
|
||||
intention, but for some reason the code was disabled by always
|
||||
freeing the hash.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/d435beb937ca38a3d3f1c6acb1b3ca06dcb3544d
|
||||
---
|
||||
lib/backend/ndb/rpmpkg.c | 16 +++-------------
|
||||
1 file changed, 3 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmpkg.c b/lib/backend/ndb/rpmpkg.c
|
||||
index b613fa5..b95f29f 100644
|
||||
--- a/lib/backend/ndb/rpmpkg.c
|
||||
+++ b/lib/backend/ndb/rpmpkg.c
|
||||
@@ -136,10 +136,6 @@ static int rpmpkgReadHeader(rpmpkgdb pkgdb)
|
||||
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;
|
||||
@@ -201,14 +197,14 @@ static int rpmpkgHashSlots(rpmpkgdb pkgdb)
|
||||
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);
|
||||
+ if (hash)
|
||||
+ free(hash);
|
||||
hash = pkgdb->slothash = xcalloc(num, sizeof(unsigned int));
|
||||
pkgdb->nslothash = num;
|
||||
} else {
|
||||
@@ -221,8 +217,6 @@ static int rpmpkgHashSlots(rpmpkgdb pkgdb)
|
||||
;
|
||||
hash[h] = i + 1;
|
||||
}
|
||||
- pkgdb->slothash = hash;
|
||||
- pkgdb->nslothash = num;
|
||||
return RPMRC_OK;
|
||||
}
|
||||
|
||||
@@ -240,10 +234,6 @@ static int rpmpkgReadSlots(rpmpkgdb pkgdb)
|
||||
free(pkgdb->slots);
|
||||
pkgdb->slots = 0;
|
||||
}
|
||||
- if (pkgdb->slothash) {
|
||||
- free(pkgdb->slothash);
|
||||
- pkgdb->slothash = 0;
|
||||
- }
|
||||
pkgdb->nslots = 0;
|
||||
pkgdb->freeslot = 0;
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -5,12 +5,14 @@ Subject: [PATCH] ndb: only clear the dbenv in the rpmdb if the last reference
|
||||
is gone
|
||||
|
||||
Otherwise we will segfault if just one index is closed.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/52c3ee60a1ce0e7e527dc396dd1e1a0e29b7b0ed
|
||||
---
|
||||
lib/backend/ndb/glue.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c
|
||||
index 376e360e3..841c2fe42 100644
|
||||
index 376e360..841c2fe 100644
|
||||
--- a/lib/backend/ndb/glue.c
|
||||
+++ b/lib/backend/ndb/glue.c
|
||||
@@ -52,8 +52,8 @@ static void closeEnv(rpmdb rdb)
|
||||
@ -24,5 +26,5 @@ index 376e360e3..841c2fe42 100644
|
||||
|
||||
static struct ndbEnv_s *openEnv(rpmdb rdb)
|
||||
--
|
||||
2.27.0
|
||||
1.8.3.1
|
||||
|
||||
|
||||
121
backport-ndb-remove-unused-lzo-compression-code.patch
Normal file
121
backport-ndb-remove-unused-lzo-compression-code.patch
Normal file
@ -0,0 +1,121 @@
|
||||
From dc0a504d3e893e40df60bd8a4a45852dcfca307a Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Fri, 10 Jan 2020 11:26:49 +0100
|
||||
Subject: [PATCH] ndb: remove unused lzo compression code
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/dc0a504d3e893e40df60bd8a4a45852dcfca307a
|
||||
---
|
||||
lib/backend/ndb/rpmpkg.c | 78 ------------------------------------------------
|
||||
1 file changed, 78 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmpkg.c b/lib/backend/ndb/rpmpkg.c
|
||||
index 0809af1..94ecde1 100644
|
||||
--- a/lib/backend/ndb/rpmpkg.c
|
||||
+++ b/lib/backend/ndb/rpmpkg.c
|
||||
@@ -19,10 +19,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);
|
||||
|
||||
@@ -1127,10 +1123,6 @@ int rpmpkgGet(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char **blobp, unsign
|
||||
return RPMRC_FAIL;
|
||||
rc = rpmpkgGetInternal(pkgdb, pkgidx, blobp, bloblp);
|
||||
rpmpkgUnlock(pkgdb, 0);
|
||||
-#ifdef RPMPKG_LZO
|
||||
- if (!rc)
|
||||
- rc = rpmpkgLZODecompress(blobp, bloblp);
|
||||
-#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1143,16 +1135,7 @@ int rpmpkgPut(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char *blob, unsigned
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -1233,64 +1216,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 = xmalloc(LZO1X_1_MEM_COMPRESS);
|
||||
- lzoblobl = 4 + 4 + blobl + blobl / 16 + 64 + 3;
|
||||
- lzoblob = xmalloc(lzoblobl);
|
||||
- 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 = xmalloc(blobl ? blobl : 1);
|
||||
- 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
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
From 1187cf005a2821d5f239bec1a0ecddfef190a125 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Tue, 14 Apr 2020 11:22:39 +0200
|
||||
Subject: [PATCH] ndb: unmap xdb's header when closing the xdb database
|
||||
|
||||
Somehow I was under the impression that mapped regions are unmapped when
|
||||
the corresponding file descriptor is closed, but that's not the case
|
||||
for POSIX systems.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/1187cf005a2821d5f239bec1a0ecddfef190a125
|
||||
---
|
||||
lib/backend/ndb/rpmxdb.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmxdb.c b/lib/backend/ndb/rpmxdb.c
|
||||
index ec408f8..ab22746 100644
|
||||
--- a/lib/backend/ndb/rpmxdb.c
|
||||
+++ b/lib/backend/ndb/rpmxdb.c
|
||||
@@ -621,6 +621,8 @@ void rpmxdbClose(rpmxdb xdb)
|
||||
}
|
||||
if (xdb->slots)
|
||||
free(xdb->slots);
|
||||
+ if (xdb->mapped)
|
||||
+ unmapheader(xdb);
|
||||
if (xdb->fd >= 0)
|
||||
close(xdb->fd);
|
||||
if (xdb->filename)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
From f674af7efbeeb44d6c0f0da8c611e6cd7257ee4f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Schroeder <mls@suse.de>
|
||||
Date: Fri, 10 Jan 2020 12:00:49 +0100
|
||||
Subject: [PATCH] ndb: use the generation instead of the current time in blobs
|
||||
|
||||
This seems to saner as the somewhat unreliable current time.
|
||||
This element is not used in normal database operation, it is
|
||||
for repair tools that need to decide which blob to take if two
|
||||
blobs have the same pkgid.
|
||||
|
||||
URL:https://github.com/rpm-software-management/rpm/commit/f674af7efbeeb44d6c0f0da8c611e6cd7257ee4f
|
||||
---
|
||||
lib/backend/ndb/rpmpkg.c | 21 ++++++++++-----------
|
||||
1 file changed, 10 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/lib/backend/ndb/rpmpkg.c b/lib/backend/ndb/rpmpkg.c
|
||||
index 2213872..922ae11 100644
|
||||
--- a/lib/backend/ndb/rpmpkg.c
|
||||
+++ b/lib/backend/ndb/rpmpkg.c
|
||||
@@ -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>
|
||||
@@ -511,7 +510,7 @@ static int rpmpkgValidateZero(rpmpkgdb pkgdb, unsigned int blkoff, unsigned int
|
||||
|
||||
/*** 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)
|
||||
@@ -520,10 +519,10 @@ static int rpmpkgValidateZero(rpmpkgdb pkgdb, unsigned int blkoff, unsigned int
|
||||
#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;
|
||||
@@ -539,7 +538,7 @@ static int rpmpkgReadBlob(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned int blko
|
||||
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 */
|
||||
@@ -584,8 +583,8 @@ static int rpmpkgReadBlob(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned int blko
|
||||
}
|
||||
if (bloblp)
|
||||
*bloblp = bloblen;
|
||||
- if (tstampp)
|
||||
- *tstampp = tstamp;
|
||||
+ if (generationp)
|
||||
+ *generationp = generation;
|
||||
return RPMRC_OK;
|
||||
}
|
||||
|
||||
@@ -668,14 +667,14 @@ static int rpmpkgMoveBlob(rpmpkgdb pkgdb, pkgslot *slot, unsigned int newblkoff)
|
||||
unsigned int blkoff = slot->blkoff;
|
||||
unsigned int blkcnt = slot->blkcnt;
|
||||
unsigned char *blob;
|
||||
- unsigned int tstamp, blobl;
|
||||
+ unsigned int generation, blobl;
|
||||
|
||||
blob = xmalloc((size_t)blkcnt * BLK_SIZE);
|
||||
- if (rpmpkgReadBlob(pkgdb, pkgidx, blkoff, blkcnt, blob, &blobl, &tstamp)) {
|
||||
+ 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;
|
||||
}
|
||||
@@ -966,7 +965,7 @@ static int rpmpkgPutInternal(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char
|
||||
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 */
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
98
rpm.spec
98
rpm.spec
@ -1,6 +1,6 @@
|
||||
Name: rpm
|
||||
Version: 4.15.1
|
||||
Release: 19
|
||||
Release: 20
|
||||
Summary: RPM Package Manager
|
||||
License: GPLv2+
|
||||
URL: http://www.rpm.org/
|
||||
@ -28,31 +28,62 @@ Patch17: backport-Fix-resource-leaks-on-zstd-open-error-paths.patch
|
||||
Patch18: backport-rpmio-initialise-libgcrypt.patch
|
||||
Patch19: backport-fix-zstd-magic.patch
|
||||
Patch20: backport-Don-t-require-signature-header-to-be-in-single-conti.patch
|
||||
Patch21: backport-ndb-only-clear-the-dbenv-in-the-rpmdb-if-the-last-re.patch
|
||||
Patch22: backport-Fix-regression-on-v3-package-handling-on-database-re.patch
|
||||
Patch23: backport-Fix-a-minor-memory-leak-on-suppressed-inhibition-loc.patch
|
||||
Patch24: backport-Fix-POPT_ARG_STRING-memleaks-in-librpmbuild.patch
|
||||
Patch25: backport-Fix-build-regression-in-commit-307872f71b357a3839fd0.patch
|
||||
Patch26: backport-Fix-isUnorderedReq-for-multiple-qualifiers.patch
|
||||
Patch27: backport-If-fork-fails-in-getOutputFrom-close-opened-unused-p.patch
|
||||
Patch28: backport-Fix-pointer-dereference-before-testing-for-NULL-in-r.patch
|
||||
Patch29: backport-Don-t-look-into-source-package-provides-in-depsolvin.patch
|
||||
Patch30: backport-rpmfiArchiveRead-use-signed-return-value-to-handle-1.patch
|
||||
Patch31: backport-Fix-bump-up-the-limit-of-signature-header-to-64MB.patch
|
||||
Patch32: backport-Remove-compare-of-global-array-tagsByName-to-NULL.patch
|
||||
Patch33: backport-Always-close-libelf-handle-1313.patch
|
||||
Patch34: backport-Add-missing-terminator-to-copyTagsFromMainDebug-arra.patch
|
||||
Patch35: backport-Fix-possible-read-beyond-buffer-in-rstrnlenhash.patch
|
||||
Patch36: backport-Make-fdSeek-return-0-on-success-1-on-error.patch
|
||||
Patch37: backport-Fix-logic-error-in-grabArgs.patch
|
||||
Patch38: backport-Use-libelf-for-determining-file-colors.patch
|
||||
Patch21: backport-Fix-regression-on-v3-package-handling-on-database-re.patch
|
||||
Patch22: backport-Fix-a-minor-memory-leak-on-suppressed-inhibition-loc.patch
|
||||
Patch23: backport-Fix-POPT_ARG_STRING-memleaks-in-librpmbuild.patch
|
||||
Patch24: backport-Fix-build-regression-in-commit-307872f71b357a3839fd0.patch
|
||||
Patch25: backport-Fix-isUnorderedReq-for-multiple-qualifiers.patch
|
||||
Patch26: backport-If-fork-fails-in-getOutputFrom-close-opened-unused-p.patch
|
||||
Patch27: backport-Fix-pointer-dereference-before-testing-for-NULL-in-r.patch
|
||||
Patch28: backport-Don-t-look-into-source-package-provides-in-depsolvin.patch
|
||||
Patch29: backport-rpmfiArchiveRead-use-signed-return-value-to-handle-1.patch
|
||||
Patch30: backport-Fix-bump-up-the-limit-of-signature-header-to-64MB.patch
|
||||
Patch31: backport-Remove-compare-of-global-array-tagsByName-to-NULL.patch
|
||||
Patch32: backport-Always-close-libelf-handle-1313.patch
|
||||
Patch33: backport-Add-missing-terminator-to-copyTagsFromMainDebug-arra.patch
|
||||
Patch34: backport-Fix-possible-read-beyond-buffer-in-rstrnlenhash.patch
|
||||
Patch35: backport-Make-fdSeek-return-0-on-success-1-on-error.patch
|
||||
Patch36: backport-Fix-logic-error-in-grabArgs.patch
|
||||
Patch37: backport-Use-libelf-for-determining-file-colors.patch
|
||||
|
||||
BuildRequires: gcc autoconf automake libtool make gawk popt-devel openssl-devel readline-devel libdb-devel
|
||||
Patch38: backport-Add-backend-name-and-path-of-main-database-file-to-d.patch
|
||||
Patch39: backport-Use-paths-from-db_ops-in-the-backends-too-where-poss.patch
|
||||
Patch40: backport-Use-the-new-backend-struct-data-for-backend-configur.patch
|
||||
Patch41: backport-Add-support-for-reading-BDB-without-the-library.patch
|
||||
Patch42: backport-Fix-building-with-no-BerkeleyDB-support.patch
|
||||
Patch43: backport-Implement-a-key-only-rpmdb-index-iterator.patch
|
||||
Patch44: backport-ndb-remove-unused-lzo-compression-code.patch
|
||||
Patch45: backport-ndb-make-ordered-slots-flag-a-boolean.patch
|
||||
Patch46: backport-ndb-drop-unused-number-of-allocated-slots.patch
|
||||
Patch47: backport-ndb-no-longer-free-the-pkgid-hash-all-the-time.patch
|
||||
Patch48: backport-ndb-add-a-verify-method.patch
|
||||
Patch49: backport-ndb-use-the-generation-instead-of-the-current-time-i.patch
|
||||
Patch50: backport-ndb-only-clear-the-dbenv-in-the-rpmdb-if-the-last-re.patch
|
||||
Patch51: backport-ndb-add-a-rpmxdbDelAllBlobs-method.patch
|
||||
Patch52: backport-ndb-implement-index-regeneration-if-the-index-is-out.patch
|
||||
Patch53: backport-Remove-the-experimental-status-from-the-ndb-database.patch
|
||||
Patch54: backport-ndb-fix-ftruncate-return-value-warning.patch
|
||||
Patch55: backport-Permit-ndb-database-queries-on-read-only-media.patch
|
||||
Patch56: backport-ndb-add-a-rpmpkgSalvage-method.patch
|
||||
Patch57: backport-Add-a-salvagedb-option-to-the-rpmdb-tool.patch
|
||||
Patch58: backport-Flush-1998-vintage-dirent.h-compatibility-mess-from-.patch
|
||||
Patch59: backport-ndb-also-copy-the-mapped-pointer-when-keeping-a-slot.patch
|
||||
Patch60: backport-ndb-do-not-map-the-index-databases-read-write-all-th.patch
|
||||
Patch61: backport-ndb-do-not-map-xdb-s-header-read-write-all-the-time.patch
|
||||
Patch62: backport-ndb-unmap-xdb-s-header-when-closing-the-xdb-database.patch
|
||||
Patch63: backport-ndb-make-rpmxdbWriteHeader-a-void-function.patch
|
||||
Patch64: backport-Add-an-index-sync-call-at-the-end-of-a-database-rebu.patch
|
||||
Patch65: backport-Deprecate-Berkeley-DB-database-backend.patch
|
||||
Patch66: backport-Always-open-and-initialize-the-entire-database-at-on.patch
|
||||
Patch67: backport-Stop-on-first-failure-when-trying-to-open-a-database.patch
|
||||
Patch68: backport-Only-attempt-loading-the-keyring-once-the-rpmdb-is-o.patch
|
||||
|
||||
BuildRequires: gcc autoconf automake libtool make gawk popt-devel openssl-devel readline-devel
|
||||
BuildRequires: zlib-devel libzstd-devel xz-devel bzip2-devel libarchive-devel ima-evm-utils-devel
|
||||
BuildRequires: dbus-devel fakechroot elfutils-devel elfutils-libelf-devel ima-evm-utils
|
||||
BuildRequires: lua-devel libcap-devel libacl-devel libselinux-devel file-devel gettext-devel ncurses-devel
|
||||
BuildRequires: system-rpm-config gdb dwz
|
||||
Requires: coreutils popt curl zstd libcap gnupg2 crontabs logrotate libdb-utils %{name}-libs
|
||||
Requires: coreutils popt curl zstd libcap gnupg2 crontabs logrotate %{name}-libs
|
||||
Obsoletes: %{name}-build-libs %{name}-sign-libs %{name}-sign %{name}-cron
|
||||
Provides: %{name}-build-libs %{name}-sign-libs %{name}-sign %{name}-cron
|
||||
Obsoletes: %{name}-plugin-selinux %{name}-plugin-syslog %{name}-plugin-systemd-inhibit %{name}-plugin-ima %{name}-plugin-prioreset
|
||||
@ -130,6 +161,7 @@ Obsoletes: apidocs
|
||||
%autosetup -n %{name}-%{version} -p1
|
||||
|
||||
sed -ie 's:^python test:python2 test:g' tests/rpmtests tests/local.at
|
||||
sed -i -e "/_db_backend/ s/ bdb/ ndb/g" macros.in
|
||||
|
||||
%build
|
||||
CPPFLAGS="$CPPFLAGS -DLUA_COMPAT_APIINTCASTS"
|
||||
@ -157,6 +189,9 @@ done;
|
||||
--with-selinux \
|
||||
--with-cap \
|
||||
--with-acl \
|
||||
--enable-ndb \
|
||||
--enable-bdb-ro \
|
||||
--enable-bdb=no \
|
||||
--with-imaevm \
|
||||
--enable-zstd \
|
||||
--enable-python \
|
||||
@ -190,14 +225,8 @@ mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/rpm
|
||||
mkdir -p $RPM_BUILD_ROOT%{_rpmconfigdir}/macros.d
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/rpm
|
||||
|
||||
for dbi in \
|
||||
Basenames Conflictname Dirnames Group Installtid Name Obsoletename \
|
||||
Packages Providename Requirename Triggername Sha1header Sigmd5 \
|
||||
__db.001 __db.002 __db.003 __db.004 __db.005 __db.006 __db.007 \
|
||||
__db.008 __db.009
|
||||
do
|
||||
touch $RPM_BUILD_ROOT/var/lib/rpm/$dbi
|
||||
done
|
||||
./rpmdb --define "_db_backend ndb" --dbpath=${PWD}/ndb --initdb
|
||||
cp -va ndb/. $RPM_BUILD_ROOT/var/lib/rpm/
|
||||
|
||||
#./rpmdb --dbpath=$RPM_BUILD_ROOT/var/lib/rpm --initdb
|
||||
|
||||
@ -234,7 +263,8 @@ make check || (cat tests/rpmtests.log; exit 0)
|
||||
%config(noreplace) %{_sysconfdir}/logrotate.d/rpm
|
||||
%dir %{_sysconfdir}/rpm
|
||||
%dir /var/lib/rpm
|
||||
%attr(0644, root, root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/lib/rpm/*
|
||||
%attr(0644, root, root) %ghost %config(missingok,noreplace) /var/lib/rpm/*
|
||||
%attr(0644, root, root) %ghost /var/lib/rpm/.*.lock
|
||||
%lang(fr) %{_mandir}/fr/man[18]/*.[18]*
|
||||
%lang(ko) %{_mandir}/ko/man[18]/*.[18]*
|
||||
%lang(ja) %{_mandir}/ja/man[18]/*.[18]*
|
||||
@ -314,7 +344,13 @@ make check || (cat tests/rpmtests.log; exit 0)
|
||||
%{_mandir}/man1/gendiff.1*
|
||||
|
||||
%changelog
|
||||
* Fri Jan 11 2021 Liquor <lirui130@huawei.com> - 4.15.1-19
|
||||
* Tue Jan 12 2021 panxiaohe <panxiaohe@huawei.com> - 4.15.1-20
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:use ndb instead of Berkeley DB, and deprecate Berkeley DB.
|
||||
|
||||
* Mon Jan 11 2021 Liquor <lirui130@huawei.com> - 4.15.1-19
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user