Band-aid for DB_VERSION_MISMATCH errors on glibc updates (#1465809)

This commit is contained in:
Panu Matilainen 2017-08-28 19:39:24 +03:00
parent d2519961ce
commit fefe4f03a3
2 changed files with 102 additions and 1 deletions

View File

@ -0,0 +1,97 @@
From 70a1efa52b2c442308fd1ddfd706770b6515a2c5 Mon Sep 17 00:00:00 2001
Message-Id: <70a1efa52b2c442308fd1ddfd706770b6515a2c5.1503938132.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Mon, 28 Aug 2017 18:56:04 +0300
Subject: [PATCH 1/3] Limit automatic fallback to DB_PRIVATE to read-only
operations
Only permit automatic fallback to the essentially lockless operation
of DB_PRIVATE when read-only database is requested. This isn't exactly
correct, as readers need locks for correct operation just like writers do,
but at least in the readonly case the database wont be damaged.
The exception to the rule is systems which don't support the shared mapping
at all so we don't have much choice. Explicitly configured
I-know-what-I'm-doing DB_PRIVATE is not affected either.
---
lib/backend/db3.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/backend/db3.c b/lib/backend/db3.c
index 26013bfa0..89d14a878 100644
--- a/lib/backend/db3.c
+++ b/lib/backend/db3.c
@@ -407,6 +407,7 @@ static int db_init(rpmdb rdb, const char * dbhome)
int rc, xx;
int retry_open = 2;
int lockfd = -1;
+ int rdonly = ((rdb->db_mode & O_ACCMODE) == O_RDONLY);
struct dbConfig_s * cfg = &rdb->cfg;
/* This is our setup, thou shall not have other setups before us */
uint32_t eflags = (DB_CREATE|DB_INIT_MPOOL|DB_INIT_CDB);
@@ -476,7 +477,7 @@ static int db_init(rpmdb rdb, const char * dbhome)
*/
if (!(eflags & DB_PRIVATE)) {
lockfd = serialize_env(dbhome);
- if (lockfd < 0) {
+ if (lockfd < 0 && rdonly) {
eflags |= DB_PRIVATE;
retry_open--;
rpmlog(RPMLOG_DEBUG, "serialize failed, using private dbenv\n");
@@ -494,7 +495,10 @@ static int db_init(rpmdb rdb, const char * dbhome)
free(fstr);
rc = (dbenv->open)(dbenv, dbhome, eflags, rdb->db_perms);
- if ((rc == EACCES || rc == EROFS) || (rc == EINVAL && errno == rc)) {
+ if (rc == EINVAL && errno == rc) {
+ eflags |= DB_PRIVATE;
+ retry_open--;
+ } else if (rdonly && (rc == EACCES || rc == EROFS)) {
eflags |= DB_PRIVATE;
retry_open--;
} else {
--
2.13.5
From 2822ccbcdf3e898b960fafb23c4d571e26cef0a4 Mon Sep 17 00:00:00 2001
Message-Id: <2822ccbcdf3e898b960fafb23c4d571e26cef0a4.1503938132.git.pmatilai@redhat.com>
In-Reply-To: <70a1efa52b2c442308fd1ddfd706770b6515a2c5.1503938132.git.pmatilai@redhat.com>
References: <70a1efa52b2c442308fd1ddfd706770b6515a2c5.1503938132.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Mon, 28 Aug 2017 19:17:24 +0300
Subject: [PATCH 2/3] Fallback to DB_PRIVATE on readonly DB_VERSION_MISMATCH
too (RhBug:1465809)
All these years BDB has been relying on undefined behavior by storing
POSIX thread objects in its persistent environment files (for the long
story, see RhBug:1394862). As a side-effect of fixing it in BDB,
all sorts of creatures from dark corners are getting dragged into
the daylight: rawhide glibc gets updated a lot and we're getting
DB_VERSION_MISMATCH hits from rpm queries from package scriptlets
(told you so...), other tools not closing their database handles
when they should etc etc. This lets those cases continue "working"
to the extent they always did (ie unreliably) for now.
We should log some diagnostic message in this case, but coming up
with an understandable and reasonably short message for this mess
isn't that easy :)
---
lib/backend/db3.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/backend/db3.c b/lib/backend/db3.c
index 89d14a878..da50dfda4 100644
--- a/lib/backend/db3.c
+++ b/lib/backend/db3.c
@@ -498,7 +498,7 @@ static int db_init(rpmdb rdb, const char * dbhome)
if (rc == EINVAL && errno == rc) {
eflags |= DB_PRIVATE;
retry_open--;
- } else if (rdonly && (rc == EACCES || rc == EROFS)) {
+ } else if (rdonly && (rc == EACCES || rc == EROFS || rc == DB_VERSION_MISMATCH)) {
eflags |= DB_PRIVATE;
retry_open--;
} else {
--
2.13.5

View File

@ -37,7 +37,7 @@
Summary: The RPM package management system
Name: rpm
Version: %{rpmver}
Release: %{?snapver:0.%{snapver}.}7%{?dist}
Release: %{?snapver:0.%{snapver}.}8%{?dist}
Group: System Environment/Base
Url: http://www.rpm.org/
Source0: http://ftp.rpm.org/releases/%{srcdir}/%{name}-%{srcver}.tar.bz2
@ -67,6 +67,7 @@ Patch7: rpm-4.13.90-macro-noquote.patch
# Patches already upstream:
Patch100: rpm-4.13.90-silent-lookup.patch
Patch101: rpm-4.13.90-db-version-mismatch.patch
# These are not yet upstream
Patch906: rpm-4.7.1-geode-i686.patch
@ -633,6 +634,9 @@ make check
%doc doc/librpm/html/*
%changelog
* Mon Aug 28 2017 Panu Matilainen <pmatilai@redhat.com> - 4.13.90-0.git14000.8
- Band-aid for DB_VERSION_MISMATCH errors on glibc updates (#1465809)
* Thu Aug 24 2017 Panu Matilainen <pmatilai@redhat.com> - 4.13.90-0.git14000.7
- Remove ugly kludges from posttrans script, BDB handles this now