*/
#include "includes.h"
-#include "lib/events/events.h"
+#include "lib/tevent/tevent.h"
#include "lib/tdb/include/tdb.h"
#include "system/network.h"
#include "system/filesys.h"
TDB_DATA key,
struct ctdb_ltdb_header *header)
{
- header->rsn = 0;
+ ZERO_STRUCTP(header);
/* initial dmaster is the lmaster */
header->dmaster = ctdb_lmaster(ctdb_db->ctdb, &key);
- header->laccessor = header->dmaster;
- header->lacount = 0;
}
/*
- fetch a record from the ltdb, separating out the header information
- and returning the body of the record. A valid (initial) header is
- returned if the record is not present
+ write a record to a normal database
*/
int ctdb_ltdb_store(struct ctdb_db_context *ctdb_db, TDB_DATA key,
struct ctdb_ltdb_header *header, TDB_DATA data)
struct ctdb_context *ctdb = ctdb_db->ctdb;
TDB_DATA rec;
int ret;
+ bool seqnum_suppressed = false;
if (ctdb->flags & CTDB_FLAG_TORTURE) {
struct ctdb_ltdb_header *h2;
memcpy(rec.dptr, header, sizeof(*header));
memcpy(rec.dptr + sizeof(*header), data.dptr, data.dsize);
- /* if this is a persistent database without NOSYNC then we
- will do this via a transaction */
- if (ctdb_db->persistent && !(ctdb_db->client_tdb_flags & TDB_NOSYNC)) {
- bool transaction_started = true;
-
- ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
- if (ret != 0) {
- transaction_started = false;
- DEBUG(DEBUG_NOTICE, ("Failed to start local transaction\n"));
- }
- ret = tdb_store(ctdb_db->ltdb->tdb, key, rec, TDB_REPLACE);
- if (ret != 0) {
- if (transaction_started) {
- tdb_transaction_cancel(ctdb_db->ltdb->tdb);
- }
- goto failed;
- }
- if (transaction_started) {
- ret = tdb_transaction_commit(ctdb_db->ltdb->tdb);
+ /* Databases with seqnum updates enabled only get their seqnum
+ changes when/if we modify the data */
+ if (ctdb_db->seqnum_update != NULL) {
+ TDB_DATA old;
+ old = tdb_fetch(ctdb_db->ltdb->tdb, key);
+
+ if ( (old.dsize == rec.dsize)
+ && !memcmp(old.dptr+sizeof(struct ctdb_ltdb_header),
+ rec.dptr+sizeof(struct ctdb_ltdb_header),
+ rec.dsize-sizeof(struct ctdb_ltdb_header)) ) {
+ tdb_remove_flags(ctdb_db->ltdb->tdb, TDB_SEQNUM);
+ seqnum_suppressed = true;
}
- } else {
- ret = tdb_store(ctdb_db->ltdb->tdb, key, rec, TDB_REPLACE);
+ if (old.dptr) free(old.dptr);
+ }
+ ret = tdb_store(ctdb_db->ltdb->tdb, key, rec, TDB_REPLACE);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, (__location__ " Failed to store dynamic data\n"));
+ }
+ if (seqnum_suppressed) {
+ tdb_add_flags(ctdb_db->ltdb->tdb, TDB_SEQNUM);
}
-failed:
talloc_free(rec.dptr);
return ret;
}
-
/*
lock a record in the ltdb, given a key
*/
{
int ret = tdb_chainunlock(ctdb_db->ltdb->tdb, key);
if (ret != 0) {
- DEBUG(DEBUG_ERR,("tdb_chainunlock failed\n"));
+ DEBUG(DEBUG_ERR,("tdb_chainunlock failed on db %s [%s]\n", ctdb_db->db_name, tdb_errorstr(ctdb_db->ltdb->tdb)));
}
return ret;
}
+
+
+/*
+ delete a record from a normal database
+*/
+int ctdb_ltdb_delete(struct ctdb_db_context *ctdb_db, TDB_DATA key)
+{
+ struct ctdb_context *ctdb = ctdb_db->ctdb;
+
+ if (ctdb_db->persistent != 0) {
+ DEBUG(DEBUG_ERR,("Trying to delete emty record in persistent database\n"));
+ return 0;
+ }
+ if (tdb_delete(ctdb_db->ltdb->tdb, key) != 0) {
+ DEBUG(DEBUG_ERR,("Failed to delete empty record."));
+ return -1;
+ }
+ return 0;
+}