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:
parent
c08f2616cd
commit
748843a3c6
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user