X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Ftools%2Ftdbtorture.c;h=32d7ea3c5a9640611508ffa0170ba2149e0ca26b;hp=2ac9a8de43975a6b36220e5ebf1a1598c2acfa93;hb=6ce40d6ab4dbd63bd76979b8491351708c3df892;hpb=1c005e1223d2f8f664ce4b3be6cd7eb4dd449844 diff --git a/ccan/tdb2/tools/tdbtorture.c b/ccan/tdb2/tools/tdbtorture.c index 2ac9a8de..32d7ea3c 100644 --- a/ccan/tdb2/tools/tdbtorture.c +++ b/ccan/tdb2/tools/tdbtorture.c @@ -20,11 +20,10 @@ #define DELETE_PROB 8 #define STORE_PROB 4 #define APPEND_PROB 6 -//#define TRANSACTION_PROB 10 -//#define TRANSACTION_PREPARE_PROB 2 +#define TRANSACTION_PROB 10 +#define TRANSACTION_PREPARE_PROB 2 #define LOCKSTORE_PROB 5 #define TRAVERSE_PROB 20 -#define TRAVERSE_READ_PROB 20 #define TRAVERSE_MOD_PROB 100 #define TRAVERSE_ABORT_PROB 500 #define CULL_PROB 100 @@ -43,47 +42,39 @@ static int count_pipe; static union tdb_attribute log_attr; static union tdb_attribute seed_attr; -#ifdef PRINTF_FMT -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, void *private, const char *format, ...) PRINTF_FMT(4,5); -#endif -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, void *private, const char *format, ...) +static void tdb_log(struct tdb_context *tdb, enum tdb_log_level level, + const char *message, void *data) { - va_list ap; - - if (level != TDB_DEBUG_TRACE) - error_count++; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); + fputs(message, stdout); fflush(stdout); #if 0 - if (level != TDB_DEBUG_TRACE) { - char *ptr; + { + char str[200]; signal(SIGUSR1, SIG_IGN); - asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); - system(ptr); - free(ptr); + sprintf(str,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); + system(str); } #endif } #include "../private.h" -static void segv_handler(int signal, siginfo_t *info, void *p) +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 %llu)\n", - getpid(), info->si_addr, db->map_ptr, db->map_size); - write(2, string, strlen(string)); - sleep(60); + 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(const char *why) +static void fatal(struct tdb_context *tdb, const char *why) { - perror(why); + fprintf(stderr, "%u:%s:%s\n", getpid(), why, + tdb ? tdb_errorstr(tdb_error(tdb)) : "(no tdb)"); error_count++; } @@ -152,7 +143,7 @@ static void addrec_db(void) #if TRANSACTION_PROB if (in_traverse == 0 && in_transaction == 0 && (always_transaction || random() % TRANSACTION_PROB == 0)) { if (tdb_transaction_start(db) != 0) { - fatal("tdb_transaction_start failed"); + fatal(db, "tdb_transaction_start failed"); } in_transaction++; goto next; @@ -160,20 +151,18 @@ static void addrec_db(void) if (in_traverse == 0 && in_transaction && random() % TRANSACTION_PROB == 0) { if (random() % TRANSACTION_PREPARE_PROB == 0) { if (tdb_transaction_prepare_commit(db) != 0) { - fatal("tdb_transaction_prepare_commit failed"); + fatal(db, "tdb_transaction_prepare_commit failed"); } } if (tdb_transaction_commit(db) != 0) { - fatal("tdb_transaction_commit failed"); + fatal(db, "tdb_transaction_commit failed"); } in_transaction--; goto next; } if (in_traverse == 0 && in_transaction && random() % TRANSACTION_PROB == 0) { - if (tdb_transaction_cancel(db) != 0) { - fatal("tdb_transaction_cancel failed"); - } + tdb_transaction_cancel(db); in_transaction--; goto next; } @@ -189,7 +178,7 @@ static void addrec_db(void) #if STORE_PROB if (random() % STORE_PROB == 0) { if (tdb_store(db, key, data, TDB_REPLACE) != 0) { - fatal("tdb_store failed"); + fatal(db, "tdb_store failed"); } goto next; } @@ -198,7 +187,7 @@ static void addrec_db(void) #if APPEND_PROB if (random() % APPEND_PROB == 0) { if (tdb_append(db, key, data) != 0) { - fatal("tdb_append failed"); + fatal(db, "tdb_append failed"); } goto next; } @@ -207,9 +196,12 @@ static void addrec_db(void) #if LOCKSTORE_PROB if (random() % LOCKSTORE_PROB == 0) { tdb_chainlock(db, key); - data = tdb_fetch(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("tdb_store failed"); + fatal(db, "tdb_store failed"); } if (data.dptr) free(data.dptr); tdb_chainunlock(db, key); @@ -227,17 +219,8 @@ static void addrec_db(void) } #endif -#if TRAVERSE_READ_PROB - if (in_traverse == 0 && random() % TRAVERSE_READ_PROB == 0) { - in_traverse++; - tdb_traverse_read(db, NULL, NULL); - in_traverse--; - goto next; - } -#endif - - data = tdb_fetch(db, key); - if (data.dptr) free(data.dptr); + if (tdb_fetch(db, key, &data) == TDB_SUCCESS) + free(data.dptr); next: free(k); @@ -257,28 +240,30 @@ static void usage(void) #if TRANSACTION_PROB " [-t]" #endif - " [-k] [-n NUM_PROCS] [-l NUM_LOOPS] [-s SEED]\n"); + " [-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. */ - write(count_pipe, &loopnum, sizeof(loopnum)); + if (write(count_pipe, &loopnum, sizeof(loopnum)) != sizeof(loopnum)) + exit(2); /* This gives a unique signature. */ kill(getpid(), SIGUSR2); } -static int run_child(int i, int seed, unsigned num_loops, unsigned start) +static int run_child(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("torture.tdb", TDB_DEFAULT, O_RDWR | O_CREAT, 0600, + db = tdb_open("torture.tdb", tdb_flags, O_RDWR | O_CREAT, 0600, &log_attr); if (!db) { - fatal("db open failed"); + fatal(NULL, "db open failed"); } #if 0 @@ -301,7 +286,7 @@ static int run_child(int i, int seed, unsigned num_loops, unsigned start) } if (error_count == 0) { - tdb_traverse_read(db, NULL, NULL); + tdb_traverse(db, NULL, NULL); #if TRANSACTION_PROB if (always_transaction) { while (in_transaction) { @@ -309,7 +294,7 @@ static int run_child(int i, int seed, unsigned num_loops, unsigned start) in_transaction--; } if (tdb_transaction_start(db) != 0) - fatal("tdb_transaction_start failed"); + fatal(db, "tdb_transaction_start failed"); } #endif tdb_traverse(db, traverse_fn, NULL); @@ -318,7 +303,7 @@ static int run_child(int i, int seed, unsigned num_loops, unsigned start) #if TRANSACTION_PROB if (always_transaction) { if (tdb_transaction_commit(db) != 0) - fatal("tdb_transaction_commit failed"); + fatal(db, "tdb_transaction_commit failed"); } #endif } @@ -338,13 +323,14 @@ int main(int argc, char * const *argv) pid_t *pids; int kill_random = 0; int *done; + int tdb_flags = TDB_DEFAULT; log_attr.base.attr = TDB_ATTRIBUTE_LOG; log_attr.base.next = &seed_attr; - log_attr.log.log_fn = tdb_log; + log_attr.log.fn = tdb_log; seed_attr.base.attr = TDB_ATTRIBUTE_SEED; - while ((c = getopt(argc, argv, "n:l:s:thk")) != -1) { + while ((c = getopt(argc, argv, "n:l:s:thkS")) != -1) { switch (c) { case 'n': num_procs = strtol(optarg, NULL, 0); @@ -355,6 +341,9 @@ int main(int argc, char * const *argv) case 's': seed = strtol(optarg, NULL, 0); break; + case 'S': + tdb_flags = TDB_NOSYNC; + break; case 't': #if TRANSACTION_PROB always_transaction = 1; @@ -380,7 +369,7 @@ int main(int argc, char * const *argv) if (num_procs == 1 && !kill_random) { /* Don't fork for this case, makes debugging easier. */ - error_count = run_child(0, seed, num_loops, 0); + error_count = run_child(0, seed, num_loops, 0, tdb_flags); goto done; } @@ -406,7 +395,7 @@ int main(int argc, char * const *argv) #endif ); } - exit(run_child(i, seed, num_loops, 0)); + exit(run_child(i, seed, num_loops, 0, tdb_flags)); } } @@ -454,13 +443,16 @@ int main(int argc, char * const *argv) || WTERMSIG(status) == SIGUSR1) { /* SIGUSR2 means they wrote to pipe. */ if (WTERMSIG(status) == SIGUSR2) { - read(pfds[0], &done[j], - sizeof(done[j])); + 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(j, seed, num_loops, - done[j])); + done[j], tdb_flags)); printf("Restarting child %i for %u-%u\n", j, done[j], num_loops); continue; @@ -487,10 +479,11 @@ done: db = tdb_open("torture.tdb", TDB_DEFAULT, O_RDWR | O_CREAT, 0600, &log_attr); if (!db) { - fatal("db open failed"); + fatal(db, "db open failed"); + exit(1); } - if (tdb_check(db, NULL, NULL) == -1) { - printf("db check failed"); + if (tdb_check(db, NULL, NULL) != 0) { + fatal(db, "db check failed"); exit(1); } tdb_close(db);