summaryrefslogtreecommitdiff
path: root/lib/tdb2/tools
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2012-06-18 22:30:26 +0930
committerRusty Russell <rusty@rustcorp.com.au>2012-06-19 05:38:06 +0200
commit16cc345d4f84367e70e133200f7aa335c2aae8c6 (patch)
tree955a33c25c19f3127e24ba6b0e108da6b1f7f804 /lib/tdb2/tools
parent76758b9767fad45ff144bbfef3ab84bca5d4650e (diff)
downloadsamba-16cc345d4f84367e70e133200f7aa335c2aae8c6.tar.gz
samba-16cc345d4f84367e70e133200f7aa335c2aae8c6.tar.bz2
samba-16cc345d4f84367e70e133200f7aa335c2aae8c6.zip
TDB2: Goodbye TDB2, Hello NTDB.
This renames everything from tdb2 to ntdb: importantly, we no longer use the tdb_ namespace, so you can link against both ntdb and tdb if you want to. This also enables building of standalone ntdb by the autobuild script. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'lib/tdb2/tools')
-rw-r--r--lib/tdb2/tools/Makefile16
-rw-r--r--lib/tdb2/tools/growtdb-bench.c114
-rw-r--r--lib/tdb2/tools/mktdb2.c29
-rw-r--r--lib/tdb2/tools/speed.c443
-rw-r--r--lib/tdb2/tools/tdb2backup.c340
-rw-r--r--lib/tdb2/tools/tdb2dump.c122
-rw-r--r--lib/tdb2/tools/tdb2restore.c231
-rw-r--r--lib/tdb2/tools/tdb2tool.c810
-rw-r--r--lib/tdb2/tools/tdb2torture.c529
9 files changed, 0 insertions, 2634 deletions
diff --git a/lib/tdb2/tools/Makefile b/lib/tdb2/tools/Makefile
deleted file mode 100644
index 11188c3baf..0000000000
--- a/lib/tdb2/tools/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-OBJS:=../../tdb2.o ../../hash.o ../../tally.o
-CFLAGS:=-I../../.. -I.. -Wall -g -O3 #-g -pg
-LDFLAGS:=-L../../..
-
-default: tdb2torture tdb2tool tdb2dump tdb2restore mktdb2 speed growtdb-bench
-
-tdb2dump: tdb2dump.c $(OBJS)
-tdb2restore: tdb2restore.c $(OBJS)
-tdb2torture: tdb2torture.c $(OBJS)
-tdb2tool: tdb2tool.c $(OBJS)
-mktdb2: mktdb2.c $(OBJS)
-speed: speed.c $(OBJS)
-growtdb-bench: growtdb-bench.c $(OBJS)
-
-clean:
- rm -f tdb2torture tdb2dump tdb2restore tdb2tool mktdb2 speed growtdb-bench
diff --git a/lib/tdb2/tools/growtdb-bench.c b/lib/tdb2/tools/growtdb-bench.c
deleted file mode 100644
index 476e8be5da..0000000000
--- a/lib/tdb2/tools/growtdb-bench.c
+++ /dev/null
@@ -1,114 +0,0 @@
-#include "tdb2.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <ccan/err/err.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-static void logfn(struct tdb_context *tdb,
- enum tdb_log_level level,
- enum TDB_ERROR ecode,
- const char *message,
- void *data)
-{
- fprintf(stderr, "tdb:%s:%s:%s\n",
- tdb_name(tdb), tdb_errorstr(ecode), message);
-}
-
-int main(int argc, char *argv[])
-{
- unsigned int i, j, users, groups;
- TDB_DATA idxkey, idxdata;
- TDB_DATA k, d, gk;
- char cmd[100];
- struct tdb_context *tdb;
- enum TDB_ERROR ecode;
- union tdb_attribute log;
-
- if (argc != 3) {
- printf("Usage: growtdb-bench <users> <groups>\n");
- exit(1);
- }
- users = atoi(argv[1]);
- groups = atoi(argv[2]);
-
- sprintf(cmd, "cat /proc/%i/statm", getpid());
-
- log.base.attr = TDB_ATTRIBUTE_LOG;
- log.base.next = NULL;
- log.log.fn = logfn;
-
- tdb = tdb_open("/tmp/growtdb.tdb", TDB_DEFAULT,
- O_RDWR|O_CREAT|O_TRUNC, 0600, &log);
-
- idxkey.dptr = (unsigned char *)"User index";
- idxkey.dsize = strlen("User index");
- idxdata.dsize = 51;
- idxdata.dptr = calloc(idxdata.dsize, 1);
-
- /* Create users. */
- k.dsize = 48;
- k.dptr = calloc(k.dsize, 1);
- d.dsize = 64;
- d.dptr = calloc(d.dsize, 1);
-
- tdb_transaction_start(tdb);
- for (i = 0; i < users; i++) {
- memcpy(k.dptr, &i, sizeof(i));
- ecode = tdb_store(tdb, k, d, TDB_INSERT);
- if (ecode != TDB_SUCCESS)
- errx(1, "tdb insert failed: %s", tdb_errorstr(ecode));
-
- /* This simulates a growing index record. */
- ecode = tdb_append(tdb, idxkey, idxdata);
- if (ecode != TDB_SUCCESS)
- errx(1, "tdb append failed: %s", tdb_errorstr(ecode));
- }
- if ((ecode = tdb_transaction_commit(tdb)) != 0)
- errx(1, "tdb commit1 failed: %s", tdb_errorstr(ecode));
-
- if ((ecode = tdb_check(tdb, NULL, NULL)) != 0)
- errx(1, "tdb_check failed after initial insert!");
-
- system(cmd);
-
- /* Now put them all in groups: add 32 bytes to each record for
- * a group. */
- gk.dsize = 48;
- gk.dptr = calloc(k.dsize, 1);
- gk.dptr[gk.dsize-1] = 1;
-
- d.dsize = 32;
- for (i = 0; i < groups; i++) {
- tdb_transaction_start(tdb);
- /* Create the "group". */
- memcpy(gk.dptr, &i, sizeof(i));
- ecode = tdb_store(tdb, gk, d, TDB_INSERT);
- if (ecode != TDB_SUCCESS)
- errx(1, "tdb insert failed: %s", tdb_errorstr(ecode));
-
- /* Now populate it. */
- for (j = 0; j < users; j++) {
- /* Append to the user. */
- memcpy(k.dptr, &j, sizeof(j));
- if ((ecode = tdb_append(tdb, k, d)) != 0)
- errx(1, "tdb append failed: %s",
- tdb_errorstr(ecode));
-
- /* Append to the group. */
- if ((ecode = tdb_append(tdb, gk, d)) != 0)
- errx(1, "tdb append failed: %s",
- tdb_errorstr(ecode));
- }
- if ((ecode = tdb_transaction_commit(tdb)) != 0)
- errx(1, "tdb commit2 failed: %s", tdb_errorstr(ecode));
- if ((ecode = tdb_check(tdb, NULL, NULL)) != 0)
- errx(1, "tdb_check failed after iteration %i!", i);
- system(cmd);
- }
-
- return 0;
-}
diff --git a/lib/tdb2/tools/mktdb2.c b/lib/tdb2/tools/mktdb2.c
deleted file mode 100644
index 35d7a07d0b..0000000000
--- a/lib/tdb2/tools/mktdb2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "tdb2.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <ccan/err/err.h>
-
-int main(int argc, char *argv[])
-{
- unsigned int i, num_recs;
- struct tdb_context *tdb;
-
- if (argc != 3 || (num_recs = atoi(argv[2])) == 0)
- errx(1, "Usage: mktdb <tdbfile> <numrecords>");
-
- tdb = tdb_open(argv[1], TDB_DEFAULT, O_CREAT|O_TRUNC|O_RDWR, 0600,NULL);
- if (!tdb)
- err(1, "Opening %s", argv[1]);
-
- for (i = 0; i < num_recs; i++) {
- TDB_DATA d;
-
- d.dptr = (void *)&i;
- d.dsize = sizeof(i);
- if (tdb_store(tdb, d, d, TDB_INSERT) != 0)
- err(1, "Failed to store record %i", i);
- }
- printf("Done\n");
- return 0;
-}
diff --git a/lib/tdb2/tools/speed.c b/lib/tdb2/tools/speed.c
deleted file mode 100644
index 259d53f6c8..0000000000
--- a/lib/tdb2/tools/speed.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/* Simple speed test for TDB */
-#include <ccan/err/err.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include "tdb2.h"
-
-/* Nanoseconds per operation */
-static size_t normalize(const struct timeval *start,
- const struct timeval *stop,
- unsigned int num)
-{
- struct timeval diff;
-
- timersub(stop, start, &diff);
-
- /* Floating point is more accurate here. */
- return (double)(diff.tv_sec * 1000000 + diff.tv_usec)
- / num * 1000;
-}
-
-static size_t file_size(void)
-{
- struct stat st;
-
- if (stat("/tmp/speed.tdb", &st) != 0)
- return -1;
- return st.st_size;
-}
-
-static int count_record(struct tdb_context *tdb,
- TDB_DATA key, TDB_DATA data, void *p)
-{
- int *total = p;
- *total += *(int *)data.dptr;
- return 0;
-}
-
-static void dump_and_clear_stats(struct tdb_context **tdb,
- int flags,
- union tdb_attribute *attr)
-{
- union tdb_attribute stats;
- enum TDB_ERROR ecode;
-
- stats.base.attr = TDB_ATTRIBUTE_STATS;
- stats.stats.size = sizeof(stats.stats);
- ecode = tdb_get_attribute(*tdb, &stats);
- if (ecode != TDB_SUCCESS)
- errx(1, "Getting stats: %s", tdb_errorstr(ecode));
-
- printf("allocs = %llu\n",
- (unsigned long long)stats.stats.allocs);
- printf(" alloc_subhash = %llu\n",
- (unsigned long long)stats.stats.alloc_subhash);
- printf(" alloc_chain = %llu\n",
- (unsigned long long)stats.stats.alloc_chain);
- printf(" alloc_bucket_exact = %llu\n",
- (unsigned long long)stats.stats.alloc_bucket_exact);
- printf(" alloc_bucket_max = %llu\n",
- (unsigned long long)stats.stats.alloc_bucket_max);
- printf(" alloc_leftover = %llu\n",
- (unsigned long long)stats.stats.alloc_leftover);
- printf(" alloc_coalesce_tried = %llu\n",
- (unsigned long long)stats.stats.alloc_coalesce_tried);
- printf(" alloc_coalesce_iterate_clash = %llu\n",
- (unsigned long long)stats.stats.alloc_coalesce_iterate_clash);
- printf(" alloc_coalesce_lockfail = %llu\n",
- (unsigned long long)stats.stats.alloc_coalesce_lockfail);
- printf(" alloc_coalesce_race = %llu\n",
- (unsigned long long)stats.stats.alloc_coalesce_race);
- printf(" alloc_coalesce_succeeded = %llu\n",
- (unsigned long long)stats.stats.alloc_coalesce_succeeded);
- printf(" alloc_coalesce_num_merged = %llu\n",
- (unsigned long long)stats.stats.alloc_coalesce_num_merged);
- printf("compares = %llu\n",
- (unsigned long long)stats.stats.compares);
- printf(" compare_wrong_bucket = %llu\n",
- (unsigned long long)stats.stats.compare_wrong_bucket);
- printf(" compare_wrong_offsetbits = %llu\n",
- (unsigned long long)stats.stats.compare_wrong_offsetbits);
- printf(" compare_wrong_keylen = %llu\n",
- (unsigned long long)stats.stats.compare_wrong_keylen);
- printf(" compare_wrong_rechash = %llu\n",
- (unsigned long long)stats.stats.compare_wrong_rechash);
- printf(" compare_wrong_keycmp = %llu\n",
- (unsigned long long)stats.stats.compare_wrong_keycmp);
- printf("transactions = %llu\n",
- (unsigned long long)stats.stats.transactions);
- printf(" transaction_cancel = %llu\n",
- (unsigned long long)stats.stats.transaction_cancel);
- printf(" transaction_nest = %llu\n",
- (unsigned long long)stats.stats.transaction_nest);
- printf(" transaction_expand_file = %llu\n",
- (unsigned long long)stats.stats.transaction_expand_file);
- printf(" transaction_read_direct = %llu\n",
- (unsigned long long)stats.stats.transaction_read_direct);
- printf(" transaction_read_direct_fail = %llu\n",
- (unsigned long long)stats.stats.transaction_read_direct_fail);
- printf(" transaction_write_direct = %llu\n",
- (unsigned long long)stats.stats.transaction_write_direct);
- printf(" transaction_write_direct_fail = %llu\n",
- (unsigned long long)stats.stats.transaction_write_direct_fail);
- printf("expands = %llu\n",
- (unsigned long long)stats.stats.expands);
- printf("frees = %llu\n",
- (unsigned long long)stats.stats.frees);
- printf("locks = %llu\n",
- (unsigned long long)stats.stats.locks);
- printf(" lock_lowlevel = %llu\n",
- (unsigned long long)stats.stats.lock_lowlevel);
- printf(" lock_nonblock = %llu\n",
- (unsigned long long)stats.stats.lock_nonblock);
- printf(" lock_nonblock_fail = %llu\n",
- (unsigned long long)stats.stats.lock_nonblock_fail);
-
- /* Now clear. */
- tdb_close(*tdb);
- *tdb = tdb_open("/tmp/speed.tdb", flags, O_RDWR, 0, attr);
-}
-
-static void tdb_log(struct tdb_context *tdb,
- enum tdb_log_level level,
- enum TDB_ERROR ecode,
- const char *message,
- void *data)
-{
- fprintf(stderr, "tdb:%s:%s:%s\n",
- tdb_name(tdb), tdb_errorstr(ecode), message);
-}
-
-int main(int argc, char *argv[])
-{
- unsigned int i, j, num = 1000, stage = 0, stopat = -1;
- int flags = TDB_DEFAULT;
- bool transaction = false, summary = false;
- TDB_DATA key, data;
- struct tdb_context *tdb;
- struct timeval start, stop;
- union tdb_attribute seed, log;
- bool do_stats = false;
- enum TDB_ERROR ecode;
-
- /* Try to keep benchmarks even. */
- seed.base.attr = TDB_ATTRIBUTE_SEED;
- seed.base.next = NULL;
- seed.seed.seed = 0;
-
- log.base.attr = TDB_ATTRIBUTE_LOG;
- log.base.next = &seed;
- log.log.fn = tdb_log;
-
- if (argv[1] && strcmp(argv[1], "--internal") == 0) {
- flags = TDB_INTERNAL;
- argc--;
- argv++;
- }
- if (argv[1] && strcmp(argv[1], "--transaction") == 0) {
- transaction = true;
- argc--;
- argv++;
- }
- if (argv[1] && strcmp(argv[1], "--no-sync") == 0) {
- flags |= TDB_NOSYNC;
- argc--;
- argv++;
- }
- if (argv[1] && strcmp(argv[1], "--summary") == 0) {
- summary = true;
- argc--;
- argv++;
- }
- if (argv[1] && strcmp(argv[1], "--stats") == 0) {
- do_stats = true;
- argc--;
- argv++;
- }
-
- tdb = tdb_open("/tmp/speed.tdb", flags, O_RDWR|O_CREAT|O_TRUNC,
- 0600, &log);
- if (!tdb)
- err(1, "Opening /tmp/speed.tdb");
-
- key.dptr = (void *)&i;
- key.dsize = sizeof(i);
- data = key;
-
- if (argv[1]) {
- num = atoi(argv[1]);
- argv++;
- argc--;
- }
-
- if (argv[1]) {
- stopat = atoi(argv[1]);
- argv++;
- argc--;
- }
-
- /* Add 1000 records. */
- printf("Adding %u records: ", num); fflush(stdout);
- if (transaction && (ecode = tdb_transaction_start(tdb)))
- errx(1, "starting transaction: %s", tdb_errorstr(ecode));
- gettimeofday(&start, NULL);
- for (i = 0; i < num; i++)
- if ((ecode = tdb_store(tdb, key, data, TDB_INSERT)) != 0)
- errx(1, "Inserting key %u in tdb: %s",
- i, tdb_errorstr(ecode));
- gettimeofday(&stop, NULL);
- if (transaction && (ecode = tdb_transaction_commit(tdb)))
- errx(1, "committing transaction: %s", tdb_errorstr(ecode));
- printf(" %zu ns (%zu bytes)\n",
- normalize(&start, &stop, num), file_size());
-
- if (tdb_check(tdb, NULL, NULL))
- errx(1, "tdb_check failed!");
- if (summary) {
- char *sumstr = NULL;
- tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
- printf("%s\n", sumstr);
- free(sumstr);
- }
- if (do_stats)
- dump_and_clear_stats(&tdb, flags, &log);
-
- if (++stage == stopat)
- exit(0);
-
- /* Finding 1000 records. */
- printf("Finding %u records: ", num); fflush(stdout);
- if (transaction && (ecode = tdb_transaction_start(tdb)))
- errx(1, "starting transaction: %s", tdb_errorstr(ecode));
- gettimeofday(&start, NULL);
- for (i = 0; i < num; i++) {
- struct tdb_data dbuf;
- if ((ecode = tdb_fetch(tdb, key, &dbuf)) != TDB_SUCCESS
- || *(int *)dbuf.dptr != i) {
- errx(1, "Fetching key %u in tdb gave %u",
- i, ecode ? ecode : *(int *)dbuf.dptr);
- }
- }
- gettimeofday(&stop, NULL);
- if (transaction && (ecode = tdb_transaction_commit(tdb)))
- errx(1, "committing transaction: %s", tdb_errorstr(ecode));
- printf(" %zu ns (%zu bytes)\n",
- normalize(&start, &stop, num), file_size());
- if (tdb_check(tdb, NULL, NULL))
- errx(1, "tdb_check failed!");
- if (summary) {
- char *sumstr = NULL;
- tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
- printf("%s\n", sumstr);
- free(sumstr);
- }
- if (do_stats)
- dump_and_clear_stats(&tdb, flags, &log);
- if (++stage == stopat)
- exit(0);
-
- /* Missing 1000 records. */
- printf("Missing %u records: ", num); fflush(stdout);
- if (transaction && (ecode = tdb_transaction_start(tdb)))
- errx(1, "starting transaction: %s", tdb_errorstr(ecode));
- gettimeofday(&start, NULL);
- for (i = num; i < num*2; i++) {
- struct tdb_data dbuf;
- ecode = tdb_fetch(tdb, key, &dbuf);
- if (ecode != TDB_ERR_NOEXIST)
- errx(1, "Fetching key %u in tdb gave %s",
- i, tdb_errorstr(ecode));
- }
- gettimeofday(&stop, NULL);
- if (transaction && (ecode = tdb_transaction_commit(tdb)))
- errx(1, "committing transaction: %s", tdb_errorstr(ecode));
- printf(" %zu ns (%zu bytes)\n",
- normalize(&start, &stop, num), file_size());
- if (tdb_check(tdb, NULL, NULL))
- errx(1, "tdb_check failed!");
- if (summary) {
- char *sumstr = NULL;
- tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
- printf("%s\n", sumstr);
- free(sumstr);
- }
- if (do_stats)
- dump_and_clear_stats(&tdb, flags, &log);
- if (++stage == stopat)
- exit(0);
-
- /* Traverse 1000 records. */
- printf("Traversing %u records: ", num); fflush(stdout);
- if (transaction && (ecode = tdb_transaction_start(tdb)))
- errx(1, "starting transaction: %s", tdb_errorstr(ecode));
- i = 0;
- gettimeofday(&start, NULL);
- if (tdb_traverse(tdb, count_record, &i) != num)
- errx(1, "Traverse returned wrong number of records");
- if (i != (num - 1) * (num / 2))
- errx(1, "Traverse tallied to %u", i);
- gettimeofday(&stop, NULL);
- if (transaction && (ecode = tdb_transaction_commit(tdb)))
- errx(1, "committing transaction: %s", tdb_errorstr(ecode));
- printf(" %zu ns (%zu bytes)\n",
- normalize(&start, &stop, num), file_size());
- if (tdb_check(tdb, NULL, NULL))
- errx(1, "tdb_check failed!");
- if (summary) {
- char *sumstr = NULL;
- tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
- printf("%s\n", sumstr);
- free(sumstr);
- }
- if (do_stats)
- dump_and_clear_stats(&tdb, flags, &log);
- if (++stage == stopat)
- exit(0);
-
- /* Delete 1000 records (not in order). */
- printf("Deleting %u records: ", num); fflush(stdout);
- if (transaction && (ecode = tdb_transaction_start(tdb)))
- errx(1, "starting transaction: %s", tdb_errorstr(ecode));
- gettimeofday(&start, NULL);
- for (j = 0; j < num; j++) {
- i = (j + 100003) % num;
- if ((ecode = tdb_delete(tdb, key)) != TDB_SUCCESS)
- errx(1, "Deleting key %u in tdb: %s",
- i, tdb_errorstr(ecode));
- }
- gettimeofday(&stop, NULL);
- if (transaction && (ecode = tdb_transaction_commit(tdb)))
- errx(1, "committing transaction: %s", tdb_errorstr(ecode));
- printf(" %zu ns (%zu bytes)\n",
- normalize(&start, &stop, num), file_size());
- if (tdb_check(tdb, NULL, NULL))
- errx(1, "tdb_check failed!");
- if (summary) {
- char *sumstr = NULL;
- tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
- printf("%s\n", sumstr);
- free(sumstr);
- }
- if (do_stats)
- dump_and_clear_stats(&tdb, flags, &log);
- if (++stage == stopat)
- exit(0);
-
- /* Re-add 1000 records (not in order). */
- printf("Re-adding %u records: ", num); fflush(stdout);
- if (transaction && (ecode = tdb_transaction_start(tdb)))
- errx(1, "starting transaction: %s", tdb_errorstr(ecode));
- gettimeofday(&start, NULL);
- for (j = 0; j < num; j++) {
- i = (j + 100003) % num;
- if ((ecode = tdb_store(tdb, key, data, TDB_INSERT)) != 0)
- errx(1, "Inserting key %u in tdb: %s",
- i, tdb_errorstr(ecode));
- }
- gettimeofday(&stop, NULL);
- if (transaction && (ecode = tdb_transaction_commit(tdb)))
- errx(1, "committing transaction: %s", tdb_errorstr(ecode));
- printf(" %zu ns (%zu bytes)\n",
- normalize(&start, &stop, num), file_size());
- if (tdb_check(tdb, NULL, NULL))
- errx(1, "tdb_check failed!");
- if (summary) {
- char *sumstr = NULL;
- tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
- printf("%s\n", sumstr);
- free(sumstr);
- }
- if (do_stats)
- dump_and_clear_stats(&tdb, flags, &log);
- if (++stage == stopat)
- exit(0);
-
- /* Append 1000 records. */
- if (transaction && (ecode = tdb_transaction_start(tdb)))
- errx(1, "starting transaction: %s", tdb_errorstr(ecode));
- printf("Appending %u records: ", num); fflush(stdout);
- gettimeofday(&start, NULL);
- for (i = 0; i < num; i++)
- if ((ecode = tdb_append(tdb, key, data)) != TDB_SUCCESS)
- errx(1, "Appending key %u in tdb: %s",
- i, tdb_errorstr(ecode));
- gettimeofday(&stop, NULL);
- if (transaction && (ecode = tdb_transaction_commit(tdb)))
- errx(1, "committing transaction: %s", tdb_errorstr(ecode));
- printf(" %zu ns (%zu bytes)\n",
- normalize(&start, &stop, num), file_size());
- if (tdb_check(tdb, NULL, NULL))
- errx(1, "tdb_check failed!");
- if (summary) {
- char *sumstr = NULL;
- tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
- printf("%s\n", sumstr);
- free(sumstr);
- }
- if (++stage == stopat)
- exit(0);
-
- /* Churn 1000 records: not in order! */
- if (transaction && (ecode = tdb_transaction_start(tdb)))
- errx(1, "starting transaction: %s", tdb_errorstr(ecode));
- printf("Churning %u records: ", num); fflush(stdout);
- gettimeofday(&start, NULL);
- for (j = 0; j < num; j++) {
- i = (j + 1000019) % num;
- if ((ecode = tdb_delete(tdb, key)) != TDB_SUCCESS)
- errx(1, "Deleting key %u in tdb: %s",
- i, tdb_errorstr(ecode));
- i += num;
- if ((ecode = tdb_store(tdb, key, data, TDB_INSERT)) != 0)
- errx(1, "Inserting key %u in tdb: %s",
- i, tdb_errorstr(ecode));
- }
- gettimeofday(&stop, NULL);
- if (transaction && (ecode = tdb_transaction_commit(tdb)))
- errx(1, "committing transaction: %s", tdb_errorstr(ecode));
- printf(" %zu ns (%zu bytes)\n",
- normalize(&start, &stop, num), file_size());
-
- if (tdb_check(tdb, NULL, NULL))
- errx(1, "tdb_check failed!");
- if (summary) {
- char *sumstr = NULL;
- tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
- printf("%s\n", sumstr);
- free(sumstr);
- }
- if (do_stats)
- dump_and_clear_stats(&tdb, flags, &log);
- if (++stage == stopat)
- exit(0);
-
- return 0;
-}
diff --git a/lib/tdb2/tools/tdb2backup.c b/lib/tdb2/tools/tdb2backup.c
deleted file mode 100644
index 37b301c548..0000000000
--- a/lib/tdb2/tools/tdb2backup.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- low level tdb backup and restore utility
- Copyright (C) Andrew Tridgell 2002
-
- 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/>.
-*/
-
-/*
-
- This program is meant for backup/restore of tdb databases. Typical usage would be:
- tdbbackup *.tdb
- when Samba shuts down cleanly, which will make a backup of all the local databases
- to *.bak files. Then on Samba startup you would use:
- tdbbackup -v *.tdb
- and this will check the databases for corruption and if corruption is detected then
- the backup will be restored.
-
- You may also like to do a backup on a regular basis while Samba is
- running, perhaps using cron.
-
- The reason this program is needed is to cope with power failures
- while Samba is running. A power failure could lead to database
- corruption and Samba will then not start correctly.
-
- Note that many of the databases in Samba are transient and thus
- don't need to be backed up, so you can optimise the above a little
- by only running the backup on the critical databases.
-
- */
-
-#include "config.h"
-#include "tdb2.h"
-#include "system/filesys.h"
-
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-
-static int failed;
-
-static void tdb_log(struct tdb_context *tdb,
- enum tdb_log_level level,
- enum TDB_ERROR ecode,
- const char *message,
- void *data)
-{
- fprintf(stderr, "%s:%s\n", tdb_errorstr(ecode), message);
-}
-
-static char *add_suffix(const char *name, const char *suffix)
-{
- char *ret;
- int len = strlen(name) + strlen(suffix) + 1;
- ret = (char *)malloc(len);
- if (!ret) {
- fprintf(stderr,"Out of memory!\n");
- exit(1);
- }
- snprintf(ret, len, "%s%s", name, suffix);
- return ret;
-}
-
-static int copy_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
- struct tdb_context *tdb_new = (struct tdb_context *)state;
- enum TDB_ERROR err;
-
- err = tdb_store(tdb_new, key, dbuf, TDB_INSERT);
- if (err) {
- fprintf(stderr,"Failed to insert into %s: %s\n",
- tdb_name(tdb_new), tdb_errorstr(err));
- failed = 1;
- return 1;
- }
- return 0;
-}
-
-
-static int test_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
- return 0;
-}
-
-/*
- carefully backup a tdb, validating the contents and
- only doing the backup if its OK
- this function is also used for restore
-*/
-static int backup_tdb(const char *old_name, const char *new_name)
-{
- struct tdb_context *tdb;
- struct tdb_context *tdb_new;
- char *tmp_name;
- struct stat st;
- int count1, count2;
- enum TDB_ERROR err;
- union tdb_attribute log_attr;
-
- tmp_name = add_suffix(new_name, ".tmp");
-
- /* stat the old tdb to find its permissions */
- if (stat(old_name, &st) != 0) {
- perror(old_name);
- free(tmp_name);
- return 1;
- }
-
- log_attr.base.attr = TDB_ATTRIBUTE_LOG;
- log_attr.base.next = NULL;
- log_attr.log.fn = tdb_log;
-
- /* open the old tdb */
- tdb = tdb_open(old_name, TDB_DEFAULT, O_RDWR, 0, &log_attr);
- if (!tdb) {
- printf("Failed to open %s\n", old_name);
- free(tmp_name);
- return 1;
- }
-
- unlink(tmp_name);
- tdb_new = tdb_open(tmp_name, TDB_DEFAULT,
- O_RDWR|O_CREAT|O_EXCL, st.st_mode & 0777,
- &log_attr);
- if (!tdb_new) {
- perror(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- err = tdb_transaction_start(tdb);
- if (err) {
- fprintf(stderr, "Failed to start transaction on old tdb: %s\n",
- tdb_errorstr(err));
- tdb_close(tdb);
- tdb_close(tdb_new);
- unlink(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* lock the backup tdb so that nobody else can change it */
- err = tdb_lockall(tdb_new);
- if (err) {
- fprintf(stderr, "Failed to lock backup tdb: %s\n",
- tdb_errorstr(err));
- tdb_close(tdb);
- tdb_close(tdb_new);
- unlink(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- failed = 0;
-
- /* traverse and copy */
- count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new);
- if (count1 < 0 || failed) {
- fprintf(stderr,"failed to copy %s\n", old_name);
- tdb_close(tdb);
- tdb_close(tdb_new);
- unlink(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* close the old tdb */
- tdb_close(tdb);
-
- /* copy done, unlock the backup tdb */
- tdb_unlockall(tdb_new);
-
-#ifdef HAVE_FDATASYNC
- if (fdatasync(tdb_fd(tdb_new)) != 0) {
-#else
- if (fsync(tdb_fd(tdb_new)) != 0) {
-#endif
- /* not fatal */
- fprintf(stderr, "failed to fsync backup file\n");
- }
-
- /* close the new tdb and re-open read-only */
- tdb_close(tdb_new);
-
- /* we don't need the hash attr any more */
- log_attr.base.next = NULL;
-
- tdb_new = tdb_open(tmp_name, TDB_DEFAULT, O_RDONLY, 0, &log_attr);
- if (!tdb_new) {
- fprintf(stderr,"failed to reopen %s\n", tmp_name);
- unlink(tmp_name);
- perror(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* traverse the new tdb to confirm */
- count2 = tdb_traverse(tdb_new, test_fn, NULL);
- if (count2 != count1) {
- fprintf(stderr,"failed to copy %s\n", old_name);
- tdb_close(tdb_new);
- unlink(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* close the new tdb and rename it to .bak */
- tdb_close(tdb_new);
- if (rename(tmp_name, new_name) != 0) {
- perror(new_name);
- free(tmp_name);
- return 1;
- }
-
- free(tmp_name);
-
- return 0;
-}
-
-/*
- verify a tdb and if it is corrupt then restore from *.bak
-*/
-static int verify_tdb(const char *fname, const char *bak_name)
-{
- struct tdb_context *tdb;
- int count = -1;
- union tdb_attribute log_attr;
-
- log_attr.base.attr = TDB_ATTRIBUTE_LOG;
- log_attr.base.next = NULL;
- log_attr.log.fn = tdb_log;
-
- /* open the tdb */
- tdb = tdb_open(fname, TDB_DEFAULT, O_RDONLY, 0, &log_attr);
-
- /* traverse the tdb, then close it */
- if (tdb) {
- count = tdb_traverse(tdb, test_fn, NULL);
- tdb_close(tdb);
- }
-
- /* count is < 0 means an error */
- if (count < 0) {
- printf("restoring %s\n", fname);
- return backup_tdb(bak_name, fname);
- }
-
- printf("%s : %d records\n", fname, count);
-
- return 0;
-}
-
-/*
- see if one file is newer than another
-*/
-static int file_newer(const char *fname1, const char *fname2)
-{
- struct stat st1, st2;
- if (stat(fname1, &st1) != 0) {
- return 0;
- }
- if (stat(fname2, &st2) != 0) {
- return 1;
- }
- return (st1.st_mtime > st2.st_mtime);
-}
-
-static void usage(void)
-{
- printf("Usage: tdb2backup [options] <fname...>\n\n");
- printf(" -h this help message\n");
- printf(" -v verify mode (restore if corrupt)\n");
- printf(" -s suffix set the backup suffix\n");
- printf(" -v verify mode (restore if corrupt)\n");
-}
-
-
- int main(int argc, char *argv[])
-{
- int i;
- int ret = 0;
- int c;
- int verify = 0;
- const char *suffix = ".bak";
-
- while ((c = getopt(argc, argv, "vhs:")) != -1) {
- switch (c) {
- case 'h':
- usage();
- exit(0);
- case 'v':
- verify = 1;
- break;
- case 's':
- suffix = optarg;
- break;
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc < 1) {
- usage();
- exit(1);
- }
-
- for (i=0; i<argc; i++) {
- const char *fname = argv[i];
- char *bak_name;
-
- bak_name = add_suffix(fname, suffix);
-
- if (verify) {
- if (verify_tdb(fname, bak_name) != 0) {
- ret = 1;
- }
- } else {
- if (file_newer(fname, bak_name) &&
- backup_tdb(fname, bak_name) != 0) {
- ret = 1;
- }
- }
-
- free(bak_name);
- }
-
- return ret;
-}
diff --git a/lib/tdb2/tools/tdb2dump.c b/lib/tdb2/tools/tdb2dump.c
deleted file mode 100644
index 40230a2643..0000000000
--- a/lib/tdb2/tools/tdb2dump.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- simple tdb2 dump util
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Rusty Russell 2011
-
- 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 "config.h"
-#include "tdb2.h"
-#ifdef HAVE_LIBREPLACE
-#include <replace.h>
-#include <system/filesys.h>
-#include <system/locale.h>
-#else
-#include <ctype.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#endif
-
-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(struct 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)
-{
- struct tdb_context *tdb;
- TDB_DATA key, value;
-
- tdb = tdb_open(fname, 0, O_RDONLY, 0, NULL);
- if (!tdb) {
- printf("Failed to open %s\n", fname);
- return 1;
- }
-
- if (!keyname) {
- tdb_traverse(tdb, traverse_fn, NULL);
- } else {
- key = tdb_mkdata(keyname, strlen(keyname));
- if (tdb_fetch(tdb, key, &value) != 0) {
- return 1;
- } else {
- print_data(value);
- free(value.dptr);
- }
- }
-
- return 0;
-}
-
-static void usage( void)
-{
- printf( "Usage: tdb2dump [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: tdb2dump <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);
-}
diff --git a/lib/tdb2/tools/tdb2restore.c b/lib/tdb2/tools/tdb2restore.c
deleted file mode 100644
index 93c6c8bfe5..0000000000
--- a/lib/tdb2/tools/tdb2restore.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- tdb2restore -- construct a tdb from tdbdump output.
- Copyright (C) Volker Lendecke 2010
- Copyright (C) Simon McVittie 2005
-
- 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 "config.h"
-#include "tdb2.h"
-#include <assert.h>
-#ifdef HAVE_LIBREPLACE
-#include <replace.h>
-#include <system/filesys.h>
-#else
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#endif
-
-static int read_linehead(FILE *f)
-{
- int i, c;
- int num_bytes;
- char prefix[128];
-
- while (1) {
- c = getc(f);
- if (c == EOF) {
- return -1;
- }
- if (c == '(') {
- break;
- }
- }
- for (i=0; i<sizeof(prefix); i++) {
- c = getc(f);
- if (c == EOF) {
- return -1;
- }
- prefix[i] = c;
- if (c == '"') {
- break;
- }
- }
- if (i == sizeof(prefix)) {
- return -1;
- }
- prefix[i] = '\0';
-
- if (sscanf(prefix, "%d) = ", &num_bytes) != 1) {
- return -1;
- }
- return num_bytes;
-}
-
-static int read_hex(void) {
- int c;
- c = getchar();
- if (c == EOF) {
- fprintf(stderr, "Unexpected EOF in data\n");
- return -1;
- } else if (c == '"') {
- fprintf(stderr, "Unexpected \\\" sequence\n");
- return -1;
- } else if ('0' <= c && c <= '9') {
- return c - '0';
- } else if ('A' <= c && c <= 'F') {
- return c - 'A' + 10;
- } else if ('a' <= c && c <= 'f') {
- return c - 'a' + 10;
- } else {
- fprintf(stderr, "Invalid hex: %c\n", c);
- return -1;
- }
-}
-
-static int read_data(FILE *f, struct tdb_data *d, size_t size) {
- int c, low, high;
- int i;
-
- d->dptr = (unsigned char *)malloc(size);
- if (d->dptr == NULL) {
- return -1;
- }
- d->dsize = size;
-
- for (i=0; i<size; i++) {
- c = getc(f);
- if (c == EOF) {
- fprintf(stderr, "Unexpected EOF in data\n");
- return 1;
- } else if (c == '"') {
- return 0;
- } else if (c == '\\') {
- high = read_hex();
- if (high < 0) {
- return -1;
- }
- high = high << 4;
- assert(high == (high & 0xf0));
- low = read_hex();
- if (low < 0) {
- return -1;
- }
- assert(low == (low & 0x0f));
- d->dptr[i] = (low|high);
- } else {
- d->dptr[i] = c;
- }
- }
- return 0;
-}
-
-static int swallow(FILE *f, const char *s, int *eof)
-{
- char line[128];
-
- if (fgets(line, sizeof(line), f) == NULL) {
- if (eof != NULL) {
- *eof = 1;
- }
- return -1;
- }
- if (strcmp(line, s) != 0) {
- return -1;
- }
- return 0;
-}
-
-static bool read_rec(FILE *f, struct tdb_context *tdb, int *eof)
-{
- int length;
- struct tdb_data key, data;
- bool ret = false;
- enum TDB_ERROR e;
-
- key.dptr = NULL;
- data.dptr = NULL;
-
- if (swallow(f, "{\n", eof) == -1) {
- goto fail;
- }
- length = read_linehead(f);
- if (length == -1) {
- goto fail;
- }
- if (read_data(f, &key, length) == -1) {
- goto fail;
- }
- if (swallow(f, "\"\n", NULL) == -1) {
- goto fail;
- }
- length = read_linehead(f);
- if (length == -1) {
- goto fail;
- }
- if (read_data(f, &data, length) == -1) {
- goto fail;
- }
- if ((swallow(f, "\"\n", NULL) == -1)
- || (swallow(f, "}\n", NULL) == -1)) {
- goto fail;
- }
- e = tdb_store(tdb, key, data, TDB_INSERT);
- if (e != TDB_SUCCESS) {
- fprintf(stderr, "TDB error: %s\n", tdb_errorstr(e));
- goto fail;
- }
-
- ret = true;
-fail:
- free(key.dptr);
- free(data.dptr);
- return ret;
-}
-
-static int restore_tdb(const char *fname)
-{
- struct tdb_context *tdb;
-
- tdb = tdb_open(fname, 0, O_RDWR|O_CREAT|O_EXCL, 0666, NULL);
- if (!tdb) {
- perror("tdb_open");
- fprintf(stderr, "Failed to open %s\n", fname);
- return 1;
- }
-
- while (1) {
- int eof = 0;
- if (!read_rec(stdin, tdb, &eof)) {
- if (eof) {
- break;
- }
- return 1;
- }
- }
- if (tdb_close(tdb)) {
- fprintf(stderr, "Error closing tdb\n");
- return 1;
- }
- fprintf(stderr, "EOF\n");
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- char *fname;
-
- if (argc < 2) {
- printf("Usage: %s dbname < tdbdump_output\n", argv[0]);
- exit(1);
- }
-
- fname = argv[1];
-
- return restore_tdb(fname);
-}
diff --git a/lib/tdb2/tools/tdb2tool.c b/lib/tdb2/tools/tdb2tool.c
deleted file mode 100644
index ae20971143..0000000000
--- a/lib/tdb2/tools/tdb2tool.c
+++ /dev/null
@@ -1,810 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba database functions
- Copyright (C) Andrew Tridgell 1999-2000
- Copyright (C) Paul `Rusty' Russell 2000
- Copyright (C) Jeremy Allison 2000
- Copyright (C) Andrew Esh 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 "config.h"
-#include "tdb2.h"
-#ifdef HAVE_LIBREPLACE
-#include <replace.h>
-#include <system/filesys.h>
-#include <system/time.h>
-#include <system/locale.h>
-#else
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdarg.h>
-#endif
-
-static int do_command(void);
-const char *cmdname;
-char *arg1, *arg2;
-size_t arg1len, arg2len;
-int bIterate = 0;
-char *line;
-TDB_DATA iterate_kbuf;
-char cmdline[1024];
-static int disable_mmap;
-
-enum commands {
- CMD_CREATE_TDB,
- CMD_OPEN_TDB,
- CMD_TRANSACTION_START,
- CMD_TRANSACTION_COMMIT,
- CMD_TRANSACTION_CANCEL,
- CMD_ERASE,
- CMD_DUMP,
- CMD_INSERT,
- CMD_MOVE,
- CMD_STORE,
- CMD_SHOW,
- CMD_KEYS,
- CMD_HEXKEYS,
- CMD_DELETE,
-#if 0
- CMD_LIST_HASH_FREE,
- CMD_LIST_FREE,
-#endif
- CMD_INFO,
- CMD_MMAP,
- CMD_SPEED,
- CMD_FIRST,
- CMD_NEXT,
- CMD_SYSTEM,
- CMD_CHECK,
- CMD_QUIT,
- CMD_HELP
-};
-
-typedef struct {
- const char *name;
- enum commands cmd;
-} COMMAND_TABLE;
-
-COMMAND_TABLE cmd_table[] = {
- {"create", CMD_CREATE_TDB},
- {"open", CMD_OPEN_TDB},
-#if 0
- {"transaction_start", CMD_TRANSACTION_START},
- {"transaction_commit", CMD_TRANSACTION_COMMIT},
- {"transaction_cancel", CMD_TRANSACTION_CANCEL},
-#endif
- {"erase", CMD_ERASE},
- {"dump", CMD_DUMP},
- {"insert", CMD_INSERT},
- {"move", CMD_MOVE},
- {"store", CMD_STORE},
- {"show", CMD_SHOW},
- {"keys", CMD_KEYS},
- {"hexkeys", CMD_HEXKEYS},
- {"delete", CMD_DELETE},
-#if 0
- {"list", CMD_LIST_HASH_FREE},
- {"free", CMD_LIST_FREE},
-#endif
- {"info", CMD_INFO},
- {"speed", CMD_SPEED},
- {"mmap", CMD_MMAP},
- {"first", CMD_FIRST},
- {"1", CMD_FIRST},
- {"next", CMD_NEXT},
- {"n", CMD_NEXT},
- {"check", CMD_CHECK},
- {"quit", CMD_QUIT},
- {"q", CMD_QUIT},
- {"!", CMD_SYSTEM},
- {NULL, CMD_HELP}
-};
-
-struct timeval tp1,tp2;
-
-static void _start_timer(void)
-{
- gettimeofday(&tp1,NULL);
-}
-
-static double _end_timer(void)
-{
- gettimeofday(&tp2,NULL);
- return((tp2.tv_sec - tp1.tv_sec) +
- (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
-}
-
-static void tdb_log(struct tdb_context *tdb,
- enum tdb_log_level level,
- enum TDB_ERROR ecode,
- const char *message,
- void *data)
-{
- fprintf(stderr, "tdb:%s:%s:%s\n",
- tdb_name(tdb), tdb_errorstr(ecode), message);
-}
-
-/* a tdb tool for manipulating a tdb database */
-
-static struct tdb_context *tdb;
-
-static int print_rec(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
-static int print_key(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
-static int print_hexkey(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
-
-static void print_asc(const char *buf,int len)
-{
- int i;
-
- /* We're probably printing ASCII strings so don't try to display
- the trailing NULL character. */
-
- if (buf[len - 1] == 0)
- len--;
-
- for (i=0;i<len;i++)
- printf("%c",isprint(buf[i])?buf[i]:'.');
-}
-
-static void print_data(const char *buf,int len)
-{
- int i=0;
- if (len<=0) return;
- printf("[%03X] ",i);
- for (i=0;i<len;) {
- printf("%02X ",(int)((unsigned char)buf[i]));
- i++;
- if (i%8 == 0) printf(" ");
- if (i%16 == 0) {
- print_asc(&buf[i-16],8); printf(" ");
- print_asc(&buf[i-8],8); printf("\n");
- if (i<len) printf("[%03X] ",i);
- }
- }
- if (i%16) {
- int n;
-
- n = 16 - (i%16);
- printf(" ");
- if (n>8) printf(" ");
- while (n--) printf(" ");
-
- n = i%16;
- if (n > 8) n = 8;
- print_asc(&buf[i-(i%16)],n); printf(" ");
- n = (i%16) - n;
- if (n>0) print_asc(&buf[i-n],n);
- printf("\n");
- }
-}
-
-static void help(void)
-{
- printf("\n"
-"tdbtool: \n"
-" create dbname : create a database\n"
-" open dbname : open an existing database\n"
-" openjh dbname : open an existing database (jenkins hash)\n"
-" transaction_start : start a transaction\n"
-" transaction_commit : commit a transaction\n"
-" transaction_cancel : cancel a transaction\n"
-" erase : erase the database\n"
-" dump : dump the database as strings\n"
-" keys : dump the database keys as strings\n"
-" hexkeys : dump the database keys as hex values\n"
-" info : print summary info about the database\n"
-" insert key data : insert a record\n"
-" move key file : move a record to a destination tdb\n"
-" store key data : store a record (replace)\n"
-" show key : show a record by key\n"
-" delete key : delete a record by key\n"
-#if 0
-" list : print the database hash table and freelist\n"
-" free : print the database freelist\n"
-#endif
-" check : check the integrity of an opened database\n"
-" speed : perform speed tests on the database\n"
-" ! command : execute system command\n"
-" 1 | first : print the first record\n"
-" n | next : print the next record\n"
-" q | quit : terminate\n"
-" \\n : repeat 'next' command\n"
-"\n");
-}
-
-static void terror(enum TDB_ERROR err, const char *why)
-{
- if (err != TDB_SUCCESS)
- printf("%s:%s\n", tdb_errorstr(err), why);
- else
- printf("%s\n", why);
-}
-
-static void create_tdb(const char *tdbname)
-{
- union tdb_attribute log_attr;
- log_attr.base.attr = TDB_ATTRIBUTE_LOG;
- log_attr.base.next = NULL;
- log_attr.log.fn = tdb_log;
-
- if (tdb) tdb_close(tdb);
- tdb = tdb_open(tdbname, (disable_mmap?TDB_NOMMAP:0),
- O_RDWR | O_CREAT | O_TRUNC, 0600, &log_attr);
- if (!tdb) {
- printf("Could not create %s: %s\n", tdbname, strerror(errno));
- }
-}
-
-static void open_tdb(const char *tdbname)
-{
- union tdb_attribute log_attr;
- log_attr.base.attr = TDB_ATTRIBUTE_LOG;
- log_attr.base.next = NULL;
- log_attr.log.fn = tdb_log;
-
- if (tdb) tdb_close(tdb);
- tdb = tdb_open(tdbname, disable_mmap?TDB_NOMMAP:0, O_RDWR, 0600,
- &log_attr);
- if (!tdb) {
- printf("Could not open %s: %s\n", tdbname, strerror(errno));
- }
-}
-
-static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen)
-{
- TDB_DATA key, dbuf;
- enum TDB_ERROR ecode;
-
- if ((keyname == NULL) || (keylen == 0)) {
- terror(TDB_SUCCESS, "need key");
- return;
- }
-
- key.dptr = (unsigned char *)keyname;
- key.dsize = keylen;
- dbuf.dptr = (unsigned char *)data;
- dbuf.dsize = datalen;
-
- ecode = tdb_store(tdb, key, dbuf, TDB_INSERT);
- if (ecode) {
- terror(ecode, "insert failed");
- }
-}
-
-static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen)
-{
- TDB_DATA key, dbuf;
- enum TDB_ERROR ecode;
-
- if ((keyname == NULL) || (keylen == 0)) {
- terror(TDB_SUCCESS, "need key");
- return;
- }
-
- if ((data == NULL) || (datalen == 0)) {
- terror(TDB_SUCCESS, "need data");
- return;
- }
-
- key.dptr = (unsigned char *)keyname;
- key.dsize = keylen;
- dbuf.dptr = (unsigned char *)data;
- dbuf.dsize = datalen;
-
- printf("Storing key:\n");
- print_rec(tdb, key, dbuf, NULL);
-
- ecode = tdb_store(tdb, key, dbuf, TDB_REPLACE);
- if (ecode) {
- terror(ecode, "store failed");
- }
-}
-
-static void show_tdb(char *keyname, size_t keylen)
-{
- TDB_DATA key, dbuf;
- enum TDB_ERROR ecode;
-
- if ((keyname == NULL) || (keylen == 0)) {
- terror(TDB_SUCCESS, "need key");
- return;
- }
-
- key.dptr = (unsigned char *)keyname;
- key.dsize = keylen;
-
- ecode = tdb_fetch(tdb, key, &dbuf);
- if (ecode) {
- terror(ecode, "fetch failed");
- return;
- }
-
- print_rec(tdb, key, dbuf, NULL);
-
- free( dbuf.dptr );
-}
-
-static void delete_tdb(char *keyname, size_t keylen)
-{
- TDB_DATA key;
- enum TDB_ERROR ecode;
-
- if ((keyname == NULL) || (keylen == 0)) {
- terror(TDB_SUCCESS, "need key");
- return;
- }
-
- key.dptr = (unsigned char *)keyname;
- key.dsize = keylen;
-
- ecode = tdb_delete(tdb, key);
- if (ecode) {
- terror(ecode, "delete failed");
- }
-}
-
-static void move_rec(char *keyname, size_t keylen, char* tdbname)
-{
- TDB_DATA key, dbuf;
- struct tdb_context *dst_tdb;
- enum TDB_ERROR ecode;
-
- if ((keyname == NULL) || (keylen == 0)) {
- terror(TDB_SUCCESS, "need key");
- return;
- }
-
- if ( !tdbname ) {
- terror(TDB_SUCCESS, "need destination tdb name");
- return;
- }
-
- key.dptr = (unsigned char *)keyname;
- key.dsize = keylen;
-
- ecode = tdb_fetch(tdb, key, &dbuf);
- if (ecode) {
- terror(ecode, "fetch failed");
- return;
- }
-
- print_rec(tdb, key, dbuf, NULL);
-
- dst_tdb = tdb_open(tdbname, 0, O_RDWR, 0600, NULL);
- if ( !dst_tdb ) {
- terror(TDB_SUCCESS, "unable to open destination tdb");
- return;
- }
-
- ecode = tdb_store( dst_tdb, key, dbuf, TDB_REPLACE);
- if (ecode)
- terror(ecode, "failed to move record");
- else
- printf("record moved\n");
-
- tdb_close( dst_tdb );
-}
-
-static int print_rec(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
- printf("\nkey %d bytes\n", (int)key.dsize);
- print_asc((const char *)key.dptr, key.dsize);
- printf("\ndata %d bytes\n", (int)dbuf.dsize);
- print_data((const char *)dbuf.dptr, dbuf.dsize);
- return 0;
-}
-
-static int print_key(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
- printf("key %d bytes: ", (int)key.dsize);
- print_asc((const char *)key.dptr, key.dsize);
- printf("\n");
- return 0;
-}
-
-static int print_hexkey(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
- printf("key %d bytes\n", (int)key.dsize);
- print_data((const char *)key.dptr, key.dsize);
- printf("\n");
- return 0;
-}
-
-static int total_bytes;
-
-static int traverse_fn(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
- total_bytes += dbuf.dsize;
- return 0;
-}
-
-static void info_tdb(void)
-{
- enum TDB_ERROR ecode;
- char *summary;
-
- ecode = tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &summary);
-
- if (ecode) {
- terror(ecode, "Getting summary");
- } else {
- printf("%s", summary);
- free(summary);
- }
-}
-
-static void speed_tdb(const char *tlimit)
-{
- unsigned timelimit = tlimit?atoi(tlimit):0;
- double t;
- int ops;
- if (timelimit == 0) timelimit = 5;
-
- ops = 0;
- printf("Testing store speed for %u seconds\n", timelimit);
- _start_timer();
- do {
- long int r = random();
- TDB_DATA key, dbuf;
- key = tdb_mkdata("store test", strlen("store test"));
- dbuf.dptr = (unsigned char *)&r;
- dbuf.dsize = sizeof(r);
- tdb_store(tdb, key, dbuf, TDB_REPLACE);
- t = _end_timer();
- ops++;
- } while (t < timelimit);
- printf("%10.3f ops/sec\n", ops/t);
-
- ops = 0;
- printf("Testing fetch speed for %u seconds\n", timelimit);
- _start_timer();
- do {
- long int r = random();
- TDB_DATA key, dbuf;
- key = tdb_mkdata("store test", strlen("store test"));
- dbuf.dptr = (unsigned char *)&r;
- dbuf.dsize = sizeof(r);
- tdb_fetch(tdb, key, &dbuf);
- t = _end_timer();
- ops++;
- } while (t < timelimit);
- printf("%10.3f ops/sec\n", ops/t);
-
- ops = 0;
- printf("Testing transaction speed for %u seconds\n", timelimit);
- _start_timer();
- do {
- long int r = random();
- TDB_DATA key, dbuf;
- key = tdb_mkdata("transaction test", strlen("transaction test"));
- dbuf.dptr = (unsigned char *)&r;
- dbuf.dsize = sizeof(r);
- tdb_transaction_start(tdb);
- tdb_store(tdb, key, dbuf, TDB_REPLACE);
- tdb_transaction_commit(tdb);
- t = _end_timer();
- ops++;
- } while (t < timelimit);
- printf("%10.3f ops/sec\n", ops/t);
-
- ops = 0;
- printf("Testing traverse speed for %u seconds\n", timelimit);
- _start_timer();
- do {
- tdb_traverse(tdb, traverse_fn, NULL);
- t = _end_timer();
- ops++;
- } while (t < timelimit);
- printf("%10.3f ops/sec\n", ops/t);
-}
-
-static void toggle_mmap(void)
-{
- disable_mmap = !disable_mmap;
- if (disable_mmap) {
- printf("mmap is disabled\n");
- } else {
- printf("mmap is enabled\n");
- }
-}
-
-static char *tdb_getline(const char *prompt)
-{
- static char thisline[1024];
- char *p;
- fputs(prompt, stdout);
- thisline[0] = 0;
- p = fgets(thisline, sizeof(thisline)-1, stdin);
- if (p) p = strchr(p, '\n');
- if (p) *p = 0;
- return p?thisline:NULL;
-}
-
-static int do_delete_fn(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf,
- void *state)
-{
- return tdb_delete(the_tdb, key);
-}
-
-static void first_record(struct tdb_context *the_tdb, TDB_DATA *pkey)
-{
- TDB_DATA dbuf;
- enum TDB_ERROR ecode;
- ecode = tdb_firstkey(the_tdb, pkey);
- if (!ecode)
- ecode = tdb_fetch(the_tdb, *pkey, &dbuf);
- if (ecode) terror(ecode, "fetch failed");
- else {
- print_rec(the_tdb, *pkey, dbuf, NULL);
- }
-}
-
-static void next_record(struct tdb_context *the_tdb, TDB_DATA *pkey)
-{
- TDB_DATA dbuf;
- enum TDB_ERROR ecode;
- ecode = tdb_nextkey(the_tdb, pkey);
-
- if (!ecode)
- ecode = tdb_fetch(the_tdb, *pkey, &dbuf);
- if (ecode)
- terror(ecode, "fetch failed");
- else
- print_rec(the_tdb, *pkey, dbuf, NULL);
-}
-
-static void check_db(struct tdb_context *the_tdb)
-{
- if (!the_tdb) {
- printf("Error: No database opened!\n");
- } else {
- if (tdb_check(the_tdb, NULL, NULL) != 0)
- printf("Integrity check for the opened database failed.\n");
- else
- printf("Database integrity is OK.\n");
- }
-}
-
-static int do_command(void)
-{
- COMMAND_TABLE *ctp = cmd_table;
- enum commands mycmd = CMD_HELP;
- int cmd_len;
-
- if (cmdname && strlen(cmdname) == 0) {
- mycmd = CMD_NEXT;
- } else {
- while (ctp->name) {
- cmd_len = strlen(ctp->name);
- if (strncmp(ctp->name,cmdname,cmd_len) == 0) {
- mycmd = ctp->cmd;
- break;
- }
- ctp++;
- }
- }
-
- switch (mycmd) {
- case CMD_CREATE_TDB:
- bIterate = 0;
- create_tdb(arg1);
- return 0;
- case CMD_OPEN_TDB:
- bIterate = 0;
- open_tdb(arg1);
- return 0;
- case CMD_SYSTEM:
- /* Shell command */
- if (system(arg1) == -1) {
- terror(TDB_SUCCESS, "system() call failed\n");
- }
- return 0;
- case CMD_QUIT:
- return 1;
- default:
- /* all the rest require a open database */
- if (!tdb) {
- bIterate = 0;
- terror(TDB_SUCCESS, "database not open");
- help();
- return 0;
- }
- switch (mycmd) {
- case CMD_TRANSACTION_START:
- bIterate = 0;
- tdb_transaction_start(tdb);
- return 0;
- case CMD_TRANSACTION_COMMIT:
- bIterate = 0;
- tdb_transaction_commit(tdb);
- return 0;
- case CMD_TRANSACTION_CANCEL:
- bIterate = 0;
- tdb_transaction_cancel(tdb);
- return 0;
- case CMD_ERASE:
- bIterate = 0;
- tdb_traverse(tdb, do_delete_fn, NULL);
- return 0;
- case CMD_DUMP:
- bIterate = 0;
- tdb_traverse(tdb, print_rec, NULL);
- return 0;
- case CMD_INSERT:
- bIterate = 0;
- insert_tdb(arg1, arg1len,arg2,arg2len);
- return 0;
- case CMD_MOVE:
- bIterate = 0;
- move_rec(arg1,arg1len,arg2);
- return 0;
- case CMD_STORE:
- bIterate = 0;
- store_tdb(arg1,arg1len,arg2,arg2len);
- return 0;
- case CMD_SHOW:
- bIterate = 0;
- show_tdb(arg1, arg1len);
- return 0;
- case CMD_KEYS:
- tdb_traverse(tdb, print_key, NULL);
- return 0;
- case CMD_HEXKEYS:
- tdb_traverse(tdb, print_hexkey, NULL);
- return 0;
- case CMD_DELETE:
- bIterate = 0;
- delete_tdb(arg1,arg1len);
- return 0;
-#if 0
- case CMD_LIST_HASH_FREE:
- tdb_dump_all(tdb);
- return 0;
- case CMD_LIST_FREE:
- tdb_printfreelist(tdb);
- return 0;
-#endif
- case CMD_INFO:
- info_tdb();
- return 0;
- case CMD_SPEED:
- speed_tdb(arg1);
- return 0;
- case CMD_MMAP:
- toggle_mmap();
- return 0;
- case CMD_FIRST:
- bIterate = 1;
- first_record(tdb, &iterate_kbuf);
- return 0;
- case CMD_NEXT:
- if (bIterate)
- next_record(tdb, &iterate_kbuf);
- return 0;
- case CMD_CHECK:
- check_db(tdb);
- return 0;
- case CMD_HELP:
- help();
- return 0;
- case CMD_CREATE_TDB:
- case CMD_OPEN_TDB:
- case CMD_SYSTEM:
- case CMD_QUIT:
- /*
- * unhandled commands. cases included here to avoid compiler
- * warnings.
- */
- return 0;
- }
- }
-
- return 0;
-}
-
-static char *convert_string(char *instring, size_t *sizep)
-{
- size_t length = 0;
- char *outp, *inp;
- char temp[3];
-
- outp = inp = instring;
-
- while (*inp) {
- if (*inp == '\\') {
- inp++;
- if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) {
- temp[0] = *inp++;
- temp[1] = '\0';
- if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) {
- temp[1] = *inp++;
- temp[2] = '\0';
- }
- *outp++ = (char)strtol((const char *)temp,NULL,16);
- } else {
- *outp++ = *inp++;
- }
- } else {
- *outp++ = *inp++;
- }
- length++;
- }
- *sizep = length;
- return instring;
-}
-
-int main(int argc, char *argv[])
-{
- cmdname = "";
- arg1 = NULL;
- arg1len = 0;
- arg2 = NULL;
- arg2len = 0;
-
- if (argv[1]) {
- cmdname = "open";
- arg1 = argv[1];
- do_command();
- cmdname = "";
- arg1 = NULL;
- }
-
- switch (argc) {
- case 1:
- case 2:
- /* Interactive mode */
- while ((cmdname = tdb_getline("tdb> "))) {
- arg2 = arg1 = NULL;
- if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) {
- arg1++;
- arg2 = arg1;
- while (*arg2) {
- if (*arg2 == ' ') {
- *arg2++ = '\0';
- break;
- }
- if ((*arg2++ == '\\') && (*arg2 == ' ')) {
- arg2++;
- }
- }
- }
- if (arg1) arg1 = convert_string(arg1,&arg1len);
- if (arg2) arg2 = convert_string(arg2,&arg2len);
- if (do_command()) break;
- }
- break;
- case 5:
- arg2 = convert_string(argv[4],&arg2len);
- case 4:
- arg1 = convert_string(argv[3],&arg1len);
- case 3:
- cmdname = argv[2];
- default:
- do_command();
- break;
- }
-
- if (tdb) tdb_close(tdb);
-
- return 0;
-}
diff --git a/lib/tdb2/tools/tdb2torture.c b/lib/tdb2/tools/tdb2torture.c
deleted file mode 100644
index 73e2e29874..0000000000
--- a/lib/tdb2/tools/tdb2torture.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/* this tests tdb by doing lots of ops from several simultaneous
- writers - that stresses the locking code.
-*/
-
-#include "config.h"
-#include "tdb2.h"
-#include <ccan/err/err.h>
-#ifdef HAVE_LIBREPLACE
-#include <replace.h>
-#else
-#include <stdlib.h>
-#include <getopt.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <time.h>
-#include <sys/wait.h>
-#endif
-
-//#define REOPEN_PROB 30
-#define DELETE_PROB 8
-#define STORE_PROB 4
-#define APPEND_PROB 6
-#define TRANSACTION_PROB 10
-#define TRANSACTION_PREPARE_PROB 2
-#define LOCKSTORE_PROB 5
-#define TRAVERSE_PROB 20
-#define TRAVERSE_MOD_PROB 100
-#define TRAVERSE_ABORT_PROB 500
-#define CULL_PROB 100
-#define KEYLEN 3
-#define DATALEN 100
-
-static struct tdb_context *db;
-static int in_transaction;
-static int in_traverse;
-static int error_count;
-#if TRANSACTION_PROB
-static int always_transaction = 0;
-#endif
-static int loopnum;
-static int count_pipe;
-static union tdb_attribute log_attr;
-static union tdb_attribute seed_attr;
-
-static void tdb_log(struct tdb_context *tdb,
- enum tdb_log_level level,
- enum TDB_ERROR ecode,
- const char *message,
- void *data)
-{
- printf("tdb:%s:%s:%s\n",
- tdb_name(tdb), tdb_errorstr(ecode), message);
- fflush(stdout);
-#if 0
- {
- char str[200];
- signal(SIGUSR1, SIG_IGN);
- sprintf(str,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid());
- system(str);
- }
-#endif
-}
-
-#include "../private.h"
-
-static void segv_handler(int sig, siginfo_t *info, void *p)
-{
- char string[100];
-
- sprintf(string, "%u: death at %p (map_ptr %p, map_size %zu)\n",
- getpid(), info->si_addr, db->file->map_ptr,
- (size_t)db->file->map_size);
- if (write(2, string, strlen(string)) > 0)
- sleep(60);
- _exit(11);
-}
-
-static void fatal(struct tdb_context *tdb, const char *why)
-{
- fprintf(stderr, "%u:%s:%s\n", getpid(), why,
- tdb ? tdb_errorstr(tdb_error(tdb)) : "(no tdb)");
- error_count++;
-}
-
-static char *randbuf(int len)
-{
- char *buf;
- int i;
- buf = (char *)malloc(len+1);
-
- for (i=0;i<len;i++) {
- buf[i] = 'a' + (rand() % 26);
- }
- buf[i] = 0;
- return buf;
-}
-
-static void addrec_db(void);
-static int modify_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
-
-#if TRAVERSE_MOD_PROB
- if (random() % TRAVERSE_MOD_PROB == 0) {
- addrec_db();
- }
-#endif
-
-#if TRAVERSE_ABORT_PROB
- if (random() % TRAVERSE_ABORT_PROB == 0)
- return 1;
-#endif
-
- return 0;
-}
-
-static void addrec_db(void)
-{
- int klen, dlen;
- char *k, *d;
- TDB_DATA key, data;
-
- klen = 1 + (rand() % KEYLEN);
- dlen = 1 + (rand() % DATALEN);
-
- k = randbuf(klen);
- d = randbuf(dlen);
-
- key.dptr = (unsigned char *)k;
- key.dsize = klen+1;
-
- data.dptr = (unsigned char *)d;
- data.dsize = dlen+1;
-
-#if REOPEN_PROB
- if (in_traverse == 0 && in_transaction == 0 && random() % REOPEN_PROB == 0) {
- tdb_reopen_all(0);
- goto next;
- }
-#endif
-
-#if TRANSACTION_PROB
- if (in_traverse == 0 && in_transaction == 0 && (always_transaction || random() % TRANSACTION_PROB == 0)) {
- if (tdb_transaction_start(db) != 0) {
- fatal(db, "tdb_transaction_start failed");
- }
- in_transaction++;
- goto next;
- }
- if (in_traverse == 0 && in_transaction && random() % TRANSACTION_PROB == 0) {
- if (random() % TRANSACTION_PREPARE_PROB == 0) {
- if (tdb_transaction_prepare_commit(db) != 0) {
- fatal(db, "tdb_transaction_prepare_commit failed");
- }
- }
- if (tdb_transaction_commit(db) != 0) {
- fatal(db, "tdb_transaction_commit failed");
- }
- in_transaction--;
- goto next;
- }
-
- if (in_traverse == 0 && in_transaction && random() % TRANSACTION_PROB == 0) {
- tdb_transaction_cancel(db);
- in_transaction--;
- goto next;
- }
-#endif
-
-#if DELETE_PROB
- if (random() % DELETE_PROB == 0) {
- tdb_delete(db, key);
- goto next;
- }
-#endif
-
-#if STORE_PROB
- if (random() % STORE_PROB == 0) {
- if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
- fatal(db, "tdb_store failed");
- }
- goto next;
- }
-#endif
-
-#if APPEND_PROB
- if (random() % APPEND_PROB == 0) {
- if (tdb_append(db, key, data) != 0) {
- fatal(db, "tdb_append failed");
- }
- goto next;
- }
-#endif
-
-#if LOCKSTORE_PROB
- if (random() % LOCKSTORE_PROB == 0) {
- tdb_chainlock(db, key);
- if (tdb_fetch(db, key, &data) != TDB_SUCCESS) {
- data.dsize = 0;
- data.dptr = NULL;
- }
- if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
- fatal(db, "tdb_store failed");
- }
- if (data.dptr) free(data.dptr);
- tdb_chainunlock(db, key);
- goto next;
- }
-#endif
-
-#if TRAVERSE_PROB
- /* FIXME: recursive traverses break transactions? */
- if (in_traverse == 0 && random() % TRAVERSE_PROB == 0) {
- in_traverse++;
- tdb_traverse(db, modify_traverse, NULL);
- in_traverse--;
- goto next;
- }
-#endif
-
- if (tdb_fetch(db, key, &data) == TDB_SUCCESS)
- free(data.dptr);
-
-next:
- free(k);
- free(d);
-}
-
-static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf,
- void *state)
-{
- tdb_delete(tdb, key);
- return 0;
-}
-
-static void usage(void)
-{
- printf("Usage: tdb2torture"
-#if TRANSACTION_PROB
- " [-t]"
-#endif
- " [-k] [-n NUM_PROCS] [-l NUM_LOOPS] [-s SEED] [-S]\n");
- exit(0);
-}
-
-static void send_count_and_suicide(int sig)
-{
- /* This ensures our successor can continue where we left off. */
- if (write(count_pipe, &loopnum, sizeof(loopnum)) != sizeof(loopnum))
- exit(2);
- /* This gives a unique signature. */
- kill(getpid(), SIGUSR2);
-}
-
-static int run_child(const char *filename, int i, int seed, unsigned num_loops,
- unsigned start, int tdb_flags)
-{
- struct sigaction act = { .sa_sigaction = segv_handler,
- .sa_flags = SA_SIGINFO };
- sigaction(11, &act, NULL);
-
- db = tdb_open(filename, tdb_flags, O_RDWR | O_CREAT, 0600,
- &log_attr);
- if (!db) {
- fatal(NULL, "db open failed");
- }
-
-#if 0
- if (i == 0) {
- printf("pid %i\n", getpid());
- sleep(9);
- } else
- sleep(10);
-#endif
-
- srand(seed + i);
- srandom(seed + i);
-
- /* Set global, then we're ready to handle being killed. */
- loopnum = start;
- signal(SIGUSR1, send_count_and_suicide);
-
- for (;loopnum<num_loops && error_count == 0;loopnum++) {
- addrec_db();
- }
-
- if (error_count == 0) {
- tdb_traverse(db, NULL, NULL);
-#if TRANSACTION_PROB
- if (always_transaction) {
- while (in_transaction) {
- tdb_transaction_cancel(db);
- in_transaction--;
- }
- if (tdb_transaction_start(db) != 0)
- fatal(db, "tdb_transaction_start failed");
- }
-#endif
- tdb_traverse(db, traverse_fn, NULL);
- tdb_traverse(db, traverse_fn, NULL);
-
-#if TRANSACTION_PROB
- if (always_transaction) {
- if (tdb_transaction_commit(db) != 0)
- fatal(db, "tdb_transaction_commit failed");
- }
-#endif
- }
-
- tdb_close(db);
-
- return (error_count < 100 ? error_count : 100);
-}
-
-static char *test_path(const char *filename)
-{
- const char *prefix = getenv("TEST_DATA_PREFIX");
-
- if (prefix) {
- char *path = NULL;
- int ret;
-
- ret = asprintf(&path, "%s/%s", prefix, filename);
- if (ret == -1) {
- return NULL;
- }
- return path;
- }
-
- return strdup(filename);
-}
-
-int main(int argc, char * const *argv)
-{
- int i, seed = -1;
- int num_loops = 5000;
- int num_procs = 3;
- int c, pfds[2];
- extern char *optarg;
- pid_t *pids;
- int kill_random = 0;
- int *done;
- int tdb_flags = TDB_DEFAULT;
- char *test_tdb;
-
- log_attr.base.attr = TDB_ATTRIBUTE_LOG;
- log_attr.base.next = &seed_attr;
- log_attr.log.fn = tdb_log;
- seed_attr.base.attr = TDB_ATTRIBUTE_SEED;
- seed_attr.base.next = NULL;
-
- while ((c = getopt(argc, argv, "n:l:s:thkS")) != -1) {
- switch (c) {
- case 'n':
- num_procs = strtol(optarg, NULL, 0);
- break;
- case 'l':
- num_loops = strtol(optarg, NULL, 0);
- break;
- case 's':
- seed = strtol(optarg, NULL, 0);
- break;
- case 'S':
- tdb_flags = TDB_NOSYNC;
- break;
- case 't':
-#if TRANSACTION_PROB
- always_transaction = 1;
-#else
- fprintf(stderr, "Transactions not supported\n");
- usage();
-#endif
- break;
- case 'k':
- kill_random = 1;
- break;
- default:
- usage();
- }
- }
-
- test_tdb = test_path("torture.tdb2");
-
- unlink(test_tdb);
-
- if (seed == -1) {
- seed = (getpid() + time(NULL)) & 0x7FFFFFFF;
- }
- seed_attr.seed.seed = (((uint64_t)seed) << 32) | seed;
-
- if (num_procs == 1 && !kill_random) {
- /* Don't fork for this case, makes debugging easier. */
- error_count = run_child(test_tdb, 0, seed, num_loops, 0,
- tdb_flags);
- goto done;
- }
-
- pids = (pid_t *)calloc(sizeof(pid_t), num_procs);
- done = (int *)calloc(sizeof(int), num_procs);
-
- if (pipe(pfds) != 0) {
- perror("Creating pipe");
- exit(1);
- }
- count_pipe = pfds[1];
-
- for (i=0;i<num_procs;i++) {
- if ((pids[i]=fork()) == 0) {
- close(pfds[0]);
- if (i == 0) {
- printf("testing with %d processes, %d loops, seed=%d%s\n",
- num_procs, num_loops, seed,
-#if TRANSACTION_PROB
- always_transaction ? " (all within transactions)" : ""
-#else
- ""
-#endif
- );
- }
- exit(run_child(test_tdb, i, seed, num_loops, 0,
- tdb_flags));
- }
- }
-
- while (num_procs) {
- int status, j;
- pid_t pid;
-
- if (error_count != 0) {
- /* try and stop the test on any failure */
- for (j=0;j<num_procs;j++) {
- if (pids[j] != 0) {
- kill(pids[j], SIGTERM);
- }
- }
- }
-
- pid = waitpid(-1, &status, kill_random ? WNOHANG : 0);
- if (pid == 0) {
- struct timespec ts;
-
- /* Sleep for 1/10 second. */
- ts.tv_sec = 0;
- ts.tv_nsec = 100000000;
- nanosleep(&ts, NULL);
-
- /* Kill someone. */
- kill(pids[random() % num_procs], SIGUSR1);
- continue;
- }
-
- if (pid == -1) {
- perror("failed to wait for child\n");
- exit(1);
- }
-
- for (j=0;j<num_procs;j++) {
- if (pids[j] == pid) break;
- }
- if (j == num_procs) {
- printf("unknown child %d exited!?\n", (int)pid);
- exit(1);
- }
- if (WIFSIGNALED(status)) {
- if (WTERMSIG(status) == SIGUSR2
- || WTERMSIG(status) == SIGUSR1) {
- /* SIGUSR2 means they wrote to pipe. */
- if (WTERMSIG(status) == SIGUSR2) {
- if (read(pfds[0], &done[j],
- sizeof(done[j]))
- != sizeof(done[j]))
- err(1,
- "Short read from child?");
- }
- pids[j] = fork();
- if (pids[j] == 0)
- exit(run_child(test_tdb, j, seed,
- num_loops, done[j],
- tdb_flags));
- printf("Restarting child %i for %u-%u\n",
- j, done[j], num_loops);
- continue;
- }
- printf("child %d exited with signal %d\n",
- (int)pid, WTERMSIG(status));
- error_count++;
- } else {
- if (WEXITSTATUS(status) != 0) {
- printf("child %d exited with status %d\n",
- (int)pid, WEXITSTATUS(status));
- error_count++;
- }
- }
- memmove(&pids[j], &pids[j+1],
- (num_procs - j - 1)*sizeof(pids[0]));
- num_procs--;
- }
-
- free(pids);
-
-done:
- if (error_count == 0) {
- db = tdb_open(test_tdb, TDB_DEFAULT, O_RDWR | O_CREAT,
- 0600, &log_attr);
- if (!db) {
- fatal(db, "db open failed");
- exit(1);
- }
- if (tdb_check(db, NULL, NULL) != 0) {
- fatal(db, "db check failed");
- exit(1);
- }
- tdb_close(db);
- printf("OK\n");
- }
-
- free(test_tdb);
- return error_count;
-}