summaryrefslogtreecommitdiff
path: root/source4/cluster/ctdb/common/ctdb_ltdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/cluster/ctdb/common/ctdb_ltdb.c')
-rw-r--r--source4/cluster/ctdb/common/ctdb_ltdb.c70
1 files changed, 56 insertions, 14 deletions
diff --git a/source4/cluster/ctdb/common/ctdb_ltdb.c b/source4/cluster/ctdb/common/ctdb_ltdb.c
index 10bcde43b5..189816229f 100644
--- a/source4/cluster/ctdb/common/ctdb_ltdb.c
+++ b/source4/cluster/ctdb/common/ctdb_ltdb.c
@@ -25,23 +25,63 @@
#include "system/filesys.h"
#include "../include/ctdb_private.h"
#include "db_wrap.h"
+#include "lib/util/dlinklist.h"
+/*
+ find an attached ctdb_db handle given a name
+ */
+struct ctdb_db_context *ctdb_db_handle(struct ctdb_context *ctdb, const char *name)
+{
+ struct ctdb_db_context *tmp_db;
+ for (tmp_db=ctdb->db_list;tmp_db;tmp_db=tmp_db->next) {
+ if (strcmp(name, tmp_db->db_name) == 0) {
+ return tmp_db;
+ }
+ }
+ return NULL;
+}
/*
attach to a specific database
*/
-int ctdb_attach(struct ctdb_context *ctdb, const char *name, int tdb_flags,
- int open_flags, mode_t mode)
+struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb, const char *name, int tdb_flags,
+ int open_flags, mode_t mode)
{
+ struct ctdb_db_context *ctdb_db, *tmp_db;
+ TDB_DATA data;
+
+ ctdb_db = talloc_zero(ctdb, struct ctdb_db_context);
+ CTDB_NO_MEMORY_NULL(ctdb, ctdb_db);
+
+ ctdb_db->ctdb = ctdb;
+ ctdb_db->db_name = talloc_strdup(ctdb_db, name);
+ CTDB_NO_MEMORY_NULL(ctdb, ctdb_db->db_name);
+
+ data.dptr = discard_const(name);
+ data.dsize = strlen(name);
+ ctdb_db->db_id = ctdb_hash(&data);
+
+ for (tmp_db=ctdb->db_list;tmp_db;tmp_db=tmp_db->next) {
+ if (tmp_db->db_id == ctdb_db->db_id) {
+ ctdb_set_error(ctdb, "CTDB database hash collission '%s' : '%s'",
+ name, tmp_db->db_name);
+ talloc_free(ctdb_db);
+ return NULL;
+ }
+ }
+
/* when we have a separate daemon this will need to be a real
file, not a TDB_INTERNAL, so the parent can access it to
for ltdb bypass */
- ctdb->ltdb = tdb_wrap_open(ctdb, name, 0, TDB_INTERNAL, open_flags, mode);
- if (ctdb->ltdb == NULL) {
+ ctdb_db->ltdb = tdb_wrap_open(ctdb, name, 0, TDB_INTERNAL, open_flags, mode);
+ if (ctdb_db->ltdb == NULL) {
ctdb_set_error(ctdb, "Failed to open tdb %s\n", name);
- return -1;
+ talloc_free(ctdb_db);
+ return NULL;
}
- return 0;
+
+ DLIST_ADD(ctdb->db_list, ctdb_db);
+ return ctdb_db;
}
/*
@@ -56,13 +96,13 @@ uint32_t ctdb_lmaster(struct ctdb_context *ctdb, const TDB_DATA *key)
/*
construct an initial header for a record with no ltdb header yet
*/
-static void ltdb_initial_header(struct ctdb_context *ctdb,
+static void ltdb_initial_header(struct ctdb_db_context *ctdb_db,
TDB_DATA key,
struct ctdb_ltdb_header *header)
{
header->rsn = 0;
/* initial dmaster is the lmaster */
- header->dmaster = ctdb_lmaster(ctdb, &key);
+ header->dmaster = ctdb_lmaster(ctdb_db->ctdb, &key);
header->laccessor = header->dmaster;
header->lacount = 0;
}
@@ -73,16 +113,17 @@ static void ltdb_initial_header(struct ctdb_context *ctdb,
and returning the body of the record. A valid (initial) header is
returned if the record is not present
*/
-int ctdb_ltdb_fetch(struct ctdb_context *ctdb,
+int ctdb_ltdb_fetch(struct ctdb_db_context *ctdb_db,
TDB_DATA key, struct ctdb_ltdb_header *header, TDB_DATA *data)
{
TDB_DATA rec;
+ struct ctdb_context *ctdb = ctdb_db->ctdb;
- rec = tdb_fetch(ctdb->ltdb->tdb, key);
+ rec = tdb_fetch(ctdb_db->ltdb->tdb, key);
if (rec.dsize < sizeof(*header)) {
/* return an initial header */
free(rec.dptr);
- ltdb_initial_header(ctdb, key, header);
+ ltdb_initial_header(ctdb_db, key, header);
data->dptr = NULL;
data->dsize = 0;
return 0;
@@ -91,7 +132,7 @@ int ctdb_ltdb_fetch(struct ctdb_context *ctdb,
*header = *(struct ctdb_ltdb_header *)rec.dptr;
data->dsize = rec.dsize - sizeof(struct ctdb_ltdb_header);
- data->dptr = talloc_memdup(ctdb, sizeof(struct ctdb_ltdb_header)+rec.dptr,
+ data->dptr = talloc_memdup(ctdb_db, sizeof(struct ctdb_ltdb_header)+rec.dptr,
data->dsize);
free(rec.dptr);
CTDB_NO_MEMORY(ctdb, data->dptr);
@@ -105,9 +146,10 @@ int ctdb_ltdb_fetch(struct ctdb_context *ctdb,
and returning the body of the record. A valid (initial) header is
returned if the record is not present
*/
-int ctdb_ltdb_store(struct ctdb_context *ctdb, TDB_DATA key,
+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;
@@ -118,7 +160,7 @@ int ctdb_ltdb_store(struct ctdb_context *ctdb, TDB_DATA key,
memcpy(rec.dptr, header, sizeof(*header));
memcpy(rec.dptr + sizeof(*header), data.dptr, data.dsize);
- ret = tdb_store(ctdb->ltdb->tdb, key, rec, TDB_REPLACE);
+ ret = tdb_store(ctdb_db->ltdb->tdb, key, rec, TDB_REPLACE);
talloc_free(rec.dptr);
return ret;