Example #1
0
/*
  freeze all the databases
 */
int32_t ctdb_control_freeze(struct ctdb_context *ctdb,
                            struct ctdb_req_control_old *c, bool *async_reply)
{
    struct ctdb_freeze_waiter *w;

    ctdb_start_freeze(ctdb);

    if (ctdb->freeze_mode == CTDB_FREEZE_FROZEN) {
        DEBUG(DEBUG_ERR, ("Freeze all: frozen\n"));
        /* we're already frozen */
        return 0;
    }

    if (ctdb->freeze_handle == NULL) {
        DEBUG(DEBUG_ERR,("No freeze lock handle when adding a waiter\n"));
        return -1;
    }

    /* If there are no databases, we are done. */
    if (ctdb->freeze_handle->num_total == 0) {
        return 0;
    }

    /* add ourselves to list of waiters */
    w = talloc(ctdb->freeze_handle, struct ctdb_freeze_waiter);
    CTDB_NO_MEMORY(ctdb, w);
    w->ctdb     = ctdb;
    w->c        = talloc_steal(w, c);
    w->status   = -1;
    talloc_set_destructor(w, ctdb_freeze_waiter_destructor);
    DLIST_ADD(ctdb->freeze_handle->waiters, w);

    /* we won't reply till later */
    *async_reply = true;
    return 0;
}
Example #2
0
/*
  modify flags on a node
 */
int32_t ctdb_control_modflags(struct ctdb_context *ctdb, TDB_DATA indata)
{
	struct ctdb_node_flag_change *c = (struct ctdb_node_flag_change *)indata.dptr;
	struct ctdb_node *node;
	uint32_t old_flags;
	int i;

	if (c->pnn >= ctdb->num_nodes) {
		DEBUG(DEBUG_ERR,(__location__ " Node %d is invalid, num_nodes :%d\n", c->pnn, ctdb->num_nodes));
		return -1;
	}

	node         = ctdb->nodes[c->pnn];
	old_flags    = node->flags;
	if (c->pnn != ctdb->pnn) {
		c->old_flags  = node->flags;
	}
	node->flags   = c->new_flags & ~NODE_FLAGS_DISCONNECTED;
	node->flags  |= (c->old_flags & NODE_FLAGS_DISCONNECTED);

	/* we dont let other nodes modify our STOPPED status */
	if (c->pnn == ctdb->pnn) {
		node->flags &= ~NODE_FLAGS_STOPPED;
		if (old_flags & NODE_FLAGS_STOPPED) {
			node->flags |= NODE_FLAGS_STOPPED;
		}
	}

	/* we dont let other nodes modify our BANNED status */
	if (c->pnn == ctdb->pnn) {
		node->flags &= ~NODE_FLAGS_BANNED;
		if (old_flags & NODE_FLAGS_BANNED) {
			node->flags |= NODE_FLAGS_BANNED;
		}
	}

	if (node->flags == c->old_flags) {
		DEBUG(DEBUG_INFO, ("Control modflags on node %u - Unchanged - flags 0x%x\n", c->pnn, node->flags));
		return 0;
	}

	DEBUG(DEBUG_INFO, ("Control modflags on node %u - flags now 0x%x\n", c->pnn, node->flags));

	if (node->flags == 0 && !ctdb->done_startup) {
		DEBUG(DEBUG_ERR, (__location__ " Node %u became healthy - force recovery for startup\n",
				  c->pnn));
		ctdb->recovery_mode = CTDB_RECOVERY_ACTIVE;
	}

	/* tell the recovery daemon something has changed */
	ctdb_daemon_send_message(ctdb, ctdb->pnn,
				 CTDB_SRVID_SET_NODE_FLAGS, indata);

	/* if we have become banned, we should go into recovery mode */
	if ((node->flags & NODE_FLAGS_BANNED) && !(c->old_flags & NODE_FLAGS_BANNED) && (node->pnn == ctdb->pnn)) {
		/* make sure we are frozen */
		DEBUG(DEBUG_NOTICE,("This node has been banned - forcing freeze and recovery\n"));
		/* Reset the generation id to 1 to make us ignore any
		   REQ/REPLY CALL/DMASTER someone sends to us.
		   We are now banned so we shouldnt service database calls
		   anymore.
		*/
		ctdb->vnn_map->generation = INVALID_GENERATION;

		for (i=1; i<=NUM_DB_PRIORITIES; i++) {
			if (ctdb_start_freeze(ctdb, i) != 0) {
				DEBUG(DEBUG_ERR,(__location__ " Failed to freeze db priority %u\n", i));
			}
		}
		ctdb_release_all_ips(ctdb);
		ctdb->recovery_mode = CTDB_RECOVERY_ACTIVE;
	}
	
	return 0;
}