struct revokechild_handle *revokechild_active;
struct ctdb_persistent_state *persistent_state;
struct trbt_tree *delete_queue;
+ struct trbt_tree *fetch_queue;
struct trbt_tree *sticky_records;
int (*ctdb_ltdb_store_fn)(struct ctdb_db_context *ctdb_db,
TDB_DATA key,
const struct ctdb_ltdb_header *hdr,
const TDB_DATA key);
+int32_t ctdb_control_vacuum_fetch(struct ctdb_context *ctdb, TDB_DATA indata);
+
/* from eventscript.c */
int ctdb_start_eventd(struct ctdb_context *ctdb);
if (ctdb_db_volatile(ctdb_db)) {
talloc_free(ctdb_db->delete_queue);
+ talloc_free(ctdb_db->fetch_queue);
ctdb_db->delete_queue = trbt_create(ctdb_db, 0);
if (ctdb_db->delete_queue == NULL) {
DEBUG(DEBUG_ERR, (__location__ " Failed to re-create "
- "the vacuum tree.\n"));
+ "the delete queue.\n"));
+ return -1;
+ }
+ ctdb_db->fetch_queue = trbt_create(ctdb_db, 0);
+ if (ctdb_db->fetch_queue == NULL) {
+ DEBUG(DEBUG_ERR, (__location__ " Failed to re-create "
+ "the fetch queue.\n"));
return -1;
}
}
CTDB_NO_MEMORY(ctdb, ctdb_db->delete_queue);
}
+ ctdb_db->fetch_queue = trbt_create(ctdb_db, 0);
+ if (ctdb_db->fetch_queue == NULL) {
+ CTDB_NO_MEMORY(ctdb, ctdb_db->fetch_queue);
+ }
+
ctdb_db->ctdb_ltdb_store_fn = ctdb_ltdb_store_server;
}
/* Disable vacuuming and drop all vacuuming data */
talloc_free(ctdb_db->vacuum_handle);
talloc_free(ctdb_db->delete_queue);
+ talloc_free(ctdb_db->fetch_queue);
/* Terminate any deferred fetch */
talloc_free(ctdb_db->deferred_fetch);
#include "common/common.h"
#include "common/logging.h"
+#include "protocol/protocol_api.h"
+
#define TIMELIMIT() timeval_current_ofs(10, 0)
enum vacuum_child_status { VACUUM_RUNNING, VACUUM_OK, VACUUM_ERROR, VACUUM_TIMEOUT};
struct vacuum_data *vdata;
};
+struct fetch_record_data {
+ TDB_DATA key;
+ uint8_t keydata[1];
+};
+
static int insert_record_into_delete_queue(struct ctdb_db_context *ctdb_db,
const struct ctdb_ltdb_header *hdr,
TDB_DATA key);
return;
}
+
+static int vacuum_fetch_parser(uint32_t reqid,
+ struct ctdb_ltdb_header *header,
+ TDB_DATA key, TDB_DATA data,
+ void *private_data)
+{
+ struct ctdb_db_context *ctdb_db = talloc_get_type_abort(
+ private_data, struct ctdb_db_context);
+ struct fetch_record_data *rd;
+ size_t len;
+ uint32_t hash;
+
+ len = offsetof(struct fetch_record_data, keydata) + key.dsize;
+
+ rd = (struct fetch_record_data *)talloc_size(ctdb_db->fetch_queue,
+ len);
+ if (rd == NULL) {
+ DEBUG(DEBUG_ERR, (__location__ " Memory error\n"));
+ return -1;
+ }
+ talloc_set_name_const(rd, "struct fetch_record_data");
+
+ rd->key.dsize = key.dsize;
+ rd->key.dptr = rd->keydata;
+ memcpy(rd->keydata, key.dptr, key.dsize);
+
+ hash = ctdb_hash(&key);
+
+ trbt_insert32(ctdb_db->fetch_queue, hash, rd);
+
+ return 0;
+}
+
+int32_t ctdb_control_vacuum_fetch(struct ctdb_context *ctdb, TDB_DATA indata)
+{
+ struct ctdb_rec_buffer *recbuf;
+ struct ctdb_db_context *ctdb_db;
+ size_t npull;
+ int ret;
+
+ ret = ctdb_rec_buffer_pull(indata.dptr, indata.dsize, ctdb, &recbuf,
+ &npull);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Invalid data in vacuum_fetch\n"));
+ return -1;
+ }
+
+ ctdb_db = find_ctdb_db(ctdb, recbuf->db_id);
+ if (ctdb_db == NULL) {
+ talloc_free(recbuf);
+ DEBUG(DEBUG_ERR, (__location__ " Unknown db 0x%08x\n",
+ recbuf->db_id));
+ return -1;
+ }
+
+ ret = ctdb_rec_buffer_traverse(recbuf, vacuum_fetch_parser, ctdb_db);
+ talloc_free(recbuf);
+ return ret;
+}