📄 locktest.c
字号:
return false; } } if (showall) { printf("reopen conn=%u f=%u\n", conn, f); } break; } return true;}static void close_files(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NSERVERS][NCONNECTIONS][NFILES]){ int server, conn, f; for (server=0;server<NSERVERS;server++) for (conn=0;conn<NCONNECTIONS;conn++) for (f=0;f<NFILES;f++) { if (fnum[server][conn][f] != -1) { smbcli_close(cli[server][conn]->tree, fnum[server][conn][f]); fnum[server][conn][f] = -1; } } for (server=0;server<NSERVERS;server++) { smbcli_unlink(cli[server][0]->tree, FILENAME); }}static void open_files(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NSERVERS][NCONNECTIONS][NFILES]){ int server, conn, f; for (server=0;server<NSERVERS;server++) for (conn=0;conn<NCONNECTIONS;conn++) for (f=0;f<NFILES;f++) { fnum[server][conn][f] = smbcli_open(cli[server][conn]->tree, FILENAME, O_RDWR|O_CREAT, DENY_NONE); if (fnum[server][conn][f] == -1) { fprintf(stderr,"Failed to open fnum[%u][%u][%u]\n", server, conn, f); exit(1); } }}static int retest(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NSERVERS][NCONNECTIONS][NFILES], int n){ int i; printf("testing %u ...\n", n); for (i=0; i<n; i++) { if (i && i % 100 == 0) { printf("%u\n", i); } if (recorded[i].needed && !test_one(cli, fnum, &recorded[i])) return i; } return n;}/* each server has two connections open to it. Each connection has two file descriptors open on the file - 8 file descriptors in total we then do random locking ops in tamdem on the 4 fnums from each server and ensure that the results match */static int test_locks(struct event_context *ev, struct loadparm_context *lp_ctx, char *share[NSERVERS]){ struct smbcli_state *cli[NSERVERS][NCONNECTIONS]; int fnum[NSERVERS][NCONNECTIONS][NFILES]; int n, i, n1, skip, r1, r2; ZERO_STRUCT(fnum); ZERO_STRUCT(cli); recorded = malloc_array_p(struct record, numops); for (n=0; n<numops; n++) {#if PRESETS if (n < sizeof(preset) / sizeof(preset[0])) { recorded[n] = preset[n]; } else {#endif recorded[n].conn = random() % NCONNECTIONS; recorded[n].f = random() % NFILES; recorded[n].start = lock_base + ((uint_t)random() % (lock_range-1)); recorded[n].len = min_length + random() % (lock_range-(recorded[n].start-lock_base)); recorded[n].start *= RANGE_MULTIPLE; recorded[n].len *= RANGE_MULTIPLE; recorded[n].pid = random()%3; if (recorded[n].pid == 2) { recorded[n].pid = 0xFFFF; /* see if its magic */ } r1 = random() % 100; r2 = random() % 100; if (r1 < READ_PCT) { recorded[n].lock_type = READ_LOCK; } else { recorded[n].lock_type = WRITE_LOCK; } if (r2 < LOCK_PCT) { recorded[n].lock_op = OP_LOCK; } else if (r2 < UNLOCK_PCT) { recorded[n].lock_op = OP_UNLOCK; } else { recorded[n].lock_op = OP_REOPEN; } recorded[n].needed = true; if (!zero_zero && recorded[n].start==0 && recorded[n].len==0) { recorded[n].len = 1; }#if PRESETS }#endif } reconnect(ev, lp_ctx, cli, fnum, share); open_files(cli, fnum); n = retest(cli, fnum, numops); if (n == numops || !analyze) { if (n != numops) { return 1; } return 0; } n++; skip = n/2; while (1) { n1 = n; close_files(cli, fnum); reconnect(ev, lp_ctx, cli, fnum, share); open_files(cli, fnum); for (i=0;i<n-skip;i+=skip) { int m, j; printf("excluding %d-%d\n", i, i+skip-1); for (j=i;j<i+skip;j++) { recorded[j].needed = false; } close_files(cli, fnum); open_files(cli, fnum); m = retest(cli, fnum, n); if (m == n) { for (j=i;j<i+skip;j++) { recorded[j].needed = true; } } else { if (i+(skip-1) < m) { memmove(&recorded[i], &recorded[i+skip], (m-(i+skip-1))*sizeof(recorded[0])); } n = m-(skip-1); i--; } } if (skip > 1) { skip = skip/2; printf("skip=%d\n", skip); continue; } if (n1 == n) break; } close_files(cli, fnum); reconnect(ev, lp_ctx, cli, fnum, share); open_files(cli, fnum); showall = true; n1 = retest(cli, fnum, n); if (n1 != n-1) { printf("ERROR - inconsistent result (%u %u)\n", n1, n); } close_files(cli, fnum); for (i=0;i<n;i++) { printf("{%d, %d, %u, %u, %.0f, %.0f, %u},\n", recorded[i].lock_op, recorded[i].lock_type, recorded[i].conn, recorded[i].f, (double)recorded[i].start, (double)recorded[i].len, recorded[i].needed); } return 1;}static void usage(poptContext pc){ printf("Usage:\n\tlocktest //server1/share1 //server2/share2 [options..]\n"); poptPrintUsage(pc, stdout, 0);}/**************************************************************************** main program****************************************************************************/ int main(int argc,char *argv[]){ char *share[NSERVERS]; int opt; int seed, server; int username_count=0; struct event_context *ev; struct loadparm_context *lp_ctx; poptContext pc; int argc_new, i; char **argv_new; enum {OPT_UNCLIST=1000}; struct poptOption long_options[] = { POPT_AUTOHELP {"seed", 0, POPT_ARG_INT, &seed, 0, "Seed to use for randomizer", NULL}, {"num-ops", 0, POPT_ARG_INT, &numops, 0, "num ops", NULL}, {"lockrange", 0, POPT_ARG_INT, &lock_range,0, "locking range", NULL}, {"lockbase", 0, POPT_ARG_INT, &lock_base, 0, "locking base", NULL}, {"minlength", 0, POPT_ARG_INT, &min_length,0, "min lock length", NULL}, {"hidefails", 0, POPT_ARG_NONE, &hide_unlock_fails,0,"hide unlock fails", NULL}, {"oplocks", 0, POPT_ARG_NONE, &use_oplocks,0, "use oplocks", NULL}, {"showall", 0, POPT_ARG_NONE, &showall, 0, "display all operations", NULL}, {"analyse", 0, POPT_ARG_NONE, &analyze, 0, "do backtrack analysis", NULL}, {"zerozero", 0, POPT_ARG_NONE, &zero_zero, 0, "do zero/zero lock", NULL}, {"exacterrors", 0, POPT_ARG_NONE, &exact_error_codes,0,"use exact error codes", NULL}, {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL}, { "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "[DOMAIN/]USERNAME[%PASSWORD]" }, POPT_COMMON_SAMBA POPT_COMMON_CONNECTION POPT_COMMON_CREDENTIALS POPT_COMMON_VERSION { NULL } }; setlinebuf(stdout); seed = time(NULL); pc = poptGetContext("locktest", argc, (const char **) argv, long_options, POPT_CONTEXT_KEEP_FIRST); poptSetOtherOptionHelp(pc, "<unc1> <unc2>"); lp_ctx = cmdline_lp_ctx; servers[0] = cli_credentials_init(talloc_autofree_context()); servers[1] = cli_credentials_init(talloc_autofree_context()); cli_credentials_guess(servers[0], lp_ctx); cli_credentials_guess(servers[1], lp_ctx); while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_UNCLIST: lp_set_cmdline(cmdline_lp_ctx, "torture:unclist", poptGetOptArg(pc)); break; case 'U': if (username_count == 2) { usage(pc); exit(1); } cli_credentials_parse_string(servers[username_count], poptGetOptArg(pc), CRED_SPECIFIED); username_count++; break; } } argv_new = discard_const_p(char *, poptGetArgs(pc)); argc_new = argc; for (i=0; i<argc; i++) { if (argv_new[i] == NULL) { argc_new = i; break; } } if (!(argc_new >= 3)) { usage(pc); exit(1); } setup_logging("locktest", DEBUG_STDOUT); for (server=0;server<NSERVERS;server++) { share[server] = argv_new[1+server]; all_string_sub(share[server],"/","\\",0); } lp_ctx = cmdline_lp_ctx; if (username_count == 0) { usage(pc); return -1; } if (username_count == 1) { servers[1] = servers[0]; } ev = event_context_init(talloc_autofree_context()); gensec_init(lp_ctx); DEBUG(0,("seed=%u base=%d range=%d min_length=%d\n", seed, lock_base, lock_range, min_length)); srandom(seed); return test_locks(ev, lp_ctx, share);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -