/* destroy a freeze handle */ static int ctdb_freeze_handle_destructor(struct ctdb_freeze_handle *h) { struct ctdb_context *ctdb = h->ctdb; DEBUG(DEBUG_ERR,("Release freeze handle\n")); /* cancel any pending transactions */ if (ctdb->freeze_transaction_started) { ctdb_db_iterator(ctdb, db_transaction_cancel_handler, NULL); ctdb->freeze_transaction_started = false; } ctdb_db_iterator(ctdb, db_thaw, NULL); ctdb->freeze_mode = CTDB_FREEZE_NONE; ctdb->freeze_handle = NULL; return 0; }
/* block until we are frozen, used during daemon startup */ bool ctdb_blocking_freeze(struct ctdb_context *ctdb) { int ret; ret = ctdb_db_iterator(ctdb, db_freeze_block, ctdb->ev); if (ret != 0) { return false; } return true; }
static int ctdb_lockall_unmark(struct ctdb_context *ctdb) { uint32_t priority; for (priority=NUM_DB_PRIORITIES; priority>0; priority--) { if (ctdb_db_iterator(ctdb, priority, db_lock_unmark_handler, NULL) != 0) { return -1; } } return 0; }
/* thaw the databases */ int32_t ctdb_control_thaw(struct ctdb_context *ctdb, bool check_recmode) { if (check_recmode && ctdb->recovery_mode == CTDB_RECOVERY_ACTIVE) { DEBUG(DEBUG_ERR, ("Failing to thaw databases while " "recovery is active\n")); return -1; } DEBUG(DEBUG_ERR,("Thawing all\n")); /* cancel any pending transactions */ if (ctdb->freeze_transaction_started) { ctdb_db_iterator(ctdb, db_transaction_cancel_handler, NULL); ctdb->freeze_transaction_started = false; } ctdb_db_iterator(ctdb, db_thaw, NULL); TALLOC_FREE(ctdb->freeze_handle); ctdb_call_resend_all(ctdb); return 0; }
int ctdb_lockall_unmark_prio(struct ctdb_context *ctdb, uint32_t priority) { /* * This function is only used by the main dameon during recovery. * At this stage, the databases have already been locked, by a * dedicated child process. The freeze_mode variable is used to track * whether the actual locks are held by the child process or not. */ if (ctdb->freeze_mode[priority] != CTDB_FREEZE_FROZEN) { DEBUG(DEBUG_ERR, ("Attempt to unmark all databases locked when not frozen\n")); return -1; } return ctdb_db_iterator(ctdb, priority, db_lock_unmark_handler, NULL); }
/* start the freeze process for a certain priority */ static void ctdb_start_freeze(struct ctdb_context *ctdb) { struct ctdb_freeze_handle *h; int ret; if (ctdb->freeze_mode == CTDB_FREEZE_FROZEN) { int count = 0; /* * Check if all the databases are frozen * * It's possible that the databases can get attached after * initial freeze. This typically happens during startup as * CTDB will only attach persistent databases and go in to * startup freeze. The recovery master during recovery will * attach all the missing databases. */ h = ctdb->freeze_handle; if (h == NULL) { ctdb->freeze_mode = CTDB_FREEZE_NONE; return; } ret = ctdb_db_iterator(ctdb, db_count, &count); if (ret != 0) { TALLOC_FREE(ctdb->freeze_handle); ctdb->freeze_mode = CTDB_FREEZE_NONE; return; } if (count != h->num_total) { DEBUG(DEBUG_ERR, ("Freeze all: incremental\n")); h->num_total = count; h->num_locked = 0; h->num_failed = 0; ctdb->freeze_mode = CTDB_FREEZE_PENDING; ret = ctdb_db_iterator(ctdb, db_freeze, h); if (ret != 0) { TALLOC_FREE(ctdb->freeze_handle); ctdb->freeze_mode = CTDB_FREEZE_NONE; } } return; } if (ctdb->freeze_handle != NULL) { /* already trying to freeze */ return; } DEBUG(DEBUG_ERR, ("Freeze all\n")); /* Stop any vacuuming going on: we don't want to wait. */ ctdb_stop_vacuuming(ctdb); /* create freeze lock children for each database */ h = talloc_zero(ctdb, struct ctdb_freeze_handle); CTDB_NO_MEMORY_FATAL(ctdb, h); h->ctdb = ctdb; talloc_set_destructor(h, ctdb_freeze_handle_destructor); ctdb->freeze_handle = h; ret = ctdb_db_iterator(ctdb, db_count, &h->num_total); if (ret != 0) { talloc_free(h); return; } ctdb->freeze_mode = CTDB_FREEZE_PENDING; ret = ctdb_db_iterator(ctdb, db_freeze, h); if (ret != 0) { talloc_free(h); return; } if (h->num_total == 0) { ctdb->freeze_mode = CTDB_FREEZE_FROZEN; } }