Exemple #1
0
/*
  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;
}
Exemple #2
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;
}
Exemple #3
0
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;
}
Exemple #4
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;
}
Exemple #5
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);
}
Exemple #6
0
/*
  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;
    }
}