return 0;
}
+/*
+ bump rsn on all records
+ */
+int ctdb_ctrl_bumprsn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid)
+{
+ int ret;
+ TDB_DATA indata, outdata;
+ int32_t res;
+
+ indata.dsize = sizeof(uint32_t);
+ indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 1);
+
+ ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
+
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_BUMP_RSN, 0, indata,
+ mem_ctx, &outdata, &res, &timeout);
+ if (ret != 0 || res != 0) {
+ DEBUG(0,(__location__ " ctdb_control for bumprsn failed\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
/*
ping a node, return number of clients connected
*/
CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
return ctdb_control_clear_db(ctdb, indata);
+ case CTDB_CONTROL_BUMP_RSN:
+ CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
+ return ctdb_control_bump_rsn(ctdb, indata);
+
case CTDB_CONTROL_PUSH_DB:
return ctdb_control_push_db(ctdb, indata);
return 0;
}
+
+static int traverse_bumprsn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p)
+{
+ struct ctdb_ltdb_header *header = (struct ctdb_ltdb_header *)data.dptr;
+ int ret;
+
+ header->rsn++;
+
+ ret = tdb_store(tdb, key, data, TDB_REPLACE);
+ if (ret) {
+ DEBUG(0,(__location__ "failed to write tdb data back ret:%d\n",ret));
+ return ret;
+ }
+ return 0;
+}
+
+int32_t ctdb_control_bump_rsn(struct ctdb_context *ctdb, TDB_DATA indata)
+{
+ uint32_t dbid = *(uint32_t *)indata.dptr;
+ struct ctdb_db_context *ctdb_db;
+
+ ctdb_db = find_ctdb_db(ctdb, dbid);
+ if (!ctdb_db) {
+ DEBUG(0,(__location__ " Unknown db 0x%08x\n",dbid));
+ return -1;
+ }
+
+ if (tdb_lockall_nonblock(ctdb_db->ltdb->tdb) != 0) {
+ DEBUG(0,(__location__ " Failed to get nonblock lock on entired db - failing\n"));
+ return -1;
+ }
+
+ tdb_traverse(ctdb_db->ltdb->tdb, traverse_bumprsn, NULL);
+
+ tdb_unlockall(ctdb_db->ltdb->tdb);
+
+ return 0;
+}
}
+static int bump_rsn_on_all_databases(struct ctdb_context *ctdb, uint32_t vnn, struct ctdb_dbid_map *dbmap, TALLOC_CTX *mem_ctx)
+{
+ int i, ret;
+
+ /* bump rsn for all records in all databases */
+ for (i=0;i<dbmap->num;i++) {
+ ret = ctdb_ctrl_bumprsn(ctdb, timeval_current_ofs(1, 0), vnn, ctdb, dbmap->dbids[i]);
+ if (ret != 0) {
+ DEBUG(0, (__location__ "Unable to bump rsn for db:0x%08x\n", dbmap->dbids[i]));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
static int push_all_local_databases(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap, uint32_t vnn, struct ctdb_dbid_map *dbmap, TALLOC_CTX *mem_ctx)
{
int i, j, ret;
}
+ /* bump the rsn number on all databases
+ */
+ ret = bump_rsn_on_all_databases(ctdb, vnn, dbmap, mem_ctx);
+ if (ret != 0) {
+ DEBUG(0, (__location__ "Unable to bump the rsn on all databases\n"));
+ return -1;
+ }
+
/* disable recovery mode */
ret = set_recovery_mode(ctdb, nodemap, CTDB_RECOVERY_NORMAL);
*/
int ctdb_ctrl_cleardb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid);
+/*
+ bump the rsn number for al records
+ */
+int ctdb_ctrl_bumprsn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid);
+
/*
write a record on a specific db (this implicitely updates dmaster of the record to locally be the vnn of the node where the control is executed on)
*/
CTDB_CONTROL_GET_PID,
CTDB_CONTROL_GET_RECMASTER,
CTDB_CONTROL_SET_RECMASTER,
+ CTDB_CONTROL_BUMP_RSN,
};
int32_t ctdb_control_push_db(struct ctdb_context *ctdb, TDB_DATA indata);
int32_t ctdb_control_set_dmaster(struct ctdb_context *ctdb, TDB_DATA indata);
int32_t ctdb_control_clear_db(struct ctdb_context *ctdb, TDB_DATA indata);
+int32_t ctdb_control_bump_rsn(struct ctdb_context *ctdb, TDB_DATA indata);
#endif