Fix last few includes to use new tdb location.
[ira/wip.git] / source4 / lib / dbwrap / dbwrap_ctdb.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Database interface wrapper around ctdbd
5
6    Copyright (C) Andrew Tridgell 2007
7    
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.
12    
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.
17    
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/>.
20 */
21
22 #include "includes.h"
23 #include "../tdb/include/tdb.h"
24 #include "lib/dbwrap/dbwrap.h"
25 #include "cluster/cluster.h"
26 #include "cluster/ctdb/include/ctdb.h"
27
28 static NTSTATUS db_ctdb_store(struct db_record *rec, TDB_DATA data, int flag)
29 {
30         struct ctdb_record_handle *h = talloc_get_type(rec->private_data, struct ctdb_record_handle);
31         int ret;
32
33         ret = ctdb_record_store(h, data);
34         if (ret != 0) {
35                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
36         }
37         return NT_STATUS_OK;
38 }
39
40 static NTSTATUS db_ctdb_delete(struct db_record *rec)
41 {
42         return rec->store(rec, tdb_null, TDB_REPLACE);
43 }
44
45
46 static struct db_record *db_ctdb_fetch_locked(struct db_context *db,
47                                               TALLOC_CTX *mem_ctx,
48                                               TDB_DATA key)
49 {
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);
53
54         rec = talloc(mem_ctx, struct db_record);
55         if (!rec) return NULL;
56
57         h = ctdb_fetch_lock(cdb, rec, key, &rec->value);
58         if (h == NULL) {
59                 talloc_free(rec);
60                 return NULL;
61         }
62
63         rec->private_data = h;
64         rec->store        = db_ctdb_store;
65         rec->delete_rec   = db_ctdb_delete;
66
67         return rec;
68 }
69
70 /*
71   fetch (unlocked, no migration) operation on ctdb
72  */
73 static int db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
74                          TDB_DATA key, TDB_DATA *data)
75 {
76         struct ctdb_db_context *cdb = talloc_get_type(db->private_data, struct ctdb_db_context);
77
78         return ctdb_fetch(cdb, mem_ctx, key, data);
79 }
80
81 struct traverse_state {
82         struct db_context *db;
83         int (*fn)(struct db_record *rec, void *private_data);
84         void *private_data;
85 };
86
87 static int traverse_callback(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, void *private_data)
88 {
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);
96         }
97         talloc_free(tmp_ctx);
98         return 0;
99 }
100
101 static int db_ctdb_traverse(struct db_context *db,
102                             int (*fn)(struct db_record *rec, void *private_data),
103                             void *private_data)
104 {
105         struct ctdb_db_context *cdb = talloc_get_type(db->private_data, struct ctdb_db_context);
106         struct traverse_state state;
107
108         state.db = db;
109         state.fn = fn;
110         state.private_data = private_data;
111
112         ctdb_traverse(cdb, traverse_callback, &state);
113         return 0;
114 }
115
116 static NTSTATUS db_ctdb_store_deny(struct db_record *rec, TDB_DATA data, int flag)
117 {
118         return NT_STATUS_MEDIA_WRITE_PROTECTED;
119 }
120
121 static NTSTATUS db_ctdb_delete_deny(struct db_record *rec)
122 {
123         return NT_STATUS_MEDIA_WRITE_PROTECTED;
124 }
125
126 static int traverse_read_callback(struct ctdb_context *ctdb, 
127                                   TDB_DATA key, TDB_DATA data, void *private_data)
128 {
129         struct traverse_state *state = (struct traverse_state *)private_data;
130         struct db_record rec;
131         rec.key = key;
132         rec.value = data;
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);
137         return 0;
138 }
139
140 static int db_ctdb_traverse_read(struct db_context *db,
141                                  int (*fn)(struct db_record *rec,
142                                            void *private_data),
143                                  void *private_data)
144 {
145         struct traverse_state state;
146         struct ctdb_db_context *cdb = talloc_get_type(db->private_data, struct ctdb_db_context);
147
148         state.db = db;
149         state.fn = fn;
150         state.private_data = private_data;
151
152         ctdb_traverse(cdb, traverse_read_callback, &state);
153         return 0;
154 }
155
156 static int db_ctdb_get_seqnum(struct db_context *db)
157 {
158         DEBUG(0,("ctdb_get_seqnum not implemented\n"));
159         return -1;
160 }
161
162 struct db_context *db_tmp_open_ctdb(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
163                                     const char *name, int tdb_flags)
164 {
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;
169
170         db = talloc_zero(mem_ctx, struct db_context);
171         if (db == NULL) {
172                 return NULL;
173         }
174
175         cdb = ctdb_attach(ctdb, name);
176         if (!cdb) {
177                 DEBUG(0,("Failed to attach to ctdb database '%s'\n", name));
178                 talloc_free(db);
179                 return NULL;
180         }
181
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;
188
189         DEBUG(3,("db_tmp_open_ctdb: opened database '%s'\n", name));
190
191         return db;
192 }