diff options
author | Amitay Isaacs <amitay@gmail.com> | 2014-09-02 16:10:20 +1000 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2014-09-05 09:30:50 +0200 |
commit | 2c57cc9597cb9cfe5ab3a458df74d6b5cda45465 (patch) | |
tree | b0dd1299b054fb0ddb832b9a05b8c2b135f28f99 /ctdb/server/ctdb_call.c | |
parent | 6f072f85a138f595494dbec137bcf23d1e666acc (diff) | |
download | samba-2c57cc9597cb9cfe5ab3a458df74d6b5cda45465.tar.gz |
ctdb-call: Drop all deferred requests from older generation
Deferring packets has a nasty interaction with recovery. All deferred
packets must be dropped when recovery happens, since those packets are
tracked as pending requests and will be re-sent with new generation.
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
Autobuild-User(master): Martin Schwenke <martins@samba.org>
Autobuild-Date(master): Fri Sep 5 09:30:50 CEST 2014 on sn-devel-104
Diffstat (limited to 'ctdb/server/ctdb_call.c')
-rw-r--r-- | ctdb/server/ctdb_call.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/ctdb/server/ctdb_call.c b/ctdb/server/ctdb_call.c index 956b3e87117..391dfb1ab5a 100644 --- a/ctdb/server/ctdb_call.c +++ b/ctdb/server/ctdb_call.c @@ -416,6 +416,8 @@ struct dmaster_defer_call { }; struct dmaster_defer_queue { + struct ctdb_context *ctdb; + uint32_t generation; struct dmaster_defer_call *deferred_calls; }; @@ -433,6 +435,11 @@ static void dmaster_defer_reprocess(struct tevent_context *ev, static int dmaster_defer_queue_destructor(struct dmaster_defer_queue *ddq) { + /* Ignore requests, if database recovery happens in-between. */ + if (ddq->generation != ddq->ctdb->vnn_map->generation) { + return 0; + } + while (ddq->deferred_calls != NULL) { struct dmaster_defer_call *call = ddq->deferred_calls; @@ -483,6 +490,8 @@ static int dmaster_defer_setup(struct ctdb_db_context *ctdb_db, talloc_free(k); return -1; } + ddq->ctdb = ctdb_db->ctdb; + ddq->generation = hdr->generation; ddq->deferred_calls = NULL; trbt_insertarray32_callback(ctdb_db->defer_dmaster, k[0], k, @@ -515,6 +524,12 @@ static int dmaster_defer_add(struct ctdb_db_context *ctdb_db, talloc_free(k); + if (ddq->generation != hdr->generation) { + talloc_set_destructor(ddq, NULL); + talloc_free(ddq); + return -1; + } + call = talloc(ddq, struct dmaster_defer_call); if (call == NULL) { DEBUG(DEBUG_ERR, ("Failed to allocate dmaster defer call\n")); |