}
/* start a transaction */
-static int partition_start_trans(struct ldb_module *module)
+int partition_start_trans(struct ldb_module *module)
{
int i;
int ret;
}
/* prepare for a commit */
-static int partition_prepare_commit(struct ldb_module *module)
+int partition_prepare_commit(struct ldb_module *module)
{
unsigned int i;
struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module),
/* end a transaction */
-static int partition_end_trans(struct ldb_module *module)
+int partition_end_trans(struct ldb_module *module)
{
int ret, ret2;
unsigned int i;
}
/* delete a transaction */
-static int partition_del_trans(struct ldb_module *module)
+int partition_del_trans(struct ldb_module *module)
{
int ret, final_ret = LDB_SUCCESS;
unsigned int i;
}
/* lock all the backends */
-static int partition_read_lock(struct ldb_module *module)
+int partition_read_lock(struct ldb_module *module)
{
int i;
int ret;
}
/* unlock all the backends */
-static int partition_read_unlock(struct ldb_module *module)
+int partition_read_unlock(struct ldb_module *module)
{
int i;
int ret = LDB_SUCCESS;
ret = partition_metadata_open(module, false);
if (ret == LDB_SUCCESS) {
- goto end;
+ /* Great, we got the DB open */
+ return LDB_SUCCESS;
}
/* metadata.tdb does not exist, create it */
"Migrating partition metadata: "
"create of metadata.tdb gave: %s\n",
ldb_errstring(ldb_module_get_ctx(module)));
- talloc_free(data->metadata);
- data->metadata = NULL;
- goto end;
+ TALLOC_FREE(data->metadata);
+ return ret;
+ }
+
+ /*
+ * We need to fill in the sequence number from the DB, so we
+ * need to get a lock over all the databases. We only read
+ * from the main partitions, but write to metadata so to avoid
+ * lock ordering we just get a transaction over the lot.
+ */
+ ret = partition_start_trans(module);
+ if (ret != LDB_SUCCESS) {
+ TALLOC_FREE(data->metadata);
+ return ret;
}
ret = partition_metadata_set_sequence_number(module);
if (ret != LDB_SUCCESS) {
- talloc_free(data->metadata);
- data->metadata = NULL;
+ TALLOC_FREE(data->metadata);
+ partition_del_trans(module);
+ return ret;
+ }
+
+ ret = partition_prepare_commit(module);
+ if (ret != LDB_SUCCESS) {
+ TALLOC_FREE(data->metadata);
+ partition_del_trans(module);
+ return ret;
+ }
+
+ ret = partition_end_trans(module);
+ if (ret != LDB_SUCCESS) {
+ /* Nothing much we can do */
+ TALLOC_FREE(data->metadata);
}
-end:
return ret;
}
*/
int partition_metadata_sequence_number(struct ldb_module *module, uint64_t *value)
{
- return partition_metadata_get_uint64(module,
- LDB_METADATA_SEQ_NUM,
- value,
- 0);
+
+ /* We have to lock all the databases as otherwise we can
+ * return a sequence number that is higher than the DB values
+ * that we can see, as those transactions close after the
+ * metadata.tdb transaction closes */
+ int ret = partition_read_lock(module);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ ret = partition_metadata_get_uint64(module,
+ LDB_METADATA_SEQ_NUM,
+ value,
+ 0);
+ if (ret == LDB_SUCCESS) {
+ ret = partition_read_unlock(module);
+ } else {
+ /* Don't overwrite the error code */
+ partition_read_unlock(module);
+ }
+ return ret;
+
}