[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-786-g79b7ba9

Andrew Tridgell tridge at samba.org
Tue Mar 31 04:16:57 GMT 2009


The branch, master has been updated
       via  79b7ba9b106791958cc42d68b11d9dea2a77f6f3 (commit)
       via  16a1903c546ac8e5ebc2a1952ce37f8ad819379b (commit)
       via  6688ee80b2d2247825efd82ee212ec926e422250 (commit)
       via  7a5e6940cf9578f865a559102c76f7c64b0ff47d (commit)
      from  046b7a35bed76f5d92a1e5f658478e25ffadf9ac (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 79b7ba9b106791958cc42d68b11d9dea2a77f6f3
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Mar 31 15:14:09 2009 +1100

    change ldb version number (as ldb_module structure has changed)

commit 16a1903c546ac8e5ebc2a1952ce37f8ad819379b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Mar 31 15:08:36 2009 +1100

    use the prepare_commit op in the partition code
    
    This makes multi-partition ldb's much safer

commit 6688ee80b2d2247825efd82ee212ec926e422250
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Mar 31 15:07:54 2009 +1100

    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.

commit 7a5e6940cf9578f865a559102c76f7c64b0ff47d
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Mar 31 15:06:23 2009 +1100

    up the version to 1.1.4 with the addition of
    tdb_transaction_prepare_commit()

-----------------------------------------------------------------------

Summary of changes:
 lib/tdb/configure.ac                       |    2 +-
 source4/dsdb/samdb/ldb_modules/partition.c |   63 +++++++++++++++++++++------
 source4/lib/ldb/configure.ac               |    2 +-
 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 +
 source4/min_versions.m4                    |    4 +-
 9 files changed, 88 insertions(+), 22 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/tdb/configure.ac b/lib/tdb/configure.ac
index 2feaa6f..c42a970 100644
--- a/lib/tdb/configure.ac
+++ b/lib/tdb/configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ(2.50)
 AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""])
 AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""])
 AC_DEFUN([SMB_ENABLE], [echo -n ""])
-AC_INIT(tdb, 1.1.3)
+AC_INIT(tdb, 1.1.4)
 AC_CONFIG_SRCDIR([common/tdb.c])
 AC_CONFIG_HEADER(include/config.h)
 AC_LIBREPLACE_ALL_CHECKS
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c
index 71a1b8e..3231f7a 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.c
+++ b/source4/dsdb/samdb/ldb_modules/partition.c
@@ -73,11 +73,14 @@ static struct partition_context *partition_init_ctx(struct ldb_module *module, s
 	return ac;
 }
 
-#define PARTITION_FIND_OP(module, op) do { \
-	struct ldb_context *ldbctx = module->ldb; \
+#define PARTITION_FIND_OP_NOERROR(module, op) do { \
         while (module && module->ops->op == NULL) module = module->next; \
+} while (0)
+
+#define PARTITION_FIND_OP(module, op) do { \
+	PARTITION_FIND_OP_NOERROR(module, op); \
         if (module == NULL) { \
-                ldb_asprintf_errstring(ldbctx, \
+                ldb_asprintf_errstring(module->ldb, \
 			"Unable to find backend operation for " #op ); \
                 return LDB_ERR_OPERATIONS_ERROR; \
         } \
@@ -654,7 +657,7 @@ static int partition_start_trans(struct ldb_module *module)
 /* end a transaction */
 static int partition_end_trans(struct ldb_module *module)
 {
-	int i, ret;
+	int i, ret, final_ret;
 	struct partition_private_data *data = talloc_get_type(module->private_data, 
 							      struct partition_private_data);
 	ret = ldb_next_end_trans(module);
@@ -662,28 +665,60 @@ static int partition_end_trans(struct ldb_module *module)
 		return ret;
 	}
 
+	/* if the backend has a prepare_commit op then use that, to ensure
+	   that all partitions are committed safely together */
+	for (i=0; data && data->partitions && data->partitions[i]; i++) {
+		struct ldb_module *next_end = data->partitions[i]->module;
+		struct ldb_module *next_prepare = data->partitions[i]->module;
+		struct ldb_module *next_del = data->partitions[i]->module;
+
+		PARTITION_FIND_OP_NOERROR(next_prepare, prepare_commit);
+		if (next_prepare == NULL) {
+			continue;
+		}
+
+		PARTITION_FIND_OP(next_end, end_transaction);
+		PARTITION_FIND_OP(next_del, del_transaction);
+
+		if (next_end != next_prepare || next_del != next_end) {
+			ldb_asprintf_errstring(module->ldb, "ERROR: Mismatch between prepare and commit ops in ldb module");
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+		
+		ret = next_prepare->ops->prepare_commit(next_prepare);
+		if (ret != LDB_SUCCESS) {
+			/* if one fails, cancel all but this one */
+			int j;
+			for (j=0; data->partitions[j]; j++) {
+				if (j == i) continue;
+				next_del = data->partitions[j]->module;
+				PARTITION_FIND_OP(next_del, del_transaction);
+				next_del->ops->del_transaction(next_del);
+			}
+			ldb_next_del_trans(module);
+			return ret;
+		}
+	}
+
 	/* Look at base DN */
 	/* Figure out which partition it is under */
 	/* Skip the lot if 'data' isn't here yet (initialistion) */
+	final_ret = LDB_SUCCESS;
+
 	for (i=0; data && data->partitions && data->partitions[i]; i++) {
 		struct ldb_module *next = data->partitions[i]->module;
 		PARTITION_FIND_OP(next, end_transaction);
 
 		ret = next->ops->end_transaction(next);
 		if (ret != LDB_SUCCESS) {
-			/* Back it out, if it fails on one */
-			for (i--; i >= 0; i--) {
-				next = data->partitions[i]->module;
-				PARTITION_FIND_OP(next, del_transaction);
-
-				next->ops->del_transaction(next);
-			}
-			ldb_next_del_trans(module);
-			return ret;
+			/* this should only be happening if we had a serious 
+			   OS or hardware error */
+			ldb_asprintf_errstring(module->ldb, "ERROR: partition commit error");
+			final_ret = ret;
 		}
 	}
 
-	return LDB_SUCCESS;
+	return final_ret;
 }
 
 /* delete a transaction */
diff --git a/source4/lib/ldb/configure.ac b/source4/lib/ldb/configure.ac
index d61b31a..b98cc88 100644
--- a/source4/lib/ldb/configure.ac
+++ b/source4/lib/ldb/configure.ac
@@ -11,7 +11,7 @@ AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""])
 AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""])
 AC_DEFUN([SMB_EXT_LIB], [echo -n ""])
 AC_DEFUN([SMB_ENABLE], [echo -n ""])
-AC_INIT(ldb, 0.9.3)
+AC_INIT(ldb, 0.9.4)
 AC_CONFIG_SRCDIR([common/ldb.c])
 
 AC_LIBREPLACE_ALL_CHECKS
diff --git a/source4/lib/ldb/external/libtdb.m4 b/source4/lib/ldb/external/libtdb.m4
index 8c2cab7..cdfc5ea 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 4e10191..e07fd43 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 ff8c1f3..0589baf 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 9df62be..0f84b67 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 5a1c8fe..370cd07 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;
 };
 
 /*
diff --git a/source4/min_versions.m4 b/source4/min_versions.m4
index 1dd3501..0469fb8 100644
--- a/source4/min_versions.m4
+++ b/source4/min_versions.m4
@@ -1,6 +1,6 @@
 # Minimum and exact required versions for various libraries 
 # if we use the ones installed in the system.
-define(TDB_MIN_VERSION,1.1.3)
+define(TDB_MIN_VERSION,1.1.4)
 define(TALLOC_MIN_VERSION,1.3.0)
-define(LDB_REQUIRED_VERSION,0.9.3)
+define(LDB_REQUIRED_VERSION,0.9.4)
 define(TEVENT_REQUIRED_VERSION,0.9.5)


-- 
Samba Shared Repository


More information about the samba-cvs mailing list