persistent: add ctdb_persistent_finish_trans3_commits().
authorMichael Adam <obnox@samba.org>
Wed, 23 Feb 2011 16:38:40 +0000 (17:38 +0100)
committerMichael Adam <obnox@samba.org>
Thu, 24 Feb 2011 09:32:00 +0000 (10:32 +0100)
This function walks all databases and checks for running trans3 commits.
It sends replies to all of them (with error code) and ends them.
To be called when a recovery finishes.

include/ctdb_private.h
server/ctdb_persistent.c

index 65397ea610473aee359bec4c591954648b344425..447d40ce3f7fe40baa941c13228b8e7e47974761 100644 (file)
@@ -1223,6 +1223,8 @@ int32_t ctdb_control_trans3_commit(struct ctdb_context *ctdb,
                                   struct ctdb_req_control *c,
                                   TDB_DATA recdata, bool *async_reply);
 
+void ctdb_persistent_finish_trans3_commits(struct ctdb_context *ctdb);
+
 int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb, uint32_t id);
 int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb, uint32_t id);
 int32_t ctdb_control_transaction_cancel(struct ctdb_context *ctdb);
index 0627037ea9246ef2dbe70df3de243aa0355a9451..b95f456ecf52ce24c58193dabef9a85f6b71bbf8 100644 (file)
@@ -118,6 +118,40 @@ static void ctdb_persistent_store_timeout(struct event_context *ev, struct timed
        talloc_free(state);
 }
 
+/**
+ * Finish pending trans3 commit controls, i.e. send
+ * reply to the client. This is called by the end-recovery
+ * control to fix the situation when a recovery interrupts
+ * the usual porgress of a transaction.
+ */
+void ctdb_persistent_finish_trans3_commits(struct ctdb_context *ctdb)
+{
+       struct ctdb_db_context *ctdb_db;
+
+       if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
+               DEBUG(DEBUG_INFO, ("ctdb_persistent_store_timeout: ignoring "
+                                  "timeout during recovery\n"));
+               return;
+       }
+
+       for (ctdb_db = ctdb->db_list; ctdb_db; ctdb_db = ctdb_db->next) {
+               struct ctdb_persistent_state *state;
+
+               if (ctdb_db->persistent_state == NULL) {
+                       continue;
+               }
+
+               state = ctdb_db->persistent_state;
+
+               ctdb_request_control_reply(ctdb, state->c, NULL,
+                                          CTDB_TRANS2_COMMIT_SOMEFAIL,
+                                          "trans3 commit ended by recovery");
+
+               /* The destructor sets ctdb_db->persistent_state to NULL. */
+               talloc_free(state);
+       }
+}
+
 /*
   store a set of persistent records - called from a ctdb client when it has updated
   some records in a persistent database. The client will have the record