Changeset 745 for trunk/server/lib/tdb/tools
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 5 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/lib/tdb/tools/tdbbackup.c
r414 r745 153 153 } 154 154 155 if (tdb_transaction_start(tdb_new) != 0) { 156 printf("Failed to start transaction on new tdb\n"); 155 /* lock the backup tdb so that nobody else can change it */ 156 if (tdb_lockall(tdb_new) != 0) { 157 printf("Failed to lock backup tdb\n"); 157 158 tdb_close(tdb); 158 159 tdb_close(tdb_new); … … 178 179 tdb_close(tdb); 179 180 180 if (tdb_transaction_commit(tdb_new) != 0) { 181 fprintf(stderr, "Failed to commit new tdb\n"); 182 tdb_close(tdb_new); 183 unlink(tmp_name); 184 free(tmp_name); 185 return 1; 181 /* copy done, unlock the backup tdb */ 182 tdb_unlockall(tdb_new); 183 184 #ifdef HAVE_FDATASYNC 185 if (fdatasync(tdb_fd(tdb_new)) != 0) { 186 #else 187 if (fsync(tdb_fd(tdb_new)) != 0) { 188 #endif 189 /* not fatal */ 190 fprintf(stderr, "failed to fsync backup file\n"); 186 191 } 187 192 -
trunk/server/lib/tdb/tools/tdbtest.c
r414 r745 216 216 } 217 217 218 static char *test_path(const char *filename) 219 { 220 const char *prefix = getenv("TEST_DATA_PREFIX"); 221 222 if (prefix) { 223 char *path = NULL; 224 int ret; 225 226 ret = asprintf(&path, "%s/%s", prefix, filename); 227 if (ret == -1) { 228 return NULL; 229 } 230 return path; 231 } 232 233 return strdup(filename); 234 } 235 218 236 int main(int argc, const char *argv[]) 219 237 { … … 221 239 int loops = 10000; 222 240 int num_entries; 223 char test_gdbm[] = "test.gdbm"; 224 225 unlink("test.gdbm"); 226 227 db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST, 241 char test_gdbm[1] = "test.gdbm"; 242 char *test_tdb; 243 244 test_gdbm[0] = test_path("test.gdbm"); 245 test_tdb = test_path("test.tdb"); 246 247 unlink(test_gdbm[0]); 248 249 db = tdb_open(test_tdb, 0, TDB_CLEAR_IF_FIRST, 228 250 O_RDWR | O_CREAT | O_TRUNC, 0600); 229 251 gdbm = gdbm_open(test_gdbm, 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST, … … 262 284 gdbm_close(gdbm); 263 285 286 free(test_gdbm[0]); 287 free(test_tdb); 288 264 289 return 0; 265 290 } -
trunk/server/lib/tdb/tools/tdbtool.c
r456 r745 418 418 static void info_tdb(void) 419 419 { 420 int count;421 total_bytes = 0; 422 if ( (count = tdb_traverse(tdb, traverse_fn, NULL)) == -1)420 char *summary = tdb_summary(tdb); 421 422 if (!summary) { 423 423 printf("Error = %s\n", tdb_errorstr(tdb)); 424 else 425 printf("%d records totalling %d bytes\n", count, total_bytes); 424 } else { 425 printf("%s", summary); 426 free(summary); 427 } 426 428 } 427 429 … … 574 576 if (cmdname) { 575 577 #endif 576 577 578 if (cmdname && strlen(cmdname) == 0) { 578 579 mycmd = CMD_NEXT; -
trunk/server/lib/tdb/tools/tdbtorture.c
r414 r745 31 31 static int error_count; 32 32 static int always_transaction = 0; 33 static int hash_size = 2; 34 static int loopnum; 35 static int count_pipe; 36 static struct tdb_logging_context log_ctx; 33 37 34 38 #ifdef PRINTF_ATTRIBUTE … … 49 53 fflush(stdout); 50 54 #if 0 51 {55 if (level != TDB_DEBUG_TRACE) { 52 56 char *ptr; 57 signal(SIGUSR1, SIG_IGN); 53 58 asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); 54 59 system(ptr); … … 212 217 static void usage(void) 213 218 { 214 printf("Usage: tdbtorture [-t] [- n NUM_PROCS] [-l NUM_LOOPS] [-s SEED] [-H HASH_SIZE]\n");219 printf("Usage: tdbtorture [-t] [-k] [-n NUM_PROCS] [-l NUM_LOOPS] [-s SEED] [-H HASH_SIZE]\n"); 215 220 exit(0); 216 221 } 217 222 218 int main(int argc, char * const *argv) 219 { 220 int i, seed = -1; 221 int num_procs = 3; 222 int num_loops = 5000; 223 int hash_size = 2; 224 int c; 225 extern char *optarg; 226 pid_t *pids; 227 228 struct tdb_logging_context log_ctx; 229 log_ctx.log_fn = tdb_log; 230 231 while ((c = getopt(argc, argv, "n:l:s:H:th")) != -1) { 232 switch (c) { 233 case 'n': 234 num_procs = strtol(optarg, NULL, 0); 235 break; 236 case 'l': 237 num_loops = strtol(optarg, NULL, 0); 238 break; 239 case 'H': 240 hash_size = strtol(optarg, NULL, 0); 241 break; 242 case 's': 243 seed = strtol(optarg, NULL, 0); 244 break; 245 case 't': 246 always_transaction = 1; 247 break; 248 default: 249 usage(); 250 } 251 } 252 253 unlink("torture.tdb"); 254 255 pids = (pid_t *)calloc(sizeof(pid_t), num_procs); 256 pids[0] = getpid(); 257 258 for (i=0;i<num_procs-1;i++) { 259 if ((pids[i+1]=fork()) == 0) break; 260 } 261 262 db = tdb_open_ex("torture.tdb", hash_size, TDB_CLEAR_IF_FIRST, 223 static void send_count_and_suicide(int sig) 224 { 225 /* This ensures our successor can continue where we left off. */ 226 write(count_pipe, &loopnum, sizeof(loopnum)); 227 /* This gives a unique signature. */ 228 kill(getpid(), SIGUSR2); 229 } 230 231 static int run_child(const char *filename, int i, int seed, unsigned num_loops, unsigned start) 232 { 233 db = tdb_open_ex(filename, hash_size, TDB_DEFAULT, 263 234 O_RDWR | O_CREAT, 0600, &log_ctx, NULL); 264 235 if (!db) { … … 266 237 } 267 238 268 if (seed == -1) {269 seed = (getpid() + time(NULL)) & 0x7FFFFFFF;270 }271 272 if (i == 0) {273 printf("testing with %d processes, %d loops, %d hash_size, seed=%d%s\n",274 num_procs, num_loops, hash_size, seed, always_transaction ? " (all within transactions)" : "");275 }276 277 239 srand(seed + i); 278 240 srandom(seed + i); 279 241 280 for (i=0;i<num_loops && error_count == 0;i++) { 242 /* Set global, then we're ready to handle being killed. */ 243 loopnum = start; 244 signal(SIGUSR1, send_count_and_suicide); 245 246 for (;loopnum<num_loops && error_count == 0;loopnum++) { 281 247 addrec_db(); 282 248 } … … 302 268 tdb_close(db); 303 269 304 if (getpid() != pids[0]) { 305 return error_count; 306 } 307 308 for (i=1;i<num_procs;i++) { 270 return (error_count < 100 ? error_count : 100); 271 } 272 273 static char *test_path(const char *filename) 274 { 275 const char *prefix = getenv("TEST_DATA_PREFIX"); 276 277 if (prefix) { 278 char *path = NULL; 279 int ret; 280 281 ret = asprintf(&path, "%s/%s", prefix, filename); 282 if (ret == -1) { 283 return NULL; 284 } 285 return path; 286 } 287 288 return strdup(filename); 289 } 290 291 int main(int argc, char * const *argv) 292 { 293 int i, seed = -1; 294 int num_loops = 5000; 295 int num_procs = 3; 296 int c, pfds[2]; 297 extern char *optarg; 298 pid_t *pids; 299 int kill_random = 0; 300 int *done; 301 char *test_tdb; 302 303 log_ctx.log_fn = tdb_log; 304 305 while ((c = getopt(argc, argv, "n:l:s:H:thk")) != -1) { 306 switch (c) { 307 case 'n': 308 num_procs = strtol(optarg, NULL, 0); 309 break; 310 case 'l': 311 num_loops = strtol(optarg, NULL, 0); 312 break; 313 case 'H': 314 hash_size = strtol(optarg, NULL, 0); 315 break; 316 case 's': 317 seed = strtol(optarg, NULL, 0); 318 break; 319 case 't': 320 always_transaction = 1; 321 break; 322 case 'k': 323 kill_random = 1; 324 break; 325 default: 326 usage(); 327 } 328 } 329 330 test_tdb = test_path("torture.tdb"); 331 332 unlink(test_tdb); 333 334 if (seed == -1) { 335 seed = (getpid() + time(NULL)) & 0x7FFFFFFF; 336 } 337 338 if (num_procs == 1 && !kill_random) { 339 /* Don't fork for this case, makes debugging easier. */ 340 error_count = run_child(test_tdb, 0, seed, num_loops, 0); 341 goto done; 342 } 343 344 pids = (pid_t *)calloc(sizeof(pid_t), num_procs); 345 done = (int *)calloc(sizeof(int), num_procs); 346 347 if (pipe(pfds) != 0) { 348 perror("Creating pipe"); 349 exit(1); 350 } 351 count_pipe = pfds[1]; 352 353 for (i=0;i<num_procs;i++) { 354 if ((pids[i]=fork()) == 0) { 355 close(pfds[0]); 356 if (i == 0) { 357 printf("Testing with %d processes, %d loops, %d hash_size, seed=%d%s\n", 358 num_procs, num_loops, hash_size, seed, always_transaction ? " (all within transactions)" : ""); 359 } 360 exit(run_child(test_tdb, i, seed, num_loops, 0)); 361 } 362 } 363 364 while (num_procs) { 309 365 int status, j; 310 366 pid_t pid; 367 311 368 if (error_count != 0) { 312 369 /* try and stop the test on any failure */ 313 for (j= 1;j<num_procs;j++) {370 for (j=0;j<num_procs;j++) { 314 371 if (pids[j] != 0) { 315 372 kill(pids[j], SIGTERM); … … 317 374 } 318 375 } 319 pid = waitpid(-1, &status, 0); 376 377 pid = waitpid(-1, &status, kill_random ? WNOHANG : 0); 378 if (pid == 0) { 379 struct timeval tv; 380 381 /* Sleep for 1/10 second. */ 382 tv.tv_sec = 0; 383 tv.tv_usec = 100000; 384 select(0, NULL, NULL, NULL, &tv); 385 386 /* Kill someone. */ 387 kill(pids[random() % num_procs], SIGUSR1); 388 continue; 389 } 390 320 391 if (pid == -1) { 321 392 perror("failed to wait for child\n"); 322 393 exit(1); 323 394 } 324 for (j=1;j<num_procs;j++) { 395 396 for (j=0;j<num_procs;j++) { 325 397 if (pids[j] == pid) break; 326 398 } … … 329 401 exit(1); 330 402 } 331 if (WEXITSTATUS(status) != 0) { 332 printf("child %d exited with status %d\n", 333 (int)pid, WEXITSTATUS(status)); 403 if (WIFSIGNALED(status)) { 404 if (WTERMSIG(status) == SIGUSR2 405 || WTERMSIG(status) == SIGUSR1) { 406 /* SIGUSR2 means they wrote to pipe. */ 407 if (WTERMSIG(status) == SIGUSR2) { 408 read(pfds[0], &done[j], 409 sizeof(done[j])); 410 } 411 pids[j] = fork(); 412 if (pids[j] == 0) 413 exit(run_child(test_tdb, j, seed, 414 num_loops, done[j])); 415 printf("Restarting child %i for %u-%u\n", 416 j, done[j], num_loops); 417 continue; 418 } 419 printf("child %d exited with signal %d\n", 420 (int)pid, WTERMSIG(status)); 334 421 error_count++; 335 } 336 pids[j] = 0; 422 } else { 423 if (WEXITSTATUS(status) != 0) { 424 printf("child %d exited with status %d\n", 425 (int)pid, WEXITSTATUS(status)); 426 error_count++; 427 } 428 } 429 memmove(&pids[j], &pids[j+1], 430 (num_procs - j - 1)*sizeof(pids[0])); 431 num_procs--; 337 432 } 338 433 339 434 free(pids); 340 435 436 done: 341 437 if (error_count == 0) { 438 db = tdb_open_ex(test_tdb, hash_size, TDB_DEFAULT, 439 O_RDWR, 0, &log_ctx, NULL); 440 if (!db) { 441 fatal("db open failed"); 442 } 443 if (tdb_check(db, NULL, NULL) == -1) { 444 printf("db check failed"); 445 exit(1); 446 } 447 tdb_close(db); 342 448 printf("OK\n"); 343 449 } 344 450 451 free(test_tdb); 345 452 return error_count; 346 453 }
Note:
See TracChangeset
for help on using the changeset viewer.