struct ctdb_transaction_handle *h;
int ret;
- /* we have a good transaction */
h = talloc_zero(mem_ctx, struct ctdb_transaction_handle);
if (h == NULL) {
DEBUG(DEBUG_ERR,(__location__ " oom for transaction handle\n"));
struct ctdb_context *ctdb = h->ctdb_db->ctdb;
struct timeval timeout;
- talloc_set_destructor(h, NULL);
-
if (h->m_write == NULL) {
/* no changes were made */
talloc_free(h);
return 0;
}
+ talloc_set_destructor(h, NULL);
+
/* our commit strategy is quite complex.
- we first try to commit the changes to all other nodes
/* tell ctdbd that we are finished with our local commit */
ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
CTDB_CONTROL_TRANS2_FINISHED, CTDB_CTRL_FLAG_NOREPLY,
- tdb_null, NULL, NULL, &status, NULL, NULL);
+ tdb_null, NULL, NULL, NULL, NULL, NULL);
talloc_free(h);
return 0;
}
for (i=0;i<m->count;i++) {
struct ctdb_ltdb_header oldheader;
struct ctdb_ltdb_header header;
- TDB_DATA key, data;
+ TDB_DATA key, data, olddata;
+ TALLOC_CTX *tmp_ctx = talloc_new(state);
rec = ctdb_marshall_loop_next(m, rec, NULL, &header, &key, &data);
if (rec == NULL) {
DEBUG(DEBUG_ERR,("Failed to get next record %d for db_id 0x%08x in ctdb_persistent_store\n",
i, state->ctdb_db->db_id));
+ talloc_free(tmp_ctx);
goto failed;
}
/* fetch the old header and ensure the rsn is less than the new rsn */
- ret = ctdb_ltdb_fetch(state->ctdb_db, key, &oldheader, NULL, NULL);
+ ret = ctdb_ltdb_fetch(state->ctdb_db, key, &oldheader, tmp_ctx, &olddata);
if (ret != 0) {
DEBUG(DEBUG_ERR,("Failed to fetch old record for db_id 0x%08x in ctdb_persistent_store\n",
state->ctdb_db->db_id));
+ talloc_free(tmp_ctx);
goto failed;
}
- if (oldheader.rsn >= header.rsn) {
+ if (oldheader.rsn >= header.rsn &&
+ (olddata.dsize != data.dsize ||
+ memcmp(olddata.dptr, data.dptr, data.dsize) != 0)) {
DEBUG(DEBUG_CRIT,("existing header for db_id 0x%08x has larger RSN %llu than new RSN %llu in ctdb_persistent_store\n",
state->ctdb_db->db_id,
(unsigned long long)oldheader.rsn, (unsigned long long)header.rsn));
+ talloc_free(tmp_ctx);
goto failed;
}
+ talloc_free(tmp_ctx);
+
ret = ctdb_ltdb_store(state->ctdb_db, key, &header, data);
if (ret != 0) {
DEBUG(DEBUG_CRIT,("Failed to store record for db_id 0x%08x in ctdb_persistent_store\n",