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
};
struct dmaster_defer_queue {
};
struct dmaster_defer_queue {
+ struct ctdb_context *ctdb;
+ uint32_t generation;
struct dmaster_defer_call *deferred_calls;
};
struct dmaster_defer_call *deferred_calls;
};
static int dmaster_defer_queue_destructor(struct dmaster_defer_queue *ddq)
{
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;
while (ddq->deferred_calls != NULL) {
struct dmaster_defer_call *call = ddq->deferred_calls;
talloc_free(k);
return -1;
}
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,
ddq->deferred_calls = NULL;
trbt_insertarray32_callback(ctdb_db->defer_dmaster, k[0], 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"));
call = talloc(ddq, struct dmaster_defer_call);
if (call == NULL) {
DEBUG(DEBUG_ERR, ("Failed to allocate dmaster defer call\n"));