summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2016-08-08 16:58:51 +0200
committerStefan Metzmacher <metze@samba.org>2016-08-10 15:08:00 +0200
commit6a9bdca12845b4b666490c3b94f54d562e89714d (patch)
tree9ef5f0925024df1381e0fbdf1931e67b3ca9ecf4
parentaa0522e00084c5b023e78dc24cad86f76a0f41a5 (diff)
downloadsamba-6a9bdca12845b4b666490c3b94f54d562e89714d.tar.gz
dbwrap_ctdb: treat empty records in ltdb as non-existing
When fetching records from remote ctdb nodes via ctdbd_parse() or in db_ctdb_traverse(), we already check for tombstone records and skip them. This was originally also done for the ltdb checks. See also bug: https://bugzilla.samba.org/show_bug.cgi?id=10008 (commit 1cae59ce112ccb51b45357a52b902f80fce1eef1). Commit 925625b52886d40b50fc631bad8bdc81970f7598 reverted part of the patch of bug 10008 due to a deadlock it introduced. This patch re-introduces the consistent treatment of empty records in the ltdb but avoids the deadlock by correctly signalling NT_STATUS_NOT_FOUND if an empty record is found authoritatively in the ltdb and not calling ctdb in this case. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12005 Pair-Programmed-With: Michael Adam <obnox@samba.org> Signed-off-by: Ralph Boehme <slow@samba.org> Signed-off-by: Michael Adam <obnox@samba.org> Autobuild-User(master): Michael Adam <obnox@samba.org> Autobuild-Date(master): Tue Aug 9 04:38:44 CEST 2016 on sn-devel-144 (cherry picked from commit 25df582739918b7afd4e5497eaffe279e2d92cd1) Autobuild-User(v4-5-test): Stefan Metzmacher <metze@samba.org> Autobuild-Date(v4-5-test): Wed Aug 10 15:08:00 CEST 2016 on sn-devel-144
-rw-r--r--source3/lib/dbwrap/dbwrap_ctdb.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c
index d86d0788f39..10f5f50adf7 100644
--- a/source3/lib/dbwrap/dbwrap_ctdb.c
+++ b/source3/lib/dbwrap/dbwrap_ctdb.c
@@ -1221,6 +1221,7 @@ struct db_ctdb_parse_record_state {
uint32_t my_vnn;
bool ask_for_readonly_copy;
bool done;
+ bool empty_record;
};
static void db_ctdb_parse_record_parser(
@@ -1240,7 +1241,16 @@ static void db_ctdb_parse_record_parser_nonpersistent(
(struct db_ctdb_parse_record_state *)private_data;
if (db_ctdb_can_use_local_hdr(header, state->my_vnn, true)) {
- state->parser(key, data, state->private_data);
+ /*
+ * A record consisting only of the ctdb header can be
+ * a validly created empty record or a tombstone
+ * record of a deleted record (not vacuumed yet). Mark
+ * it accordingly.
+ */
+ state->empty_record = (data.dsize == 0);
+ if (!state->empty_record) {
+ state->parser(key, data, state->private_data);
+ }
state->done = true;
} else {
/*
@@ -1267,6 +1277,7 @@ static NTSTATUS db_ctdb_parse_record(struct db_context *db, TDB_DATA key,
state.parser = parser;
state.private_data = private_data;
state.my_vnn = ctdbd_vnn(ctx->conn);
+ state.empty_record = false;
if (ctx->transaction != NULL) {
struct db_ctdb_transaction_handle *h = ctx->transaction;
@@ -1298,6 +1309,20 @@ static NTSTATUS db_ctdb_parse_record(struct db_context *db, TDB_DATA key,
status = db_ctdb_ltdb_parse(
ctx, key, db_ctdb_parse_record_parser_nonpersistent, &state);
if (NT_STATUS_IS_OK(status) && state.done) {
+ if (state.empty_record) {
+ /*
+ * We know authoritatively, that this is an empty
+ * record. Since ctdb does not distinguish between empty
+ * and deleted records, this can be a record stored as
+ * empty or a not-yet-vacuumed tombstone record of a
+ * deleted record. Now Samba right now can live without
+ * empty records, so we can safely report this record
+ * as non-existing.
+ *
+ * See bugs 10008 and 12005.
+ */
+ return NT_STATUS_NOT_FOUND;
+ }
return NT_STATUS_OK;
}