diff options
Diffstat (limited to 'lib/tdb2/tools')
-rw-r--r-- | lib/tdb2/tools/Makefile | 16 | ||||
-rw-r--r-- | lib/tdb2/tools/growtdb-bench.c | 114 | ||||
-rw-r--r-- | lib/tdb2/tools/mktdb2.c | 29 | ||||
-rw-r--r-- | lib/tdb2/tools/speed.c | 443 | ||||
-rw-r--r-- | lib/tdb2/tools/tdb2backup.c | 340 | ||||
-rw-r--r-- | lib/tdb2/tools/tdb2dump.c | 122 | ||||
-rw-r--r-- | lib/tdb2/tools/tdb2restore.c | 231 | ||||
-rw-r--r-- | lib/tdb2/tools/tdb2tool.c | 810 | ||||
-rw-r--r-- | lib/tdb2/tools/tdb2torture.c | 529 |
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; -} |