summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/ldb/common/ldb.c37
-rw-r--r--source4/lib/ldb/common/ldb_modules.c19
-rw-r--r--source4/lib/ldb/include/ldb_module.h1
3 files changed, 51 insertions, 6 deletions
diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c
index 38cc0c880b..dc3032643c 100644
--- a/source4/lib/ldb/common/ldb.c
+++ b/source4/lib/ldb/common/ldb.c
@@ -282,15 +282,20 @@ void ldb_reset_err_string(struct ldb_context *ldb)
}
}
-#define FIRST_OP(ldb, op) do { \
+#define FIRST_OP_NOERR(ldb, op) do { \
module = ldb->modules; \
while (module && module->ops->op == NULL) module = module->next; \
- if (module == NULL) { \
+} while (0)
+
+#define FIRST_OP(ldb, op) do { \
+ FIRST_OP_NOERR(ldb, op); \
+ if (module == NULL) { \
ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \
return LDB_ERR_OPERATIONS_ERROR; \
} \
} while (0)
+
/*
start a transaction
*/
@@ -337,6 +342,7 @@ int ldb_transaction_commit(struct ldb_context *ldb)
struct ldb_module *module;
int status;
+
ldb->transaction_active--;
ldb_debug(ldb, LDB_DEBUG_TRACE,
@@ -355,10 +361,30 @@ int ldb_transaction_commit(struct ldb_context *ldb)
return LDB_ERR_OPERATIONS_ERROR;
}
- FIRST_OP(ldb, end_transaction);
+ /* call prepare transaction if available */
+ FIRST_OP_NOERR(ldb, prepare_commit);
+ if (module != NULL) {
+ status = module->ops->prepare_commit(module);
+ if (status != LDB_SUCCESS) {
+ /* if a module fails the prepare then we need
+ to call the end transaction for everyone */
+ /* preserve err string */
+ FIRST_OP(ldb, end_transaction);
+ module->ops->end_transaction(module);
+ if (ldb->err_string == NULL) {
+ /* no error string was setup by the backend */
+ ldb_asprintf_errstring(ldb,
+ "ldb transaction prepare commit: %s (%d)",
+ ldb_strerror(status),
+ status);
+ }
+ return status;
+ }
+ }
ldb_reset_err_string(ldb);
+ FIRST_OP(ldb, end_transaction);
status = module->ops->end_transaction(module);
if (status != LDB_SUCCESS) {
if (ldb->err_string == NULL) {
@@ -368,6 +394,9 @@ int ldb_transaction_commit(struct ldb_context *ldb)
ldb_strerror(status),
status);
}
+ /* cancel the transaction */
+ FIRST_OP(ldb, del_transaction);
+ module->ops->del_transaction(module);
}
return status;
}
@@ -393,7 +422,7 @@ int ldb_transaction_cancel(struct ldb_context *ldb)
if (ldb->transaction_active < 0) {
ldb_debug(ldb, LDB_DEBUG_FATAL,
- "commit called but no ldb transactions are active!");
+ "cancel called but no ldb transactions are active!");
ldb->transaction_active = 0;
return LDB_ERR_OPERATIONS_ERROR;
}
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c
index 05dffd005a..b792daa913 100644
--- a/source4/lib/ldb/common/ldb_modules.c
+++ b/source4/lib/ldb/common/ldb_modules.c
@@ -472,10 +472,14 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
which makes writing a module simpler, and makes it more likely to keep working
when ldb is extended
*/
-#define FIND_OP(module, op) do { \
- struct ldb_context *ldb = module->ldb; \
+#define FIND_OP_NOERR(module, op) do { \
module = module->next; \
while (module && module->ops->op == NULL) module = module->next; \
+} while (0)
+
+#define FIND_OP(module, op) do { \
+ struct ldb_context *ldb = module->ldb; \
+ FIND_OP_NOERR(module, op); \
if (module == NULL) { \
ldb_asprintf_errstring(ldb, "Unable to find backend operation for " #op ); \
return LDB_ERR_OPERATIONS_ERROR; \
@@ -595,6 +599,17 @@ int ldb_next_end_trans(struct ldb_module *module)
return module->ops->end_transaction(module);
}
+int ldb_next_prepare_commit(struct ldb_module *module)
+{
+ FIND_OP_NOERR(module, prepare_commit);
+ if (module == NULL) {
+ /* we are allowed to have no prepare commit in
+ backends */
+ return LDB_SUCCESS;
+ }
+ return module->ops->prepare_commit(module);
+}
+
int ldb_next_del_trans(struct ldb_module *module)
{
FIND_OP(module, del_transaction);
diff --git a/source4/lib/ldb/include/ldb_module.h b/source4/lib/ldb/include/ldb_module.h
index cc24d8a6c0..1d6329ca2f 100644
--- a/source4/lib/ldb/include/ldb_module.h
+++ b/source4/lib/ldb/include/ldb_module.h
@@ -127,6 +127,7 @@ int ldb_next_request(struct ldb_module *module, struct ldb_request *request);
int ldb_next_start_trans(struct ldb_module *module);
int ldb_next_end_trans(struct ldb_module *module);
int ldb_next_del_trans(struct ldb_module *module);
+int ldb_next_prepare_commit(struct ldb_module *module);
int ldb_next_init(struct ldb_module *module);
void ldb_set_errstring(struct ldb_context *ldb, const char *err_string);