teknoraver / rpms / rpm

Forked from rpms/rpm 4 months ago
Clone

Blame rpm-4.11.x-cursor-failchk.patch

Panu Matilainen e3501f
commit 452553111b9929074bcbb77a49c041582daae0e8
Panu Matilainen e3501f
Author: Panu Matilainen <pmatilai@redhat.com>
Panu Matilainen e3501f
Date:   Tue Feb 5 10:11:19 2013 +0200
Panu Matilainen e3501f
Panu Matilainen e3501f
    Check for stale db locks when opening write-cursors
Panu Matilainen e3501f
    
Panu Matilainen e3501f
    - During long-running transactions its entirely possible for some
Panu Matilainen e3501f
      other player to come and go leaving stale locks behind and cause
Panu Matilainen e3501f
      the transaction to get stuck until the cavalry comes along in the
Panu Matilainen e3501f
      form of somebody else opening the rpmdb, clearing the blockage.
Panu Matilainen e3501f
    - Presumably dbenv->failchk() is not entirely free of cost so we only
Panu Matilainen e3501f
      do this for writes which are way more critical and also more prone to
Panu Matilainen e3501f
      getting stuck.
Panu Matilainen e3501f
    - dbenv->failchk() could return DB_RUNRECOVER in which case we should
Panu Matilainen e3501f
      abort everything but we lack a mechanism to do it... just add
Panu Matilainen e3501f
      a reminder comment for now.
Panu Matilainen e3501f
Panu Matilainen e3501f
diff --git a/lib/backend/db3.c b/lib/backend/db3.c
Panu Matilainen e3501f
index 656486b..de8071b 100644
Panu Matilainen e3501f
--- a/lib/backend/db3.c
Panu Matilainen e3501f
+++ b/lib/backend/db3.c
Panu Matilainen e3501f
@@ -248,7 +248,7 @@ dbiCursor dbiCursorInit(dbiIndex dbi, unsigned int flags)
Panu Matilainen e3501f
 	DB * db = dbi->dbi_db;
Panu Matilainen e3501f
 	DBC * cursor;
Panu Matilainen e3501f
 	int cflags;
Panu Matilainen e3501f
-	int rc;
Panu Matilainen e3501f
+	int rc = 0;
Panu Matilainen e3501f
 	uint32_t eflags = db_envflags(db);
Panu Matilainen e3501f
 	
Panu Matilainen e3501f
        /* DB_WRITECURSOR requires CDB and writable db */
Panu Matilainen e3501f
@@ -259,8 +259,23 @@ dbiCursor dbiCursorInit(dbiIndex dbi, unsigned int flags)
Panu Matilainen e3501f
 	} else
Panu Matilainen e3501f
 	    cflags = 0;
Panu Matilainen e3501f
 
Panu Matilainen e3501f
-	rc = db->cursor(db, NULL, &cursor, cflags);
Panu Matilainen e3501f
-	rc = cvtdberr(dbi, "db->cursor", rc, _debug);
Panu Matilainen e3501f
+	/*
Panu Matilainen e3501f
+	 * Check for stale locks which could block writes "forever".
Panu Matilainen e3501f
+	 * XXX: Should we also do this on reads? Reads are less likely
Panu Matilainen e3501f
+	 *      to get blocked so it seems excessive...
Panu Matilainen e3501f
+	 * XXX: On DB_RUNRECOVER, we should abort everything. Now
Panu Matilainen e3501f
+	 *      we'll just fail to open a cursor again and again and again.
Panu Matilainen e3501f
+	 */
Panu Matilainen e3501f
+	if (cflags & DB_WRITECURSOR) {
Panu Matilainen e3501f
+	    DB_ENV *dbenv = db->get_env(db);
Panu Matilainen e3501f
+	    rc = dbenv->failchk(dbenv, 0);
Panu Matilainen e3501f
+	    rc = cvtdberr(dbi, "dbenv->failchk", rc, _debug);
Panu Matilainen e3501f
+	}
Panu Matilainen e3501f
+
Panu Matilainen e3501f
+	if (rc == 0) {
Panu Matilainen e3501f
+	    rc = db->cursor(db, NULL, &cursor, cflags);
Panu Matilainen e3501f
+	    rc = cvtdberr(dbi, "db->cursor", rc, _debug);
Panu Matilainen e3501f
+	}
Panu Matilainen e3501f
 
Panu Matilainen e3501f
 	if (rc == 0) {
Panu Matilainen e3501f
 	    dbc = xcalloc(1, sizeof(*dbc));