2a6d8977002168d58ae35026bd711f68a85548a6
[samba.git] / lib / tdb / common / tdb.c
1  /*
2    Unix SMB/CIFS implementation.
3
4    trivial database library
5
6    Copyright (C) Andrew Tridgell              1999-2005
7    Copyright (C) Paul `Rusty' Russell              2000
8    Copyright (C) Jeremy Allison                    2000-2003
9
10      ** NOTE! The following LGPL license applies to the tdb
11      ** library. This does NOT imply that all of Samba is released
12      ** under the LGPL
13
14    This library is free software; you can redistribute it and/or
15    modify it under the terms of the GNU Lesser General Public
16    License as published by the Free Software Foundation; either
17    version 3 of the License, or (at your option) any later version.
18
19    This library is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    Lesser General Public License for more details.
23
24    You should have received a copy of the GNU Lesser General Public
25    License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 */
27
28 #include "tdb_private.h"
29
30 _PUBLIC_ TDB_DATA tdb_null;
31
32 /*
33   non-blocking increment of the tdb sequence number if the tdb has been opened using
34   the TDB_SEQNUM flag
35 */
36 _PUBLIC_ void tdb_increment_seqnum_nonblock(struct tdb_context *tdb)
37 {
38         tdb_off_t seqnum=0;
39
40         if (!(tdb->flags & TDB_SEQNUM)) {
41                 return;
42         }
43
44         /* we ignore errors from this, as we have no sane way of
45            dealing with them.
46         */
47         tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
48         seqnum++;
49         tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum);
50 }
51
52 /*
53   increment the tdb sequence number if the tdb has been opened using
54   the TDB_SEQNUM flag
55 */
56 static void tdb_increment_seqnum(struct tdb_context *tdb)
57 {
58         if (!(tdb->flags & TDB_SEQNUM)) {
59                 return;
60         }
61
62         if (tdb->transaction != NULL) {
63                 tdb_increment_seqnum_nonblock(tdb);
64                 return;
65         }
66
67         if (tdb_nest_lock(tdb, TDB_SEQNUM_OFS, F_WRLCK,
68                           TDB_LOCK_WAIT|TDB_LOCK_PROBE) != 0) {
69                 return;
70         }
71
72         tdb_increment_seqnum_nonblock(tdb);
73
74         tdb_nest_unlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, false);
75 }
76
77 static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data)
78 {
79         return memcmp(data.dptr, key.dptr, data.dsize);
80 }
81
82 void tdb_chainwalk_init(struct tdb_chainwalk_ctx *ctx, tdb_off_t ptr)
83 {
84         *ctx = (struct tdb_chainwalk_ctx) { .slow_ptr = ptr };
85 }
86
87 bool tdb_chainwalk_check(struct tdb_context *tdb,
88                          struct tdb_chainwalk_ctx *ctx,
89                          tdb_off_t next_ptr)
90 {
91         int ret;
92
93         if (ctx->slow_chase) {
94                 ret = tdb_ofs_read(tdb, ctx->slow_ptr, &ctx->slow_ptr);
95                 if (ret == -1) {
96                         return false;
97                 }
98         }
99         ctx->slow_chase = !ctx->slow_chase;
100
101         if (next_ptr == ctx->slow_ptr) {
102                 tdb->ecode = TDB_ERR_CORRUPT;
103                 TDB_LOG((tdb, TDB_DEBUG_ERROR,
104                          "tdb_chainwalk_check: circular chain\n"));
105                 return false;
106         }
107
108         return true;
109 }
110
111 /* Returns 0 on fail.  On success, return offset of record, and fills
112    in rec */
113 static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash,
114                         struct tdb_record *r)
115 {
116         tdb_off_t rec_ptr;
117         struct tdb_chainwalk_ctx chainwalk;
118
119         /* read in the hash top */
120         if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
121                 return 0;
122
123         tdb_chainwalk_init(&chainwalk, rec_ptr);
124
125         /* keep looking until we find the right record */
126         while (rec_ptr) {
127                 bool ok;
128
129                 if (tdb_rec_read(tdb, rec_ptr, r) == -1)
130                         return 0;
131
132                 if (!TDB_DEAD(r) && hash==r->full_hash
133                     && key.dsize==r->key_len
134                     && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r),
135                                       r->key_len, tdb_key_compare,
136                                       NULL) == 0) {
137                         return rec_ptr;
138                 }
139                 rec_ptr = r->next;
140
141                 ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr);
142                 if (!ok) {
143                         return 0;
144                 }
145         }
146         tdb->ecode = TDB_ERR_NOEXIST;
147         return 0;
148 }
149
150 /* As tdb_find, but if you succeed, keep the lock */
151 tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype,
152                            struct tdb_record *rec)
153 {
154         uint32_t rec_ptr;
155
156         if (tdb_lock(tdb, BUCKET(hash), locktype) == -1)
157                 return 0;
158         if (!(rec_ptr = tdb_find(tdb, key, hash, rec)))
159                 tdb_unlock(tdb, BUCKET(hash), locktype);
160         return rec_ptr;
161 }
162
163 static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key);
164
165 struct tdb_update_hash_state {
166         const TDB_DATA *dbufs;
167         int num_dbufs;
168         tdb_len_t dbufs_len;
169 };
170
171 static int tdb_update_hash_cmp(TDB_DATA key, TDB_DATA data, void *private_data)
172 {
173         struct tdb_update_hash_state *state = private_data;
174         unsigned char *dptr = data.dptr;
175         int i;
176
177         if (state->dbufs_len != data.dsize) {
178                 return -1;
179         }
180
181         for (i=0; i<state->num_dbufs; i++) {
182                 TDB_DATA dbuf = state->dbufs[i];
183                 int ret;
184                 ret = memcmp(dptr, dbuf.dptr, dbuf.dsize);
185                 if (ret != 0) {
186                         return -1;
187                 }
188                 dptr += dbuf.dsize;
189         }
190
191         return 0;
192 }
193
194 /* update an entry in place - this only works if the new data size
195    is <= the old data size and the key exists.
196    on failure return -1.
197 */
198 static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key,
199                            uint32_t hash,
200                            const TDB_DATA *dbufs, int num_dbufs,
201                            tdb_len_t dbufs_len)
202 {
203         struct tdb_record rec;
204         tdb_off_t rec_ptr, ofs;
205         int i;
206
207         /* find entry */
208         if (!(rec_ptr = tdb_find(tdb, key, hash, &rec)))
209                 return -1;
210
211         /* it could be an exact duplicate of what is there - this is
212          * surprisingly common (eg. with a ldb re-index). */
213         if (rec.data_len == dbufs_len) {
214                 struct tdb_update_hash_state state = {
215                         .dbufs = dbufs, .num_dbufs = num_dbufs,
216                         .dbufs_len = dbufs_len
217                 };
218                 int ret;
219
220                 ret = tdb_parse_record(tdb, key, tdb_update_hash_cmp, &state);
221                 if (ret == 0) {
222                         return 0;
223                 }
224         }
225
226         /* must be long enough key, data and tailer */
227         if (rec.rec_len < key.dsize + dbufs_len + sizeof(tdb_off_t)) {
228                 tdb->ecode = TDB_SUCCESS; /* Not really an error */
229                 return -1;
230         }
231
232         ofs = rec_ptr + sizeof(rec) + rec.key_len;
233
234         for (i=0; i<num_dbufs; i++) {
235                 TDB_DATA dbuf = dbufs[i];
236                 int ret;
237
238                 ret = tdb->methods->tdb_write(tdb, ofs, dbuf.dptr, dbuf.dsize);
239                 if (ret == -1) {
240                         return -1;
241                 }
242                 ofs += dbuf.dsize;
243         }
244
245         if (dbufs_len != rec.data_len) {
246                 /* update size */
247                 rec.data_len = dbufs_len;
248                 return tdb_rec_write(tdb, rec_ptr, &rec);
249         }
250
251         return 0;
252 }
253
254 /* find an entry in the database given a key */
255 /* If an entry doesn't exist tdb_err will be set to
256  * TDB_ERR_NOEXIST. If a key has no data attached
257  * then the TDB_DATA will have zero length but
258  * a non-zero pointer
259  */
260 static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key)
261 {
262         tdb_off_t rec_ptr;
263         struct tdb_record rec;
264         TDB_DATA ret;
265         uint32_t hash;
266
267         /* find which hash bucket it is in */
268         hash = tdb->hash_fn(&key);
269         if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec)))
270                 return tdb_null;
271
272         ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len,
273                                   rec.data_len);
274         ret.dsize = rec.data_len;
275         tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
276         return ret;
277 }
278
279 _PUBLIC_ TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key)
280 {
281         TDB_DATA ret = _tdb_fetch(tdb, key);
282
283         tdb_trace_1rec_retrec(tdb, "tdb_fetch", key, ret);
284         return ret;
285 }
286
287 /*
288  * Find an entry in the database and hand the record's data to a parsing
289  * function. The parsing function is executed under the chain read lock, so it
290  * should be fast and should not block on other syscalls.
291  *
292  * DON'T CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS.
293  *
294  * For mmapped tdb's that do not have a transaction open it points the parsing
295  * function directly at the mmap area, it avoids the malloc/memcpy in this
296  * case. If a transaction is open or no mmap is available, it has to do
297  * malloc/read/parse/free.
298  *
299  * This is interesting for all readers of potentially large data structures in
300  * the tdb records, ldb indexes being one example.
301  *
302  * Return -1 if the record was not found.
303  */
304
305 _PUBLIC_ int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key,
306                      int (*parser)(TDB_DATA key, TDB_DATA data,
307                                    void *private_data),
308                      void *private_data)
309 {
310         tdb_off_t rec_ptr;
311         struct tdb_record rec;
312         int ret;
313         uint32_t hash;
314
315         /* find which hash bucket it is in */
316         hash = tdb->hash_fn(&key);
317
318         if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
319                 /* record not found */
320                 tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, -1);
321                 tdb->ecode = TDB_ERR_NOEXIST;
322                 return -1;
323         }
324         tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, 0);
325
326         ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len,
327                              rec.data_len, parser, private_data);
328
329         tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
330
331         return ret;
332 }
333
334 /* check if an entry in the database exists
335
336    note that 1 is returned if the key is found and 0 is returned if not found
337    this doesn't match the conventions in the rest of this module, but is
338    compatible with gdbm
339 */
340 static int tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash)
341 {
342         struct tdb_record rec;
343
344         if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0)
345                 return 0;
346         tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
347         return 1;
348 }
349
350 _PUBLIC_ int tdb_exists(struct tdb_context *tdb, TDB_DATA key)
351 {
352         uint32_t hash = tdb->hash_fn(&key);
353         int ret;
354
355         ret = tdb_exists_hash(tdb, key, hash);
356         tdb_trace_1rec_ret(tdb, "tdb_exists", key, ret);
357         return ret;
358 }
359
360 /* actually delete an entry in the database given the offset */
361 int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct tdb_record *rec)
362 {
363         tdb_off_t last_ptr, i;
364         struct tdb_record lastrec;
365
366         if (tdb->read_only || tdb->traverse_read) return -1;
367
368         if (((tdb->traverse_write != 0) && (!TDB_DEAD(rec))) ||
369             tdb_write_lock_record(tdb, rec_ptr) == -1) {
370                 /* Someone traversing here: mark it as dead */
371                 rec->magic = TDB_DEAD_MAGIC;
372                 return tdb_rec_write(tdb, rec_ptr, rec);
373         }
374         if (tdb_write_unlock_record(tdb, rec_ptr) != 0)
375                 return -1;
376
377         /* find previous record in hash chain */
378         if (tdb_ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1)
379                 return -1;
380         for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next)
381                 if (tdb_rec_read(tdb, i, &lastrec) == -1)
382                         return -1;
383
384         /* unlink it: next ptr is at start of record. */
385         if (last_ptr == 0)
386                 last_ptr = TDB_HASH_TOP(rec->full_hash);
387         if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1)
388                 return -1;
389
390         /* recover the space */
391         if (tdb_free(tdb, rec_ptr, rec) == -1)
392                 return -1;
393         return 0;
394 }
395
396 static int tdb_count_dead(struct tdb_context *tdb, uint32_t hash)
397 {
398         int res = 0;
399         tdb_off_t rec_ptr;
400         struct tdb_record rec;
401
402         /* read in the hash top */
403         if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
404                 return 0;
405
406         while (rec_ptr) {
407                 if (tdb_rec_read(tdb, rec_ptr, &rec) == -1)
408                         return 0;
409
410                 if (rec.magic == TDB_DEAD_MAGIC) {
411                         res += 1;
412                 }
413                 rec_ptr = rec.next;
414         }
415         return res;
416 }
417
418 /*
419  * Purge all DEAD records from a hash chain
420  */
421 int tdb_purge_dead(struct tdb_context *tdb, uint32_t hash)
422 {
423         int res = -1;
424         struct tdb_record rec;
425         tdb_off_t rec_ptr;
426
427         if (tdb_lock_nonblock(tdb, -1, F_WRLCK) == -1) {
428                 /*
429                  * Don't block the freelist if not strictly necessary
430                  */
431                 return -1;
432         }
433
434         /* read in the hash top */
435         if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
436                 goto fail;
437
438         while (rec_ptr) {
439                 tdb_off_t next;
440
441                 if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) {
442                         goto fail;
443                 }
444
445                 next = rec.next;
446
447                 if (rec.magic == TDB_DEAD_MAGIC
448                     && tdb_do_delete(tdb, rec_ptr, &rec) == -1) {
449                         goto fail;
450                 }
451                 rec_ptr = next;
452         }
453         res = 0;
454  fail:
455         tdb_unlock(tdb, -1, F_WRLCK);
456         return res;
457 }
458
459 /* delete an entry in the database given a key */
460 static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash)
461 {
462         tdb_off_t rec_ptr;
463         struct tdb_record rec;
464         int ret;
465
466         if (tdb->read_only || tdb->traverse_read) {
467                 tdb->ecode = TDB_ERR_RDONLY;
468                 return -1;
469         }
470
471         rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec);
472         if (rec_ptr == 0) {
473                 return -1;
474         }
475
476         if (tdb->max_dead_records != 0) {
477
478                 uint32_t magic = TDB_DEAD_MAGIC;
479
480                 /*
481                  * Allow for some dead records per hash chain, mainly for
482                  * tdb's with a very high create/delete rate like locking.tdb.
483                  */
484
485                 if (tdb_count_dead(tdb, hash) >= tdb->max_dead_records) {
486                         /*
487                          * Don't let the per-chain freelist grow too large,
488                          * delete all existing dead records
489                          */
490                         tdb_purge_dead(tdb, hash);
491                 }
492
493                 /*
494                  * Just mark the record as dead.
495                  */
496                 ret = tdb_ofs_write(
497                         tdb, rec_ptr + offsetof(struct tdb_record, magic),
498                         &magic);
499         }
500         else {
501                 ret = tdb_do_delete(tdb, rec_ptr, &rec);
502         }
503
504         if (ret == 0) {
505                 tdb_increment_seqnum(tdb);
506         }
507
508         if (tdb_unlock(tdb, BUCKET(hash), F_WRLCK) != 0)
509                 TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n"));
510         return ret;
511 }
512
513 _PUBLIC_ int tdb_delete(struct tdb_context *tdb, TDB_DATA key)
514 {
515         uint32_t hash = tdb->hash_fn(&key);
516         int ret;
517
518         ret = tdb_delete_hash(tdb, key, hash);
519         tdb_trace_1rec_ret(tdb, "tdb_delete", key, ret);
520         return ret;
521 }
522
523 /*
524  * See if we have a dead record around with enough space
525  */
526 tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash,
527                         struct tdb_record *r, tdb_len_t length,
528                         tdb_off_t *p_last_ptr)
529 {
530         tdb_off_t rec_ptr, last_ptr;
531         struct tdb_chainwalk_ctx chainwalk;
532         tdb_off_t best_rec_ptr = 0;
533         tdb_off_t best_last_ptr = 0;
534         struct tdb_record best = { .rec_len = UINT32_MAX };
535
536         length += sizeof(tdb_off_t); /* tailer */
537
538         last_ptr = TDB_HASH_TOP(hash);
539
540         /* read in the hash top */
541         if (tdb_ofs_read(tdb, last_ptr, &rec_ptr) == -1)
542                 return 0;
543
544         tdb_chainwalk_init(&chainwalk, rec_ptr);
545
546         /* keep looking until we find the right record */
547         while (rec_ptr) {
548                 bool ok;
549
550                 if (tdb_rec_read(tdb, rec_ptr, r) == -1)
551                         return 0;
552
553                 if (TDB_DEAD(r) && (r->rec_len >= length) &&
554                     (r->rec_len < best.rec_len)) {
555                         best_rec_ptr = rec_ptr;
556                         best_last_ptr = last_ptr;
557                         best = *r;
558                 }
559                 last_ptr = rec_ptr;
560                 rec_ptr = r->next;
561
562                 ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr);
563                 if (!ok) {
564                         return 0;
565                 }
566         }
567
568         if (best.rec_len == UINT32_MAX) {
569                 return 0;
570         }
571
572         *r = best;
573         *p_last_ptr = best_last_ptr;
574         return best_rec_ptr;
575 }
576
577 static int _tdb_storev(struct tdb_context *tdb, TDB_DATA key,
578                        const TDB_DATA *dbufs, int num_dbufs,
579                        int flag, uint32_t hash)
580 {
581         struct tdb_record rec;
582         tdb_off_t rec_ptr, ofs;
583         tdb_len_t rec_len, dbufs_len;
584         int i;
585         int ret = -1;
586
587         dbufs_len = 0;
588
589         for (i=0; i<num_dbufs; i++) {
590                 size_t dsize = dbufs[i].dsize;
591
592                 if ((dsize != 0) && (dbufs[i].dptr == NULL)) {
593                         tdb->ecode = TDB_ERR_EINVAL;
594                         goto fail;
595                 }
596
597                 dbufs_len += dsize;
598                 if (dbufs_len < dsize) {
599                         tdb->ecode = TDB_ERR_OOM;
600                         goto fail;
601                 }
602         }
603
604         rec_len = key.dsize + dbufs_len;
605         if ((rec_len < key.dsize) || (rec_len < dbufs_len)) {
606                 tdb->ecode = TDB_ERR_OOM;
607                 goto fail;
608         }
609
610         /* check for it existing, on insert. */
611         if (flag == TDB_INSERT) {
612                 if (tdb_exists_hash(tdb, key, hash)) {
613                         tdb->ecode = TDB_ERR_EXISTS;
614                         goto fail;
615                 }
616         } else {
617                 /* first try in-place update, on modify or replace. */
618                 if (tdb_update_hash(tdb, key, hash, dbufs, num_dbufs,
619                                     dbufs_len) == 0) {
620                         goto done;
621                 }
622                 if (tdb->ecode == TDB_ERR_NOEXIST &&
623                     flag == TDB_MODIFY) {
624                         /* if the record doesn't exist and we are in TDB_MODIFY mode then
625                          we should fail the store */
626                         goto fail;
627                 }
628         }
629         /* reset the error code potentially set by the tdb_update_hash() */
630         tdb->ecode = TDB_SUCCESS;
631
632         /* delete any existing record - if it doesn't exist we don't
633            care.  Doing this first reduces fragmentation, and avoids
634            coalescing with `allocated' block before it's updated. */
635         if (flag != TDB_INSERT)
636                 tdb_delete_hash(tdb, key, hash);
637
638         /* we have to allocate some space */
639         rec_ptr = tdb_allocate(tdb, hash, rec_len, &rec);
640
641         if (rec_ptr == 0) {
642                 goto fail;
643         }
644
645         /* Read hash top into next ptr */
646         if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1)
647                 goto fail;
648
649         rec.key_len = key.dsize;
650         rec.data_len = dbufs_len;
651         rec.full_hash = hash;
652         rec.magic = TDB_MAGIC;
653
654         ofs = rec_ptr;
655
656         /* write out and point the top of the hash chain at it */
657         ret = tdb_rec_write(tdb, ofs, &rec);
658         if (ret == -1) {
659                 goto fail;
660         }
661         ofs += sizeof(rec);
662
663         ret = tdb->methods->tdb_write(tdb, ofs, key.dptr, key.dsize);
664         if (ret == -1) {
665                 goto fail;
666         }
667         ofs += key.dsize;
668
669         for (i=0; i<num_dbufs; i++) {
670                 if (dbufs[i].dsize == 0) {
671                         continue;
672                 }
673
674                 ret = tdb->methods->tdb_write(tdb, ofs, dbufs[i].dptr,
675                                               dbufs[i].dsize);
676                 if (ret == -1) {
677                         goto fail;
678                 }
679                 ofs += dbufs[i].dsize;
680         }
681
682         ret = tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr);
683         if (ret == -1) {
684                 /* Need to tdb_unallocate() here */
685                 goto fail;
686         }
687
688  done:
689         ret = 0;
690  fail:
691         if (ret == 0) {
692                 tdb_increment_seqnum(tdb);
693         }
694         return ret;
695 }
696
697 static int _tdb_store(struct tdb_context *tdb, TDB_DATA key,
698                       TDB_DATA dbuf, int flag, uint32_t hash)
699 {
700         return _tdb_storev(tdb, key, &dbuf, 1, flag, hash);
701 }
702
703 /* store an element in the database, replacing any existing element
704    with the same key
705
706    return 0 on success, -1 on failure
707 */
708 _PUBLIC_ int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
709 {
710         uint32_t hash;
711         int ret;
712
713         if (tdb->read_only || tdb->traverse_read) {
714                 tdb->ecode = TDB_ERR_RDONLY;
715                 tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, -1);
716                 return -1;
717         }
718
719         /* find which hash bucket it is in */
720         hash = tdb->hash_fn(&key);
721         if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
722                 return -1;
723
724         ret = _tdb_store(tdb, key, dbuf, flag, hash);
725         tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, ret);
726         tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
727         return ret;
728 }
729
730 _PUBLIC_ int tdb_storev(struct tdb_context *tdb, TDB_DATA key,
731                         const TDB_DATA *dbufs, int num_dbufs, int flag)
732 {
733         uint32_t hash;
734         int ret;
735
736         if (tdb->read_only || tdb->traverse_read) {
737                 tdb->ecode = TDB_ERR_RDONLY;
738                 tdb_trace_1plusn_rec_flag_ret(tdb, "tdb_storev", key,
739                                               dbufs, num_dbufs, flag, -1);
740                 return -1;
741         }
742
743         /* find which hash bucket it is in */
744         hash = tdb->hash_fn(&key);
745         if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
746                 return -1;
747
748         ret = _tdb_storev(tdb, key, dbufs, num_dbufs, flag, hash);
749         tdb_trace_1plusn_rec_flag_ret(tdb, "tdb_storev", key,
750                                       dbufs, num_dbufs, flag, -1);
751         tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
752         return ret;
753 }
754
755 /* Append to an entry. Create if not exist. */
756 _PUBLIC_ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
757 {
758         uint32_t hash;
759         TDB_DATA dbufs[2];
760         int ret = -1;
761
762         /* find which hash bucket it is in */
763         hash = tdb->hash_fn(&key);
764         if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
765                 return -1;
766
767         dbufs[0] = _tdb_fetch(tdb, key);
768         dbufs[1] = new_dbuf;
769
770         ret = _tdb_storev(tdb, key, dbufs, 2, 0, hash);
771         tdb_trace_2rec_retrec(tdb, "tdb_append", key, dbufs[0], dbufs[1]);
772
773         tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
774         SAFE_FREE(dbufs[0].dptr);
775         return ret;
776 }
777
778
779 /*
780   return the name of the current tdb file
781   useful for external logging functions
782 */
783 _PUBLIC_ const char *tdb_name(struct tdb_context *tdb)
784 {
785         return tdb->name;
786 }
787
788 /*
789   return the underlying file descriptor being used by tdb, or -1
790   useful for external routines that want to check the device/inode
791   of the fd
792 */
793 _PUBLIC_ int tdb_fd(struct tdb_context *tdb)
794 {
795         return tdb->fd;
796 }
797
798 /*
799   return the current logging function
800   useful for external tdb routines that wish to log tdb errors
801 */
802 _PUBLIC_ tdb_log_func tdb_log_fn(struct tdb_context *tdb)
803 {
804         return tdb->log.log_fn;
805 }
806
807
808 /*
809   get the tdb sequence number. Only makes sense if the writers opened
810   with TDB_SEQNUM set. Note that this sequence number will wrap quite
811   quickly, so it should only be used for a 'has something changed'
812   test, not for code that relies on the count of the number of changes
813   made. If you want a counter then use a tdb record.
814
815   The aim of this sequence number is to allow for a very lightweight
816   test of a possible tdb change.
817 */
818 _PUBLIC_ int tdb_get_seqnum(struct tdb_context *tdb)
819 {
820         tdb_off_t seqnum=0;
821
822         tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
823         return seqnum;
824 }
825
826 _PUBLIC_ int tdb_hash_size(struct tdb_context *tdb)
827 {
828         return tdb->hash_size;
829 }
830
831 _PUBLIC_ size_t tdb_map_size(struct tdb_context *tdb)
832 {
833         return tdb->map_size;
834 }
835
836 _PUBLIC_ int tdb_get_flags(struct tdb_context *tdb)
837 {
838         return tdb->flags;
839 }
840
841 _PUBLIC_ void tdb_add_flags(struct tdb_context *tdb, unsigned flags)
842 {
843         if ((flags & TDB_ALLOW_NESTING) &&
844             (flags & TDB_DISALLOW_NESTING)) {
845                 tdb->ecode = TDB_ERR_NESTING;
846                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_add_flags: "
847                         "allow_nesting and disallow_nesting are not allowed together!"));
848                 return;
849         }
850
851         if (flags & TDB_ALLOW_NESTING) {
852                 tdb->flags &= ~TDB_DISALLOW_NESTING;
853         }
854         if (flags & TDB_DISALLOW_NESTING) {
855                 tdb->flags &= ~TDB_ALLOW_NESTING;
856         }
857
858         tdb->flags |= flags;
859 }
860
861 _PUBLIC_ void tdb_remove_flags(struct tdb_context *tdb, unsigned flags)
862 {
863         if ((flags & TDB_ALLOW_NESTING) &&
864             (flags & TDB_DISALLOW_NESTING)) {
865                 tdb->ecode = TDB_ERR_NESTING;
866                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: "
867                         "allow_nesting and disallow_nesting are not allowed together!"));
868                 return;
869         }
870
871         if ((flags & TDB_NOLOCK) &&
872             (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) &&
873             (tdb->mutexes == NULL)) {
874                 tdb->ecode = TDB_ERR_LOCK;
875                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: "
876                          "Can not remove NOLOCK flag on mutexed databases"));
877                 return;
878         }
879
880         if (flags & TDB_ALLOW_NESTING) {
881                 tdb->flags |= TDB_DISALLOW_NESTING;
882         }
883         if (flags & TDB_DISALLOW_NESTING) {
884                 tdb->flags |= TDB_ALLOW_NESTING;
885         }
886
887         tdb->flags &= ~flags;
888 }
889
890
891 /*
892   enable sequence number handling on an open tdb
893 */
894 _PUBLIC_ void tdb_enable_seqnum(struct tdb_context *tdb)
895 {
896         tdb->flags |= TDB_SEQNUM;
897 }
898
899
900 /*
901   add a region of the file to the freelist. Length is the size of the region in bytes,
902   which includes the free list header that needs to be added
903  */
904 static int tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t length)
905 {
906         struct tdb_record rec;
907         if (length <= sizeof(rec)) {
908                 /* the region is not worth adding */
909                 return 0;
910         }
911         if (length + offset > tdb->map_size) {
912                 TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: adding region beyond end of file\n"));
913                 return -1;
914         }
915         memset(&rec,'\0',sizeof(rec));
916         rec.rec_len = length - sizeof(rec);
917         if (tdb_free(tdb, offset, &rec) == -1) {
918                 TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: failed to add free record\n"));
919                 return -1;
920         }
921         return 0;
922 }
923
924 /*
925   wipe the entire database, deleting all records. This can be done
926   very fast by using a allrecord lock. The entire data portion of the
927   file becomes a single entry in the freelist.
928
929   This code carefully steps around the recovery area, leaving it alone
930  */
931 _PUBLIC_ int tdb_wipe_all(struct tdb_context *tdb)
932 {
933         uint32_t i;
934         tdb_off_t offset = 0;
935         ssize_t data_len;
936         tdb_off_t recovery_head;
937         tdb_len_t recovery_size = 0;
938
939         if (tdb_lockall(tdb) != 0) {
940                 return -1;
941         }
942
943         tdb_trace(tdb, "tdb_wipe_all");
944
945         /* see if the tdb has a recovery area, and remember its size
946            if so. We don't want to lose this as otherwise each
947            tdb_wipe_all() in a transaction will increase the size of
948            the tdb by the size of the recovery area */
949         if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) {
950                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery head\n"));
951                 goto failed;
952         }
953
954         if (recovery_head != 0) {
955                 struct tdb_record rec;
956                 if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) {
957                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery record\n"));
958                         return -1;
959                 }
960                 recovery_size = rec.rec_len + sizeof(rec);
961         }
962
963         /* wipe the hashes */
964         for (i=0;i<tdb->hash_size;i++) {
965                 if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) {
966                         TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i));
967                         goto failed;
968                 }
969         }
970
971         /* wipe the freelist */
972         if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) {
973                 TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n"));
974                 goto failed;
975         }
976
977         /* add all the rest of the file to the freelist, possibly leaving a gap
978            for the recovery area */
979         if (recovery_size == 0) {
980                 /* the simple case - the whole file can be used as a freelist */
981                 data_len = (tdb->map_size - TDB_DATA_START(tdb->hash_size));
982                 if (tdb_free_region(tdb, TDB_DATA_START(tdb->hash_size), data_len) != 0) {
983                         goto failed;
984                 }
985         } else {
986                 /* we need to add two freelist entries - one on either
987                    side of the recovery area
988
989                    Note that we cannot shift the recovery area during
990                    this operation. Only the transaction.c code may
991                    move the recovery area or we risk subtle data
992                    corruption
993                 */
994                 data_len = (recovery_head - TDB_DATA_START(tdb->hash_size));
995                 if (tdb_free_region(tdb, TDB_DATA_START(tdb->hash_size), data_len) != 0) {
996                         goto failed;
997                 }
998                 /* and the 2nd free list entry after the recovery area - if any */
999                 data_len = tdb->map_size - (recovery_head+recovery_size);
1000                 if (tdb_free_region(tdb, recovery_head+recovery_size, data_len) != 0) {
1001                         goto failed;
1002                 }
1003         }
1004
1005         tdb_increment_seqnum_nonblock(tdb);
1006
1007         if (tdb_unlockall(tdb) != 0) {
1008                 TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n"));
1009                 goto failed;
1010         }
1011
1012         return 0;
1013
1014 failed:
1015         tdb_unlockall(tdb);
1016         return -1;
1017 }
1018
1019 struct traverse_state {
1020         bool error;
1021         struct tdb_context *dest_db;
1022 };
1023
1024 /*
1025   traverse function for repacking
1026  */
1027 static int repack_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data)
1028 {
1029         struct traverse_state *state = (struct traverse_state *)private_data;
1030         if (tdb_store(state->dest_db, key, data, TDB_INSERT) != 0) {
1031                 state->error = true;
1032                 return -1;
1033         }
1034         return 0;
1035 }
1036
1037 /*
1038   repack a tdb
1039  */
1040 _PUBLIC_ int tdb_repack(struct tdb_context *tdb)
1041 {
1042         struct tdb_context *tmp_db;
1043         struct traverse_state state;
1044
1045         tdb_trace(tdb, "tdb_repack");
1046
1047         if (tdb_transaction_start(tdb) != 0) {
1048                 TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to start transaction\n"));
1049                 return -1;
1050         }
1051
1052         tmp_db = tdb_open("tmpdb", tdb_hash_size(tdb), TDB_INTERNAL, O_RDWR|O_CREAT, 0);
1053         if (tmp_db == NULL) {
1054                 TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to create tmp_db\n"));
1055                 tdb_transaction_cancel(tdb);
1056                 return -1;
1057         }
1058
1059         state.error = false;
1060         state.dest_db = tmp_db;
1061
1062         if (tdb_traverse_read(tdb, repack_traverse, &state) == -1) {
1063                 TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying out\n"));
1064                 tdb_transaction_cancel(tdb);
1065                 tdb_close(tmp_db);
1066                 return -1;
1067         }
1068
1069         if (state.error) {
1070                 TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during traversal\n"));
1071                 tdb_transaction_cancel(tdb);
1072                 tdb_close(tmp_db);
1073                 return -1;
1074         }
1075
1076         if (tdb_wipe_all(tdb) != 0) {
1077                 TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to wipe database\n"));
1078                 tdb_transaction_cancel(tdb);
1079                 tdb_close(tmp_db);
1080                 return -1;
1081         }
1082
1083         state.error = false;
1084         state.dest_db = tdb;
1085
1086         if (tdb_traverse_read(tmp_db, repack_traverse, &state) == -1) {
1087                 TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying back\n"));
1088                 tdb_transaction_cancel(tdb);
1089                 tdb_close(tmp_db);
1090                 return -1;
1091         }
1092
1093         if (state.error) {
1094                 TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during second traversal\n"));
1095                 tdb_transaction_cancel(tdb);
1096                 tdb_close(tmp_db);
1097                 return -1;
1098         }
1099
1100         tdb_close(tmp_db);
1101
1102         if (tdb_transaction_commit(tdb) != 0) {
1103                 TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to commit\n"));
1104                 return -1;
1105         }
1106
1107         return 0;
1108 }
1109
1110 /* Even on files, we can get partial writes due to signals. */
1111 bool tdb_write_all(int fd, const void *buf, size_t count)
1112 {
1113         while (count) {
1114                 ssize_t ret;
1115                 ret = write(fd, buf, count);
1116                 if (ret < 0)
1117                         return false;
1118                 buf = (const char *)buf + ret;
1119                 count -= ret;
1120         }
1121         return true;
1122 }
1123
1124 bool tdb_add_off_t(tdb_off_t a, tdb_off_t b, tdb_off_t *pret)
1125 {
1126         tdb_off_t ret = a + b;
1127
1128         if ((ret < a) || (ret < b)) {
1129                 return false;
1130         }
1131         *pret = ret;
1132         return true;
1133 }
1134
1135 #ifdef TDB_TRACE
1136 static void tdb_trace_write(struct tdb_context *tdb, const char *str)
1137 {
1138         if (!tdb_write_all(tdb->tracefd, str, strlen(str))) {
1139                 close(tdb->tracefd);
1140                 tdb->tracefd = -1;
1141         }
1142 }
1143
1144 static void tdb_trace_start(struct tdb_context *tdb)
1145 {
1146         tdb_off_t seqnum=0;
1147         char msg[sizeof(tdb_off_t) * 4 + 1];
1148
1149         tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
1150         snprintf(msg, sizeof(msg), "%u ", seqnum);
1151         tdb_trace_write(tdb, msg);
1152 }
1153
1154 static void tdb_trace_end(struct tdb_context *tdb)
1155 {
1156         tdb_trace_write(tdb, "\n");
1157 }
1158
1159 static void tdb_trace_end_ret(struct tdb_context *tdb, int ret)
1160 {
1161         char msg[sizeof(ret) * 4 + 4];
1162         snprintf(msg, sizeof(msg), " = %i\n", ret);
1163         tdb_trace_write(tdb, msg);
1164 }
1165
1166 static void tdb_trace_record(struct tdb_context *tdb, TDB_DATA rec)
1167 {
1168         char msg[20 + rec.dsize*2], *p;
1169         unsigned int i;
1170
1171         /* We differentiate zero-length records from non-existent ones. */
1172         if (rec.dptr == NULL) {
1173                 tdb_trace_write(tdb, " NULL");
1174                 return;
1175         }
1176
1177         /* snprintf here is purely cargo-cult programming. */
1178         p = msg;
1179         p += snprintf(p, sizeof(msg), " %zu:", rec.dsize);
1180         for (i = 0; i < rec.dsize; i++)
1181                 p += snprintf(p, 2, "%02x", rec.dptr[i]);
1182
1183         tdb_trace_write(tdb, msg);
1184 }
1185
1186 void tdb_trace(struct tdb_context *tdb, const char *op)
1187 {
1188         tdb_trace_start(tdb);
1189         tdb_trace_write(tdb, op);
1190         tdb_trace_end(tdb);
1191 }
1192
1193 void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op)
1194 {
1195         char msg[sizeof(tdb_off_t) * 4 + 1];
1196
1197         snprintf(msg, sizeof(msg), "%u ", seqnum);
1198         tdb_trace_write(tdb, msg);
1199         tdb_trace_write(tdb, op);
1200         tdb_trace_end(tdb);
1201 }
1202
1203 void tdb_trace_open(struct tdb_context *tdb, const char *op,
1204                     unsigned hash_size, unsigned tdb_flags, unsigned open_flags)
1205 {
1206         char msg[128];
1207
1208         snprintf(msg, sizeof(msg),
1209                  "%s %u 0x%x 0x%x", op, hash_size, tdb_flags, open_flags);
1210         tdb_trace_start(tdb);
1211         tdb_trace_write(tdb, msg);
1212         tdb_trace_end(tdb);
1213 }
1214
1215 void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret)
1216 {
1217         tdb_trace_start(tdb);
1218         tdb_trace_write(tdb, op);
1219         tdb_trace_end_ret(tdb, ret);
1220 }
1221
1222 void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret)
1223 {
1224         tdb_trace_start(tdb);
1225         tdb_trace_write(tdb, op);
1226         tdb_trace_write(tdb, " =");
1227         tdb_trace_record(tdb, ret);
1228         tdb_trace_end(tdb);
1229 }
1230
1231 void tdb_trace_1rec(struct tdb_context *tdb, const char *op,
1232                     TDB_DATA rec)
1233 {
1234         tdb_trace_start(tdb);
1235         tdb_trace_write(tdb, op);
1236         tdb_trace_record(tdb, rec);
1237         tdb_trace_end(tdb);
1238 }
1239
1240 void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op,
1241                         TDB_DATA rec, int ret)
1242 {
1243         tdb_trace_start(tdb);
1244         tdb_trace_write(tdb, op);
1245         tdb_trace_record(tdb, rec);
1246         tdb_trace_end_ret(tdb, ret);
1247 }
1248
1249 void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op,
1250                            TDB_DATA rec, TDB_DATA ret)
1251 {
1252         tdb_trace_start(tdb);
1253         tdb_trace_write(tdb, op);
1254         tdb_trace_record(tdb, rec);
1255         tdb_trace_write(tdb, " =");
1256         tdb_trace_record(tdb, ret);
1257         tdb_trace_end(tdb);
1258 }
1259
1260 void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op,
1261                              TDB_DATA rec1, TDB_DATA rec2, unsigned flag,
1262                              int ret)
1263 {
1264         char msg[1 + sizeof(ret) * 4];
1265
1266         snprintf(msg, sizeof(msg), " %#x", flag);
1267         tdb_trace_start(tdb);
1268         tdb_trace_write(tdb, op);
1269         tdb_trace_record(tdb, rec1);
1270         tdb_trace_record(tdb, rec2);
1271         tdb_trace_write(tdb, msg);
1272         tdb_trace_end_ret(tdb, ret);
1273 }
1274
1275 void tdb_trace_1plusn_rec_flag_ret(struct tdb_context *tdb, const char *op,
1276                                    TDB_DATA rec,
1277                                    const TDB_DATA *recs, int num_recs,
1278                                    unsigned flag, int ret)
1279 {
1280         char msg[1 + sizeof(ret) * 4];
1281         int i;
1282
1283         snprintf(msg, sizeof(msg), " %#x", flag);
1284         tdb_trace_start(tdb);
1285         tdb_trace_write(tdb, op);
1286         tdb_trace_record(tdb, rec);
1287         for (i=0; i<num_recs; i++) {
1288                 tdb_trace_record(tdb, recs[i]);
1289         }
1290         tdb_trace_write(tdb, msg);
1291         tdb_trace_end_ret(tdb, ret);
1292 }
1293
1294 void tdb_trace_2rec_retrec(struct tdb_context *tdb, const char *op,
1295                            TDB_DATA rec1, TDB_DATA rec2, TDB_DATA ret)
1296 {
1297         tdb_trace_start(tdb);
1298         tdb_trace_write(tdb, op);
1299         tdb_trace_record(tdb, rec1);
1300         tdb_trace_record(tdb, rec2);
1301         tdb_trace_write(tdb, " =");
1302         tdb_trace_record(tdb, ret);
1303         tdb_trace_end(tdb);
1304 }
1305 #endif