From 6688ee80b2d2247825efd82ee212ec926e422250 Mon Sep 17 00:00:00 2001
From: Andrew Tridgell <tridge@samba.org>
Date: Tue, 31 Mar 2009 15:07:54 +1100
Subject: added support for a prepare_commit() op in ldb modules

This op will be used by the partition module to give us good
transaction semantics across the 4 partitions that sam.ldb uses.
---
 source4/lib/ldb/external/libtdb.m4   |  2 +-
 source4/lib/ldb/include/ldb_module.h |  1 +
 source4/lib/ldb/ldb.mk               |  2 +-
 source4/lib/ldb/ldb_tdb/ldb_tdb.c    | 33 +++++++++++++++++++++++++++++++--
 source4/lib/ldb/ldb_tdb/ldb_tdb.h    |  1 +
 5 files changed, 35 insertions(+), 4 deletions(-)

(limited to 'source4/lib')

diff --git a/source4/lib/ldb/external/libtdb.m4 b/source4/lib/ldb/external/libtdb.m4
index 8c2cab702f..cdfc5ea2fb 100644
--- a/source4/lib/ldb/external/libtdb.m4
+++ b/source4/lib/ldb/external/libtdb.m4
@@ -4,4 +4,4 @@ AC_SUBST(TDB_LIBS)
 
 AC_CHECK_HEADER(tdb.h,
    [AC_CHECK_LIB(tdb, tdb_open, [TDB_LIBS="-ltdb"]) ],
-   [PKG_CHECK_MODULES(TDB, tdb >= 1.1.0)])
+   [PKG_CHECK_MODULES(TDB, tdb >= 1.1.4)])
diff --git a/source4/lib/ldb/include/ldb_module.h b/source4/lib/ldb/include/ldb_module.h
index 4e1019184d..e07fd43e27 100644
--- a/source4/lib/ldb/include/ldb_module.h
+++ b/source4/lib/ldb/include/ldb_module.h
@@ -52,6 +52,7 @@ struct ldb_module_ops {
 	int (*request)(struct ldb_module *, struct ldb_request *); /* match any other operation */
 	int (*extended)(struct ldb_module *, struct ldb_request *); /* extended operations */
 	int (*start_transaction)(struct ldb_module *);
+	int (*prepare_commit)(struct ldb_module *);
 	int (*end_transaction)(struct ldb_module *);
 	int (*del_transaction)(struct ldb_module *);
 	int (*sequence_number)(struct ldb_module *, struct ldb_request *);
diff --git a/source4/lib/ldb/ldb.mk b/source4/lib/ldb/ldb.mk
index ff8c1f3baf..0589baf5d4 100644
--- a/source4/lib/ldb/ldb.mk
+++ b/source4/lib/ldb/ldb.mk
@@ -66,7 +66,7 @@ build-python:: ldb.$(SHLIBEXT)
 
 pyldb.o: $(ldbdir)/pyldb.c
 	$(CC) $(PICFLAG) -c $(ldbdir)/pyldb.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
-	
+
 ldb.$(SHLIBEXT): pyldb.o
 	$(SHLD) $(SHLD_FLAGS) -o ldb.$(SHLIBEXT) pyldb.o $(LIB_FLAGS) `$(PYTHON_CONFIG) --ldflags`
 
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 9df62be936..0f84b67afa 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -857,18 +857,46 @@ static int ltdb_start_trans(struct ldb_module *module)
 	return LDB_SUCCESS;
 }
 
-static int ltdb_end_trans(struct ldb_module *module)
+static int ltdb_prepare_commit(struct ldb_module *module)
 {
 	void *data = ldb_module_get_private(module);
 	struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
 
-	ltdb->in_transaction--;
+	if (ltdb->in_transaction != 1) {
+		return LDB_SUCCESS;
+	}
 
 	if (ltdb_index_transaction_commit(module) != 0) {
 		tdb_transaction_cancel(ltdb->tdb);
+		ltdb->in_transaction--;
+		return ltdb_err_map(tdb_error(ltdb->tdb));
+	}
+
+	if (tdb_transaction_prepare_commit(ltdb->tdb) != 0) {
+		ltdb->in_transaction--;
 		return ltdb_err_map(tdb_error(ltdb->tdb));
 	}
 
+	ltdb->prepared_commit = true;
+
+	return LDB_SUCCESS;
+}
+
+static int ltdb_end_trans(struct ldb_module *module)
+{
+	void *data = ldb_module_get_private(module);
+	struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
+
+	if (!ltdb->prepared_commit) {
+		int ret = ltdb_prepare_commit(module);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
+	ltdb->in_transaction--;
+	ltdb->prepared_commit = false;
+
 	if (tdb_transaction_commit(ltdb->tdb) != 0) {
 		return ltdb_err_map(tdb_error(ltdb->tdb));
 	}
@@ -1209,6 +1237,7 @@ static const struct ldb_module_ops ltdb_ops = {
 	.extended          = ltdb_handle_request,
 	.start_transaction = ltdb_start_trans,
 	.end_transaction   = ltdb_end_trans,
+	.prepare_commit    = ltdb_prepare_commit,
 	.del_transaction   = ltdb_del_trans,
 };
 
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
index 5a1c8fee2d..370cd0729b 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -30,6 +30,7 @@ struct ltdb_private {
 
 	bool check_base;
 	struct ltdb_idxptr *idxptr;
+	bool prepared_commit;
 };
 
 /*
-- 
cgit