summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-03-31 15:53:17 +1100
committerAndrew Tridgell <tridge@samba.org>2009-03-31 15:53:17 +1100
commit15e6def45d528b10f9ac2ecb917ff13ca6187711 (patch)
treeb085d7bb56cb8fc1293ecaf71108e223b74e703d /source4
parent631e688c821b78d09d77f5940074800525c554aa (diff)
parent79b7ba9b106791958cc42d68b11d9dea2a77f6f3 (diff)
downloadsamba-15e6def45d528b10f9ac2ecb917ff13ca6187711.tar.gz
samba-15e6def45d528b10f9ac2ecb917ff13ca6187711.tar.bz2
samba-15e6def45d528b10f9ac2ecb917ff13ca6187711.zip
Merge branch 'master' into wspp-schema
Diffstat (limited to 'source4')
-rw-r--r--source4/dsdb/samdb/ldb_modules/partition.c63
-rw-r--r--source4/lib/ldb/configure.ac2
-rw-r--r--source4/lib/ldb/external/libtdb.m42
-rw-r--r--source4/lib/ldb/include/ldb_module.h1
-rw-r--r--source4/lib/ldb/ldb.mk2
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c33
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.h1
-rw-r--r--source4/min_versions.m44
8 files changed, 87 insertions, 21 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c
index 71a1b8e942..3231f7ab0f 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 d61b31afd4..b98cc88537 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 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;
};
/*
diff --git a/source4/min_versions.m4 b/source4/min_versions.m4
index 1dd3501b99..0469fb827a 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)