s4-dsdb: ensure that new partitions inherit any transaction
authorAndrew Tridgell <tridge@samba.org>
Fri, 23 Oct 2009 11:46:09 +0000 (22:46 +1100)
committerAndrew Tridgell <tridge@samba.org>
Sun, 25 Oct 2009 02:15:18 +0000 (13:15 +1100)
source4/dsdb/samdb/ldb_modules/partition.c
source4/dsdb/samdb/ldb_modules/partition.h
source4/dsdb/samdb/ldb_modules/partition_init.c

index 779b8b5a35b2737756fe855fc2d2ce1295de8a25..64015ed7b16e0f7d22981557d3fa4f233a91c50f 100644 (file)
@@ -690,6 +690,9 @@ static int partition_start_trans(struct ldb_module *module)
                        return ret;
                }
        }
+
+       data->in_transaction++;
+
        return LDB_SUCCESS;
 }
 
@@ -737,6 +740,12 @@ static int partition_end_trans(struct ldb_module *module)
                }
        }
 
+       if (data->in_transaction == 0) {
+               DEBUG(0,("partition end transaction mismatch\n"));
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       data->in_transaction--;
+
        return ldb_next_end_trans(module);
 }
 
@@ -756,6 +765,12 @@ static int partition_del_trans(struct ldb_module *module)
                }
        }       
 
+       if (data->in_transaction == 0) {
+               DEBUG(0,("partition del transaction mismatch\n"));
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       data->in_transaction--;
+
        ret = ldb_next_del_trans(module);
        if (ret != LDB_SUCCESS) {
                final_ret = ret;
index 3572f17109dd7d60b556f25e41d3412d3054878c..dda0b865156616dd2e5449492e814c718429efe8 100644 (file)
@@ -45,6 +45,7 @@ struct partition_private_data {
        const char *ldapBackend;
 
        uint64_t metadata_seq;
+       uint32_t in_transaction;
 };
 
 #define PARTITION_FIND_OP_NOERROR(module, op) do { \
index 28eab9b2eece561324819ab05c4d5623cff8d44b..5967bc81593884a2da3029aed8ea34e9b9960d02 100644 (file)
@@ -282,6 +282,16 @@ static int new_partition_from_dn(struct ldb_context *ldb, struct partition_priva
 
        talloc_steal((*partition), (*partition)->module);
 
+       /* if we were in a transaction then we need to start a
+          transaction on this new partition, otherwise we'll get a
+          transaction mismatch when we end the transaction */
+       if (data->in_transaction) {
+               struct ldb_module *next = (*partition)->module;
+               PARTITION_FIND_OP(next, start_transaction);
+
+               ret = next->ops->start_transaction(next);
+       }
+
        return ret;
 }
 
@@ -698,17 +708,6 @@ int partition_create(struct ldb_module *module, struct ldb_request *req)
                if (ret != LDB_SUCCESS) {
                        return ret;
                }
-               
-               /* Start a transaction on the DB (as it won't be in one being brand new) */
-               {
-                       struct ldb_module *next = partition->module;
-                       PARTITION_FIND_OP(next, start_transaction);
-                       
-                       ret = next->ops->start_transaction(next);
-                       if (ret != LDB_SUCCESS) {
-                               return ret;
-                       }
-               }
        }
        
        ret = new_partition_set_replicated_metadata(ldb, module, last_req, data, partition);