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