Commit b929638e authored by Rusty Russell's avatar Rusty Russell

tdb2: Remove unused tdb1 functions.

We're going to use TDB2's API, so some TDB1 APIs are obviously unnecessary.  
We also get rid of USE_RIGHT_MERGES and TRACE code.
parent fab544c2
...@@ -32,8 +32,6 @@ ...@@ -32,8 +32,6 @@
#include <sys/types.h> #include <sys/types.h>
/* For O_* flags. */ /* For O_* flags. */
#include <sys/stat.h> #include <sys/stat.h>
/* For sig_atomic_t. */
#include <signal.h>
#endif #endif
/** Flags to tdb1_store() */ /** Flags to tdb1_store() */
...@@ -106,16 +104,6 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag ...@@ -106,16 +104,6 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag
void tdb1_set_max_dead(struct tdb1_context *tdb, int max_dead); void tdb1_set_max_dead(struct tdb1_context *tdb, int max_dead);
int tdb1_reopen(struct tdb1_context *tdb);
int tdb1_reopen_all(int parent_longlived);
void tdb1_set_logging_function(struct tdb1_context *tdb, const struct tdb1_logging_context *log_ctx);
enum TDB1_ERROR tdb1_error(struct tdb1_context *tdb);
const char *tdb1_errorstr(struct tdb1_context *tdb);
TDB1_DATA tdb1_fetch(struct tdb1_context *tdb, TDB1_DATA key); TDB1_DATA tdb1_fetch(struct tdb1_context *tdb, TDB1_DATA key);
int tdb1_parse_record(struct tdb1_context *tdb, TDB1_DATA key, int tdb1_parse_record(struct tdb1_context *tdb, TDB1_DATA key,
...@@ -143,32 +131,16 @@ int tdb1_exists(struct tdb1_context *tdb, TDB1_DATA key); ...@@ -143,32 +131,16 @@ int tdb1_exists(struct tdb1_context *tdb, TDB1_DATA key);
int tdb1_lockall(struct tdb1_context *tdb); int tdb1_lockall(struct tdb1_context *tdb);
int tdb1_lockall_nonblock(struct tdb1_context *tdb);
int tdb1_unlockall(struct tdb1_context *tdb); int tdb1_unlockall(struct tdb1_context *tdb);
int tdb1_lockall_read(struct tdb1_context *tdb); int tdb1_lockall_read(struct tdb1_context *tdb);
int tdb1_lockall_read_nonblock(struct tdb1_context *tdb);
int tdb1_unlockall_read(struct tdb1_context *tdb); int tdb1_unlockall_read(struct tdb1_context *tdb);
int tdb1_lockall_mark(struct tdb1_context *tdb);
int tdb1_lockall_unmark(struct tdb1_context *tdb);
const char *tdb1_name(struct tdb1_context *tdb);
int tdb1_fd(struct tdb1_context *tdb);
tdb1_log_func tdb1_log_fn(struct tdb1_context *tdb); tdb1_log_func tdb1_log_fn(struct tdb1_context *tdb);
void *tdb1_get_logging_private(struct tdb1_context *tdb);
int tdb1_transaction_start(struct tdb1_context *tdb); int tdb1_transaction_start(struct tdb1_context *tdb);
int tdb1_transaction_start_nonblock(struct tdb1_context *tdb);
int tdb1_transaction_prepare_commit(struct tdb1_context *tdb); int tdb1_transaction_prepare_commit(struct tdb1_context *tdb);
int tdb1_transaction_commit(struct tdb1_context *tdb); int tdb1_transaction_commit(struct tdb1_context *tdb);
...@@ -179,16 +151,6 @@ int tdb1_get_seqnum(struct tdb1_context *tdb); ...@@ -179,16 +151,6 @@ int tdb1_get_seqnum(struct tdb1_context *tdb);
int tdb1_hash_size(struct tdb1_context *tdb); int tdb1_hash_size(struct tdb1_context *tdb);
size_t tdb1_map_size(struct tdb1_context *tdb);
int tdb1_get_flags(struct tdb1_context *tdb);
void tdb1_add_flags(struct tdb1_context *tdb, unsigned flag);
void tdb1_remove_flags(struct tdb1_context *tdb, unsigned flag);
void tdb1_enable_seqnum(struct tdb1_context *tdb);
void tdb1_increment_seqnum_nonblock(struct tdb1_context *tdb); void tdb1_increment_seqnum_nonblock(struct tdb1_context *tdb);
unsigned int tdb1_jenkins_hash(TDB1_DATA *key); unsigned int tdb1_jenkins_hash(TDB1_DATA *key);
...@@ -201,24 +163,16 @@ int tdb1_check(struct tdb1_context *tdb, ...@@ -201,24 +163,16 @@ int tdb1_check(struct tdb1_context *tdb,
/* Low level locking functions: use with care */ /* Low level locking functions: use with care */
int tdb1_chainlock(struct tdb1_context *tdb, TDB1_DATA key); int tdb1_chainlock(struct tdb1_context *tdb, TDB1_DATA key);
int tdb1_chainlock_nonblock(struct tdb1_context *tdb, TDB1_DATA key);
int tdb1_chainunlock(struct tdb1_context *tdb, TDB1_DATA key); int tdb1_chainunlock(struct tdb1_context *tdb, TDB1_DATA key);
int tdb1_chainlock_read(struct tdb1_context *tdb, TDB1_DATA key); int tdb1_chainlock_read(struct tdb1_context *tdb, TDB1_DATA key);
int tdb1_chainunlock_read(struct tdb1_context *tdb, TDB1_DATA key); int tdb1_chainunlock_read(struct tdb1_context *tdb, TDB1_DATA key);
int tdb1_chainlock_mark(struct tdb1_context *tdb, TDB1_DATA key);
int tdb1_chainlock_unmark(struct tdb1_context *tdb, TDB1_DATA key);
void tdb1_setalarm_sigptr(struct tdb1_context *tdb, volatile sig_atomic_t *sigptr);
/* wipe and repack */ /* wipe and repack */
int tdb1_wipe_all(struct tdb1_context *tdb); int tdb1_wipe_all(struct tdb1_context *tdb);
int tdb1_repack(struct tdb1_context *tdb); int tdb1_repack(struct tdb1_context *tdb);
/* Debug functions. Not used in production. */ /* Debug functions. Not used in production. */
void tdb1_dump_all(struct tdb1_context *tdb);
int tdb1_printfreelist(struct tdb1_context *tdb);
int tdb1_validate_freelist(struct tdb1_context *tdb, int *pnum_entries);
int tdb1_freelist_size(struct tdb1_context *tdb);
char *tdb1_summary(struct tdb1_context *tdb); char *tdb1_summary(struct tdb1_context *tdb);
extern TDB1_DATA tdb1_null; extern TDB1_DATA tdb1_null;
......
/*
Unix SMB/CIFS implementation.
trivial database library
Copyright (C) Andrew Tridgell 1999-2005
Copyright (C) Paul `Rusty' Russell 2000
Copyright (C) Jeremy Allison 2000-2003
** NOTE! The following LGPL license applies to the tdb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "tdb1_private.h"
static tdb1_off_t tdb1_dump_record(struct tdb1_context *tdb, int hash,
tdb1_off_t offset)
{
struct tdb1_record rec;
tdb1_off_t tailer_ofs, tailer;
if (tdb->methods->tdb1_read(tdb, offset, (char *)&rec,
sizeof(rec), TDB1_DOCONV()) == -1) {
printf("ERROR: failed to read record at %u\n", offset);
return 0;
}
printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%d "
"key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n",
hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len,
rec.full_hash, rec.magic);
tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb1_off_t);
if (tdb1_ofs_read(tdb, tailer_ofs, &tailer) == -1) {
printf("ERROR: failed to read tailer at %u\n", tailer_ofs);
return rec.next;
}
if (tailer != rec.rec_len + sizeof(rec)) {
printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n",
(unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec)));
}
return rec.next;
}
static int tdb1_dump_chain(struct tdb1_context *tdb, int i)
{
tdb1_off_t rec_ptr, top;
top = TDB1_HASH_TOP(i);
if (tdb1_lock(tdb, i, F_WRLCK) != 0)
return -1;
if (tdb1_ofs_read(tdb, top, &rec_ptr) == -1)
return tdb1_unlock(tdb, i, F_WRLCK);
if (rec_ptr)
printf("hash=%d\n", i);
while (rec_ptr) {
rec_ptr = tdb1_dump_record(tdb, i, rec_ptr);
}
return tdb1_unlock(tdb, i, F_WRLCK);
}
_PUBLIC_ void tdb1_dump_all(struct tdb1_context *tdb)
{
int i;
for (i=0;i<tdb->header.hash_size;i++) {
tdb1_dump_chain(tdb, i);
}
printf("freelist:\n");
tdb1_dump_chain(tdb, -1);
}
_PUBLIC_ int tdb1_printfreelist(struct tdb1_context *tdb)
{
int ret;
long total_free = 0;
tdb1_off_t offset, rec_ptr;
struct tdb1_record rec;
if ((ret = tdb1_lock(tdb, -1, F_WRLCK)) != 0)
return ret;
offset = TDB1_FREELIST_TOP;
/* read in the freelist top */
if (tdb1_ofs_read(tdb, offset, &rec_ptr) == -1) {
tdb1_unlock(tdb, -1, F_WRLCK);
return 0;
}
printf("freelist top=[0x%08x]\n", rec_ptr );
while (rec_ptr) {
if (tdb->methods->tdb1_read(tdb, rec_ptr, (char *)&rec,
sizeof(rec), TDB1_DOCONV()) == -1) {
tdb1_unlock(tdb, -1, F_WRLCK);
return -1;
}
if (rec.magic != TDB1_FREE_MAGIC) {
printf("bad magic 0x%08x in free list\n", rec.magic);
tdb1_unlock(tdb, -1, F_WRLCK);
return -1;
}
printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)] (end = 0x%08x)\n",
rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len);
total_free += rec.rec_len;
/* move to the next record */
rec_ptr = rec.next;
}
printf("total rec_len = [0x%08x (%d)]\n", (int)total_free,
(int)total_free);
return tdb1_unlock(tdb, -1, F_WRLCK);
}
/*
Unix SMB/CIFS implementation.
trivial database library
Copyright (C) Andrew Tridgell 1999-2005
Copyright (C) Paul `Rusty' Russell 2000
Copyright (C) Jeremy Allison 2000-2003
** NOTE! The following LGPL license applies to the tdb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "tdb1_private.h"
_PUBLIC_ enum TDB1_ERROR tdb1_error(struct tdb1_context *tdb)
{
return tdb->ecode;
}
static struct tdb1_errname {
enum TDB1_ERROR ecode; const char *estring;
} emap[] = { {TDB1_SUCCESS, "Success"},
{TDB1_ERR_CORRUPT, "Corrupt database"},
{TDB1_ERR_IO, "IO Error"},
{TDB1_ERR_LOCK, "Locking error"},
{TDB1_ERR_OOM, "Out of memory"},
{TDB1_ERR_EXISTS, "Record exists"},
{TDB1_ERR_NOLOCK, "Lock exists on other keys"},
{TDB1_ERR_EINVAL, "Invalid parameter"},
{TDB1_ERR_NOEXIST, "Record does not exist"},
{TDB1_ERR_RDONLY, "write not permitted"} };
/* Error string for the last tdb error */
_PUBLIC_ const char *tdb1_errorstr(struct tdb1_context *tdb)
{
uint32_t i;
for (i = 0; i < sizeof(emap) / sizeof(struct tdb1_errname); i++)
if (tdb->ecode == emap[i].ecode)
return emap[i].estring;
return "Invalid error code";
}
...@@ -27,12 +27,6 @@ ...@@ -27,12 +27,6 @@
#include "tdb1_private.h" #include "tdb1_private.h"
/* 'right' merges can involve O(n^2) cost when combined with a
traverse, so they are disabled until we find a way to do them in
O(1) time
*/
#define USE_RIGHT_MERGES 0
/* read a freelist record and check for simple errors */ /* read a freelist record and check for simple errors */
int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, struct tdb1_record *rec) int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, struct tdb1_record *rec)
{ {
...@@ -62,29 +56,6 @@ int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, struct tdb1_rec ...@@ -62,29 +56,6 @@ int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, struct tdb1_rec
} }
#if USE_RIGHT_MERGES
/* Remove an element from the freelist. Must have alloc lock. */
static int remove_from_freelist(struct tdb1_context *tdb, tdb1_off_t off, tdb1_off_t next)
{
tdb1_off_t last_ptr, i;
/* read in the freelist top */
last_ptr = TDB1_FREELIST_TOP;
while (tdb1_ofs_read(tdb, last_ptr, &i) != -1 && i != 0) {
if (i == off) {
/* We've found it! */
return tdb1_ofs_write(tdb, last_ptr, &next);
}
/* Follow chain (next offset is at start of record) */
last_ptr = i;
}
tdb->ecode = TDB1_ERR_CORRUPT;
TDB1_LOG((tdb, TDB1_DEBUG_FATAL,"remove_from_freelist: not on list at off=%d\n", off));
return -1;
}
#endif
/* update a record tailer (must hold allocation lock) */ /* update a record tailer (must hold allocation lock) */
static int update_tailer(struct tdb1_context *tdb, tdb1_off_t offset, static int update_tailer(struct tdb1_context *tdb, tdb1_off_t offset,
const struct tdb1_record *rec) const struct tdb1_record *rec)
...@@ -111,33 +82,6 @@ int tdb1_free(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *r ...@@ -111,33 +82,6 @@ int tdb1_free(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *r
goto fail; goto fail;
} }
#if USE_RIGHT_MERGES
/* Look right first (I'm an Australian, dammit) */
if (offset + sizeof(*rec) + rec->rec_len + sizeof(*rec) <= tdb->map_size) {
tdb1_off_t right = offset + sizeof(*rec) + rec->rec_len;
struct tdb1_record r;
if (tdb->methods->tdb1_read(tdb, right, &r, sizeof(r), TDB1_DOCONV()) == -1) {
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_free: right read failed at %u\n", right));
goto left;
}
/* If it's free, expand to include it. */
if (r.magic == TDB1_FREE_MAGIC) {
if (remove_from_freelist(tdb, right, r.next) == -1) {
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_free: right free failed at %u\n", right));
goto left;
}
rec->rec_len += sizeof(r) + r.rec_len;
if (update_tailer(tdb, offset, rec) == -1) {
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_free: update_tailer failed at %u\n", offset));
goto fail;
}
}
}
left:
#endif
/* Look left */ /* Look left */
if (offset - sizeof(tdb1_off_t) > TDB1_DATA_START(tdb->header.hash_size)) { if (offset - sizeof(tdb1_off_t) > TDB1_DATA_START(tdb->header.hash_size)) {
tdb1_off_t left = offset - sizeof(tdb1_off_t); tdb1_off_t left = offset - sizeof(tdb1_off_t);
...@@ -361,26 +305,3 @@ tdb1_off_t tdb1_allocate(struct tdb1_context *tdb, tdb1_len_t length, struct tdb ...@@ -361,26 +305,3 @@ tdb1_off_t tdb1_allocate(struct tdb1_context *tdb, tdb1_len_t length, struct tdb
tdb1_unlock(tdb, -1, F_WRLCK); tdb1_unlock(tdb, -1, F_WRLCK);
return 0; return 0;
} }
/*
return the size of the freelist - used to decide if we should repack
*/
_PUBLIC_ int tdb1_freelist_size(struct tdb1_context *tdb)
{
tdb1_off_t ptr;
int count=0;
if (tdb1_lock(tdb, -1, F_RDLCK) == -1) {
return -1;
}
ptr = TDB1_FREELIST_TOP;
while (tdb1_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) {
count++;
}
tdb1_unlock(tdb, -1, F_RDLCK);
return count;
}
/*
Unix SMB/CIFS implementation.
trivial database library
Copyright (C) Jeremy Allison 2006
** NOTE! The following LGPL license applies to the tdb
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "tdb1_private.h"
/* Check the freelist is good and contains no loops.
Very memory intensive - only do this as a consistency
checker. Heh heh - uses an in memory tdb as the storage
for the "seen" record list. For some reason this strikes
me as extremely clever as I don't have to write another tree
data structure implementation :-).
*/
static int seen_insert(struct tdb1_context *mem_tdb, tdb1_off_t rec_ptr)
{
TDB1_DATA key, data;
memset(&data, '\0', sizeof(data));
key.dptr = (unsigned char *)&rec_ptr;
key.dsize = sizeof(rec_ptr);
return tdb1_store(mem_tdb, key, data, TDB1_INSERT);
}
_PUBLIC_ int tdb1_validate_freelist(struct tdb1_context *tdb, int *pnum_entries)
{
struct tdb1_context *mem_tdb = NULL;
struct tdb1_record rec;
tdb1_off_t rec_ptr, last_ptr;
int ret = -1;
*pnum_entries = 0;
mem_tdb = tdb1_open("flval", tdb->header.hash_size,
TDB1_INTERNAL, O_RDWR, 0600);
if (!mem_tdb) {
return -1;
}
if (tdb1_lock(tdb, -1, F_WRLCK) == -1) {
tdb1_close(mem_tdb);
return 0;
}
last_ptr = TDB1_FREELIST_TOP;
/* Store the TDB1_FREELIST_TOP record. */
if (seen_insert(mem_tdb, last_ptr) == -1) {
tdb->ecode = TDB1_ERR_CORRUPT;
ret = -1;
goto fail;
}
/* read in the freelist top */
if (tdb1_ofs_read(tdb, TDB1_FREELIST_TOP, &rec_ptr) == -1) {
goto fail;
}
while (rec_ptr) {
/* If we can't store this record (we've seen it
before) then the free list has a loop and must
be corrupt. */
if (seen_insert(mem_tdb, rec_ptr)) {
tdb->ecode = TDB1_ERR_CORRUPT;
ret = -1;
goto fail;
}
if (tdb1_rec_free_read(tdb, rec_ptr, &rec) == -1) {
goto fail;
}
/* move to the next record */
last_ptr = rec_ptr;
rec_ptr = rec.next;
*pnum_entries += 1;
}
ret = 0;
fail:
tdb1_close(mem_tdb);
tdb1_unlock(tdb, -1, F_WRLCK);
return ret;
}
...@@ -27,11 +27,6 @@ ...@@ -27,11 +27,6 @@
#include "tdb1_private.h" #include "tdb1_private.h"
_PUBLIC_ void tdb1_setalarm_sigptr(struct tdb1_context *tdb, volatile sig_atomic_t *ptr)
{
tdb->interrupt_sig_ptr = ptr;
}
static int fcntl_lock(struct tdb1_context *tdb, static int fcntl_lock(struct tdb1_context *tdb,
int rw, off_t off, off_t len, bool waitflag) int rw, off_t off, off_t len, bool waitflag)
{ {
...@@ -155,12 +150,6 @@ int tdb1_brlock(struct tdb1_context *tdb, ...@@ -155,12 +150,6 @@ int tdb1_brlock(struct tdb1_context *tdb,
do { do {
ret = fcntl_lock(tdb, rw_type, offset, len, ret = fcntl_lock(tdb, rw_type, offset, len,
flags & TDB1_LOCK_WAIT); flags & TDB1_LOCK_WAIT);
/* Check for a sigalarm break. */
if (ret == -1 && errno == EINTR &&
tdb->interrupt_sig_ptr &&
*tdb->interrupt_sig_ptr) {
break;
}
} while (ret == -1 && errno == EINTR); } while (ret == -1 && errno == EINTR);
if (ret == -1) { if (ret == -1) {
...@@ -379,13 +368,6 @@ int tdb1_lock(struct tdb1_context *tdb, int list, int ltype) ...@@ -379,13 +368,6 @@ int tdb1_lock(struct tdb1_context *tdb, int list, int ltype)
return ret; return ret;
} }
/* lock a list in the database. list -1 is the alloc list. non-blocking lock */
int tdb1_lock_nonblock(struct tdb1_context *tdb, int list, int ltype)
{
return tdb1_lock_list(tdb, list, ltype, TDB1_LOCK_NOWAIT);
}
int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype, int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype,
bool mark_lock) bool mark_lock)
{ {
...@@ -649,25 +631,6 @@ _PUBLIC_ int tdb1_lockall(struct tdb1_context *tdb) ...@@ -649,25 +631,6 @@ _PUBLIC_ int tdb1_lockall(struct tdb1_context *tdb)
return tdb1_allrecord_lock(tdb, F_WRLCK, TDB1_LOCK_WAIT, false); return tdb1_allrecord_lock(tdb, F_WRLCK, TDB1_LOCK_WAIT, false);
} }
/* lock entire database with write lock - mark only */
_PUBLIC_ int tdb1_lockall_mark(struct tdb1_context *tdb)
{
return tdb1_allrecord_lock(tdb, F_WRLCK, TDB1_LOCK_MARK_ONLY, false);
}
/* unlock entire database with write lock - unmark only */
_PUBLIC_ int tdb1_lockall_unmark(struct tdb1_context *tdb)
{
return tdb1_allrecord_unlock(tdb, F_WRLCK, true);
}
/* lock entire database with write lock - nonblocking varient */
_PUBLIC_ int tdb1_lockall_nonblock(struct tdb1_context *tdb)
{
int ret = tdb1_allrecord_lock(tdb, F_WRLCK, TDB1_LOCK_NOWAIT, false);
return ret;
}
/* unlock entire database with write lock */ /* unlock entire database with write lock */
_PUBLIC_ int tdb1_unlockall(struct tdb1_context *tdb) _PUBLIC_ int tdb1_unlockall(struct tdb1_context *tdb)
{ {
...@@ -680,13 +643,6 @@ _PUBLIC_ int tdb1_lockall_read(struct tdb1_context *tdb) ...@@ -680,13 +643,6 @@ _PUBLIC_ int tdb1_lockall_read(struct tdb1_context *tdb)
return tdb1_allrecord_lock(tdb, F_RDLCK, TDB1_LOCK_WAIT, false); return tdb1_allrecord_lock(tdb, F_RDLCK, TDB1_LOCK_WAIT, false);
} }
/* lock entire database with read lock - nonblock varient */
_PUBLIC_ int tdb1_lockall_read_nonblock(struct tdb1_context *tdb)
{
int ret = tdb1_allrecord_lock(tdb, F_RDLCK, TDB1_LOCK_NOWAIT, false);
return ret;
}
/* unlock entire database with read lock */ /* unlock entire database with read lock */
_PUBLIC_ int tdb1_unlockall_read(struct tdb1_context *tdb) _PUBLIC_ int tdb1_unlockall_read(struct tdb1_context *tdb)
{ {
...@@ -701,30 +657,6 @@ _PUBLIC_ int tdb1_chainlock(struct tdb1_context *tdb, TDB1_DATA key) ...@@ -701,30 +657,6 @@ _PUBLIC_ int tdb1_chainlock(struct tdb1_context *tdb, TDB1_DATA key)
return ret; return ret;
} }
/* lock/unlock one hash chain, non-blocking. This is meant to be used
to reduce contention - it cannot guarantee how many records will be
locked */
_PUBLIC_ int tdb1_chainlock_nonblock(struct tdb1_context *tdb, TDB1_DATA key)
{
int ret = tdb1_lock_nonblock(tdb, TDB1_BUCKET(tdb->hash_fn(&key)), F_WRLCK);
return ret;
}
/* mark a chain as locked without actually locking it. Warning! use with great caution! */
_PUBLIC_ int tdb1_chainlock_mark(struct tdb1_context *tdb, TDB1_DATA key)
{
int ret = tdb1_nest_lock(tdb, lock_offset(TDB1_BUCKET(tdb->hash_fn(&key))),
F_WRLCK, TDB1_LOCK_MARK_ONLY);
return ret;
}
/* unmark a chain as locked without actually locking it. Warning! use with great caution! */
_PUBLIC_ int tdb1_chainlock_unmark(struct tdb1_context *tdb, TDB1_DATA key)
{
return tdb1_nest_unlock(tdb, lock_offset(TDB1_BUCKET(tdb->hash_fn(&key))),
F_WRLCK, true);
}
_PUBLIC_ int tdb1_chainunlock(struct tdb1_context *tdb, TDB1_DATA key) _PUBLIC_ int tdb1_chainunlock(struct tdb1_context *tdb, TDB1_DATA key)
{ {
return tdb1_unlock(tdb, TDB1_BUCKET(tdb->hash_fn(&key)), F_WRLCK); return tdb1_unlock(tdb, TDB1_BUCKET(tdb->hash_fn(&key)), F_WRLCK);
......
...@@ -495,115 +495,3 @@ _PUBLIC_ int tdb1_close(struct tdb1_context *tdb) ...@@ -495,115 +495,3 @@ _PUBLIC_ int tdb1_close(struct tdb1_context *tdb)
return ret; return ret;
} }
/* register a loging function */
_PUBLIC_ void tdb1_set_logging_function(struct tdb1_context *tdb,
const struct tdb1_logging_context *log_ctx)
{
tdb->log = *log_ctx;
}
_PUBLIC_ void *tdb1_get_logging_private(struct tdb1_context *tdb)
{
return tdb->log.log_private;
}
static int tdb1_reopen_internal(struct tdb1_context *tdb, bool active_lock)
{
#if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \
!defined(LIBREPLACE_PWRITE_NOT_REPLACED)
struct stat st;
#endif
if (tdb->flags & TDB1_INTERNAL) {
return 0; /* Nothing to do. */
}
if (tdb1_have_extra_locks(tdb)) {
TDB1_LOG((tdb, TDB1_DEBUG_ERROR, "tdb1_reopen: reopen not allowed with locks held\n"));
goto fail;
}
if (tdb->transaction != 0) {
TDB1_LOG((tdb, TDB1_DEBUG_ERROR, "tdb1_reopen: reopen not allowed inside a transaction\n"));
goto fail;
}
/* If we have real pread & pwrite, we can skip reopen. */
#if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \
!defined(LIBREPLACE_PWRITE_NOT_REPLACED)
if (tdb1_munmap(tdb) != 0) {
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_reopen: munmap failed (%s)\n", strerror(errno)));
goto fail;
}
if (close(tdb->fd) != 0)
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_reopen: WARNING closing tdb->fd failed!\n"));
tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
if (tdb->fd == -1) {
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_reopen: open failed (%s)\n", strerror(errno)));
goto fail;
}
if (fstat(tdb->fd, &st) != 0) {
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_reopen: fstat failed (%s)\n", strerror(errno)));
goto fail;
}
if (st.st_ino != tdb->inode || st.st_dev != tdb->device) {
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_reopen: file dev/inode has changed!\n"));
goto fail;
}
tdb1_mmap(tdb);
#endif /* fake pread or pwrite */
/* We may still think we hold the active lock. */
tdb->num_lockrecs = 0;
SAFE_FREE(tdb->lockrecs);
if (active_lock && tdb1_nest_lock(tdb, TDB1_ACTIVE_LOCK, F_RDLCK, TDB1_LOCK_WAIT) == -1) {
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_reopen: failed to obtain active lock\n"));
goto fail;
}
return 0;
fail:
tdb1_close(tdb);
return -1;
}
/* reopen a tdb - this can be used after a fork to ensure that we have an independent
seek pointer from our parent and to re-establish locks */
_PUBLIC_ int tdb1_reopen(struct tdb1_context *tdb)
{
return tdb1_reopen_internal(tdb, tdb->flags & TDB1_CLEAR_IF_FIRST);
}
/* reopen all tdb's */
_PUBLIC_ int tdb1_reopen_all(int parent_longlived)
{
struct tdb1_context *tdb;
for (tdb=tdb1s; tdb; tdb = tdb->next) {
bool active_lock = (tdb->flags & TDB1_CLEAR_IF_FIRST);
/*
* If the parent is longlived (ie. a
* parent daemon architecture), we know
* it will keep it's active lock on a
* tdb opened with CLEAR_IF_FIRST. Thus
* for child processes we don't have to
* add an active lock. This is essential
* to improve performance on systems that
* keep POSIX locks as a non-scalable data
* structure in the kernel.
*/
if (parent_longlived) {
/* Ensure no clear-if-first. */
active_lock = false;
}
if (tdb1_reopen_internal(tdb, active_lock) != 0)
return -1;
}
return 0;
}
...@@ -61,6 +61,9 @@ ...@@ -61,6 +61,9 @@
#include "tdb1.h" #include "tdb1.h"
/* Temporary wrapper to avoid undue churn in test/ */
#define tdb1_error(tdb) ((tdb)->ecode)
/* #define TDB_TRACE 1 */ /* #define TDB_TRACE 1 */
#ifndef HAVE_GETPAGESIZE #ifndef HAVE_GETPAGESIZE
#define getpagesize() 0x2000 #define getpagesize() 0x2000
...@@ -221,20 +224,14 @@ struct tdb1_context { ...@@ -221,20 +224,14 @@ struct tdb1_context {
struct tdb1_transaction *transaction; struct tdb1_transaction *transaction;
int page_size; int page_size;
int max_dead_records; int max_dead_records;
#ifdef TDB1_TRACE
int tracefd;
#endif
volatile sig_atomic_t *interrupt_sig_ptr;
}; };
/* /*
internal prototypes internal prototypes
*/ */
int tdb1_munmap(struct tdb1_context *tdb); int tdb1_munmap(struct tdb1_context *tdb);
void tdb1_mmap(struct tdb1_context *tdb); void tdb1_mmap(struct tdb1_context *tdb);
int tdb1_lock(struct tdb1_context *tdb, int list, int ltype); int tdb1_lock(struct tdb1_context *tdb, int list, int ltype);
int tdb1_lock_nonblock(struct tdb1_context *tdb, int list, int ltype);
int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype, int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype,
enum tdb1_lock_flags flags); enum tdb1_lock_flags flags);
int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype, int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype,
......
...@@ -661,25 +661,6 @@ failed: ...@@ -661,25 +661,6 @@ failed:
} }
/*
return the name of the current tdb file
useful for external logging functions
*/
_PUBLIC_ const char *tdb1_name(struct tdb1_context *tdb)
{
return tdb->name;
}
/*
return the underlying file descriptor being used by tdb, or -1
useful for external routines that want to check the device/inode
of the fd
*/
_PUBLIC_ int tdb1_fd(struct tdb1_context *tdb)
{
return tdb->fd;
}
/* /*
return the current logging function return the current logging function
useful for external tdb routines that wish to log tdb errors useful for external tdb routines that wish to log tdb errors
...@@ -713,65 +694,6 @@ _PUBLIC_ int tdb1_hash_size(struct tdb1_context *tdb) ...@@ -713,65 +694,6 @@ _PUBLIC_ int tdb1_hash_size(struct tdb1_context *tdb)
return tdb->header.hash_size; return tdb->header.hash_size;
} }
_PUBLIC_ size_t tdb1_map_size(struct tdb1_context *tdb)
{
return tdb->map_size;
}
_PUBLIC_ int tdb1_get_flags(struct tdb1_context *tdb)
{
return tdb->flags;
}
_PUBLIC_ void tdb1_add_flags(struct tdb1_context *tdb, unsigned flags)
{
if ((flags & TDB1_ALLOW_NESTING) &&
(flags & TDB1_DISALLOW_NESTING)) {
tdb->ecode = TDB1_ERR_NESTING;
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_add_flags: "
"allow_nesting and disallow_nesting are not allowed together!"));
return;
}
if (flags & TDB1_ALLOW_NESTING) {
tdb->flags &= ~TDB1_DISALLOW_NESTING;
}
if (flags & TDB1_DISALLOW_NESTING) {
tdb->flags &= ~TDB1_ALLOW_NESTING;
}
tdb->flags |= flags;
}
_PUBLIC_ void tdb1_remove_flags(struct tdb1_context *tdb, unsigned flags)
{
if ((flags & TDB1_ALLOW_NESTING) &&
(flags & TDB1_DISALLOW_NESTING)) {
tdb->ecode = TDB1_ERR_NESTING;
TDB1_LOG((tdb, TDB1_DEBUG_FATAL, "tdb1_remove_flags: "
"allow_nesting and disallow_nesting are not allowed together!"));
return;
}
if (flags & TDB1_ALLOW_NESTING) {
tdb->flags |= TDB1_DISALLOW_NESTING;
}
if (flags & TDB1_DISALLOW_NESTING) {
tdb->flags |= TDB1_ALLOW_NESTING;
}
tdb->flags &= ~flags;
}
/*
enable sequence number handling on an open tdb
*/
_PUBLIC_ void tdb1_enable_seqnum(struct tdb1_context *tdb)
{
tdb->flags |= TDB1_SEQNUM;
}
/* /*
add a region of the file to the freelist. Length is the size of the region in bytes, add a region of the file to the freelist. Length is the size of the region in bytes,
......
...@@ -532,11 +532,6 @@ _PUBLIC_ int tdb1_transaction_start(struct tdb1_context *tdb) ...@@ -532,11 +532,6 @@ _PUBLIC_ int tdb1_transaction_start(struct tdb1_context *tdb)
return _tdb1_transaction_start(tdb, TDB1_LOCK_WAIT); return _tdb1_transaction_start(tdb, TDB1_LOCK_WAIT);
} }
_PUBLIC_ int tdb1_transaction_start_nonblock(struct tdb1_context *tdb)
{
return _tdb1_transaction_start(tdb, TDB1_LOCK_NOWAIT|TDB1_LOCK_PROBE);
}
/* /*
sync to disk sync to disk
*/ */
......
...@@ -10,7 +10,7 @@ static unsigned int tdb1_dumb_hash(TDB1_DATA *key) ...@@ -10,7 +10,7 @@ static unsigned int tdb1_dumb_hash(TDB1_DATA *key)
static void log_fn(struct tdb1_context *tdb, enum tdb1_debug_level level, const char *fmt, ...) static void log_fn(struct tdb1_context *tdb, enum tdb1_debug_level level, const char *fmt, ...)
{ {
unsigned int *count = tdb1_get_logging_private(tdb); unsigned int *count = tdb->log.log_private;
if (strstr(fmt, "hash")) if (strstr(fmt, "hash"))
(*count)++; (*count)++;
} }
......
...@@ -36,12 +36,12 @@ static int traverse1(struct tdb1_context *tdb, TDB1_DATA key, TDB1_DATA data, ...@@ -36,12 +36,12 @@ static int traverse1(struct tdb1_context *tdb, TDB1_DATA key, TDB1_DATA data,
{ {
ok1(correct_key(key)); ok1(correct_key(key));
ok1(correct_data(data)); ok1(correct_data(data));
ok1(external_agent_operation1(agent, TRANSACTION_START, tdb1_name(tdb)) ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
== WOULD_HAVE_BLOCKED); == WOULD_HAVE_BLOCKED);
tdb1_traverse(tdb, traverse2, NULL); tdb1_traverse(tdb, traverse2, NULL);
/* That should *not* release the transaction lock! */ /* That should *not* release the transaction lock! */
ok1(external_agent_operation1(agent, TRANSACTION_START, tdb1_name(tdb)) ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
== WOULD_HAVE_BLOCKED); == WOULD_HAVE_BLOCKED);
return 0; return 0;
} }
...@@ -60,10 +60,10 @@ int main(int argc, char *argv[]) ...@@ -60,10 +60,10 @@ int main(int argc, char *argv[])
O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
ok1(tdb); ok1(tdb);
ok1(external_agent_operation1(agent, OPEN, tdb1_name(tdb)) == SUCCESS); ok1(external_agent_operation1(agent, OPEN, tdb->name) == SUCCESS);
ok1(external_agent_operation1(agent, TRANSACTION_START, tdb1_name(tdb)) ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
== SUCCESS); == SUCCESS);
ok1(external_agent_operation1(agent, TRANSACTION_COMMIT, tdb1_name(tdb)) ok1(external_agent_operation1(agent, TRANSACTION_COMMIT, tdb->name)
== SUCCESS); == SUCCESS);
key.dsize = strlen("hi"); key.dsize = strlen("hi");
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
static void log_fn(struct tdb1_context *tdb, enum tdb1_debug_level level, const char *fmt, ...) static void log_fn(struct tdb1_context *tdb, enum tdb1_debug_level level, const char *fmt, ...)
{ {
unsigned int *count = tdb1_get_logging_private(tdb); unsigned int *count = tdb->log.log_private;
if (strstr(fmt, "spinlocks")) if (strstr(fmt, "spinlocks"))
(*count)++; (*count)++;
} }
......
...@@ -54,24 +54,24 @@ int main(int argc, char *argv[]) ...@@ -54,24 +54,24 @@ int main(int argc, char *argv[])
ok1(tdb1_store(tdb, key, data, TDB1_INSERT) == 0); ok1(tdb1_store(tdb, key, data, TDB1_INSERT) == 0);
ok1(external_agent_operation1(agent, OPEN, tdb1_name(tdb)) == SUCCESS); ok1(external_agent_operation1(agent, OPEN, tdb->name) == SUCCESS);
ok1(tdb1_transaction_start(tdb) == 0); ok1(tdb1_transaction_start(tdb) == 0);
ok1(external_agent_operation1(agent, TRANSACTION_START, tdb1_name(tdb)) ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
== WOULD_HAVE_BLOCKED); == WOULD_HAVE_BLOCKED);
tdb1_traverse(tdb, traverse, NULL); tdb1_traverse(tdb, traverse, NULL);
/* That should *not* release the transaction lock! */ /* That should *not* release the transaction lock! */
ok1(external_agent_operation1(agent, TRANSACTION_START, tdb1_name(tdb)) ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
== WOULD_HAVE_BLOCKED); == WOULD_HAVE_BLOCKED);
tdb1_traverse_read(tdb, traverse, NULL); tdb1_traverse_read(tdb, traverse, NULL);
/* That should *not* release the transaction lock! */ /* That should *not* release the transaction lock! */
ok1(external_agent_operation1(agent, TRANSACTION_START, tdb1_name(tdb)) ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
== WOULD_HAVE_BLOCKED); == WOULD_HAVE_BLOCKED);
ok1(tdb1_transaction_commit(tdb) == 0); ok1(tdb1_transaction_commit(tdb) == 0);
/* Now we should be fine. */ /* Now we should be fine. */
ok1(external_agent_operation1(agent, TRANSACTION_START, tdb1_name(tdb)) ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
== SUCCESS); == SUCCESS);
tdb1_close(tdb); tdb1_close(tdb);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
static void log_fn(struct tdb1_context *tdb, enum tdb1_debug_level level, const char *fmt, ...) static void log_fn(struct tdb1_context *tdb, enum tdb1_debug_level level, const char *fmt, ...)
{ {
unsigned int *count = tdb1_get_logging_private(tdb); unsigned int *count = tdb->log.log_private;
if (strstr(fmt, "hash")) if (strstr(fmt, "hash"))
(*count)++; (*count)++;
} }
......
...@@ -36,7 +36,7 @@ static enum agent_return do_operation(enum operation op, const char *name) ...@@ -36,7 +36,7 @@ static enum agent_return do_operation(enum operation op, const char *name)
switch (op) { switch (op) {
case OPEN: case OPEN:
if (tdb) { if (tdb) {
diag("Already have tdb %s open", tdb1_name(tdb)); diag("Already have tdb %s open", tdb->name);
return OTHER_FAILURE; return OTHER_FAILURE;
} }
tdb = tdb1_open_ex(name, 0, TDB1_DEFAULT, O_RDWR, 0, tdb = tdb1_open_ex(name, 0, TDB1_DEFAULT, O_RDWR, 0,
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <ccan/tdb2/transaction.c> #include <ccan/tdb2/transaction.c>
#include <ccan/tdb2/traverse.c> #include <ccan/tdb2/traverse.c>
#include <ccan/tdb2/tdb1_check.c> #include <ccan/tdb2/tdb1_check.c>
#include <ccan/tdb2/tdb1_error.c>
#include <ccan/tdb2/tdb1_freelist.c> #include <ccan/tdb2/tdb1_freelist.c>
#include <ccan/tdb2/tdb1_hash.c> #include <ccan/tdb2/tdb1_hash.c>
#include <ccan/tdb2/tdb1_io.c> #include <ccan/tdb2/tdb1_io.c>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment