1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-24 02:04:21 +03:00

added paranoid transaction ids

(This used to be ctdb commit afc1da53873cdbd31fcc8c6b22fae262e344cf6e)
This commit is contained in:
Andrew Tridgell 2008-01-06 13:24:55 +11:00
parent c08f2616cd
commit 748843a3c6
4 changed files with 45 additions and 16 deletions

View File

@ -996,6 +996,11 @@ struct ctdb_node_map {
struct ctdb_node_and_flags nodes[1];
};
struct ctdb_control_wipe_database {
uint32_t db_id;
uint32_t transaction_id;
};
int32_t ctdb_control_traverse_start(struct ctdb_context *ctdb, TDB_DATA indata,
TDB_DATA *outdata, uint32_t srcnode);
int32_t ctdb_control_traverse_all(struct ctdb_context *ctdb, TDB_DATA data, TDB_DATA *outdata);
@ -1177,8 +1182,8 @@ int32_t ctdb_control_update_record(struct ctdb_context *ctdb,
struct ctdb_req_control *c, TDB_DATA recdata,
bool *async_reply);
int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb);
int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb);
int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb, uint32_t id);
int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb, uint32_t id);
int32_t ctdb_control_wipe_database(struct ctdb_context *ctdb, TDB_DATA indata);
#endif

View File

@ -310,13 +310,15 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
return ctdb_control_send_gratious_arp(ctdb, indata);
case CTDB_CONTROL_TRANSACTION_START:
return ctdb_control_transaction_start(ctdb);
CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
return ctdb_control_transaction_start(ctdb, *(uint32_t *)indata.dptr);
case CTDB_CONTROL_TRANSACTION_COMMIT:
return ctdb_control_transaction_commit(ctdb);
CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
return ctdb_control_transaction_commit(ctdb, *(uint32_t *)indata.dptr);
case CTDB_CONTROL_WIPE_DATABASE:
CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_wipe_database));
return ctdb_control_wipe_database(ctdb, indata);
default:

View File

@ -59,6 +59,7 @@ struct ctdb_freeze_handle {
int fd;
struct ctdb_freeze_waiter *waiters;
bool transaction_started;
uint32_t transaction_id;
};
/*
@ -285,7 +286,7 @@ int32_t ctdb_control_thaw(struct ctdb_context *ctdb)
/*
start a transaction on all databases - used for recovery
*/
int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb)
int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb, uint32_t id)
{
struct ctdb_db_context *ctdb_db;
@ -320,6 +321,7 @@ int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb)
}
ctdb->freeze_handle->transaction_started = true;
ctdb->freeze_handle->transaction_id = id;
return 0;
}
@ -327,7 +329,7 @@ int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb)
/*
commit transactions on all databases
*/
int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb)
int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb, uint32_t id)
{
struct ctdb_db_context *ctdb_db;
@ -341,6 +343,11 @@ int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb)
return -1;
}
if (id != ctdb->freeze_handle->transaction_id) {
DEBUG(0,(__location__ " incorrect transaction id 0x%x in commit\n", id));
return -1;
}
for (ctdb_db=ctdb->db_list;ctdb_db;ctdb_db=ctdb_db->next) {
tdb_add_flags(ctdb_db->ltdb->tdb, TDB_NOLOCK);
if (tdb_transaction_commit(ctdb_db->ltdb->tdb) != 0) {
@ -355,6 +362,7 @@ int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb)
}
ctdb->freeze_handle->transaction_started = false;
ctdb->freeze_handle->transaction_id = 0;
return 0;
}
@ -364,8 +372,8 @@ int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb)
*/
int32_t ctdb_control_wipe_database(struct ctdb_context *ctdb, TDB_DATA indata)
{
struct ctdb_control_wipe_database w = *(struct ctdb_control_wipe_database *)indata.dptr;
struct ctdb_db_context *ctdb_db;
uint32_t db_id = *(uint32_t *)indata.dptr;
if (ctdb->freeze_mode != CTDB_FREEZE_FROZEN) {
DEBUG(0,(__location__ " Failed transaction_start while not frozen\n"));
@ -377,9 +385,14 @@ int32_t ctdb_control_wipe_database(struct ctdb_context *ctdb, TDB_DATA indata)
return -1;
}
ctdb_db = find_ctdb_db(ctdb, db_id);
if (w.transaction_id != ctdb->freeze_handle->transaction_id) {
DEBUG(0,(__location__ " incorrect transaction id 0x%x in commit\n", w.transaction_id));
return -1;
}
ctdb_db = find_ctdb_db(ctdb, w.db_id);
if (!ctdb_db) {
DEBUG(0,(__location__ " Unknown db 0x%x\n", db_id));
DEBUG(0,(__location__ " Unknown db 0x%x\n", w.db_id));
return -1;
}

View File

@ -982,12 +982,14 @@ static int recover_database(struct ctdb_recoverd *rec,
TALLOC_CTX *mem_ctx,
uint32_t dbid,
uint32_t pnn,
struct ctdb_node_map *nodemap)
struct ctdb_node_map *nodemap,
uint32_t transaction_id)
{
struct tdb_wrap *recdb;
int ret;
struct ctdb_context *ctdb = rec->ctdb;
TDB_DATA data;
struct ctdb_control_wipe_database w;
recdb = create_recdb(ctdb, mem_ctx);
if (recdb == NULL) {
@ -1004,8 +1006,11 @@ static int recover_database(struct ctdb_recoverd *rec,
DEBUG(0, (__location__ " Recovery - pulled remote database 0x%x\n", dbid));
/* wipe all the remote databases. This is safe as we are in a transaction */
data.dptr = (void *)&dbid;
data.dsize = sizeof(uint32_t);
w.db_id = dbid;
w.transaction_id = transaction_id;
data.dptr = (void *)&w;
data.dsize = sizeof(w);
if (async_control_on_active_nodes(ctdb, CTDB_CONTROL_WIPE_DATABASE,
nodemap, data, true) != 0) {
@ -1040,6 +1045,7 @@ static int do_recovery(struct ctdb_recoverd *rec,
int i, j, ret;
uint32_t generation;
struct ctdb_dbid_map *dbmap;
TDB_DATA data;
DEBUG(0, (__location__ " Starting do_recovery\n"));
@ -1116,8 +1122,11 @@ static int do_recovery(struct ctdb_recoverd *rec,
return -1;
}
data.dptr = (void *)&generation;
data.dsize = sizeof(uint32_t);
if (async_control_on_active_nodes(ctdb, CTDB_CONTROL_TRANSACTION_START,
nodemap, tdb_null, true) != 0) {
nodemap, data, true) != 0) {
DEBUG(0, (__location__ " Unable to start transactions. Recovery failed.\n"));
return -1;
}
@ -1125,7 +1134,7 @@ static int do_recovery(struct ctdb_recoverd *rec,
DEBUG(0,(__location__ " started transactions on all nodes\n"));
for (i=0;i<dbmap->num;i++) {
if (recover_database(rec, mem_ctx, dbmap->dbs[i].dbid, pnn, nodemap) != 0) {
if (recover_database(rec, mem_ctx, dbmap->dbs[i].dbid, pnn, nodemap, generation) != 0) {
DEBUG(0, (__location__ " Failed to recover database 0x%x\n", dbmap->dbs[i].dbid));
return -1;
}
@ -1135,7 +1144,7 @@ static int do_recovery(struct ctdb_recoverd *rec,
/* commit all the changes */
if (async_control_on_active_nodes(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
nodemap, tdb_null, true) != 0) {
nodemap, data, true) != 0) {
DEBUG(0, (__location__ " Unable to commit recovery changes. Recovery failed.\n"));
return -1;
}