Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
5 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/lib/tdb/tools/tdbbackup.c

    r414 r745  
    153153        }
    154154
    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");
    157158                tdb_close(tdb);
    158159                tdb_close(tdb_new);
     
    178179        tdb_close(tdb);
    179180
    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");
    186191        }
    187192
  • trunk/server/lib/tdb/tools/tdbtest.c

    r414 r745  
    216216}
    217217
     218static 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
    218236 int main(int argc, const char *argv[])
    219237{
     
    221239        int loops = 10000;
    222240        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,
    228250                      O_RDWR | O_CREAT | O_TRUNC, 0600);
    229251        gdbm = gdbm_open(test_gdbm, 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST,
     
    262284        gdbm_close(gdbm);
    263285
     286        free(test_gdbm[0]);
     287        free(test_tdb);
     288
    264289        return 0;
    265290}
  • trunk/server/lib/tdb/tools/tdbtool.c

    r456 r745  
    418418static void info_tdb(void)
    419419{
    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) {
    423423                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        }
    426428}
    427429
     
    574576    if (cmdname) {
    575577#endif
    576 
    577578        if (cmdname && strlen(cmdname) == 0) {
    578579                mycmd = CMD_NEXT;
  • trunk/server/lib/tdb/tools/tdbtorture.c

    r414 r745  
    3131static int error_count;
    3232static int always_transaction = 0;
     33static int hash_size = 2;
     34static int loopnum;
     35static int count_pipe;
     36static struct tdb_logging_context log_ctx;
    3337
    3438#ifdef PRINTF_ATTRIBUTE
     
    4953        fflush(stdout);
    5054#if 0
    51         {
     55        if (level != TDB_DEBUG_TRACE) {
    5256                char *ptr;
     57                signal(SIGUSR1, SIG_IGN);
    5358                asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid());
    5459                system(ptr);
     
    212217static void usage(void)
    213218{
    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");
    215220        exit(0);
    216221}
    217222
    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,
     223static 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
     231static 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,
    263234                         O_RDWR | O_CREAT, 0600, &log_ctx, NULL);
    264235        if (!db) {
     
    266237        }
    267238
    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 
    277239        srand(seed + i);
    278240        srandom(seed + i);
    279241
    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++) {
    281247                addrec_db();
    282248        }
     
    302268        tdb_close(db);
    303269
    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
     273static 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
     291int 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) {
    309365                int status, j;
    310366                pid_t pid;
     367
    311368                if (error_count != 0) {
    312369                        /* try and stop the test on any failure */
    313                         for (j=1;j<num_procs;j++) {
     370                        for (j=0;j<num_procs;j++) {
    314371                                if (pids[j] != 0) {
    315372                                        kill(pids[j], SIGTERM);
     
    317374                        }
    318375                }
    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
    320391                if (pid == -1) {
    321392                        perror("failed to wait for child\n");
    322393                        exit(1);
    323394                }
    324                 for (j=1;j<num_procs;j++) {
     395
     396                for (j=0;j<num_procs;j++) {
    325397                        if (pids[j] == pid) break;
    326398                }
     
    329401                        exit(1);
    330402                }
    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));
    334421                        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--;
    337432        }
    338433
    339434        free(pids);
    340435
     436done:
    341437        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);
    342448                printf("OK\n");
    343449        }
    344450
     451        free(test_tdb);
    345452        return error_count;
    346453}
Note: See TracChangeset for help on using the changeset viewer.