/* 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; }
/* 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; }