1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

ctdb-daemon: Drop priorites from freeze/thaw code

Parallel database recovery freezes databases in parallel and irrespective
of database priority.  So drop priority from freeze/thaw code.
Database priority will be dropped completely soon.

Now FREEZE and THAW controls operate on all the databases.

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
This commit is contained in:
Amitay Isaacs 2016-07-19 16:32:16 +10:00 committed by Amitay Isaacs
parent 9338443a92
commit 79b6b4b621
4 changed files with 53 additions and 100 deletions

View File

@ -296,8 +296,8 @@ struct ctdb_context {
TALLOC_CTX *keepalive_ctx;
TALLOC_CTX *check_public_ifaces_ctx;
struct ctdb_tunable_list tunable;
enum ctdb_freeze_mode freeze_mode[NUM_DB_PRIORITIES+1];
struct ctdb_freeze_handle *freeze_handles[NUM_DB_PRIORITIES+1];
enum ctdb_freeze_mode freeze_mode;
struct ctdb_freeze_handle *freeze_handle;
bool freeze_transaction_started;
uint32_t freeze_transaction_id;
ctdb_sock_addr *address;
@ -658,8 +658,7 @@ int32_t ctdb_control_db_thaw(struct ctdb_context *ctdb, uint32_t db_id);
int32_t ctdb_control_freeze(struct ctdb_context *ctdb,
struct ctdb_req_control_old *c, bool *async_reply);
int32_t ctdb_control_thaw(struct ctdb_context *ctdb, uint32_t priority,
bool check_recmode);
int32_t ctdb_control_thaw(struct ctdb_context *ctdb, bool check_recmode);
bool ctdb_blocking_freeze(struct ctdb_context *ctdb);

View File

@ -319,7 +319,7 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
case CTDB_CONTROL_THAW:
CHECK_CONTROL_DATA_SIZE(0);
return ctdb_control_thaw(ctdb, (uint32_t)c->srvid, true);
return ctdb_control_thaw(ctdb, true);
case CTDB_CONTROL_SET_RECMODE:
CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));

View File

@ -289,14 +289,12 @@ struct ctdb_freeze_waiter {
struct ctdb_freeze_waiter *next, *prev;
struct ctdb_context *ctdb;
struct ctdb_req_control_old *c;
uint32_t priority;
int32_t status;
};
/* a handle to a freeze lock child process */
struct ctdb_freeze_handle {
struct ctdb_context *ctdb;
uint32_t priority;
unsigned int num_total, num_locked, num_failed;
struct ctdb_freeze_waiter *waiters;
};
@ -314,19 +312,18 @@ static int ctdb_freeze_handle_destructor(struct ctdb_freeze_handle *h)
{
struct ctdb_context *ctdb = h->ctdb;
DEBUG(DEBUG_ERR,("Release freeze handle for prio %u\n", h->priority));
DEBUG(DEBUG_ERR,("Release freeze handle\n"));
/* cancel any pending transactions */
if (ctdb->freeze_transaction_started) {
ctdb_db_prio_iterator(ctdb, h->priority,
db_transaction_cancel_handler, NULL);
ctdb_db_iterator(ctdb, db_transaction_cancel_handler, NULL);
ctdb->freeze_transaction_started = false;
}
ctdb_db_prio_iterator(ctdb, h->priority, db_thaw, NULL);
ctdb_db_iterator(ctdb, db_thaw, NULL);
ctdb->freeze_mode[h->priority] = CTDB_FREEZE_NONE;
ctdb->freeze_handles[h->priority] = NULL;
ctdb->freeze_mode = CTDB_FREEZE_NONE;
ctdb->freeze_handle = NULL;
return 0;
}
@ -340,7 +337,7 @@ static void ctdb_freeze_lock_handler(void *private_data, bool locked)
struct ctdb_freeze_handle);
struct ctdb_freeze_waiter *w;
if (h->ctdb->freeze_mode[h->priority] == CTDB_FREEZE_FROZEN) {
if (h->ctdb->freeze_mode == CTDB_FREEZE_FROZEN) {
DEBUG(DEBUG_INFO,("freeze child died - unfreezing\n"));
talloc_free(h);
return;
@ -353,10 +350,10 @@ static void ctdb_freeze_lock_handler(void *private_data, bool locked)
return;
}
h->ctdb->freeze_mode[h->priority] = CTDB_FREEZE_FROZEN;
h->ctdb->freeze_mode = CTDB_FREEZE_FROZEN;
/* notify the waiters */
if (h != h->ctdb->freeze_handles[h->priority]) {
if (h != h->ctdb->freeze_handle) {
DEBUG(DEBUG_ERR,("lockwait finished but h is not linked\n"));
}
while ((w = h->waiters)) {
@ -441,17 +438,12 @@ static int db_freeze(struct ctdb_db_context *ctdb_db, void *private_data)
/*
start the freeze process for a certain priority
*/
static void ctdb_start_freeze(struct ctdb_context *ctdb, uint32_t priority)
static void ctdb_start_freeze(struct ctdb_context *ctdb)
{
struct ctdb_freeze_handle *h;
int ret;
if ((priority < 1) || (priority > NUM_DB_PRIORITIES)) {
DEBUG(DEBUG_ERR,(__location__ " Invalid db priority : %u\n", priority));
ctdb_fatal(ctdb, "Internal error");
}
if (ctdb->freeze_mode[priority] == CTDB_FREEZE_FROZEN) {
if (ctdb->freeze_mode == CTDB_FREEZE_FROZEN) {
int count = 0;
/*
@ -464,45 +456,43 @@ static void ctdb_start_freeze(struct ctdb_context *ctdb, uint32_t priority)
* attach all the missing databases.
*/
h = ctdb->freeze_handles[priority];
h = ctdb->freeze_handle;
if (h == NULL) {
ctdb->freeze_mode[priority] = CTDB_FREEZE_NONE;
ctdb->freeze_mode = CTDB_FREEZE_NONE;
return;
}
ret = ctdb_db_prio_iterator(ctdb, priority, db_count, &count);
ret = ctdb_db_iterator(ctdb, db_count, &count);
if (ret != 0) {
TALLOC_FREE(ctdb->freeze_handles[priority]);
ctdb->freeze_mode[priority] = CTDB_FREEZE_NONE;
TALLOC_FREE(ctdb->freeze_handle);
ctdb->freeze_mode = CTDB_FREEZE_NONE;
return;
}
if (count != h->num_total) {
DEBUG(DEBUG_ERR, ("Freeze priority %u: incremental\n",
priority));
DEBUG(DEBUG_ERR, ("Freeze all: incremental\n"));
h->num_total = count;
h->num_locked = 0;
h->num_failed = 0;
ctdb->freeze_mode[priority] = CTDB_FREEZE_PENDING;
ctdb->freeze_mode = CTDB_FREEZE_PENDING;
ret = ctdb_db_prio_iterator(ctdb, priority,
db_freeze, h);
ret = ctdb_db_iterator(ctdb, db_freeze, h);
if (ret != 0) {
TALLOC_FREE(ctdb->freeze_handles[priority]);
ctdb->freeze_mode[priority] = CTDB_FREEZE_NONE;
TALLOC_FREE(ctdb->freeze_handle);
ctdb->freeze_mode = CTDB_FREEZE_NONE;
}
}
return;
}
if (ctdb->freeze_handles[priority] != NULL) {
if (ctdb->freeze_handle != NULL) {
/* already trying to freeze */
return;
}
DEBUG(DEBUG_ERR, ("Freeze priority %u\n", priority));
DEBUG(DEBUG_ERR, ("Freeze all\n"));
/* Stop any vacuuming going on: we don't want to wait. */
ctdb_stop_vacuuming(ctdb);
@ -511,26 +501,25 @@ static void ctdb_start_freeze(struct ctdb_context *ctdb, uint32_t priority)
h = talloc_zero(ctdb, struct ctdb_freeze_handle);
CTDB_NO_MEMORY_FATAL(ctdb, h);
h->ctdb = ctdb;
h->priority = priority;
talloc_set_destructor(h, ctdb_freeze_handle_destructor);
ctdb->freeze_handles[priority] = h;
ctdb->freeze_handle = h;
ret = ctdb_db_prio_iterator(ctdb, priority, db_count, &h->num_total);
ret = ctdb_db_iterator(ctdb, db_count, &h->num_total);
if (ret != 0) {
talloc_free(h);
return;
}
ctdb->freeze_mode[priority] = CTDB_FREEZE_PENDING;
ctdb->freeze_mode = CTDB_FREEZE_PENDING;
ret = ctdb_db_prio_iterator(ctdb, priority, db_freeze, h);
ret = ctdb_db_iterator(ctdb, db_freeze, h);
if (ret != 0) {
talloc_free(h);
return;
}
if (h->num_total == 0) {
ctdb->freeze_mode[priority] = CTDB_FREEZE_FROZEN;
ctdb->freeze_mode = CTDB_FREEZE_FROZEN;
}
}
@ -544,52 +533,39 @@ static int ctdb_freeze_waiter_destructor(struct ctdb_freeze_waiter *w)
}
/*
freeze the databases
freeze all the databases
*/
int32_t ctdb_control_freeze(struct ctdb_context *ctdb, struct ctdb_req_control_old *c, bool *async_reply)
int32_t ctdb_control_freeze(struct ctdb_context *ctdb,
struct ctdb_req_control_old *c, bool *async_reply)
{
struct ctdb_freeze_waiter *w;
uint32_t priority;
priority = (uint32_t)c->srvid;
ctdb_start_freeze(ctdb);
if (priority == 0) {
DEBUG(DEBUG_ERR,("Freeze priority 0 requested, remapping to priority 1\n"));
priority = 1;
}
if ((priority < 1) || (priority > NUM_DB_PRIORITIES)) {
DEBUG(DEBUG_ERR,(__location__ " Invalid db priority : %u\n", priority));
return -1;
}
ctdb_start_freeze(ctdb, priority);
if (ctdb->freeze_mode[priority] == CTDB_FREEZE_FROZEN) {
DEBUG(DEBUG_ERR, ("Freeze priority %u: frozen\n", priority));
if (ctdb->freeze_mode == CTDB_FREEZE_FROZEN) {
DEBUG(DEBUG_ERR, ("Freeze all: frozen\n"));
/* we're already frozen */
return 0;
}
if (ctdb->freeze_handles[priority] == NULL) {
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_handles[priority]->num_total == 0) {
if (ctdb->freeze_handle->num_total == 0) {
return 0;
}
/* add ourselves to list of waiters */
w = talloc(ctdb->freeze_handles[priority], struct ctdb_freeze_waiter);
w = talloc(ctdb->freeze_handle, struct ctdb_freeze_waiter);
CTDB_NO_MEMORY(ctdb, w);
w->ctdb = ctdb;
w->c = talloc_steal(w, c);
w->priority = priority;
w->status = -1;
talloc_set_destructor(w, ctdb_freeze_waiter_destructor);
DLIST_ADD(ctdb->freeze_handles[priority]->waiters, w);
DLIST_ADD(ctdb->freeze_handle->waiters, w);
/* we won't reply till later */
*async_reply = true;
@ -630,47 +606,32 @@ bool ctdb_blocking_freeze(struct ctdb_context *ctdb)
}
static void thaw_priority(struct ctdb_context *ctdb, uint32_t priority)
static void thaw_priority(struct ctdb_context *ctdb)
{
DEBUG(DEBUG_ERR,("Thawing priority %u\n", priority));
DEBUG(DEBUG_ERR,("Thawing all\n"));
/* cancel any pending transactions */
if (ctdb->freeze_transaction_started) {
ctdb_db_prio_iterator(ctdb, priority,
db_transaction_cancel_handler, NULL);
ctdb_db_iterator(ctdb, db_transaction_cancel_handler, NULL);
ctdb->freeze_transaction_started = false;
}
ctdb_db_prio_iterator(ctdb, priority, db_thaw, NULL);
TALLOC_FREE(ctdb->freeze_handles[priority]);
ctdb_db_iterator(ctdb, db_thaw, NULL);
TALLOC_FREE(ctdb->freeze_handle);
}
/*
thaw the databases
*/
int32_t ctdb_control_thaw(struct ctdb_context *ctdb, uint32_t priority,
bool check_recmode)
int32_t ctdb_control_thaw(struct ctdb_context *ctdb, bool check_recmode)
{
if (priority > NUM_DB_PRIORITIES) {
DEBUG(DEBUG_ERR,(__location__ " Invalid db priority : %u\n",
priority));
return -1;
}
if (check_recmode && ctdb->recovery_mode == CTDB_RECOVERY_ACTIVE) {
DEBUG(DEBUG_ERR, ("Failing to thaw databases while "
"recovery is active\n"));
return -1;
}
if (priority == 0) {
int i;
for (i=1;i<=NUM_DB_PRIORITIES; i++) {
thaw_priority(ctdb, i);
}
} else {
thaw_priority(ctdb, priority);
}
thaw_priority(ctdb);
ctdb_call_resend_all(ctdb);
return 0;
@ -1022,7 +983,7 @@ bool ctdb_db_prio_frozen(struct ctdb_context *ctdb, uint32_t priority)
return false;
}
if (ctdb->freeze_mode[priority] != CTDB_FREEZE_FROZEN) {
if (ctdb->freeze_mode != CTDB_FREEZE_FROZEN) {
return false;
}
@ -1031,12 +992,8 @@ bool ctdb_db_prio_frozen(struct ctdb_context *ctdb, uint32_t priority)
bool ctdb_db_all_frozen(struct ctdb_context *ctdb)
{
int i;
for (i=1; i<=NUM_DB_PRIORITIES; i++) {
if (ctdb->freeze_mode[i] != CTDB_FREEZE_FROZEN) {
return false;
}
if (ctdb->freeze_mode != CTDB_FREEZE_FROZEN) {
return false;
}
return true;
}

View File

@ -852,7 +852,6 @@ int32_t ctdb_control_set_recmode(struct ctdb_context *ctdb,
const char **errormsg)
{
uint32_t recmode = *(uint32_t *)indata.dptr;
int i;
struct ctdb_db_context *ctdb_db;
struct set_recmode_state *state;
struct ctdb_cluster_mutex_handle *h;
@ -896,10 +895,8 @@ int32_t ctdb_control_set_recmode(struct ctdb_context *ctdb,
}
/* force the databases to thaw */
for (i=1; i<=NUM_DB_PRIORITIES; i++) {
if (ctdb_db_prio_frozen(ctdb, i)) {
ctdb_control_thaw(ctdb, i, false);
}
if (ctdb_db_all_frozen(ctdb)) {
ctdb_control_thaw(ctdb, false);
}
if (ctdb->recovery_lock == NULL) {