[Date Prev][Date Next] [Chronological] [Thread] [Top]

two phase commit for cache failure (ITS#1575)



Full_Name: Jong Hyuk Choi
Version: HEAD as of Jan 31
OS: Redhat 7.1
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (198.81.209.17)


A patch for a better interaction of caches and transactions.
If cache add or update fails after txn_commit, 
there is no way of aborting the transaction in the current HEAD.
The patch first prepares the transaction commit by txn_prepare,
complete the cache add or update, and if they succeed, do txn_commit.

The following is the diff :
=========================================================================
diff -Naur ldap-head-Jan31/servers/slapd/back-bdb/add.c
ldap-head-Jan31new/servers/slapd/back-bdb/add.c
--- ldap-head-Jan31/servers/slapd/back-bdb/add.c	Tue Jan 29 03:53:47 2002
+++ ldap-head-Jan31new/servers/slapd/back-bdb/add.c	Fri Feb  1 21:34:24 2002
@@ -13,6 +13,8 @@
 #include "back-bdb.h"
 #include "external.h"
 
+static char bdb_gid[DB_XIDDATASIZE];
+
 int
 bdb_add(
 	BackendDB	*be,
@@ -351,40 +353,51 @@
 	}
 
 	if( op->o_noop ) {
-		rc = txn_abort( ltid );
-	} else {
-		rc = txn_commit( ltid, 0 );
+		if ((rc=txn_abort( ltid )) != 0)
+			text = "txn_abort (no-op) failed";
+		else
+			rc = LDAP_SUCCESS;
+	}
+	else {
+#if DB_VERSION_MAJOR < 4
+		if ((rc=txn_prepare( ltid, bdb_gid )) != 0)
+#else
+		if ((rc=ltid->prepare( ltid, bdb_gid )) != 0)
+#endif
+			text = "txn_prepare failed";
+		else {
+			if (bdb_cache_add_entry_rw(&bdb->bi_cache,
+						e, CACHE_WRITE_LOCK) != 0) {
+				if ((rc=txn_abort ( ltid )) != 0)
+					text = "cache add & txn_abort failed";
+				else {
+					rc = LDAP_OTHER;
+					text = "cache add failed";
+				}
+			}
+			else {
+				if ((rc=txn_commit ( ltid, 0 )) != 0)
+					text = "txn_commit failed";
+				else
+					rc = LDAP_SUCCESS;
+			}
+		}
 	}
+
 	ltid = NULL;
 	op->o_private = NULL;
 
-	if( rc != 0 ) {
-		Debug( LDAP_DEBUG_TRACE,
-			"bdb_add: txn_%s failed: %s (%d)\n",
-			op->o_noop ? "abort (no-op)" : "commit",
-			db_strerror(rc), rc );
-		rc = LDAP_OTHER;
-		text = "commit failed";
-
-	} else {
-		/* add the entry to the entry cache */
-		/* we should add to cache only upon free of txn-abort */
-		if (!op->o_noop &&
-			bdb_cache_add_entry_rw(&bdb->bi_cache, e, CACHE_WRITE_LOCK) != 0)
-		{
-			text = "cache add failed";
-			goto return_results;
-		}
- 
-		Debug( LDAP_DEBUG_TRACE,
-			"bdb_add: added%s id=%08lx dn=\"%s\"\n",
-			op->o_noop ? " (no-op)" : "",
-			e->e_id, e->e_dn );
-		rc = LDAP_SUCCESS;
+	if (rc == LDAP_SUCCESS) {
+		Debug(LDAP_DEBUG_TRACE, "bdb_add: added%s id=%08lx dn=\"%s\"\n",
+			op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );
 		text = NULL;
+		bdb_cache_entry_commit( e );
+	}
+	else {
+		Debug( LDAP_DEBUG_TRACE, "bdb_add: %s : %s (%d)\n",
+			text, db_strerror(rc), rc );
+		rc = LDAP_OTHER;
 	}
-
-	bdb_cache_entry_commit( e );
 
 return_results:
 	send_ldap_result( conn, op, rc,
diff -Naur ldap-head-Jan31/servers/slapd/back-bdb/modrdn.c
ldap-head-Jan31new/servers/slapd/back-bdb/modrdn.c
--- ldap-head-Jan31/servers/slapd/back-bdb/modrdn.c	Tue Jan 29 03:53:48 2002
+++ ldap-head-Jan31new/servers/slapd/back-bdb/modrdn.c	Fri Feb  1 21:34:33 2002
@@ -13,6 +13,8 @@
 #include "back-bdb.h"
 #include "external.h"
 
+static char bdb_gid[DB_XIDDATASIZE];
+
 int
 bdb_modrdn(
     Backend	*be,
@@ -623,30 +625,50 @@
 	}
 
 	if( op->o_noop ) {
-		rc = txn_abort( ltid );
-	} else {
-		rc = txn_commit( ltid, 0 );
-	}
+		if ((rc=txn_abort( ltid )) != 0)
+			text = "txn_abort (no-op) failed";
+		else
+			rc = LDAP_SUCCESS;
+	}
+	else {
+#if DB_VERSION_MAJOR < 4
+                if ((rc=txn_prepare( ltid, bdb_gid )) != 0)
+#else
+		if ((rc=ltid->prepare( ltid, bdb_gid )) != 0)
+#endif
+			text = "txn_prepare failed";
+		else {
+			if (bdb_cache_update_entry(&bdb->bi_cache, e) == -1) {
+				if ((rc=txn_abort ( ltid )) != 0)
+					text ="cache update & txn_abort failed";
+				else {
+					rc = LDAP_OTHER;
+					text = "cache update failed";
+				}
+			}
+			else {
+				if ((rc=txn_commit ( ltid, 0 )) != 0)
+					text = "txn_commit failed";
+				else
+					rc = LDAP_SUCCESS;
+			}
+		}
+        }
+ 
 	ltid = NULL;
 	op->o_private = NULL;
-
-	if( rc != 0 ) {
-		Debug( LDAP_DEBUG_TRACE,
-			"bdb_modrdn: txn_%s failed: %s (%d)\n",
-			op->o_noop ? "abort (no-op)" : "commit",
-			db_strerror(rc), rc );
-		rc = LDAP_OTHER;
-		text = "commit failed";
-
-	} else {
-		(void) bdb_cache_update_entry(&bdb->bi_cache, e);
-		Debug( LDAP_DEBUG_TRACE,
-			"bdb_modrdn: added%s id=%08lx dn=\"%s\"\n",
-			op->o_noop ? " (no-op)" : "",
-			e->e_id, e->e_dn );
-		rc = LDAP_SUCCESS;
+ 
+	if (rc == LDAP_SUCCESS) {
+		Debug(LDAP_DEBUG_TRACE,
+			"bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n",
+			op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );
 		text = NULL;
 		bdb_cache_entry_commit( e );
+	}
+	else {
+		Debug( LDAP_DEBUG_TRACE, "bdb_add: %s : %s (%d)\n",
+			text, db_strerror(rc), rc );
+		rc = LDAP_OTHER;
 	}
 
 return_results: