r20918: a bit more debugging, and remove the hackish /dev/null writes I used
[Samba.git] / source / cluster / ctdb / common / ctdb_ltdb.c
blobcc49aa501619952737fbe492395accda85b62b2b
1 /*
2 ctdb ltdb code
4 Copyright (C) Andrew Tridgell 2006
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "includes.h"
22 #include "lib/events/events.h"
23 #include "lib/tdb/include/tdb.h"
24 #include "system/network.h"
25 #include "system/filesys.h"
26 #include "cluster/ctdb/include/ctdb_private.h"
29 attach to a specific database
31 int ctdb_attach(struct ctdb_context *ctdb, const char *name, int tdb_flags,
32 int open_flags, mode_t mode)
34 /* when we have a separate daemon this will need to be a real
35 file, not a TDB_INTERNAL, so the parent can access it to
36 for ltdb bypass */
37 ctdb->ltdb = tdb_open(name, 0, /* tdb_flags */ TDB_INTERNAL, open_flags, mode);
38 if (ctdb->ltdb == NULL) {
39 ctdb_set_error(ctdb, "Failed to open tdb %s\n", name);
40 return -1;
42 return 0;
46 return the lmaster given a key
48 uint32_t ctdb_lmaster(struct ctdb_context *ctdb, const TDB_DATA *key)
50 return ctdb_hash(key) % ctdb->num_nodes;
55 construct an initial header for a record with no ltdb header yet
57 static void ltdb_initial_header(struct ctdb_context *ctdb,
58 TDB_DATA key,
59 struct ctdb_ltdb_header *header)
61 header->rsn = 0;
62 /* initial dmaster is the lmaster */
63 header->dmaster = ctdb_lmaster(ctdb, &key);
64 header->laccessor = header->dmaster;
65 header->lacount = 0;
70 fetch a record from the ltdb, separating out the header information
71 and returning the body of the record. A valid (initial) header is
72 returned if the record is not present
74 int ctdb_ltdb_fetch(struct ctdb_context *ctdb,
75 TDB_DATA key, struct ctdb_ltdb_header *header, TDB_DATA *data)
77 TDB_DATA rec;
79 rec = tdb_fetch(ctdb->ltdb, key);
80 if (rec.dsize < sizeof(*header)) {
81 /* return an initial header */
82 free(rec.dptr);
83 ltdb_initial_header(ctdb, key, header);
84 data->dptr = NULL;
85 data->dsize = 0;
86 return 0;
89 *header = *(struct ctdb_ltdb_header *)rec.dptr;
91 data->dsize = rec.dsize - sizeof(struct ctdb_ltdb_header);
92 data->dptr = talloc_memdup(ctdb, sizeof(struct ctdb_ltdb_header)+rec.dptr,
93 data->dsize);
94 free(rec.dptr);
95 CTDB_NO_MEMORY(ctdb, data->dptr);
97 return 0;
102 fetch a record from the ltdb, separating out the header information
103 and returning the body of the record. A valid (initial) header is
104 returned if the record is not present
106 int ctdb_ltdb_store(struct ctdb_context *ctdb, TDB_DATA key,
107 struct ctdb_ltdb_header *header, TDB_DATA data)
109 TDB_DATA rec;
110 int ret;
112 rec.dsize = sizeof(*header) + data.dsize;
113 rec.dptr = talloc_size(ctdb, rec.dsize);
114 CTDB_NO_MEMORY(ctdb, rec.dptr);
116 memcpy(rec.dptr, header, sizeof(*header));
117 memcpy(rec.dptr + sizeof(*header), data.dptr, data.dsize);
119 ret = tdb_store(ctdb->ltdb, key, rec, TDB_REPLACE);
120 talloc_free(rec.dptr);
122 return ret;