2 Unix SMB/CIFS implementation.
4 Database interface wrapper around ctdbd
6 Copyright (C) Andrew Tridgell 2007
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "../tdb/include/tdb.h"
24 #include "lib/dbwrap/dbwrap.h"
25 #include "cluster/cluster.h"
26 #include "cluster/ctdb/include/ctdb.h"
28 static NTSTATUS db_ctdb_store(struct db_record *rec, TDB_DATA data, int flag)
30 struct ctdb_record_handle *h = talloc_get_type(rec->private_data, struct ctdb_record_handle);
33 ret = ctdb_record_store(h, data);
35 return NT_STATUS_INTERNAL_DB_CORRUPTION;
40 static NTSTATUS db_ctdb_delete(struct db_record *rec)
42 return rec->store(rec, tdb_null, TDB_REPLACE);
46 static struct db_record *db_ctdb_fetch_locked(struct db_context *db,
50 struct db_record *rec;
51 struct ctdb_record_handle *h;
52 struct ctdb_db_context *cdb = talloc_get_type(db->private_data, struct ctdb_db_context);
54 rec = talloc(mem_ctx, struct db_record);
55 if (!rec) return NULL;
57 h = ctdb_fetch_lock(cdb, rec, key, &rec->value);
63 rec->private_data = h;
64 rec->store = db_ctdb_store;
65 rec->delete_rec = db_ctdb_delete;
71 fetch (unlocked, no migration) operation on ctdb
73 static int db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
74 TDB_DATA key, TDB_DATA *data)
76 struct ctdb_db_context *cdb = talloc_get_type(db->private_data, struct ctdb_db_context);
78 return ctdb_fetch(cdb, mem_ctx, key, data);
81 struct traverse_state {
82 struct db_context *db;
83 int (*fn)(struct db_record *rec, void *private_data);
87 static int traverse_callback(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, void *private_data)
89 struct traverse_state *state = (struct traverse_state *)private_data;
90 struct db_record *rec;
91 TALLOC_CTX *tmp_ctx = talloc_new(state->db);
92 /* we have to give them a locked record to prevent races */
93 rec = db_ctdb_fetch_locked(state->db, tmp_ctx, key);
94 if (rec && rec->value.dsize > 0) {
95 state->fn(rec, state->private_data);
101 static int db_ctdb_traverse(struct db_context *db,
102 int (*fn)(struct db_record *rec, void *private_data),
105 struct ctdb_db_context *cdb = talloc_get_type(db->private_data, struct ctdb_db_context);
106 struct traverse_state state;
110 state.private_data = private_data;
112 ctdb_traverse(cdb, traverse_callback, &state);
116 static NTSTATUS db_ctdb_store_deny(struct db_record *rec, TDB_DATA data, int flag)
118 return NT_STATUS_MEDIA_WRITE_PROTECTED;
121 static NTSTATUS db_ctdb_delete_deny(struct db_record *rec)
123 return NT_STATUS_MEDIA_WRITE_PROTECTED;
126 static int traverse_read_callback(struct ctdb_context *ctdb,
127 TDB_DATA key, TDB_DATA data, void *private_data)
129 struct traverse_state *state = (struct traverse_state *)private_data;
130 struct db_record rec;
133 rec.store = db_ctdb_store_deny;
134 rec.delete_rec = db_ctdb_delete_deny;
135 rec.private_data = state->db;
136 state->fn(&rec, state->private_data);
140 static int db_ctdb_traverse_read(struct db_context *db,
141 int (*fn)(struct db_record *rec,
145 struct traverse_state state;
146 struct ctdb_db_context *cdb = talloc_get_type(db->private_data, struct ctdb_db_context);
150 state.private_data = private_data;
152 ctdb_traverse(cdb, traverse_read_callback, &state);
156 static int db_ctdb_get_seqnum(struct db_context *db)
158 DEBUG(0,("ctdb_get_seqnum not implemented\n"));
162 struct db_context *db_tmp_open_ctdb(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
163 const char *name, int tdb_flags)
165 struct db_context *db;
166 struct ctdb_context *ctdb = talloc_get_type(cluster_backend_handle(),
167 struct ctdb_context);
168 struct ctdb_db_context *cdb;
170 db = talloc_zero(mem_ctx, struct db_context);
175 cdb = ctdb_attach(ctdb, name);
177 DEBUG(0,("Failed to attach to ctdb database '%s'\n", name));
182 db->private_data = cdb;
183 db->fetch_locked = db_ctdb_fetch_locked;
184 db->fetch = db_ctdb_fetch;
185 db->traverse = db_ctdb_traverse;
186 db->traverse_read = db_ctdb_traverse_read;
187 db->get_seqnum = db_ctdb_get_seqnum;
189 DEBUG(3,("db_tmp_open_ctdb: opened database '%s'\n", name));