Deferred attach : at early startup, defer any db attach calls until we are out of...
[sahlberg/ctdb.git] / server / ctdb_recover.c
index 111d7a98327f623700ab41f1b8d9610750e53ff9..8f79f84665a78ddb89b96cf4e740e5697ddff139 100644 (file)
@@ -57,7 +57,11 @@ static int ctdb_lock_all_databases_mark(struct ctdb_context *ctdb, uint32_t prio
                if (strstr(ctdb_db->db_name, "notify") != NULL) {
                        continue;
                }
+               if (tdb_transaction_write_lock_mark(ctdb_db->ltdb->tdb) != 0) {
+                       return -1;
+               }
                if (tdb_lockall_mark(ctdb_db->ltdb->tdb) != 0) {
+                       tdb_transaction_write_lock_unmark(ctdb_db->ltdb->tdb);
                        return -1;
                }
        }
@@ -68,7 +72,11 @@ static int ctdb_lock_all_databases_mark(struct ctdb_context *ctdb, uint32_t prio
                if (strstr(ctdb_db->db_name, "notify") == NULL) {
                        continue;
                }
+               if (tdb_transaction_write_lock_mark(ctdb_db->ltdb->tdb) != 0) {
+                       return -1;
+               }
                if (tdb_lockall_mark(ctdb_db->ltdb->tdb) != 0) {
+                       tdb_transaction_write_lock_unmark(ctdb_db->ltdb->tdb);
                        return -1;
                }
        }
@@ -95,6 +103,7 @@ static int ctdb_lock_all_databases_unmark(struct ctdb_context *ctdb, uint32_t pr
                if (ctdb_db->priority != priority) {
                        continue;
                }
+               tdb_transaction_write_lock_unmark(ctdb_db->ltdb->tdb);
                if (tdb_lockall_unmark(ctdb_db->ltdb->tdb) != 0) {
                        return -1;
                }
@@ -621,6 +630,11 @@ static void set_recmode_handler(struct event_context *ev, struct fd_event *fde,
 
        state->ctdb->recovery_mode = state->recmode;
 
+       /* release any deferred attach calls from clients */
+       if (state->recmode == CTDB_RECOVERY_NORMAL) {
+               ctdb_process_deferred_attach(state->ctdb);
+       }
+
        ctdb_request_control_reply(state->ctdb, state->c, NULL, 0, NULL);
        talloc_free(state);
        return;
@@ -639,6 +653,22 @@ ctdb_drop_all_ips_event(struct event_context *ev, struct timed_event *te,
        ctdb_release_all_ips(ctdb);
 }
 
+/*
+ * Set up an event to drop all public ips if we remain in recovery for too
+ * long
+ */
+int ctdb_deferred_drop_all_ips(struct ctdb_context *ctdb)
+{
+       if (ctdb->release_ips_ctx != NULL) {
+               talloc_free(ctdb->release_ips_ctx);
+       }
+       ctdb->release_ips_ctx = talloc_new(ctdb);
+       CTDB_NO_MEMORY(ctdb, ctdb->release_ips_ctx);
+
+       event_add_timed(ctdb->ev, ctdb->release_ips_ctx, timeval_current_ofs(ctdb->tunable.recovery_drop_all_ips, 0), ctdb_drop_all_ips_event, ctdb);
+       return 0;
+}
+
 /*
   set the recovery mode
  */
@@ -659,11 +689,9 @@ int32_t ctdb_control_set_recmode(struct ctdb_context *ctdb,
                talloc_free(ctdb->release_ips_ctx);
                ctdb->release_ips_ctx = NULL;
        } else {
-               talloc_free(ctdb->release_ips_ctx);
-               ctdb->release_ips_ctx = talloc_new(ctdb);
-               CTDB_NO_MEMORY(ctdb, ctdb->release_ips_ctx);
-
-               event_add_timed(ctdb->ev, ctdb->release_ips_ctx, timeval_current_ofs(ctdb->tunable.recovery_drop_all_ips, 0), ctdb_drop_all_ips_event, ctdb);
+               if (ctdb_deferred_drop_all_ips(ctdb) != 0) {
+                       DEBUG(DEBUG_ERR,("Failed to set up deferred drop all ips\n"));
+               }
        }
 
        if (recmode != ctdb->recovery_mode) {
@@ -693,6 +721,11 @@ int32_t ctdb_control_set_recmode(struct ctdb_context *ctdb,
        state->fd[0] = -1;
        state->fd[1] = -1;
 
+       /* release any deferred attach calls from clients */
+       if (recmode == CTDB_RECOVERY_NORMAL) {
+               ctdb_process_deferred_attach(ctdb);
+       }
+
        if (ctdb->tunable.verify_recovery_lock == 0) {
                /* dont need to verify the reclock file */
                ctdb->recovery_mode = recmode;