Commit 41391dd9 authored by Rusty Russell's avatar Rusty Russell

Better tdb tracing, start of decent replay_trace.

parent 72c55b03
......@@ -413,21 +413,21 @@ static int _tdb_unlockall(struct tdb_context *tdb, int ltype)
/* lock entire database with write lock */
int tdb_lockall(struct tdb_context *tdb)
{
tdb_trace(tdb, "tdb_lockall\n");
tdb_trace(tdb, "tdb_lockall");
return _tdb_lockall(tdb, F_WRLCK, F_SETLKW);
}
/* lock entire database with write lock - mark only */
int tdb_lockall_mark(struct tdb_context *tdb)
{
tdb_trace(tdb, "tdb_lockall_mark\n");
tdb_trace(tdb, "tdb_lockall_mark");
return _tdb_lockall(tdb, F_WRLCK | TDB_MARK_LOCK, F_SETLKW);
}
/* unlock entire database with write lock - unmark only */
int tdb_lockall_unmark(struct tdb_context *tdb)
{
tdb_trace(tdb, "tdb_lockall_unmark\n");
tdb_trace(tdb, "tdb_lockall_unmark");
return _tdb_unlockall(tdb, F_WRLCK | TDB_MARK_LOCK);
}
......@@ -435,21 +435,21 @@ int tdb_lockall_unmark(struct tdb_context *tdb)
int tdb_lockall_nonblock(struct tdb_context *tdb)
{
int ret = _tdb_lockall(tdb, F_WRLCK, F_SETLK);
tdb_trace(tdb, "tdb_lockall_nonblock = %i\n", ret);
tdb_trace_ret(tdb, "tdb_lockall_nonblock", ret);
return ret;
}
/* unlock entire database with write lock */
int tdb_unlockall(struct tdb_context *tdb)
{
tdb_trace(tdb, "tdb_unlockall\n");
tdb_trace(tdb, "tdb_unlockall");
return _tdb_unlockall(tdb, F_WRLCK);
}
/* lock entire database with read lock */
int tdb_lockall_read(struct tdb_context *tdb)
{
tdb_trace(tdb, "tdb_lockall_read\n");
tdb_trace(tdb, "tdb_lockall_read");
return _tdb_lockall(tdb, F_RDLCK, F_SETLKW);
}
......@@ -457,14 +457,14 @@ int tdb_lockall_read(struct tdb_context *tdb)
int tdb_lockall_read_nonblock(struct tdb_context *tdb)
{
int ret = _tdb_lockall(tdb, F_RDLCK, F_SETLK);
tdb_trace(tdb, "tdb_lockall_read_nonblock = %i\n", ret);
tdb_trace_ret(tdb, "tdb_lockall_read_nonblock", ret);
return ret;
}
/* unlock entire database with read lock */
int tdb_unlockall_read(struct tdb_context *tdb)
{
tdb_trace(tdb, "tdb_unlockall_read\n");
tdb_trace(tdb, "tdb_unlockall_read");
return _tdb_unlockall(tdb, F_RDLCK);
}
......@@ -472,10 +472,9 @@ int tdb_unlockall_read(struct tdb_context *tdb)
contention - it cannot guarantee how many records will be locked */
int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key)
{
tdb_trace(tdb, "tdb_chainlock ");
tdb_trace_record(tdb, key);
tdb_trace(tdb, "\n");
return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
int ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
tdb_trace_1rec(tdb, "tdb_chainlock", key);
return ret;
}
/* lock/unlock one hash chain, non-blocking. This is meant to be used
......@@ -484,56 +483,45 @@ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key)
int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key)
{
int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
tdb_trace(tdb, "tdb_chainlock_nonblock ");
tdb_trace_record(tdb, key);
tdb_trace(tdb, "= %i\n", ret);
tdb_trace_1rec_ret(tdb, "tdb_chainlock_nonblock", key, ret);
return ret;
}
/* mark a chain as locked without actually locking it. Warning! use with great caution! */
int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key)
{
tdb_trace(tdb, "tdb_chainlock_mark ");
tdb_trace_record(tdb, key);
tdb_trace(tdb, "\n");
return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK);
int ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK);
tdb_trace_1rec(tdb, "tdb_chainlock_mark", key);
return ret;
}
/* unmark a chain as locked without actually locking it. Warning! use with great caution! */
int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key)
{
tdb_trace(tdb, "tdb_chainlock_unmark ");
tdb_trace_record(tdb, key);
tdb_trace(tdb, "\n");
tdb_trace_1rec(tdb, "tdb_chainlock_unmark", key);
return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK);
}
int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key)
{
tdb_trace(tdb, "tdb_chainunlock ");
tdb_trace_record(tdb, key);
tdb_trace(tdb, "\n");
tdb_trace_1rec(tdb, "tdb_chainlock", key);
return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
}
int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key)
{
tdb_trace(tdb, "tdb_chainlock_read ");
tdb_trace_record(tdb, key);
tdb_trace(tdb, "\n");
return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
int ret;
ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
tdb_trace_1rec(tdb, "tdb_chainlock_read", key);
return ret;
}
int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key)
{
tdb_trace(tdb, "tdb_chainunlock_read ");
tdb_trace_record(tdb, key);
tdb_trace(tdb, "\n");
tdb_trace_1rec(tdb, "tdb_chainunlock_read", key);
return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
}
/* record lock stops delete underneath */
int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off)
{
......
......@@ -163,19 +163,6 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
goto fail;
}
#ifdef TDB_TRACE
if (!(tdb_flags & TDB_INTERNAL)) {
sprintf(tracefile, "%s.trace.%u", name, getpid());
tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600);
if (tdb->tracefd < 0)
goto fail;
tdb_trace(tdb, "tdb_open %s %u %#x %#x %p\n",
name, hash_size, tdb_flags, open_flags, hash_fn);
} else
/* All writes will fail. That's OK. */
tdb->tracefd = -1;
#endif
tdb_io_init(tdb);
tdb->fd = -1;
tdb->name = NULL;
......@@ -222,6 +209,10 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!"));
goto fail;
}
#ifdef TDB_TRACE
/* All tracing will fail. That's ok. */
tdb->tracefd = -1;
#endif
goto internal;
}
......@@ -330,6 +321,15 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
goto fail;
}
#ifdef TDB_TRACE
sprintf(tracefile, "%s.trace.%u", name, getpid());
tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600);
if (tdb->tracefd < 0)
goto fail;
tdb_enable_seqnum(tdb);
tdb_trace_open(tdb, "tdb_open", hash_size, tdb_flags, open_flags);
#endif
internal:
/* Internal (memory-only) databases skip all the code above to
* do with disk files, and resume here by releasing their
......@@ -383,7 +383,7 @@ int tdb_close(struct tdb_context *tdb)
struct tdb_context **i;
int ret = 0;
tdb_trace(tdb, "tdb_close\n");
tdb_trace(tdb, "tdb_close");
if (tdb->transaction) {
tdb_transaction_cancel_internal(tdb);
}
......
This diff is collapsed.
......@@ -89,15 +89,32 @@ typedef uint32_t tdb_off_t;
#define TDB_LOG(x) tdb->log.log_fn x
#ifdef TDB_TRACE
void tdb_trace(const struct tdb_context *tdb, const char *fmt, ...);
void tdb_trace_record(const struct tdb_context *tdb, TDB_DATA rec);
void tdb_trace(struct tdb_context *tdb, const char *op);
void tdb_trace_open(struct tdb_context *tdb, const char *op,
unsigned hash_size, unsigned tdb_flags, unsigned open_flags);
void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret);
void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret);
void tdb_trace_1rec(struct tdb_context *tdb, const char *op,
TDB_DATA rec);
void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op,
TDB_DATA rec, int ret);
void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op,
TDB_DATA rec, TDB_DATA ret);
void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op,
TDB_DATA rec1, TDB_DATA rec2, unsigned flag,
int ret);
void tdb_trace_2rec_retrec(struct tdb_context *tdb, const char *op,
TDB_DATA rec1, TDB_DATA rec2, TDB_DATA ret);
#else
static inline void tdb_trace(const struct tdb_context *tdb, const char *fmt, ...)
{
}
static inline void tdb_trace_record(const struct tdb_context *tdb, TDB_DATA rec)
{
}
#define tdb_trace(tdb, op)
#define tdb_trace_open(tdb, op, hash_size, tdb_flags, open_flags)
#define tdb_trace_ret(tdb, op, ret)
#define tdb_trace_retrec(tdb, op, ret)
#define tdb_trace_1rec(tdb, op, rec)
#define tdb_trace_1rec_ret(tdb, op, rec, ret)
#define tdb_trace_1rec_retrec(tdb, op, rec, ret)
#define tdb_trace_2rec_flag_ret(tdb, op, rec1, rec2, flag, ret)
#define tdb_trace_2rec_retrec(tdb, op, rec1, rec2, ret)
#endif /* !TDB_TRACE */
/* lock offsets */
......
LDLIBS:=-lccan
CFLAGS:=-I../../.. -Wall -g -pg -O3
CFLAGS:=-I../../.. -Wall -O3 #-g -pg
LDFLAGS:=-L../../..
default: replay_trace tdbtorture
default: replay_trace tdbtorture tdbdump
replay_trace: replay_trace.c keywords.c
$(LINK.c) $< $(LOADLIBES) $(LDLIBS) -o $@
keywords.c: keywords.gperf
gperf $< > $@
clean:
rm -f replay_trace tdbtorture *.o
rm -f replay_trace tdbtorture tdbdump *.o
/* ANSI-C code produced by gperf version 3.0.3 */
/* Command-line: gperf keywords.gperf */
/* Computed positions: -k'5,$' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
#endif
#line 1 "keywords.gperf"
#line 4 "keywords.gperf"
struct op_table {
const char *name;
enum op_type type;
void (*enhance_op)(const char *filename,
struct op op[], unsigned int op_num, char *words[]);
};
/* maximum key range = 43, duplicates = 0 */
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static unsigned int
hash_keyword (register const char *str, register unsigned int len)
{
static const unsigned char asso_values[] =
{
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 15, 51, 25,
5, 0, 10, 0, 0, 0, 51, 0, 0, 0,
15, 51, 15, 51, 51, 0, 5, 0, 51, 0,
51, 15, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51
};
return len + asso_values[(unsigned char)str[4]] + asso_values[(unsigned char)str[len - 1]];
}
#ifdef __GNUC__
__inline
#ifdef __GNUC_STDC_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
const struct op_table *
find_keyword (register const char *str, register unsigned int len)
{
enum
{
TOTAL_KEYWORDS = 33,
MIN_WORD_LENGTH = 8,
MAX_WORD_LENGTH = 29,
MIN_HASH_VALUE = 8,
MAX_HASH_VALUE = 50
};
static const struct op_table wordlist[] =
{
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
#line 44 "keywords.gperf"
{"traverse", OP_TDB_TRAVERSE, op_add_key_data,},
#line 34 "keywords.gperf"
{"tdb_store", OP_TDB_STORE, op_add_store,},
#line 33 "keywords.gperf"
{"tdb_exists", OP_TDB_EXISTS, op_add_key_ret,},
#line 16 "keywords.gperf"
{"tdb_lockall", OP_TDB_LOCKALL, op_add_nothing,},
#line 37 "keywords.gperf"
{"tdb_wipe_all", OP_TDB_WIPE_ALL, op_add_nothing,},
#line 20 "keywords.gperf"
{"tdb_unlockall", OP_TDB_UNLOCKALL, op_add_nothing,},
#line 36 "keywords.gperf"
{"tdb_get_seqnum", OP_TDB_GET_SEQNUM, op_add_seqnum,},
#line 48 "keywords.gperf"
{"tdb_delete", OP_TDB_DELETE, op_add_key_ret,},
#line 17 "keywords.gperf"
{"tdb_lockall_mark", OP_TDB_LOCKALL_MARK, op_add_nothing,},
{""},
#line 18 "keywords.gperf"
{"tdb_lockall_unmark", OP_TDB_LOCKALL_UNMARK, op_add_nothing,},
#line 47 "keywords.gperf"
{"tdb_fetch", OP_TDB_FETCH, op_add_key_data,},
#line 19 "keywords.gperf"
{"tdb_lockall_nonblock", OP_TDB_LOCKALL_NONBLOCK, op_add_nothing,},
#line 21 "keywords.gperf"
{"tdb_lockall_read", OP_TDB_LOCKALL_READ, op_add_nothing,},
{""},
#line 23 "keywords.gperf"
{"tdb_unlockall_read", OP_TDB_UNLOCKALL_READ, op_add_nothing,},
{""},
#line 22 "keywords.gperf"
{"tdb_lockall_read_nonblock", OP_TDB_LOCKALL_READ_NONBLOCK, op_add_nothing,},
#line 43 "keywords.gperf"
{"tdb_traverse_end", OP_TDB_TRAVERSE_END, op_analyze_traverse,},
#line 39 "keywords.gperf"
{"tdb_transaction_cancel", OP_TDB_TRANSACTION_CANCEL, op_add_nothing,},
#line 42 "keywords.gperf"
{"tdb_traverse_start", OP_TDB_TRAVERSE_START, op_add_traverse,},
#line 31 "keywords.gperf"
{"tdb_increment_seqnum_nonblock", OP_TDB_INCREMENT_SEQNUM_NONBLOCK, op_add_nothing,},
#line 35 "keywords.gperf"
{"tdb_append", OP_TDB_APPEND, op_add_append,},
#line 38 "keywords.gperf"
{"tdb_transaction_start", OP_TDB_TRANSACTION_START, op_add_nothing,},
#line 40 "keywords.gperf"
{"tdb_transaction_commit", OP_TDB_TRANSACTION_COMMIT, op_add_nothing,},
#line 41 "keywords.gperf"
{"tdb_traverse_read_start", OP_TDB_TRAVERSE_READ_START, op_add_traverse,},
{""}, {""},
#line 32 "keywords.gperf"
{"tdb_parse_record", OP_TDB_PARSE_RECORD, op_add_key_ret,},
#line 45 "keywords.gperf"
{"tdb_firstkey", OP_TDB_FIRSTKEY, op_add_key,},
#line 24 "keywords.gperf"
{"tdb_chainlock", OP_TDB_CHAINLOCK, op_add_key,},
{""},
#line 28 "keywords.gperf"
{"tdb_chainunlock", OP_TDB_CHAINUNLOCK, op_add_key,},
#line 46 "keywords.gperf"
{"tdb_nextkey", OP_TDB_NEXTKEY, op_add_key_data,},
{""},
#line 26 "keywords.gperf"
{"tdb_chainlock_mark", OP_TDB_CHAINLOCK_MARK, op_add_key,},
{""},
#line 27 "keywords.gperf"
{"tdb_chainlock_unmark", OP_TDB_CHAINLOCK_UNMARK, op_add_key,},
{""},
#line 25 "keywords.gperf"
{"tdb_chainlock_nonblock", OP_TDB_CHAINLOCK_NONBLOCK, op_add_key_ret,},
#line 29 "keywords.gperf"
{"tdb_chainlock_read", OP_TDB_CHAINLOCK_READ, op_add_key,},
{""},
#line 30 "keywords.gperf"
{"tdb_chainunlock_read", OP_TDB_CHAINUNLOCK_READ, op_add_key,}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
register int key = hash_keyword (str, len);
if (key <= MAX_HASH_VALUE && key >= 0)
{
register const char *s = wordlist[key].name;
if (*str == *s && !strcmp (str + 1, s + 1))
return &wordlist[key];
}
}
return 0;
}
%{
%}
%language=ANSI-C
struct op_table {
const char *name;
enum op_type type;
void (*enhance_op)(const char *filename,
struct op op[], unsigned int op_num, char *words[]);
};
%define hash-function-name hash_keyword
%define lookup-function-name find_keyword
%readonly-tables
%struct-type
%enum
%%
tdb_lockall, OP_TDB_LOCKALL, op_add_nothing,
tdb_lockall_mark, OP_TDB_LOCKALL_MARK, op_add_nothing,
tdb_lockall_unmark, OP_TDB_LOCKALL_UNMARK, op_add_nothing,
tdb_lockall_nonblock, OP_TDB_LOCKALL_NONBLOCK, op_add_nothing,
tdb_unlockall, OP_TDB_UNLOCKALL, op_add_nothing,
tdb_lockall_read, OP_TDB_LOCKALL_READ, op_add_nothing,
tdb_lockall_read_nonblock, OP_TDB_LOCKALL_READ_NONBLOCK, op_add_nothing,
tdb_unlockall_read, OP_TDB_UNLOCKALL_READ, op_add_nothing,
tdb_chainlock, OP_TDB_CHAINLOCK, op_add_key,
tdb_chainlock_nonblock, OP_TDB_CHAINLOCK_NONBLOCK, op_add_key_ret,
tdb_chainlock_mark, OP_TDB_CHAINLOCK_MARK, op_add_key,
tdb_chainlock_unmark, OP_TDB_CHAINLOCK_UNMARK, op_add_key,
tdb_chainunlock, OP_TDB_CHAINUNLOCK, op_add_key,
tdb_chainlock_read, OP_TDB_CHAINLOCK_READ, op_add_key,
tdb_chainunlock_read, OP_TDB_CHAINUNLOCK_READ, op_add_key,
tdb_increment_seqnum_nonblock, OP_TDB_INCREMENT_SEQNUM_NONBLOCK, op_add_nothing,
tdb_parse_record, OP_TDB_PARSE_RECORD, op_add_key_ret,
tdb_exists, OP_TDB_EXISTS, op_add_key_ret,
tdb_store, OP_TDB_STORE, op_add_store,
tdb_append, OP_TDB_APPEND, op_add_append,
tdb_get_seqnum, OP_TDB_GET_SEQNUM, op_add_seqnum,
tdb_wipe_all, OP_TDB_WIPE_ALL, op_add_nothing,
tdb_transaction_start, OP_TDB_TRANSACTION_START, op_add_nothing,
tdb_transaction_cancel, OP_TDB_TRANSACTION_CANCEL, op_add_nothing,
tdb_transaction_commit, OP_TDB_TRANSACTION_COMMIT, op_add_nothing,
tdb_traverse_read_start, OP_TDB_TRAVERSE_READ_START, op_add_traverse,
tdb_traverse_start, OP_TDB_TRAVERSE_START, op_add_traverse,
tdb_traverse_end, OP_TDB_TRAVERSE_END, op_analyze_traverse,
traverse, OP_TDB_TRAVERSE, op_add_key_data,
tdb_firstkey, OP_TDB_FIRSTKEY, op_add_key,
tdb_nextkey, OP_TDB_NEXTKEY, op_add_key_data,
tdb_fetch, OP_TDB_FETCH, op_add_key_data,
tdb_delete, OP_TDB_DELETE, op_add_key_ret,
This diff is collapsed.
/*
Unix SMB/CIFS implementation.
simple tdb dump util
Copyright (C) Andrew Tridgell 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <ccan/tdb/tdb.h>
#include <stdlib.h>
#include <getopt.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <ctype.h>
static void print_data(TDB_DATA d)
{
unsigned char *p = (unsigned char *)d.dptr;
int len = d.dsize;
while (len--) {
if (isprint(*p) && !strchr("\"\\", *p)) {
fputc(*p, stdout);
} else {
printf("\\%02X", *p);
}
p++;
}
}
static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
printf("{\n");
printf("key(%d) = \"", (int)key.dsize);
print_data(key);
printf("\"\n");
printf("data(%d) = \"", (int)dbuf.dsize);
print_data(dbuf);
printf("\"\n");
printf("}\n");
return 0;
}
static int dump_tdb(const char *fname, const char *keyname)
{
TDB_CONTEXT *tdb;
TDB_DATA key, value;
tdb = tdb_open(fname, 0, 0, O_RDONLY, 0);
if (!tdb) {
printf("Failed to open %s\n", fname);
return 1;
}
if (!keyname) {
tdb_traverse(tdb, traverse_fn, NULL);
} else {
key.dptr = (void *)keyname;
key.dsize = strlen( keyname);
value = tdb_fetch(tdb, key);
if (!value.dptr) {
return 1;
} else {
print_data(value);
free(value.dptr);
}
}
return 0;
}
static void usage( void)
{
printf( "Usage: tdbdump [options] <filename>\n\n");
printf( " -h this help message\n");
printf( " -k keyname dumps value of keyname\n");
}
int main(int argc, char *argv[])
{
char *fname, *keyname=NULL;
int c;
if (argc < 2) {
printf("Usage: tdbdump <fname>\n");
exit(1);
}
while ((c = getopt( argc, argv, "hk:")) != -1) {
switch (c) {
case 'h':
usage();
exit( 0);
case 'k':
keyname = optarg;
break;
default:
usage();
exit( 1);
}
}
fname = argv[optind];
return dump_tdb(fname, keyname);
}
......@@ -20,6 +20,7 @@
#define DELETE_PROB 8
#define STORE_PROB 4
#define APPEND_PROB 6
#if 0
#define TRANSACTION_PROB 10
#define TRANSACTION_PREPARE_PROB 2
#define LOCKSTORE_PROB 5
......@@ -27,6 +28,7 @@
#define TRAVERSE_READ_PROB 20
#define TRAVERSE_MOD_PROB 100
#define TRAVERSE_ABORT_PROB 500
#endif
#define CULL_PROB 100
#define KEYLEN 3
#define DATALEN 100
......
......@@ -457,7 +457,7 @@ int tdb_transaction_cancel_internal(struct tdb_context *tdb)
*/
int tdb_transaction_start(struct tdb_context *tdb)
{
tdb_trace(tdb, "tdb_transaction_start\n");
tdb_trace(tdb, "tdb_transaction_start");
/* some sanity checks */
if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) {
......@@ -566,7 +566,7 @@ fail:
*/
int tdb_transaction_cancel(struct tdb_context *tdb)
{
tdb_trace(tdb, "tdb_transaction_cancel\n");
tdb_trace(tdb, "tdb_transaction_cancel");
return tdb_transaction_cancel_internal(tdb);
}
/*
......@@ -851,7 +851,7 @@ int tdb_transaction_commit(struct tdb_context *tdb)
uint32_t zero = 0;
int i;
tdb_trace(tdb, "tdb_transaction_commit\n");
tdb_trace(tdb, "tdb_transaction_commit");
if (tdb->transaction == NULL) {
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n"));
return -1;
......
......@@ -169,10 +169,7 @@ static int tdb_traverse_internal(struct tdb_context *tdb,
dbuf.dptr = key.dptr + rec.key_len;
dbuf.dsize = rec.data_len;
tdb_trace(tdb, "traverse ");
tdb_trace_record(tdb, key);
tdb_trace_record(tdb, dbuf);
tdb_trace(tdb, "\n");
tdb_trace_1rec_retrec(tdb, "traverse", key, dbuf);
/* Drop chain lock, call out */
if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0) {
......@@ -182,7 +179,7 @@ static int tdb_traverse_internal(struct tdb_context *tdb,
}
if (fn && fn(tdb, key, dbuf, private_data)) {
/* They want us to terminate traversal */
tdb_trace(tdb, "tdb_traverse_end = %i\n", count);
tdb_trace_ret(tdb, "tdb_traverse_end", count);
ret = count;
if (tdb_unlock_record(tdb, tl->off) != 0) {
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: unlock_record failed!\n"));;
......@@ -193,7 +190,7 @@ static int tdb_traverse_internal(struct tdb_context *tdb,
}
SAFE_FREE(key.dptr);
}
tdb_trace(tdb, "tdb_traverse_end\n");
tdb_trace(tdb, "tdb_traverse_end");
out:
tdb->travlocks.next = tl->next;
if (ret < 0)
......@@ -219,7 +216,7 @@ int tdb_traverse_read(struct tdb_context *tdb,
}
tdb->traverse_read++;
tdb_trace(tdb, "tdb_traverse_read_start\n");
tdb_trace(tdb, "tdb_traverse_read_start");
ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
tdb->traverse_read--;
......@@ -253,7 +250,7 @@ int tdb_traverse(struct tdb_context *tdb,
}
tdb->traverse_write++;
tdb_trace(tdb, "tdb_traverse_start\n");
tdb_trace(tdb, "tdb_traverse_start");
ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
tdb->traverse_write--;
......@@ -279,16 +276,14 @@ TDB_DATA tdb_firstkey(struct tdb_context *tdb)
/* Grab first record: locks chain and returned record. */
if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) {
tdb_trace(tdb, "tdb_firstkey = ENOENT\n");
tdb_trace_retrec(tdb, "tdb_firstkey", tdb_null);
return tdb_null;
}
/* now read the key */
key.dsize = rec.key_len;
key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize);
tdb_trace(tdb, "tdb_firstkey = ");
tdb_trace_record(tdb, key);
tdb_trace(tdb, "\n");
tdb_trace_retrec(tdb, "tdb_firstkey", key);
/* Unlock the hash chain of the record we just read. */
if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0)
......@@ -314,9 +309,8 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
|| memcmp(k, oldkey.dptr, oldkey.dsize) != 0) {
/* No, it wasn't: unlock it and start from scratch */
if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) {
tdb_trace(tdb, "tdb_nextkey ");
tdb_trace_record(tdb, oldkey);
tdb_trace(tdb, "= ENOENT\n");
tdb_trace_1rec_retrec(tdb, "tdb_nextkey",
oldkey, tdb_null);
SAFE_FREE(k);
return tdb_null;
}
......@@ -334,9 +328,7 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
/* No previous element: do normal find, and lock record */
tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec);
if (!tdb->travlocks.off) {
tdb_trace(tdb, "tdb_nextkey ");
tdb_trace_record(tdb, oldkey);
tdb_trace(tdb, "= ENOENT\n");
tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, tdb_null);
return tdb_null;
}
tdb->travlocks.hash = BUCKET(rec.full_hash);
......@@ -360,11 +352,7 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
/* Unlock the chain of old record */
if (tdb_unlock(tdb, BUCKET(oldhash), tdb->travlocks.lock_rw) != 0)
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
tdb_trace(tdb, "tdb_nextkey ");
tdb_trace_record(tdb, oldkey);
tdb_trace(tdb, "= ");
tdb_trace_record(tdb, key);
tdb_trace(tdb, "\n");
tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, key);
return key;
}
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