Commit 4e185ad8 authored by Rusty Russell's avatar Rusty Russell

tdb2: clean up logging

Logged errors should always set tdb->ecode before they are called, and
there's little reason to have a sprintf-style logging function since
we can do the formatting internally.

Change the tdb_log attribute to just take a "const char *", and create
a new tdb_logerr() helper which sets ecode and calls it.  As a bonus,
mark it COLD so the compiler can optimize appropriately knowing that
it's unlikely to be invoked.
parent 57680260
This diff is collapsed.
...@@ -118,8 +118,8 @@ static int remove_from_list(struct tdb_context *tdb, ...@@ -118,8 +118,8 @@ static int remove_from_list(struct tdb_context *tdb,
#ifdef DEBUG #ifdef DEBUG
if (tdb_read_off(tdb, off) != r_off) { if (tdb_read_off(tdb, off) != r_off) {
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_DEBUG_FATAL,
"remove_from_list: %llu bad prev in list %llu\n", "remove_from_list: %llu bad prev in list %llu",
(long long)r_off, (long long)b_off); (long long)r_off, (long long)b_off);
return -1; return -1;
} }
...@@ -136,9 +136,9 @@ static int remove_from_list(struct tdb_context *tdb, ...@@ -136,9 +136,9 @@ static int remove_from_list(struct tdb_context *tdb,
#ifdef DEBUG #ifdef DEBUG
if (tdb_read_off(tdb, off) & TDB_OFF_MASK != r_off) { if (tdb_read_off(tdb, off) & TDB_OFF_MASK != r_off) {
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_DEBUG_FATAL,
"remove_from_list: %llu bad list %llu\n", "remove_from_list: %llu bad list %llu",
(long long)r_off, (long long)b_off); (long long)r_off, (long long)b_off);
return -1; return -1;
} }
#endif #endif
...@@ -176,9 +176,10 @@ static int enqueue_in_free(struct tdb_context *tdb, ...@@ -176,9 +176,10 @@ static int enqueue_in_free(struct tdb_context *tdb,
new.next + offsetof(struct tdb_free_record, new.next + offsetof(struct tdb_free_record,
magic_and_prev)) magic_and_prev))
!= magic) { != magic) {
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_DEBUG_FATAL,
"enqueue_in_free: %llu bad head prev %llu\n", "enqueue_in_free: %llu bad head"
(long long)new.next, (long long)b_off); " prev %llu",
(long long)new.next, (long long)b_off);
return -1; return -1;
} }
#endif #endif
...@@ -331,10 +332,9 @@ static int coalesce(struct tdb_context *tdb, ...@@ -331,10 +332,9 @@ static int coalesce(struct tdb_context *tdb,
goto err; goto err;
if (frec_len(&rec) != data_len) { if (frec_len(&rec) != data_len) {
tdb->ecode = TDB_ERR_CORRUPT; tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_DEBUG_FATAL,
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, "coalesce: expected data len %zu not %zu",
"coalesce: expected data len %llu not %llu\n", (size_t)data_len, (size_t)frec_len(&rec));
(long long)data_len, (long long)frec_len(&rec));
goto err; goto err;
} }
...@@ -412,8 +412,8 @@ again: ...@@ -412,8 +412,8 @@ again:
if (frec_magic(r) != TDB_FREE_MAGIC) { if (frec_magic(r) != TDB_FREE_MAGIC) {
tdb_access_release(tdb, r); tdb_access_release(tdb, r);
tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv, tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_DEBUG_FATAL,
"lock_and_alloc: %llu non-free 0x%llx\n", "lock_and_alloc: %llu non-free 0x%llx",
(long long)off, (long long)r->magic_and_prev); (long long)off, (long long)r->magic_and_prev);
goto unlock_err; goto unlock_err;
} }
...@@ -566,9 +566,8 @@ int set_used_header(struct tdb_context *tdb, ...@@ -566,9 +566,8 @@ int set_used_header(struct tdb_context *tdb,
if (rec_key_length(rec) != keylen if (rec_key_length(rec) != keylen
|| rec_data_length(rec) != datalen || rec_data_length(rec) != datalen
|| rec_extra_padding(rec) != actuallen - (keylen + datalen)) { || rec_extra_padding(rec) != actuallen - (keylen + datalen)) {
tdb->ecode = TDB_ERR_IO; tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_ERROR,
tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv, "Could not encode k=%llu,d=%llu,a=%llu",
"Could not encode k=%llu,d=%llu,a=%llu\n",
(long long)keylen, (long long)datalen, (long long)keylen, (long long)datalen,
(long long)actuallen); (long long)actuallen);
return -1; return -1;
...@@ -588,8 +587,8 @@ static int tdb_expand(struct tdb_context *tdb, tdb_len_t size) ...@@ -588,8 +587,8 @@ static int tdb_expand(struct tdb_context *tdb, tdb_len_t size)
/* Need to hold a hash lock to expand DB: transactions rely on it. */ /* Need to hold a hash lock to expand DB: transactions rely on it. */
if (!(tdb->flags & TDB_NOLOCK) if (!(tdb->flags & TDB_NOLOCK)
&& !tdb->allrecord_lock.count && !tdb_has_hash_locks(tdb)) { && !tdb->allrecord_lock.count && !tdb_has_hash_locks(tdb)) {
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, tdb_logerr(tdb, TDB_ERR_LOCK, TDB_DEBUG_ERROR,
"tdb_expand: must hold lock during expand\n"); "tdb_expand: must hold lock during expand");
return -1; return -1;
} }
......
...@@ -561,10 +561,11 @@ int next_in_hash(struct tdb_context *tdb, int ltype, ...@@ -561,10 +561,11 @@ int next_in_hash(struct tdb_context *tdb, int ltype,
return -1; return -1;
} }
if (rec_magic(&rec) != TDB_MAGIC) { if (rec_magic(&rec) != TDB_MAGIC) {
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, tdb_logerr(tdb, TDB_ERR_CORRUPT,
"next_in_hash:" TDB_DEBUG_FATAL,
" corrupt record at %llu\n", "next_in_hash:"
(long long)off); " corrupt record at %llu",
(long long)off);
return -1; return -1;
} }
......
...@@ -56,9 +56,9 @@ void tdb_mmap(struct tdb_context *tdb) ...@@ -56,9 +56,9 @@ void tdb_mmap(struct tdb_context *tdb)
*/ */
if (tdb->map_ptr == MAP_FAILED) { if (tdb->map_ptr == MAP_FAILED) {
tdb->map_ptr = NULL; tdb->map_ptr = NULL;
tdb->log(tdb, TDB_DEBUG_WARNING, tdb->log_priv, tdb_logerr(tdb, TDB_SUCCESS, TDB_DEBUG_WARNING,
"tdb_mmap failed for size %lld (%s)\n", "tdb_mmap failed for size %lld (%s)",
(long long)tdb->map_size, strerror(errno)); (long long)tdb->map_size, strerror(errno));
} }
} }
...@@ -70,7 +70,6 @@ void tdb_mmap(struct tdb_context *tdb) ...@@ -70,7 +70,6 @@ void tdb_mmap(struct tdb_context *tdb)
static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, bool probe) static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, bool probe)
{ {
struct stat st; struct stat st;
int ret;
/* We can't hold pointers during this: we could unmap! */ /* We can't hold pointers during this: we could unmap! */
assert(!tdb->direct_access assert(!tdb->direct_access
...@@ -81,11 +80,9 @@ static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, bool probe) ...@@ -81,11 +80,9 @@ static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, bool probe)
return 0; return 0;
if (tdb->flags & TDB_INTERNAL) { if (tdb->flags & TDB_INTERNAL) {
if (!probe) { if (!probe) {
/* Ensure ecode is set for log fn. */ tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL,
tdb->ecode = TDB_ERR_IO;
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv,
"tdb_oob len %lld beyond internal" "tdb_oob len %lld beyond internal"
" malloc size %lld\n", " malloc size %lld",
(long long)len, (long long)len,
(long long)tdb->map_size); (long long)tdb->map_size);
} }
...@@ -95,22 +92,20 @@ static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, bool probe) ...@@ -95,22 +92,20 @@ static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, bool probe)
if (tdb_lock_expand(tdb, F_RDLCK) != 0) if (tdb_lock_expand(tdb, F_RDLCK) != 0)
return -1; return -1;
ret = fstat(tdb->fd, &st); if (fstat(tdb->fd, &st) != 0) {
tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL,
tdb_unlock_expand(tdb, F_RDLCK); "Failed to fstat file: %s", strerror(errno));
tdb_unlock_expand(tdb, F_RDLCK);
if (ret == -1) {
tdb->ecode = TDB_ERR_IO;
return -1; return -1;
} }
tdb_unlock_expand(tdb, F_RDLCK);
if (st.st_size < (size_t)len) { if (st.st_size < (size_t)len) {
if (!probe) { if (!probe) {
/* Ensure ecode is set for log fn. */ tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL,
tdb->ecode = TDB_ERR_IO; "tdb_oob len %zu beyond eof at %zu",
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, (size_t)len, st.st_size);
"tdb_oob len %lld beyond eof at %lld\n",
(long long)len, (long long)st.st_size);
} }
return -1; return -1;
} }
...@@ -180,11 +175,7 @@ int zero_out(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len) ...@@ -180,11 +175,7 @@ int zero_out(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len)
char buf[8192] = { 0 }; char buf[8192] = { 0 };
void *p = tdb->methods->direct(tdb, off, len); void *p = tdb->methods->direct(tdb, off, len);
if (tdb->read_only) { assert(!tdb->read_only);
tdb->ecode = TDB_ERR_RDONLY;
return -1;
}
if (p) { if (p) {
memset(p, 0, len); memset(p, 0, len);
return 0; return 0;
...@@ -275,15 +266,17 @@ bool tdb_read_all(int fd, void *buf, size_t len) ...@@ -275,15 +266,17 @@ bool tdb_read_all(int fd, void *buf, size_t len)
static int tdb_write(struct tdb_context *tdb, tdb_off_t off, static int tdb_write(struct tdb_context *tdb, tdb_off_t off,
const void *buf, tdb_len_t len) const void *buf, tdb_len_t len)
{ {
if (len == 0) {
return 0;
}
if (tdb->read_only) { if (tdb->read_only) {
tdb->ecode = TDB_ERR_RDONLY; tdb_logerr(tdb, TDB_ERR_RDONLY, TDB_DEBUG_WARNING,
"Write to read-only database");
return -1; return -1;
} }
/* FIXME: Bogus optimization? */
if (len == 0) {
return 0;
}
if (tdb->methods->oob(tdb, off + len, 0) != 0) if (tdb->methods->oob(tdb, off + len, 0) != 0)
return -1; return -1;
...@@ -291,11 +284,9 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, ...@@ -291,11 +284,9 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off,
memcpy(off + (char *)tdb->map_ptr, buf, len); memcpy(off + (char *)tdb->map_ptr, buf, len);
} else { } else {
if (!tdb_pwrite_all(tdb->fd, buf, len, off)) { if (!tdb_pwrite_all(tdb->fd, buf, len, off)) {
tdb->ecode = TDB_ERR_IO; tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL,
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, "tdb_write failed at %zu len=%zu (%s)",
"tdb_write failed at %llu len=%llu (%s)\n", (size_t)off, (size_t)len, strerror(errno));
(long long)off, (long long)len,
strerror(errno));
return -1; return -1;
} }
} }
...@@ -314,14 +305,12 @@ static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, ...@@ -314,14 +305,12 @@ static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf,
memcpy(buf, off + (char *)tdb->map_ptr, len); memcpy(buf, off + (char *)tdb->map_ptr, len);
} else { } else {
if (!tdb_pread_all(tdb->fd, buf, len, off)) { if (!tdb_pread_all(tdb->fd, buf, len, off)) {
/* Ensure ecode is set for log fn. */ tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL,
tdb->ecode = TDB_ERR_IO; "tdb_read failed at %zu "
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, "len=%zu (%s) map_size=%zu",
"tdb_read failed at %lld " (size_t)off, (size_t)len,
"len=%lld (%s) map_size=%lld\n",
(long long)off, (long long)len,
strerror(errno), strerror(errno),
(long long)tdb->map_size); (size_t)tdb->map_size);
return -1; return -1;
} }
} }
...@@ -335,10 +324,9 @@ int tdb_write_convert(struct tdb_context *tdb, tdb_off_t off, ...@@ -335,10 +324,9 @@ int tdb_write_convert(struct tdb_context *tdb, tdb_off_t off,
if (unlikely((tdb->flags & TDB_CONVERT))) { if (unlikely((tdb->flags & TDB_CONVERT))) {
void *conv = malloc(len); void *conv = malloc(len);
if (!conv) { if (!conv) {
tdb->ecode = TDB_ERR_OOM; tdb_logerr(tdb, TDB_ERR_OOM, TDB_DEBUG_FATAL,
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, "tdb_write: no memory converting"
"tdb_write: no memory converting %zu bytes\n", " %zu bytes", len);
len);
return -1; return -1;
} }
memcpy(conv, rec, len); memcpy(conv, rec, len);
...@@ -362,7 +350,8 @@ int tdb_read_convert(struct tdb_context *tdb, tdb_off_t off, ...@@ -362,7 +350,8 @@ int tdb_read_convert(struct tdb_context *tdb, tdb_off_t off,
int tdb_write_off(struct tdb_context *tdb, tdb_off_t off, tdb_off_t val) int tdb_write_off(struct tdb_context *tdb, tdb_off_t off, tdb_off_t val)
{ {
if (tdb->read_only) { if (tdb->read_only) {
tdb->ecode = TDB_ERR_RDONLY; tdb_logerr(tdb, TDB_ERR_RDONLY, TDB_DEBUG_WARNING,
"Write to read-only database");
return -1; return -1;
} }
...@@ -383,12 +372,12 @@ static void *_tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, ...@@ -383,12 +372,12 @@ static void *_tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset,
/* some systems don't like zero length malloc */ /* some systems don't like zero length malloc */
buf = malloc(prefix + len ? prefix + len : 1); buf = malloc(prefix + len ? prefix + len : 1);
if (unlikely(!buf)) { if (!buf) {
tdb->ecode = TDB_ERR_OOM; tdb_logerr(tdb, TDB_ERR_OOM, TDB_DEBUG_ERROR,
tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv, "tdb_alloc_read malloc failed len=%zu",
"tdb_alloc_read malloc failed len=%lld\n", (size_t)(prefix + len));
(long long)prefix + len); } else if (unlikely(tdb->methods->read(tdb, offset, buf+prefix,
} else if (unlikely(tdb->methods->read(tdb, offset, buf+prefix, len))) { len) == -1)) {
free(buf); free(buf);
buf = NULL; buf = NULL;
} }
...@@ -409,9 +398,8 @@ static int fill(struct tdb_context *tdb, ...@@ -409,9 +398,8 @@ static int fill(struct tdb_context *tdb,
size_t n = len > size ? size : len; size_t n = len > size ? size : len;
if (!tdb_pwrite_all(tdb->fd, buf, n, off)) { if (!tdb_pwrite_all(tdb->fd, buf, n, off)) {
tdb->ecode = TDB_ERR_IO; tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL,
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, "fill write failed: giving up!");
"fill write failed: giving up!\n");
return -1; return -1;
} }
len -= n; len -= n;
...@@ -427,14 +415,16 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_len_t addition) ...@@ -427,14 +415,16 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_len_t addition)
char buf[8192]; char buf[8192];
if (tdb->read_only) { if (tdb->read_only) {
tdb->ecode = TDB_ERR_RDONLY; tdb_logerr(tdb, TDB_ERR_RDONLY, TDB_DEBUG_WARNING,
"Expand on read-only database");
return -1; return -1;
} }
if (tdb->flags & TDB_INTERNAL) { if (tdb->flags & TDB_INTERNAL) {
char *new = realloc(tdb->map_ptr, tdb->map_size + addition); char *new = realloc(tdb->map_ptr, tdb->map_size + addition);
if (!new) { if (!new) {
tdb->ecode = TDB_ERR_OOM; tdb_logerr(tdb, TDB_ERR_OOM, TDB_DEBUG_FATAL,
"No memory to expand database");
return -1; return -1;
} }
tdb->map_ptr = new; tdb->map_ptr = new;
...@@ -495,7 +485,8 @@ void *tdb_access_write(struct tdb_context *tdb, ...@@ -495,7 +485,8 @@ void *tdb_access_write(struct tdb_context *tdb,
void *ret = NULL; void *ret = NULL;
if (tdb->read_only) { if (tdb->read_only) {
tdb->ecode = TDB_ERR_RDONLY; tdb_logerr(tdb, TDB_ERR_RDONLY, TDB_DEBUG_WARNING,
"Write to read-only database");
return NULL; return NULL;
} }
......
This diff is collapsed.
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "config.h" #include "config.h"
#include <ccan/tdb2/tdb2.h> #include <ccan/tdb2/tdb2.h>
#include <ccan/likely/likely.h> #include <ccan/likely/likely.h>
#include <ccan/compiler/compiler.h>
#ifdef HAVE_BYTESWAP_H #ifdef HAVE_BYTESWAP_H
#include <byteswap.h> #include <byteswap.h>
#endif #endif
...@@ -308,8 +309,8 @@ struct tdb_context { ...@@ -308,8 +309,8 @@ struct tdb_context {
uint32_t flags; uint32_t flags;
/* Logging function */ /* Logging function */
tdb_logfn_t log; tdb_logfn_t logfn;
void *log_priv; void *log_private;
/* Hash function. */ /* Hash function. */
tdb_hashfn_t khash; tdb_hashfn_t khash;
...@@ -328,7 +329,7 @@ struct tdb_context { ...@@ -328,7 +329,7 @@ struct tdb_context {
/* Lock information */ /* Lock information */
struct tdb_lock_type allrecord_lock; struct tdb_lock_type allrecord_lock;
uint64_t num_lockrecs; size_t num_lockrecs;
struct tdb_lock_type *lockrecs; struct tdb_lock_type *lockrecs;
struct tdb_attribute_stats *stats; struct tdb_attribute_stats *stats;
...@@ -529,6 +530,12 @@ int next_in_hash(struct tdb_context *tdb, int ltype, ...@@ -529,6 +530,12 @@ int next_in_hash(struct tdb_context *tdb, int ltype,
int tdb_transaction_recover(struct tdb_context *tdb); int tdb_transaction_recover(struct tdb_context *tdb);
bool tdb_needs_recovery(struct tdb_context *tdb); bool tdb_needs_recovery(struct tdb_context *tdb);
/* tdb.c: */
void COLD tdb_logerr(struct tdb_context *tdb,
enum TDB_ERROR ecode,
enum tdb_debug_level level,
const char *fmt, ...);
#ifdef TDB_TRACE #ifdef TDB_TRACE
void tdb_trace(struct tdb_context *tdb, const char *op); void tdb_trace(struct tdb_context *tdb, const char *op);
void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op); void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op);
......
...@@ -164,7 +164,8 @@ char *tdb_summary(struct tdb_context *tdb, enum tdb_summary_flags flags) ...@@ -164,7 +164,8 @@ char *tdb_summary(struct tdb_context *tdb, enum tdb_summary_flags flags)
buckets = tally_new(HISTO_HEIGHT); buckets = tally_new(HISTO_HEIGHT);
if (!flists || !hashes || !freet || !keys || !data || !extra if (!flists || !hashes || !freet || !keys || !data || !extra
|| !uncoal || !buckets) { || !uncoal || !buckets) {
tdb->ecode = TDB_ERR_OOM; tdb_logerr(tdb, TDB_ERR_OOM, TDB_DEBUG_ERROR,
"tdb_summary: failed to allocate tally structures");
goto unlock; goto unlock;
} }
......
This diff is collapsed.
...@@ -67,7 +67,7 @@ enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, ...@@ -67,7 +67,7 @@ enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,
/* flags for tdb_summary. Logical or to combine. */ /* flags for tdb_summary. Logical or to combine. */
enum tdb_summary_flags { TDB_SUMMARY_HISTOGRAMS = 1 }; enum tdb_summary_flags { TDB_SUMMARY_HISTOGRAMS = 1 };
/* debugging uses one of the following levels */ /* logging uses one of the following levels */
enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR,
TDB_DEBUG_WARNING, TDB_DEBUG_TRACE}; TDB_DEBUG_WARNING, TDB_DEBUG_TRACE};
...@@ -80,7 +80,7 @@ struct tdb_context; ...@@ -80,7 +80,7 @@ struct tdb_context;
/* FIXME: Make typesafe */ /* FIXME: Make typesafe */
typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *);
typedef void (*tdb_logfn_t)(struct tdb_context *, enum tdb_debug_level, void *priv, const char *, ...) PRINTF_FMT(4, 5); typedef void (*tdb_logfn_t)(struct tdb_context *, enum tdb_debug_level, void *, const char *);
typedef uint64_t (*tdb_hashfn_t)(const void *key, size_t len, uint64_t seed, typedef uint64_t (*tdb_hashfn_t)(const void *key, size_t len, uint64_t seed,
void *priv); void *priv);
...@@ -161,8 +161,8 @@ int tdb_check(struct tdb_context *tdb, ...@@ -161,8 +161,8 @@ int tdb_check(struct tdb_context *tdb,
int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), int (*check)(TDB_DATA key, TDB_DATA data, void *private_data),
void *private_data); void *private_data);
enum TDB_ERROR tdb_error(struct tdb_context *tdb); enum TDB_ERROR tdb_error(const struct tdb_context *tdb);
const char *tdb_errorstr(struct tdb_context *tdb); const char *tdb_errorstr(const struct tdb_context *tdb);
int tdb_transaction_start(struct tdb_context *tdb); int tdb_transaction_start(struct tdb_context *tdb);
void tdb_transaction_cancel(struct tdb_context *tdb); void tdb_transaction_cancel(struct tdb_context *tdb);
......
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <ccan/tap/tap.h> #include <ccan/tap/tap.h>
#include "logging.h" #include "logging.h"
...@@ -16,24 +14,13 @@ union tdb_attribute tap_log_attr = { ...@@ -16,24 +14,13 @@ union tdb_attribute tap_log_attr = {
void tap_log_fn(struct tdb_context *tdb, void tap_log_fn(struct tdb_context *tdb,
enum tdb_debug_level level, void *priv, enum tdb_debug_level level, void *priv,
const char *fmt, ...) const char *message)
{ {
va_list ap;
char *p;
if (suppress_logging) if (suppress_logging)
return; return;
va_start(ap, fmt); diag("tdb log level %u: %s%s", level, log_prefix, message);
if (vasprintf(&p, fmt, ap) == -1)
abort();
/* Strip trailing \n: diag adds it. */
if (p[strlen(p)-1] == '\n')
p[strlen(p)-1] = '\0';
diag("tdb log level %u: %s%s", level, log_prefix, p);
free(p);
if (level != TDB_DEBUG_TRACE) if (level != TDB_DEBUG_TRACE)
tap_log_messages++; tap_log_messages++;
va_end(ap);
} }
...@@ -11,7 +11,7 @@ extern union tdb_attribute tap_log_attr; ...@@ -11,7 +11,7 @@ extern union tdb_attribute tap_log_attr;
void tap_log_fn(struct tdb_context *tdb, void tap_log_fn(struct tdb_context *tdb,
enum tdb_debug_level level, void *priv, enum tdb_debug_level level, void *priv,
const char *fmt, ...); const char *message);
static inline bool data_equal(struct tdb_data a, struct tdb_data b) static inline bool data_equal(struct tdb_data a, struct tdb_data b)
{ {
......
...@@ -12,7 +12,7 @@ int main(int argc, char *argv[]) ...@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
{ {
unsigned int i; unsigned int i;
struct tdb_used_record rec; struct tdb_used_record rec;
struct tdb_context tdb = { .log = tap_log_fn, .log_priv = NULL }; struct tdb_context tdb = { .logfn = tap_log_fn };
plan_tests(64 + 32 + 48*6 + 1); plan_tests(64 + 32 + 48*6 + 1);
......
...@@ -13,7 +13,7 @@ static int log_count = 0; ...@@ -13,7 +13,7 @@ static int log_count = 0;
/* Normally we get a log when setting random seed. */ /* Normally we get a log when setting random seed. */
static void my_log_fn(struct tdb_context *tdb, static void my_log_fn(struct tdb_context *tdb,
enum tdb_debug_level level, void *priv, enum tdb_debug_level level, void *priv,
const char *fmt, ...) const char *message)
{ {
log_count++; log_count++;
} }
......
...@@ -120,7 +120,7 @@ int main(int argc, char *argv[]) ...@@ -120,7 +120,7 @@ int main(int argc, char *argv[])
hattr.base.next = &tap_log_attr; hattr.base.next = &tap_log_attr;
plan_tests(sizeof(flags) / sizeof(flags[0]) * 50 + 1); plan_tests(sizeof(flags) / sizeof(flags[0]) * 53 + 1);
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
tdb = tdb_open("run-traverse.tdb", flags[i], tdb = tdb_open("run-traverse.tdb", flags[i],
O_RDWR|O_CREAT|O_TRUNC, 0600, &hattr); O_RDWR|O_CREAT|O_TRUNC, 0600, &hattr);
...@@ -182,6 +182,7 @@ int main(int argc, char *argv[]) ...@@ -182,6 +182,7 @@ int main(int argc, char *argv[])
ok1(td.low <= NUM_RECORDS / 2); ok1(td.low <= NUM_RECORDS / 2);
ok1(td.high > NUM_RECORDS / 2); ok1(td.high > NUM_RECORDS / 2);
ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0);
ok1(tap_log_messages == 0);
/* Growing traverse. Expect failure on r/o traverse. */ /* Growing traverse. Expect failure on r/o traverse. */
tgd.calls = 0; tgd.calls = 0;
...@@ -193,6 +194,8 @@ int main(int argc, char *argv[]) ...@@ -193,6 +194,8 @@ int main(int argc, char *argv[])
ok1(tgd.error == TDB_ERR_RDONLY); ok1(tgd.error == TDB_ERR_RDONLY);
ok1(tgd.calls == 1); ok1(tgd.calls == 1);
ok1(!tgd.mismatch); ok1(!tgd.mismatch);
ok1(tap_log_messages == 1);
tap_log_messages = 0;
ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Deleting traverse. Expect failure on r/o traverse. */ /* Deleting traverse. Expect failure on r/o traverse. */
...@@ -209,6 +212,8 @@ int main(int argc, char *argv[]) ...@@ -209,6 +212,8 @@ int main(int argc, char *argv[])
ok1(!td.mismatch); ok1(!td.mismatch);
ok1(td.calls == 1); ok1(td.calls == 1);
ok1(td.low == td.high); ok1(td.low == td.high);
ok1(tap_log_messages == 1);
tap_log_messages = 0;
ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Deleting traverse (delete everything). */ /* Deleting traverse (delete everything). */
......
This diff is collapsed.
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