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_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); }
int main(int argc, const char *argv[]) { int i, seed=0; int loops = 10000; int num_entries; char test_gdbm[] = "test.gdbm"; unlink("test.gdbm"); db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT | O_TRUNC, 0600); gdbm = gdbm_open(test_gdbm, 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST, 0600, NULL); if (!db || !gdbm) { fatal("db open failed"); } #if 1 srand(seed); _start_timer(); for (i=0;i<loops;i++) addrec_gdbm(); printf("gdbm got %.2f ops/sec\n", i/_end_timer()); #endif merge_test(); srand(seed); _start_timer(); for (i=0;i<loops;i++) addrec_db(); printf("tdb got %.2f ops/sec\n", i/_end_timer()); if (tdb_validate_freelist(db, &num_entries) == -1) { printf("tdb freelist is corrupt\n"); } else { printf("tdb freelist is good (%d entries)\n", num_entries); } compare_db(); printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL)); printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL)); tdb_close(db); gdbm_close(gdbm); return 0; }
static int run_child(const char *filename, int i, int seed, unsigned num_loops, unsigned start) { db = tdb_open_ex(filename, hash_size, TDB_DEFAULT, O_RDWR | O_CREAT, 0600, &log_ctx, NULL); if (!db) { fatal("db open failed"); } 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_read(db, NULL, NULL); if (always_transaction) { while (in_transaction) { tdb_transaction_cancel(db); in_transaction--; } if (tdb_transaction_start(db) != 0) fatal("tdb_transaction_start failed"); } tdb_traverse(db, traverse_fn, NULL); tdb_traverse(db, traverse_fn, NULL); if (always_transaction) { if (tdb_transaction_commit(db) != 0) fatal("tdb_transaction_commit failed"); } } tdb_close(db); return (error_count < 100 ? error_count : 100); }
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; }
int main(int argc, char * const *argv) { int i, seed = -1; int num_procs = 3; int num_loops = 5000; int hash_size = 2; int c; extern char *optarg; pid_t *pids; struct tdb_logging_context log_ctx; log_ctx.log_fn = tdb_log; while ((c = getopt(argc, argv, "n:l:s:H:h")) != -1) { switch (c) { case 'n': num_procs = strtol(optarg, NULL, 0); break; case 'l': num_loops = strtol(optarg, NULL, 0); break; case 'H': hash_size = strtol(optarg, NULL, 0); break; case 's': seed = strtol(optarg, NULL, 0); break; default: usage(); } } unlink("torture.tdb"); pids = (pid_t *)calloc(sizeof(pid_t), num_procs); pids[0] = getpid(); for (i=0;i<num_procs-1;i++) { if ((pids[i+1]=fork()) == 0) break; } db = tdb_open_ex("torture.tdb", hash_size, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0600, &log_ctx, NULL); if (!db) { fatal("db open failed"); } if (seed == -1) { seed = (getpid() + time(NULL)) & 0x7FFFFFFF; } if (i == 0) { printf("testing with %d processes, %d loops, %d hash_size, seed=%d\n", num_procs, num_loops, hash_size, seed); } srand(seed + i); srandom(seed + i); for (i=0;i<num_loops && error_count == 0;i++) { addrec_db(); } if (error_count == 0) { tdb_traverse_read(db, NULL, NULL); tdb_traverse(db, traverse_fn, NULL); tdb_traverse(db, traverse_fn, NULL); } tdb_close(db); if (getpid() != pids[0]) { return error_count; } for (i=1;i<num_procs;i++) { int status, j; pid_t pid; if (error_count != 0) { /* try and stop the test on any failure */ for (j=1;j<num_procs;j++) { if (pids[j] != 0) { kill(pids[j], SIGTERM); } } } pid = waitpid(-1, &status, 0); if (pid == -1) { perror("failed to wait for child\n"); exit(1); } for (j=1;j<num_procs;j++) { if (pids[j] == pid) break; } if (j == num_procs) { printf("unknown child %d exited!?\n", (int)pid); exit(1); } if (WEXITSTATUS(status) != 0) { printf("child %d exited with status %d\n", (int)pid, WEXITSTATUS(status)); error_count++; } pids[j] = 0; } if (error_count == 0) { printf("OK\n"); } return error_count; }