diff options
author | Ralph Boehme <slow@samba.org> | 2016-08-08 16:58:51 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2016-08-10 15:08:00 +0200 |
commit | 6a9bdca12845b4b666490c3b94f54d562e89714d (patch) | |
tree | 9ef5f0925024df1381e0fbdf1931e67b3ca9ecf4 | |
parent | aa0522e00084c5b023e78dc24cad86f76a0f41a5 (diff) | |
download | samba-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.c | 27 |
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; } |