From 128c67b7f1b5e682f346aa2448ec107ab757f1c7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 Nov 2012 14:15:25 +0100 Subject: [PATCH 01/16] dbwrap: Use dbwrap_parse_record in dbwrap_fetch_uint32_bystring --- lib/dbwrap/dbwrap_util.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/lib/dbwrap/dbwrap_util.c b/lib/dbwrap/dbwrap_util.c index d0a34cc..4185fff 100644 --- a/lib/dbwrap/dbwrap_util.c +++ b/lib/dbwrap/dbwrap_util.c @@ -97,32 +97,46 @@ NTSTATUS dbwrap_store_int32_bystring(struct db_context *db, const char *keystr, return status; } +struct dbwrap_fetch_uint32_state { + NTSTATUS status; + uint32_t result; +}; + +static void dbwrap_fetch_uint32_parser(TDB_DATA key, TDB_DATA data, + void *private_data) +{ + struct dbwrap_fetch_uint32_state *state = + (struct dbwrap_fetch_uint32_state *)private_data; + + if (data.dsize != sizeof(state->result)) { + state->status = NT_STATUS_INTERNAL_DB_CORRUPTION; + return; + } + state->result = IVAL(data.dptr, 0); + state->status = NT_STATUS_OK; +} + NTSTATUS dbwrap_fetch_uint32_bystring(struct db_context *db, const char *keystr, uint32_t *val) { - TDB_DATA dbuf; + struct dbwrap_fetch_uint32_state state; NTSTATUS status; if (val == NULL) { return NT_STATUS_INVALID_PARAMETER; } - status = dbwrap_fetch_bystring(db, talloc_tos(), keystr, &dbuf); + state.status = NT_STATUS_INTERNAL_ERROR; + + status = dbwrap_parse_record(db, string_term_tdb_data(keystr), + dbwrap_fetch_uint32_parser, &state); if (!NT_STATUS_IS_OK(status)) { return status; } - - if ((dbuf.dptr == NULL) || (dbuf.dsize == 0)) { - return NT_STATUS_NOT_FOUND; - } - if (dbuf.dsize != sizeof(uint32_t)) { - TALLOC_FREE(dbuf.dptr); - return NT_STATUS_UNSUCCESSFUL; + if (NT_STATUS_IS_OK(state.status)) { + *val = state.result; } - - *val = IVAL(dbuf.dptr, 0); - TALLOC_FREE(dbuf.dptr); - return NT_STATUS_OK; + return state.status; } NTSTATUS dbwrap_store_uint32_bystring(struct db_context *db, -- 1.7.9.5 From f1112098b2f896dd5dbfd73d7cd8c826e467e02c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 7 Nov 2012 21:24:27 +0100 Subject: [PATCH 02/16] s3: test dbwrap_ctdb --- source3/Makefile.in | 1 + source3/torture/proto.h | 1 + source3/torture/test_dbwrap_ctdb.c | 122 ++++++++++++++++++++++++++++++++++++ source3/torture/torture.c | 1 + source3/wscript_build | 1 + 5 files changed, 126 insertions(+) create mode 100644 source3/torture/test_dbwrap_ctdb.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 990217c..40bdd8a 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1268,6 +1268,7 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta torture/test_notify.o \ torture/test_dbwrap_watch.o \ torture/test_idmap_tdb_common.o \ + torture/test_dbwrap_ctdb.o \ torture/t_strappend.o SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) $(TLDAP_OBJ) \ diff --git a/source3/torture/proto.h b/source3/torture/proto.h index 0c6fc70..4f4c9e2 100644 --- a/source3/torture/proto.h +++ b/source3/torture/proto.h @@ -110,5 +110,6 @@ bool run_notify_bench2(int dummy); bool run_notify_bench3(int dummy); bool run_dbwrap_watch1(int dummy); bool run_idmap_tdb_common_test(int dummy); +bool run_local_dbwrap_ctdb(int dummy); #endif /* __TORTURE_H__ */ diff --git a/source3/torture/test_dbwrap_ctdb.c b/source3/torture/test_dbwrap_ctdb.c new file mode 100644 index 0000000..c45c3f6 --- /dev/null +++ b/source3/torture/test_dbwrap_ctdb.c @@ -0,0 +1,122 @@ +/* + * Unix SMB/CIFS implementation. + * Test dbwrap_ctdb API + * Copyright (C) Volker Lendecke 2012 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "includes.h" +#include "torture/proto.h" +#include "system/filesys.h" +#include "lib/dbwrap/dbwrap.h" +#include "lib/dbwrap/dbwrap_ctdb.h" + +bool run_local_dbwrap_ctdb(int dummy) +{ + struct db_context *db; + int res; + bool ret = false; + NTSTATUS status; + uint32_t val; + + db = db_open_ctdb(talloc_tos(), "torture.tdb", 0, TDB_DEFAULT, + O_RDWR, 0755, DBWRAP_LOCK_ORDER_1); + if (db == NULL) { + perror("db_open_ctdb failed"); + goto fail; + } + + res = dbwrap_transaction_start(db); + if (res != 0) { + fprintf(stderr, "dbwrap_transaction_start failed"); + goto fail; + } + res = dbwrap_transaction_cancel(db); + if (res != 0) { + fprintf(stderr, "dbwrap_transaction_cancel failed"); + goto fail; + } + + res = dbwrap_transaction_start(db); + if (res != 0) { + fprintf(stderr, "dbwrap_transaction_start failed"); + goto fail; + } + + status = dbwrap_store_uint32_bystring(db, "foo", 1); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "store_uint32 failed: %s\n", + nt_errstr(status)); + goto fail; + } + status = dbwrap_fetch_uint32_bystring(db, "foo", &val); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "store_uint32 failed: %s\n", + nt_errstr(status)); + goto fail; + } + if (val != 1) { + fprintf(stderr, "fetch_uint32 gave %u, expected 1", + (unsigned)val); + goto fail; + } + + status = dbwrap_store_uint32_bystring(db, "bar", 5); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "store_uint32 failed: %s\n", + nt_errstr(status)); + goto fail; + } + status = dbwrap_fetch_uint32_bystring(db, "bar", &val); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "store_uint32 failed: %s\n", + nt_errstr(status)); + goto fail; + } + if (val != 5) { + fprintf(stderr, "fetch_uint32 gave %u, expected 1", + (unsigned)val); + goto fail; + } + + status = dbwrap_store_uint32_bystring(db, "foo", 2); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "store_uint32 failed: %s\n", + nt_errstr(status)); + goto fail; + } + status = dbwrap_fetch_uint32_bystring(db, "foo", &val); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "store_uint32 failed: %s\n", + nt_errstr(status)); + goto fail; + } + if (val != 2) { + fprintf(stderr, "fetch_uint32 gave %u, expected 1", + (unsigned)val); + goto fail; + } + + res = dbwrap_transaction_commit(db); + if (res != 0) { + fprintf(stderr, "dbwrap_transaction_commit failed"); + goto fail; + } + + ret = true; +fail: + TALLOC_FREE(db); + return ret; +} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 0cca680..89b34e4 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -9150,6 +9150,7 @@ static struct { { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0}, { "local-tdb-opener", run_local_tdb_opener, 0 }, { "local-tdb-writer", run_local_tdb_writer, 0 }, + { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 }, {NULL, NULL, 0}}; diff --git a/source3/wscript_build b/source3/wscript_build index 351d22d..7ed7350 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -557,6 +557,7 @@ SMBTORTURE_SRC1 = '''torture/torture.c torture/nbio.c torture/scanner.c torture/ lib/tevent_barrier.c torture/test_dbwrap_watch.c torture/test_idmap_tdb_common.c + torture/test_dbwrap_ctdb.c torture/t_strappend.c''' SMBTORTURE_SRC = '''${SMBTORTURE_SRC1} -- 1.7.9.5 From b9327556973e24bc3782da70394d3ce927cb6653 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 7 Nov 2012 16:25:31 +0100 Subject: [PATCH 03/16] s3: Remove header==NULL code from db_ctdb_marshall_record The only call chain (via db_ctdb_marshall_add) has header != NULL --- source3/lib/dbwrap/dbwrap_ctdb.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index e4c87ea..5be4bf7 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -177,9 +177,6 @@ static NTSTATUS db_ctdb_ltdb_store(struct db_ctdb_ctx *db, /* form a ctdb_rec_data record from a key/data pair - - note that header may be NULL. If not NULL then it is included in the data portion - of the record */ static struct ctdb_rec_data *db_ctdb_marshall_record(TALLOC_CTX *mem_ctx, uint32_t reqid, TDB_DATA key, @@ -190,7 +187,7 @@ static struct ctdb_rec_data *db_ctdb_marshall_record(TALLOC_CTX *mem_ctx, uint32 struct ctdb_rec_data *d; length = offsetof(struct ctdb_rec_data, data) + key.dsize + - data.dsize + (header?sizeof(*header):0); + data.dsize + sizeof(*header); d = (struct ctdb_rec_data *)talloc_size(mem_ctx, length); if (d == NULL) { return NULL; @@ -199,14 +196,10 @@ static struct ctdb_rec_data *db_ctdb_marshall_record(TALLOC_CTX *mem_ctx, uint32 d->reqid = reqid; d->keylen = key.dsize; memcpy(&d->data[0], key.dptr, key.dsize); - if (header) { - d->datalen = data.dsize + sizeof(*header); - memcpy(&d->data[key.dsize], header, sizeof(*header)); - memcpy(&d->data[key.dsize+sizeof(*header)], data.dptr, data.dsize); - } else { - d->datalen = data.dsize; - memcpy(&d->data[key.dsize], data.dptr, data.dsize); - } + + d->datalen = data.dsize + sizeof(*header); + memcpy(&d->data[key.dsize], header, sizeof(*header)); + memcpy(&d->data[key.dsize+sizeof(*header)], data.dptr, data.dsize); return d; } -- 1.7.9.5 From 720cff062480371fb5d954c069206c7c81824715 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 7 Nov 2012 16:39:16 +0100 Subject: [PATCH 04/16] s3: Slightly simplify db_ctdb_transaction_commit Avoid an unnecessary "else". --- source3/lib/dbwrap/dbwrap_ctdb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 5be4bf7..d352404 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -836,7 +836,8 @@ again: if (new_seqnum == old_seqnum) { /* Recovery prevented all our changes: retry. */ goto again; - } else if (new_seqnum != (old_seqnum + 1)) { + } + if (new_seqnum != (old_seqnum + 1)) { DEBUG(0, (__location__ " ERROR: new_seqnum[%lu] != " "old_seqnum[%lu] + (0 or 1) after failed " "TRANS3_COMMIT - this should not happen!\n", -- 1.7.9.5 From fbf4d73e0d9dcc3ec36aa6604b15d82ce46958f2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 Nov 2012 11:37:30 +0100 Subject: [PATCH 05/16] s3: Add db_ctdb_ltdb_parse --- source3/lib/dbwrap/dbwrap_ctdb.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index d352404..981d149 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -88,6 +88,47 @@ static NTSTATUS tdb_error_to_ntstatus(struct tdb_context *tdb) return map_nt_error_from_tdb(tret); } +struct db_ctdb_ltdb_parse_state { + void (*parser)(TDB_DATA key, struct ctdb_ltdb_header *header, + TDB_DATA data, void *private_data); + void *private_data; +}; + +static int db_ctdb_ltdb_parser(TDB_DATA key, TDB_DATA data, + void *private_data) +{ + struct db_ctdb_ltdb_parse_state *state = + (struct db_ctdb_ltdb_parse_state *)private_data; + + if (data.dsize < sizeof(struct ctdb_ltdb_header)) { + return -1; + } + state->parser( + key, (struct ctdb_ltdb_header *)data.dptr, + make_tdb_data(data.dptr + sizeof(struct ctdb_ltdb_header), + data.dsize - sizeof(struct ctdb_ltdb_header)), + state->private_data); + return 0; +} + +static NTSTATUS db_ctdb_ltdb_parse( + struct tdb_context *tdb, TDB_DATA key, + void (*parser)(TDB_DATA key, struct ctdb_ltdb_header *header, + TDB_DATA data, void *private_data), + void *private_data) +{ + struct db_ctdb_ltdb_parse_state state; + int ret; + + state.parser = parser; + state.private_data = private_data; + + ret = tdb_parse_record(tdb, key, db_ctdb_ltdb_parser, &state); + if (ret == -1) { + return NT_STATUS_NOT_FOUND; + } + return NT_STATUS_OK; +} /** * fetch a record from the tdb, separating out the header -- 1.7.9.5 From 5898791bd57376b21c2f4bbd791da05915fe13e2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 Nov 2012 11:52:43 +0100 Subject: [PATCH 06/16] s3: Use db_ctdb_ltdb_parse in db_ctdb_ltdb_fetch --- source3/lib/dbwrap/dbwrap_ctdb.c | 76 +++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 981d149..8ec5f84 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -130,6 +130,39 @@ static NTSTATUS db_ctdb_ltdb_parse( return NT_STATUS_OK; } +struct db_ctdb_ltdb_fetch_state { + struct ctdb_ltdb_header *header; + TALLOC_CTX *mem_ctx; + TDB_DATA *data; + bool oom; +}; + +static void db_ctdb_ltdb_fetch_parser( + TDB_DATA key, struct ctdb_ltdb_header *header, + TDB_DATA data, void *private_data) +{ + struct db_ctdb_ltdb_fetch_state *state = + (struct db_ctdb_ltdb_fetch_state *)private_data; + + if (state->header != NULL) { + memcpy(state->header, header, sizeof(struct ctdb_ltdb_header)); + } + if (state->data == NULL) { + return; + } + state->data->dsize = data.dsize; + if (data.dsize == 0) { + state->data->dptr = NULL; + return; + } + state->data->dptr = talloc_memdup(state->mem_ctx, data.dptr, + data.dsize); + if (state->data->dptr == NULL) { + state->oom = true; + return; + } +} + /** * fetch a record from the tdb, separating out the header * information and returning the body of the record. @@ -140,12 +173,17 @@ static NTSTATUS db_ctdb_ltdb_fetch(struct db_ctdb_ctx *db, TALLOC_CTX *mem_ctx, TDB_DATA *data) { - TDB_DATA rec; + struct db_ctdb_ltdb_fetch_state state; NTSTATUS status; - rec = tdb_fetch_compat(db->wtdb->tdb, key); - if (rec.dsize < sizeof(struct ctdb_ltdb_header)) { - status = NT_STATUS_NOT_FOUND; + state.header = header; + state.mem_ctx = mem_ctx; + state.data = data; + state.oom = false; + + status = db_ctdb_ltdb_parse(db->wtdb->tdb, key, + db_ctdb_ltdb_fetch_parser, &state); + if (!NT_STATUS_IS_OK(status)) { if (data) { ZERO_STRUCTP(data); } @@ -153,34 +191,12 @@ static NTSTATUS db_ctdb_ltdb_fetch(struct db_ctdb_ctx *db, header->dmaster = (uint32_t)-1; header->rsn = 0; } - goto done; - } - - if (header) { - *header = *(struct ctdb_ltdb_header *)rec.dptr; + return status; } - - if (data) { - data->dsize = rec.dsize - sizeof(struct ctdb_ltdb_header); - if (data->dsize == 0) { - data->dptr = NULL; - } else { - data->dptr = (unsigned char *)talloc_memdup(mem_ctx, - rec.dptr - + sizeof(struct ctdb_ltdb_header), - data->dsize); - if (data->dptr == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - } + if (state.oom) { + return NT_STATUS_NO_MEMORY; } - - status = NT_STATUS_OK; - -done: - SAFE_FREE(rec.dptr); - return status; + return NT_STATUS_OK; } /* -- 1.7.9.5 From 27eddd7482166a95b778b961bb00b5b4c7578807 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 Nov 2012 12:00:11 +0100 Subject: [PATCH 07/16] s3: Use db_ctdb_ltdb_parse in db_ctdb_fetch_db_seqnum_from_db --- source3/lib/dbwrap/dbwrap_ctdb.c | 41 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 8ec5f84..4786c3d 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -740,6 +740,19 @@ static NTSTATUS db_ctdb_delete_transaction(struct db_record *rec) return status; } +static void db_ctdb_fetch_db_seqnum_parser( + TDB_DATA key, struct ctdb_ltdb_header *header, + TDB_DATA data, void *private_data) +{ + uint64_t *seqnum = (uint64_t *)private_data; + + if (data.dsize != sizeof(uint64_t)) { + *seqnum = 0; + return; + } + memcpy(seqnum, data.dptr, sizeof(*seqnum)); +} + /** * Fetch the db sequence number of a persistent db directly from the db. */ @@ -747,36 +760,24 @@ static NTSTATUS db_ctdb_fetch_db_seqnum_from_db(struct db_ctdb_ctx *db, uint64_t *seqnum) { NTSTATUS status; - const char *keyname = CTDB_DB_SEQNUM_KEY; TDB_DATA key; - TDB_DATA data; - struct ctdb_ltdb_header header; - TALLOC_CTX *mem_ctx = talloc_stackframe(); if (seqnum == NULL) { return NT_STATUS_INVALID_PARAMETER; } - key = string_term_tdb_data(keyname); + key = string_term_tdb_data(CTDB_DB_SEQNUM_KEY); - status = db_ctdb_ltdb_fetch(db, key, &header, mem_ctx, &data); - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) - { - goto done; - } - - status = NT_STATUS_OK; + status = db_ctdb_ltdb_parse( + db->wtdb->tdb, key, db_ctdb_fetch_db_seqnum_parser, seqnum); - if (data.dsize != sizeof(uint64_t)) { + if (NT_STATUS_IS_OK(status)) { + return NT_STATUS_OK; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { *seqnum = 0; - goto done; + return NT_STATUS_OK; } - - *seqnum = *(uint64_t *)data.dptr; - -done: - TALLOC_FREE(mem_ctx); return status; } -- 1.7.9.5 From f9cde3f27e624a8339e5e50dfdc29ad456caca60 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 10 Nov 2012 14:42:21 +0100 Subject: [PATCH 08/16] s3: Slightly simplify db_ctdb_marshall_loop_next Both callers give a key argument --- source3/lib/dbwrap/dbwrap_ctdb.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 4786c3d..52b1b8f 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -338,10 +338,9 @@ static struct ctdb_rec_data *db_ctdb_marshall_loop_next(struct ctdb_marshall_buf *reqid = r->reqid; } - if (key != NULL) { - key->dptr = &r->data[0]; - key->dsize = r->keylen; - } + key->dptr = &r->data[0]; + key->dsize = r->keylen; + if (data != NULL) { data->dptr = &r->data[r->keylen]; data->dsize = r->datalen; -- 1.7.9.5 From aec0810831207a68badf076d34a3558140bf27eb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 10 Nov 2012 14:46:10 +0100 Subject: [PATCH 09/16] s3: Factor out db_ctdb_marshall_loop_next_key from db_ctdb_marshall_loop_next --- source3/lib/dbwrap/dbwrap_ctdb.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 52b1b8f..7c29f93 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -323,24 +323,40 @@ static TDB_DATA db_ctdb_marshall_finish(struct ctdb_marshall_buffer *m) - pass r==NULL to start - loop the number of times indicated by m->count */ +static struct ctdb_rec_data *db_ctdb_marshall_loop_next_key( + struct ctdb_marshall_buffer *m, struct ctdb_rec_data *r, TDB_DATA *key) +{ + if (r == NULL) { + r = (struct ctdb_rec_data *)&m->data[0]; + } else { + r = (struct ctdb_rec_data *)(r->length + (uint8_t *)r); + } + + key->dptr = &r->data[0]; + key->dsize = r->keylen; + return r; +} + +/* + loop over a marshalling buffer + + - pass r==NULL to start + - loop the number of times indicated by m->count +*/ static struct ctdb_rec_data *db_ctdb_marshall_loop_next(struct ctdb_marshall_buffer *m, struct ctdb_rec_data *r, uint32_t *reqid, struct ctdb_ltdb_header *header, TDB_DATA *key, TDB_DATA *data) { + r = db_ctdb_marshall_loop_next_key(m, r, key); if (r == NULL) { - r = (struct ctdb_rec_data *)&m->data[0]; - } else { - r = (struct ctdb_rec_data *)(r->length + (uint8_t *)r); + return NULL; } if (reqid != NULL) { *reqid = r->reqid; } - key->dptr = &r->data[0]; - key->dsize = r->keylen; - if (data != NULL) { data->dptr = &r->data[r->keylen]; data->dsize = r->datalen; @@ -1437,9 +1453,8 @@ static int db_ctdb_traverse(struct db_context *db, for (i=0; icount; i++) { TDB_DATA key; - rec =db_ctdb_marshall_loop_next(mbuf, rec, - NULL, NULL, - &key, NULL); + rec =db_ctdb_marshall_loop_next_key( + mbuf, rec, &key); SMB_ASSERT(rec != NULL); if (!tdb_exists(ltdb, key)) { -- 1.7.9.5 From 60f9a7e2a80ddd2aabea12c61fc266e5fb2166ba Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 10 Nov 2012 15:03:35 +0100 Subject: [PATCH 10/16] s3: Factor out db_ctdb_marshall_buf_parse from db_ctdb_marshall_buf_next --- source3/lib/dbwrap/dbwrap_ctdb.c | 69 ++++++++++++-------------------------- 1 file changed, 21 insertions(+), 48 deletions(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 7c29f93..4026617 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -337,43 +337,22 @@ static struct ctdb_rec_data *db_ctdb_marshall_loop_next_key( return r; } -/* - loop over a marshalling buffer - - - pass r==NULL to start - - loop the number of times indicated by m->count -*/ -static struct ctdb_rec_data *db_ctdb_marshall_loop_next(struct ctdb_marshall_buffer *m, struct ctdb_rec_data *r, - uint32_t *reqid, - struct ctdb_ltdb_header *header, - TDB_DATA *key, TDB_DATA *data) +static bool db_ctdb_marshall_buf_parse( + struct ctdb_rec_data *r, uint32_t *reqid, + struct ctdb_ltdb_header **header, TDB_DATA *data) { - r = db_ctdb_marshall_loop_next_key(m, r, key); - if (r == NULL) { - return NULL; + if (r->datalen < sizeof(struct ctdb_ltdb_header)) { + return false; } - if (reqid != NULL) { - *reqid = r->reqid; - } + *reqid = r->reqid; - if (data != NULL) { - data->dptr = &r->data[r->keylen]; - data->dsize = r->datalen; - if (header != NULL) { - data->dptr += sizeof(*header); - data->dsize -= sizeof(*header); - } - } + data->dptr = &r->data[r->keylen] + sizeof(struct ctdb_ltdb_header); + data->dsize = r->datalen - sizeof(struct ctdb_ltdb_header); - if (header != NULL) { - if (r->datalen < sizeof(*header)) { - return NULL; - } - *header = *(struct ctdb_ltdb_header *)&r->data[r->keylen]; - } + *header = (struct ctdb_ltdb_header *)&r->data[r->keylen]; - return r; + return true; } /** @@ -459,8 +438,7 @@ static bool pull_newest_from_marshall_buffer(struct ctdb_marshall_buffer *buf, TDB_DATA *pdata) { struct ctdb_rec_data *rec = NULL; - struct ctdb_ltdb_header h; - bool found = false; + struct ctdb_ltdb_header *h = NULL; TDB_DATA data; int i; @@ -468,9 +446,6 @@ static bool pull_newest_from_marshall_buffer(struct ctdb_marshall_buffer *buf, return false; } - ZERO_STRUCT(h); - ZERO_STRUCT(data); - /* * Walk the list of records written during this * transaction. If we want to read one we have already @@ -480,26 +455,24 @@ static bool pull_newest_from_marshall_buffer(struct ctdb_marshall_buffer *buf, */ for (i=0; icount; i++) { - TDB_DATA tkey, tdata; + TDB_DATA tkey; uint32_t reqid; - struct ctdb_ltdb_header hdr; - - ZERO_STRUCT(hdr); - rec = db_ctdb_marshall_loop_next(buf, rec, &reqid, &hdr, &tkey, - &tdata); + rec = db_ctdb_marshall_loop_next_key(buf, rec, &tkey); if (rec == NULL) { return false; } - if (tdb_data_equal(key, tkey)) { - found = true; - data = tdata; - h = hdr; + if (!tdb_data_equal(key, tkey)) { + continue; + } + + if (!db_ctdb_marshall_buf_parse(rec, &reqid, &h, &data)) { + return false; } } - if (!found) { + if (h == NULL) { return false; } @@ -513,7 +486,7 @@ static bool pull_newest_from_marshall_buffer(struct ctdb_marshall_buffer *buf, } if (pheader != NULL) { - *pheader = h; + *pheader = *h; } return true; -- 1.7.9.5 From 44e7df43f24e3c94f521f2f1099a74581c40556c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 Nov 2012 12:13:39 +0100 Subject: [PATCH 11/16] s3: Factor out parse_newest_in_marshall_buffer from pull_newest_from_marshall_buffer --- source3/lib/dbwrap/dbwrap_ctdb.c | 66 +++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 4026617..72c6bf9 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -431,11 +431,11 @@ static int db_ctdb_transaction_start(struct db_context *db) return 0; } -static bool pull_newest_from_marshall_buffer(struct ctdb_marshall_buffer *buf, - TDB_DATA key, - struct ctdb_ltdb_header *pheader, - TALLOC_CTX *mem_ctx, - TDB_DATA *pdata) +static bool parse_newest_in_marshall_buffer( + struct ctdb_marshall_buffer *buf, TDB_DATA key, + void (*parser)(TDB_DATA key, struct ctdb_ltdb_header *header, + TDB_DATA data, void *private_data), + void *private_data) { struct ctdb_rec_data *rec = NULL; struct ctdb_ltdb_header *h = NULL; @@ -476,19 +476,55 @@ static bool pull_newest_from_marshall_buffer(struct ctdb_marshall_buffer *buf, return false; } - if (pdata != NULL) { - data.dptr = (uint8_t *)talloc_memdup(mem_ctx, data.dptr, - data.dsize); - if ((data.dsize != 0) && (data.dptr == NULL)) { - return false; - } - *pdata = data; - } + parser(key, h, data, private_data); + + return true; +} + +struct pull_newest_from_marshall_buffer_state { + struct ctdb_ltdb_header *pheader; + TALLOC_CTX *mem_ctx; + TDB_DATA *pdata; +}; + +static void pull_newest_from_marshall_buffer_parser( + TDB_DATA key, struct ctdb_ltdb_header *header, + TDB_DATA data, void *private_data) +{ + struct pull_newest_from_marshall_buffer_state *state = + (struct pull_newest_from_marshall_buffer_state *)private_data; - if (pheader != NULL) { - *pheader = *h; + if (state->pheader != NULL) { + memcpy(state->pheader, header, sizeof(*state->pheader)); } + if (state->pdata != NULL) { + state->pdata->dsize = data.dsize; + state->pdata->dptr = (uint8_t *)talloc_memdup( + state->mem_ctx, data.dptr, data.dsize); + } +} + +static bool pull_newest_from_marshall_buffer(struct ctdb_marshall_buffer *buf, + TDB_DATA key, + struct ctdb_ltdb_header *pheader, + TALLOC_CTX *mem_ctx, + TDB_DATA *pdata) +{ + struct pull_newest_from_marshall_buffer_state state; + + state.pheader = pheader; + state.mem_ctx = mem_ctx; + state.pdata = pdata; + if (!parse_newest_in_marshall_buffer( + buf, key, pull_newest_from_marshall_buffer_parser, + &state)) { + return false; + } + if ((pdata != NULL) && (pdata->dsize != 0) && (pdata->dptr == NULL)) { + /* ENOMEM */ + return false; + } return true; } -- 1.7.9.5 From a651122827bb4b9930fc7d826ef75c2fa8601565 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 Nov 2012 13:03:56 +0100 Subject: [PATCH 12/16] s3: Avoid db_ctdb_fetch for persistent databases --- source3/lib/dbwrap/dbwrap_ctdb.c | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 72c6bf9..65d9b1e 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -1346,15 +1346,60 @@ static NTSTATUS db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, return status; } +struct db_ctdb_parse_record_state { + void (*parser)(TDB_DATA key, TDB_DATA data, void *private_data); + void *private_data; +}; + +static void db_ctdb_parse_record_parser( + TDB_DATA key, struct ctdb_ltdb_header *header, + TDB_DATA data, void *private_data) +{ + struct db_ctdb_parse_record_state *state = + (struct db_ctdb_parse_record_state *)private_data; + state->parser(key, data, state->private_data); +} + static NTSTATUS db_ctdb_parse_record(struct db_context *db, TDB_DATA key, void (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { + struct db_ctdb_ctx *ctx = talloc_get_type_abort( + db->private_data, struct db_ctdb_ctx); + struct db_ctdb_parse_record_state state; NTSTATUS status; TDB_DATA data; + state.parser = parser; + state.private_data = private_data; + + if (ctx->transaction != NULL) { + struct db_ctdb_transaction_handle *h = ctx->transaction; + bool found; + + /* + * Transactions only happen for persistent db's. + */ + + found = parse_newest_in_marshall_buffer( + h->m_write, key, db_ctdb_parse_record_parser, &state); + + if (found) { + return NT_STATUS_OK; + } + } + + if (db->persistent) { + /* + * Persistent db, but not found in the transaction buffer + */ + return db_ctdb_ltdb_parse( + ctx->wtdb->tdb, key, + db_ctdb_parse_record_parser, &state); + } + status = db_ctdb_fetch(db, talloc_tos(), key, &data); if (!NT_STATUS_IS_OK(status)) { return status; -- 1.7.9.5 From a740422b8c13cc20c680e794141397a78027658c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 Nov 2012 13:06:38 +0100 Subject: [PATCH 13/16] s3: Remove unused code for fetching persistent ctdb records The only entry point here is parse_record, and this catches the persistent case with a direct parse now --- source3/lib/dbwrap/dbwrap_ctdb.c | 129 -------------------------------------- 1 file changed, 129 deletions(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 65d9b1e..593d8d6 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -130,75 +130,6 @@ static NTSTATUS db_ctdb_ltdb_parse( return NT_STATUS_OK; } -struct db_ctdb_ltdb_fetch_state { - struct ctdb_ltdb_header *header; - TALLOC_CTX *mem_ctx; - TDB_DATA *data; - bool oom; -}; - -static void db_ctdb_ltdb_fetch_parser( - TDB_DATA key, struct ctdb_ltdb_header *header, - TDB_DATA data, void *private_data) -{ - struct db_ctdb_ltdb_fetch_state *state = - (struct db_ctdb_ltdb_fetch_state *)private_data; - - if (state->header != NULL) { - memcpy(state->header, header, sizeof(struct ctdb_ltdb_header)); - } - if (state->data == NULL) { - return; - } - state->data->dsize = data.dsize; - if (data.dsize == 0) { - state->data->dptr = NULL; - return; - } - state->data->dptr = talloc_memdup(state->mem_ctx, data.dptr, - data.dsize); - if (state->data->dptr == NULL) { - state->oom = true; - return; - } -} - -/** - * fetch a record from the tdb, separating out the header - * information and returning the body of the record. - */ -static NTSTATUS db_ctdb_ltdb_fetch(struct db_ctdb_ctx *db, - TDB_DATA key, - struct ctdb_ltdb_header *header, - TALLOC_CTX *mem_ctx, - TDB_DATA *data) -{ - struct db_ctdb_ltdb_fetch_state state; - NTSTATUS status; - - state.header = header; - state.mem_ctx = mem_ctx; - state.data = data; - state.oom = false; - - status = db_ctdb_ltdb_parse(db->wtdb->tdb, key, - db_ctdb_ltdb_fetch_parser, &state); - if (!NT_STATUS_IS_OK(status)) { - if (data) { - ZERO_STRUCTP(data); - } - if (header) { - header->dmaster = (uint32_t)-1; - header->rsn = 0; - } - return status; - } - if (state.oom) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - /* * Store a record together with the ctdb record header * in the local copy of the database. @@ -528,58 +459,6 @@ static bool pull_newest_from_marshall_buffer(struct ctdb_marshall_buffer *buf, return true; } -/* - fetch a record inside a transaction - */ -static NTSTATUS db_ctdb_transaction_fetch(struct db_ctdb_ctx *db, - TALLOC_CTX *mem_ctx, - TDB_DATA key, TDB_DATA *data) -{ - struct db_ctdb_transaction_handle *h = db->transaction; - NTSTATUS status; - bool found; - - found = pull_newest_from_marshall_buffer(h->m_write, key, NULL, - mem_ctx, data); - if (found) { - return NT_STATUS_OK; - } - - status = db_ctdb_ltdb_fetch(h->ctx, key, NULL, mem_ctx, data); - - if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { - *data = tdb_null; - } - - return status; -} - -/** - * Fetch a record from a persistent database - * without record locking and without an active transaction. - * - * This just fetches from the local database copy. - * Since the databases are kept in syc cluster-wide, - * there is no point in doing a ctdb call to fetch the - * record from the lmaster. It does even harm since migration - * of records bump their RSN and hence render the persistent - * database inconsistent. - */ -static NTSTATUS db_ctdb_fetch_persistent(struct db_ctdb_ctx *db, - TALLOC_CTX *mem_ctx, - TDB_DATA key, TDB_DATA *data) -{ - NTSTATUS status; - - status = db_ctdb_ltdb_fetch(db, key, NULL, mem_ctx, data); - - if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { - *data = tdb_null; - } - - return status; -} - static NTSTATUS db_ctdb_store_transaction(struct db_record *rec, TDB_DATA data, int flag); static NTSTATUS db_ctdb_delete_transaction(struct db_record *rec); @@ -1295,14 +1174,6 @@ static NTSTATUS db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, NTSTATUS status; TDB_DATA ctdb_data; - if (ctx->transaction) { - return db_ctdb_transaction_fetch(ctx, mem_ctx, key, data); - } - - if (db->persistent) { - return db_ctdb_fetch_persistent(ctx, mem_ctx, key, data); - } - /* try a direct fetch */ ctdb_data = tdb_fetch_compat(ctx->wtdb->tdb, key); -- 1.7.9.5 From f43475cf84d7be92697792c55de83233ab5c73ed Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 Nov 2012 13:27:07 +0100 Subject: [PATCH 14/16] s3: Factor out db_ctdb_can_use_local_hdr from db_ctdb_can_use_local_copy --- source3/lib/dbwrap/dbwrap_ctdb.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 593d8d6..2630889 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -969,18 +969,9 @@ static int db_ctdb_record_destr(struct db_record* data) * Check whether we have a valid local copy of the given record, * either for reading or for writing. */ -static bool db_ctdb_can_use_local_copy(TDB_DATA ctdb_data, bool read_only) +static bool db_ctdb_can_use_local_hdr(const struct ctdb_ltdb_header *hdr, + bool read_only) { - struct ctdb_ltdb_header *hdr; - - if (ctdb_data.dptr == NULL) - return false; - - if (ctdb_data.dsize < sizeof(struct ctdb_ltdb_header)) - return false; - - hdr = (struct ctdb_ltdb_header *)ctdb_data.dptr; - #ifdef HAVE_CTDB_WANT_READONLY_DECL if (hdr->dmaster != get_my_vnn()) { /* If we're not dmaster, it must be r/o copy. */ @@ -996,6 +987,18 @@ static bool db_ctdb_can_use_local_copy(TDB_DATA ctdb_data, bool read_only) #endif } +static bool db_ctdb_can_use_local_copy(TDB_DATA ctdb_data, bool read_only) +{ + if (ctdb_data.dptr == NULL) + return false; + + if (ctdb_data.dsize < sizeof(struct ctdb_ltdb_header)) + return false; + + return db_ctdb_can_use_local_hdr( + (struct ctdb_ltdb_header *)ctdb_data.dptr, read_only); +} + static struct db_record *fetch_locked_internal(struct db_ctdb_ctx *ctx, TALLOC_CTX *mem_ctx, TDB_DATA key, -- 1.7.9.5 From a30c5a95f85ada39ba522adea5697bc676389405 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 Nov 2012 13:36:48 +0100 Subject: [PATCH 15/16] s3: Directly parse local existing records in db_ctdb_parse_record --- source3/lib/dbwrap/dbwrap_ctdb.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 2630889..4a0ca96 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -1223,6 +1223,7 @@ static NTSTATUS db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, struct db_ctdb_parse_record_state { void (*parser)(TDB_DATA key, TDB_DATA data, void *private_data); void *private_data; + bool done; }; static void db_ctdb_parse_record_parser( @@ -1234,6 +1235,19 @@ static void db_ctdb_parse_record_parser( state->parser(key, data, state->private_data); } +static void db_ctdb_parse_record_parser_nonpersistent( + TDB_DATA key, struct ctdb_ltdb_header *header, + TDB_DATA data, void *private_data) +{ + struct db_ctdb_parse_record_state *state = + (struct db_ctdb_parse_record_state *)private_data; + + if (db_ctdb_can_use_local_hdr(header, true)) { + state->parser(key, data, state->private_data); + state->done = true; + } +} + static NTSTATUS db_ctdb_parse_record(struct db_context *db, TDB_DATA key, void (*parser)(TDB_DATA key, TDB_DATA data, @@ -1274,6 +1288,15 @@ static NTSTATUS db_ctdb_parse_record(struct db_context *db, TDB_DATA key, db_ctdb_parse_record_parser, &state); } + state.done = false; + + status = db_ctdb_ltdb_parse( + ctx->wtdb->tdb, key, db_ctdb_parse_record_parser_nonpersistent, + &state); + if (NT_STATUS_IS_OK(status) && state.done) { + return NT_STATUS_OK; + } + status = db_ctdb_fetch(db, talloc_tos(), key, &data); if (!NT_STATUS_IS_OK(status)) { return status; -- 1.7.9.5 From 68b864b7b936864772847fa3ffe40483b42bc294 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 Nov 2012 13:42:23 +0100 Subject: [PATCH 16/16] s3: Remove db_ctdb_fetch --- source3/lib/dbwrap/dbwrap_ctdb.c | 66 +++++++------------------------------- 1 file changed, 11 insertions(+), 55 deletions(-) diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 4a0ca96..d0ec2ff 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -1166,63 +1166,10 @@ static struct db_record *db_ctdb_try_fetch_locked(struct db_context *db, return fetch_locked_internal(ctx, mem_ctx, key, true); } -/* - fetch (unlocked, no migration) operation on ctdb - */ -static NTSTATUS db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, - TDB_DATA key, TDB_DATA *data) -{ - struct db_ctdb_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_ctdb_ctx); - NTSTATUS status; - TDB_DATA ctdb_data; - - /* try a direct fetch */ - ctdb_data = tdb_fetch_compat(ctx->wtdb->tdb, key); - - /* - * See if we have a valid record and we are the dmaster. If so, we can - * take the shortcut and just return it. - * we bypass the dmaster check for persistent databases - */ - if (db_ctdb_can_use_local_copy(ctdb_data, true)) { - /* - * We have a valid local copy - avoid the ctdb protocol op - */ - data->dsize = ctdb_data.dsize - sizeof(struct ctdb_ltdb_header); - - data->dptr = (uint8_t *)talloc_memdup( - mem_ctx, ctdb_data.dptr+sizeof(struct ctdb_ltdb_header), - data->dsize); - - SAFE_FREE(ctdb_data.dptr); - - if (data->dptr == NULL) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; - } - - SAFE_FREE(ctdb_data.dptr); - - /* - * We weren't able to get it locally - ask ctdb to fetch it for us. - * If we already had *something*, it's probably worth making a local - * read-only copy. - */ - status = ctdbd_fetch(messaging_ctdbd_connection(), ctx->db_id, key, - mem_ctx, data, - ctdb_data.dsize >= sizeof(struct ctdb_ltdb_header)); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(5, ("ctdbd_fetch failed: %s\n", nt_errstr(status))); - } - - return status; -} - struct db_ctdb_parse_record_state { void (*parser)(TDB_DATA key, TDB_DATA data, void *private_data); void *private_data; + bool ask_for_readonly_copy; bool done; }; @@ -1245,6 +1192,13 @@ static void db_ctdb_parse_record_parser_nonpersistent( if (db_ctdb_can_use_local_hdr(header, true)) { state->parser(key, data, state->private_data); state->done = true; + } else { + /* + * We found something in the db, so it seems that this record, + * while not usable locally right now, is popular. Ask for a + * R/O copy. + */ + state->ask_for_readonly_copy = true; } } @@ -1289,6 +1243,7 @@ static NTSTATUS db_ctdb_parse_record(struct db_context *db, TDB_DATA key, } state.done = false; + state.ask_for_readonly_copy = false; status = db_ctdb_ltdb_parse( ctx->wtdb->tdb, key, db_ctdb_parse_record_parser_nonpersistent, @@ -1297,7 +1252,8 @@ static NTSTATUS db_ctdb_parse_record(struct db_context *db, TDB_DATA key, return NT_STATUS_OK; } - status = db_ctdb_fetch(db, talloc_tos(), key, &data); + status = ctdbd_fetch(messaging_ctdbd_connection(), ctx->db_id, key, + talloc_tos(), &data, state.ask_for_readonly_copy); if (!NT_STATUS_IS_OK(status)) { return status; } -- 1.7.9.5