関数 | |
static void | tdb_log (struct tdb_context *tdb, enum tdb_debug_level level, const char *format,...) PRINTF_ATTRIBUTE(3 |
static void | fatal (const char *why) |
static char * | randbuf (int len) |
static int | cull_traverse (struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) |
static void | addrec_db (void) |
static int | traverse_fn (struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) |
static void | usage (void) |
int | main (int argc, char *const *argv) |
変数 | |
static struct tdb_context * | db |
static int | in_transaction |
static int | error_count |
static void static void tdb_log | ( | struct tdb_context * | tdb, | |
enum tdb_debug_level | level, | |||
const char * | format, | |||
... | ||||
) | [static] |
tdbtorture.c の 35 行で定義されています。
参照先 asprintf()・error_count.
00036 { 00037 va_list ap; 00038 00039 error_count++; 00040 00041 va_start(ap, format); 00042 vfprintf(stdout, format, ap); 00043 va_end(ap); 00044 fflush(stdout); 00045 #if 0 00046 { 00047 char *ptr; 00048 asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); 00049 system(ptr); 00050 free(ptr); 00051 } 00052 #endif 00053 }
static void fatal | ( | const char * | why | ) | [static] |
tdbtorture.c の 55 行で定義されています。
参照先 error_count.
00056 { 00057 perror(why); 00058 error_count++; 00059 }
static char* randbuf | ( | int | len | ) | [static] |
static int cull_traverse | ( | struct tdb_context * | tdb, | |
TDB_DATA | key, | |||
TDB_DATA | dbuf, | |||
void * | state | |||
) | [static] |
tdbtorture.c の 74 行で定義されています。
参照先 tdb・tdb_delete().
参照元 addrec_db().
00076 { 00077 #if CULL_PROB 00078 if (random() % CULL_PROB == 0) { 00079 tdb_delete(tdb, key); 00080 } 00081 #endif 00082 return 0; 00083 }
static void addrec_db | ( | void | ) | [static] |
tdbtorture.c の 85 行で定義されています。
参照先 cull_traverse()・db・TDB_DATA::dptr・TDB_DATA::dsize・fatal()・in_transaction・tdb_context::next・randbuf()・tdb_append()・tdb_chainlock()・tdb_chainunlock()・tdb_delete()・tdb_fetch()・tdb_reopen_all()・tdb_store()・tdb_transaction_cancel()・tdb_transaction_commit()・tdb_transaction_start()・tdb_traverse()・tdb_traverse_read().
00086 { 00087 int klen, dlen; 00088 char *k, *d; 00089 TDB_DATA key, data; 00090 00091 klen = 1 + (rand() % KEYLEN); 00092 dlen = 1 + (rand() % DATALEN); 00093 00094 k = randbuf(klen); 00095 d = randbuf(dlen); 00096 00097 key.dptr = (unsigned char *)k; 00098 key.dsize = klen+1; 00099 00100 data.dptr = (unsigned char *)d; 00101 data.dsize = dlen+1; 00102 00103 #if TRANSACTION_PROB 00104 if (in_transaction == 0 && random() % TRANSACTION_PROB == 0) { 00105 if (tdb_transaction_start(db) != 0) { 00106 fatal("tdb_transaction_start failed"); 00107 } 00108 in_transaction++; 00109 goto next; 00110 } 00111 if (in_transaction && random() % TRANSACTION_PROB == 0) { 00112 if (tdb_transaction_commit(db) != 0) { 00113 fatal("tdb_transaction_commit failed"); 00114 } 00115 in_transaction--; 00116 goto next; 00117 } 00118 if (in_transaction && random() % TRANSACTION_PROB == 0) { 00119 if (tdb_transaction_cancel(db) != 0) { 00120 fatal("tdb_transaction_cancel failed"); 00121 } 00122 in_transaction--; 00123 goto next; 00124 } 00125 #endif 00126 00127 #if REOPEN_PROB 00128 if (in_transaction == 0 && random() % REOPEN_PROB == 0) { 00129 tdb_reopen_all(0); 00130 goto next; 00131 } 00132 #endif 00133 00134 #if DELETE_PROB 00135 if (random() % DELETE_PROB == 0) { 00136 tdb_delete(db, key); 00137 goto next; 00138 } 00139 #endif 00140 00141 #if STORE_PROB 00142 if (random() % STORE_PROB == 0) { 00143 if (tdb_store(db, key, data, TDB_REPLACE) != 0) { 00144 fatal("tdb_store failed"); 00145 } 00146 goto next; 00147 } 00148 #endif 00149 00150 #if APPEND_PROB 00151 if (random() % APPEND_PROB == 0) { 00152 if (tdb_append(db, key, data) != 0) { 00153 fatal("tdb_append failed"); 00154 } 00155 goto next; 00156 } 00157 #endif 00158 00159 #if LOCKSTORE_PROB 00160 if (random() % LOCKSTORE_PROB == 0) { 00161 tdb_chainlock(db, key); 00162 data = tdb_fetch(db, key); 00163 if (tdb_store(db, key, data, TDB_REPLACE) != 0) { 00164 fatal("tdb_store failed"); 00165 } 00166 if (data.dptr) free(data.dptr); 00167 tdb_chainunlock(db, key); 00168 goto next; 00169 } 00170 #endif 00171 00172 #if TRAVERSE_PROB 00173 if (random() % TRAVERSE_PROB == 0) { 00174 tdb_traverse(db, cull_traverse, NULL); 00175 goto next; 00176 } 00177 #endif 00178 00179 #if TRAVERSE_READ_PROB 00180 if (random() % TRAVERSE_READ_PROB == 0) { 00181 tdb_traverse_read(db, NULL, NULL); 00182 goto next; 00183 } 00184 #endif 00185 00186 data = tdb_fetch(db, key); 00187 if (data.dptr) free(data.dptr); 00188 00189 next: 00190 free(k); 00191 free(d); 00192 }
static int traverse_fn | ( | struct tdb_context * | tdb, | |
TDB_DATA | key, | |||
TDB_DATA | dbuf, | |||
void * | state | |||
) | [static] |
tdbtorture.c の 194 行で定義されています。
参照先 tdb・tdb_delete().
00196 { 00197 tdb_delete(tdb, key); 00198 return 0; 00199 }
static void usage | ( | void | ) | [static] |
tdbtorture.c の 201 行で定義されています。
参照先 printf().
00202 { 00203 printf("Usage: tdbtorture [-n NUM_PROCS] [-l NUM_LOOPS] [-s SEED] [-H HASH_SIZE]\n"); 00204 exit(0); 00205 }
int main | ( | int | argc, | |
char *const * | argv | |||
) |
tdbtorture.c の 207 行で定義されています。
参照先 addrec_db()・c・db・error_count・fatal()・tdb_logging_context::log_fn・optarg・printf()・status・tdb_close()・tdb_log()・tdb_open_ex()・tdb_traverse()・tdb_traverse_read()・traverse_fn()・usage().
00208 { 00209 int i, seed = -1; 00210 int num_procs = 3; 00211 int num_loops = 5000; 00212 int hash_size = 2; 00213 int c; 00214 extern char *optarg; 00215 pid_t *pids; 00216 00217 struct tdb_logging_context log_ctx; 00218 log_ctx.log_fn = tdb_log; 00219 00220 while ((c = getopt(argc, argv, "n:l:s:H:h")) != -1) { 00221 switch (c) { 00222 case 'n': 00223 num_procs = strtol(optarg, NULL, 0); 00224 break; 00225 case 'l': 00226 num_loops = strtol(optarg, NULL, 0); 00227 break; 00228 case 'H': 00229 hash_size = strtol(optarg, NULL, 0); 00230 break; 00231 case 's': 00232 seed = strtol(optarg, NULL, 0); 00233 break; 00234 default: 00235 usage(); 00236 } 00237 } 00238 00239 unlink("torture.tdb"); 00240 00241 pids = calloc(sizeof(pid_t), num_procs); 00242 pids[0] = getpid(); 00243 00244 for (i=0;i<num_procs-1;i++) { 00245 if ((pids[i+1]=fork()) == 0) break; 00246 } 00247 00248 db = tdb_open_ex("torture.tdb", hash_size, TDB_CLEAR_IF_FIRST, 00249 O_RDWR | O_CREAT, 0600, &log_ctx, NULL); 00250 if (!db) { 00251 fatal("db open failed"); 00252 } 00253 00254 if (seed == -1) { 00255 seed = (getpid() + time(NULL)) & 0x7FFFFFFF; 00256 } 00257 00258 if (i == 0) { 00259 printf("testing with %d processes, %d loops, %d hash_size, seed=%d\n", 00260 num_procs, num_loops, hash_size, seed); 00261 } 00262 00263 srand(seed + i); 00264 srandom(seed + i); 00265 00266 for (i=0;i<num_loops && error_count == 0;i++) { 00267 addrec_db(); 00268 } 00269 00270 if (error_count == 0) { 00271 tdb_traverse_read(db, NULL, NULL); 00272 tdb_traverse(db, traverse_fn, NULL); 00273 tdb_traverse(db, traverse_fn, NULL); 00274 } 00275 00276 tdb_close(db); 00277 00278 if (getpid() != pids[0]) { 00279 return error_count; 00280 } 00281 00282 for (i=1;i<num_procs;i++) { 00283 int status, j; 00284 pid_t pid; 00285 if (error_count != 0) { 00286 /* try and stop the test on any failure */ 00287 for (j=1;j<num_procs;j++) { 00288 if (pids[j] != 0) { 00289 kill(pids[j], SIGTERM); 00290 } 00291 } 00292 } 00293 pid = waitpid(-1, &status, 0); 00294 if (pid == -1) { 00295 perror("failed to wait for child\n"); 00296 exit(1); 00297 } 00298 for (j=1;j<num_procs;j++) { 00299 if (pids[j] == pid) break; 00300 } 00301 if (j == num_procs) { 00302 printf("unknown child %d exited!?\n", (int)pid); 00303 exit(1); 00304 } 00305 if (WEXITSTATUS(status) != 0) { 00306 printf("child %d exited with status %d\n", 00307 (int)pid, WEXITSTATUS(status)); 00308 error_count++; 00309 } 00310 pids[j] = 0; 00311 } 00312 00313 if (error_count == 0) { 00314 printf("OK\n"); 00315 } 00316 00317 return error_count; 00318 }
struct tdb_context* db [static] |
tdbtorture.c の 28 行で定義されています。
int in_transaction [static] |
int error_count [static] |