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

