summaryrefslogtreecommitdiff
path: root/source4/lib/tdb/tools
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/tdb/tools')
-rw-r--r--source4/lib/tdb/tools/tdbtool.c26
-rw-r--r--source4/lib/tdb/tools/tdbtorture.c129
2 files changed, 114 insertions, 41 deletions
diff --git a/source4/lib/tdb/tools/tdbtool.c b/source4/lib/tdb/tools/tdbtool.c
index 5a8c871699..0941a73118 100644
--- a/source4/lib/tdb/tools/tdbtool.c
+++ b/source4/lib/tdb/tools/tdbtool.c
@@ -34,6 +34,7 @@
#include <sys/time.h>
#include <ctype.h>
#include <signal.h>
+#include <stdarg.h>
#include "tdb.h"
/* a tdb tool for manipulating a tdb database */
@@ -77,6 +78,19 @@ static void print_asc(unsigned char *buf,int len)
printf("%c",isprint(buf[i])?buf[i]:'.');
}
+#ifdef PRINTF_ATTRIBUTE
+static void tdb_log(struct tdb_context *t, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4);
+#endif
+static void tdb_log(struct tdb_context *t, int level, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+ fflush(stdout);
+}
+
static void print_data(unsigned char *buf,int len)
{
int i=0;
@@ -131,7 +145,7 @@ static void help(void)
"\n");
}
-static void terror(char *why)
+static void terror(const char *why)
{
printf("%s\n", why);
}
@@ -175,8 +189,8 @@ static void create_tdb(void)
return;
}
if (tdb) tdb_close(tdb);
- tdb = tdb_open(tok, 0, TDB_CLEAR_IF_FIRST,
- O_RDWR | O_CREAT | O_TRUNC, 0600);
+ tdb = tdb_open_ex(tok, 0, TDB_CLEAR_IF_FIRST,
+ O_RDWR | O_CREAT | O_TRUNC, 0600, tdb_log, NULL);
if (!tdb) {
printf("Could not create %s: %s\n", tok, strerror(errno));
}
@@ -190,7 +204,7 @@ static void open_tdb(void)
return;
}
if (tdb) tdb_close(tdb);
- tdb = tdb_open(tok, 0, 0, O_RDWR, 0600);
+ tdb = tdb_open_ex(tok, 0, 0, O_RDWR, 0600, tdb_log, NULL);
if (!tdb) {
printf("Could not open %s: %s\n", tok, strerror(errno));
}
@@ -326,7 +340,7 @@ static void move_rec(void)
print_rec(tdb, key, dbuf, NULL);
- dst_tdb = tdb_open(file, 0, 0, O_RDWR, 0600);
+ dst_tdb = tdb_open_ex(file, 0, 0, O_RDWR, 0600, tdb_log, NULL);
if ( !dst_tdb ) {
terror("unable to open destination tdb");
return;
@@ -377,7 +391,7 @@ static void info_tdb(void)
printf("%d records totalling %d bytes\n", count, total_bytes);
}
-static char *tdb_getline(char *prompt)
+static char *tdb_getline(const char *prompt)
{
static char line[1024];
char *p;
diff --git a/source4/lib/tdb/tools/tdbtorture.c b/source4/lib/tdb/tools/tdbtorture.c
index 0cf82fa5a5..b0a2e7484f 100644
--- a/source4/lib/tdb/tools/tdbtorture.c
+++ b/source4/lib/tdb/tools/tdbtorture.c
@@ -1,6 +1,8 @@
/* this tests tdb by doing lots of ops from several simultaneous
- writers - that stresses the locking code. Build with TDB_DEBUG=1
- for best effect */
+ writers - that stresses the locking code.
+*/
+
+#define _GNU_SOURCE
#ifndef _SAMBA_BUILD_
#include <stdlib.h>
@@ -28,11 +30,14 @@
#endif
+#include <getopt.h>
+
#define REOPEN_PROB 30
#define DELETE_PROB 8
#define STORE_PROB 4
#define APPEND_PROB 6
-#define LOCKSTORE_PROB 0
+#define TRANSACTION_PROB 10
+#define LOCKSTORE_PROB 5
#define TRAVERSE_PROB 20
#define CULL_PROB 100
#define KEYLEN 3
@@ -40,6 +45,7 @@
#define LOCKLEN 20
static struct tdb_context *db;
+static int in_transaction;
#ifdef PRINTF_ATTRIBUTE
static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4);
@@ -84,25 +90,25 @@ static char *randbuf(int len)
static int cull_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf,
void *state)
{
+#if CULL_PROB
if (random() % CULL_PROB == 0) {
tdb_delete(tdb, key);
}
+#endif
return 0;
}
static void addrec_db(void)
{
- int klen, dlen, slen;
- char *k, *d, *s;
- TDB_DATA key, data, lockkey;
+ int klen, dlen;
+ char *k, *d;
+ TDB_DATA key, data;
klen = 1 + (rand() % KEYLEN);
dlen = 1 + (rand() % DATALEN);
- slen = 1 + (rand() % LOCKLEN);
k = randbuf(klen);
d = randbuf(dlen);
- s = randbuf(slen);
key.dptr = (unsigned char *)k;
key.dsize = klen+1;
@@ -110,11 +116,32 @@ static void addrec_db(void)
data.dptr = (unsigned char *)d;
data.dsize = dlen+1;
- lockkey.dptr = (unsigned char *)s;
- lockkey.dsize = slen+1;
+#if TRANSACTION_PROB
+ if (in_transaction == 0 && random() % TRANSACTION_PROB == 0) {
+ if (tdb_transaction_start(db) != 0) {
+ fatal("tdb_transaction_start failed");
+ }
+ in_transaction++;
+ goto next;
+ }
+ if (in_transaction && random() % TRANSACTION_PROB == 0) {
+ if (tdb_transaction_commit(db) != 0) {
+ fatal("tdb_transaction_commit failed");
+ }
+ in_transaction--;
+ goto next;
+ }
+ if (in_transaction && random() % TRANSACTION_PROB == 0) {
+ if (tdb_transaction_cancel(db) != 0) {
+ fatal("tdb_transaction_cancel failed");
+ }
+ in_transaction--;
+ goto next;
+ }
+#endif
#if REOPEN_PROB
- if (random() % REOPEN_PROB == 0) {
+ if (in_transaction == 0 && random() % REOPEN_PROB == 0) {
tdb_reopen_all();
goto next;
}
@@ -147,13 +174,13 @@ static void addrec_db(void)
#if LOCKSTORE_PROB
if (random() % LOCKSTORE_PROB == 0) {
- tdb_chainlock(db, lockkey);
+ tdb_chainlock(db, key);
data = tdb_fetch(db, key);
if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
fatal("tdb_store failed");
}
if (data.dptr) free(data.dptr);
- tdb_chainunlock(db, lockkey);
+ tdb_chainunlock(db, key);
goto next;
}
#endif
@@ -171,7 +198,6 @@ static void addrec_db(void)
next:
free(k);
free(d);
- free(s);
}
static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf,
@@ -181,38 +207,71 @@ static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf,
return 0;
}
-#ifndef NPROC
-#define NPROC 2
-#endif
-
-#ifndef NLOOPS
-#define NLOOPS 5000
-#endif
-
- int main(int argc, const char *argv[])
+static void usage(void)
{
- int i, seed=0;
- int loops = NLOOPS;
- pid_t pids[NPROC];
+ printf("Usage: tdbtorture [-n NUM_PROCS] [-l NUM_LOOPS] [-s SEED] [-H HASH_SIZE]\n");
+ exit(0);
+}
- pids[0] = getpid();
+ int main(int argc, char * const *argv)
+{
+ int i, seed = -1;
+ int num_procs = 2;
+ int num_loops = 5000;
+ int hash_size = 2;
+ int c;
+ extern char *optarg;
+ pid_t *pids;
+
+ while ((c = getopt(argc, argv, "n:l:s:H:h")) != -1) {
+ switch (c) {
+ case 'n':
+ num_procs = strtol(optarg, NULL, 0);
+ break;
+ case 'l':
+ num_loops = strtol(optarg, NULL, 0);
+ break;
+ case 'H':
+ hash_size = strtol(optarg, NULL, 0);
+ break;
+ case 's':
+ seed = strtol(optarg, NULL, 0);
+ break;
+ default:
+ usage();
+ }
+ }
unlink("torture.tdb");
- for (i=0;i<NPROC-1;i++) {
+ pids = calloc(sizeof(pid_t), num_procs);
+ pids[0] = getpid();
+
+ for (i=0;i<num_procs-1;i++) {
if ((pids[i+1]=fork()) == 0) break;
}
- db = tdb_open("torture.tdb", 2, TDB_CLEAR_IF_FIRST,
- O_RDWR | O_CREAT, 0600);
+ db = tdb_open_ex("torture.tdb", hash_size, TDB_CLEAR_IF_FIRST,
+ O_RDWR | O_CREAT, 0600, tdb_log, NULL);
if (!db) {
fatal("db open failed");
}
- tdb_logging_function(db, tdb_log);
- srand(seed + getpid());
- srandom(seed + getpid() + time(NULL));
- for (i=0;i<loops;i++) addrec_db();
+ if (seed == -1) {
+ seed = (getpid() + time(NULL)) & 0x7FFFFFFF;
+ }
+
+ if (i == 0) {
+ printf("testing with %d processes, %d loops, %d hash_size, seed=%d\n",
+ num_procs, num_loops, hash_size, seed);
+ }
+
+ srand(seed + i);
+ srandom(seed + i);
+
+ for (i=0;i<num_loops;i++) {
+ addrec_db();
+ }
tdb_traverse(db, NULL, NULL);
tdb_traverse(db, traverse_fn, NULL);
@@ -221,7 +280,7 @@ static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf,
tdb_close(db);
if (getpid() == pids[0]) {
- for (i=0;i<NPROC-1;i++) {
+ for (i=0;i<num_procs-1;i++) {
int status;
if (waitpid(pids[i+1], &status, 0) != pids[i+1]) {
printf("failed to wait for %d\n",