static void wt_open_corrupt(const char *sfx) { WT_CONNECTION *conn; int ret; char buf[1024]; #ifdef HAVE_ATTACH WT_UNUSED(buf); WT_UNUSED(conn); WT_UNUSED(ret); WT_UNUSED(sfx); #else conn = NULL; if (sfx != NULL) testutil_check(__wt_snprintf(buf, sizeof(buf), "%s.%s", home, sfx)); else testutil_check(__wt_snprintf(buf, sizeof(buf), "%s", home)); ret = wiredtiger_open(buf, &event_handler, NULL, &conn); /* * Not all out of sync combinations lead to corruption. We keep * the previous checkpoint in the file so some combinations of * future or old turtle files and metadata files will succeed. */ if (ret != WT_TRY_SALVAGE && ret != 0) fprintf(stderr, "OPEN_CORRUPT: wiredtiger_open returned %d\n", ret); testutil_assert(ret == WT_TRY_SALVAGE || ret == 0); #endif exit (EXIT_SUCCESS); }
/* * copy_database -- * Copy the database to the specified suffix. In addition, make a copy * of the metadata and turtle files in that new directory. */ static void copy_database(const char *sfx) { WT_DECL_RET; char buf[1024]; testutil_check(__wt_snprintf(buf, sizeof(buf), "rm -rf ./%s.%s; mkdir ./%s.%s; " "cp -p %s/* ./%s.%s", home, sfx, home, sfx, home, home, sfx)); printf("copy: %s\n", buf); if ((ret = system(buf)) < 0) testutil_die(ret, "system: %s", buf); /* * Now, in the copied directory make a save copy of the * metadata and turtle files to move around and restore * as needed during testing. */ testutil_check(__wt_snprintf(buf, sizeof(buf), "cp -p %s.%s/%s %s.%s/%s.%s", home, sfx, WT_METADATA_TURTLE, home, sfx, WT_METADATA_TURTLE, SAVE)); if ((ret = system(buf)) < 0) testutil_die(ret, "system: %s", buf); testutil_check(__wt_snprintf(buf, sizeof(buf), "cp -p %s.%s/%s %s.%s/%s.%s", home, sfx, WT_METAFILE, home, sfx, WT_METAFILE, SAVE)); if ((ret = system(buf)) < 0) testutil_die(ret, "system: %s", buf); }
void wts_rebalance(void) { WT_CONNECTION *conn; WT_SESSION *session; char cmd[1024]; if (g.c_rebalance == 0) return; track("rebalance", 0ULL, NULL); /* Dump the current object. */ testutil_check(__wt_snprintf(cmd, sizeof(cmd), ".." DIR_DELIM_STR ".." DIR_DELIM_STR "wt" " -h %s dump -f %s/rebalance.orig %s", g.home, g.home, g.uri)); testutil_checkfmt(system(cmd), "command failed: %s", cmd); /* Rebalance, then verify the object. */ wts_reopen(); conn = g.wts_conn; testutil_check(conn->open_session(conn, NULL, NULL, &session)); if (g.logging != 0) (void)g.wt_api->msg_printf(g.wt_api, session, "=============== rebalance start ==============="); testutil_checkfmt( session->rebalance(session, g.uri, NULL), "%s", g.uri); if (g.logging != 0) (void)g.wt_api->msg_printf(g.wt_api, session, "=============== rebalance stop ==============="); testutil_check(session->close(session, NULL)); wts_verify("post-rebalance verify"); wts_close(); testutil_check(__wt_snprintf(cmd, sizeof(cmd), ".." DIR_DELIM_STR ".." DIR_DELIM_STR "wt" " -h %s dump -f %s/rebalance.new %s", g.home, g.home, g.uri)); testutil_checkfmt(system(cmd), "command failed: %s", cmd); /* Compare the old/new versions of the object. */ #ifdef _WIN32 testutil_check(__wt_snprintf(cmd, sizeof(cmd), "fc /b %s\\rebalance.orig %s\\rebalance.new > NUL", g.home, g.home)); #else testutil_check(__wt_snprintf(cmd, sizeof(cmd), "cmp %s/rebalance.orig %s/rebalance.new > /dev/null", g.home, g.home)); #endif testutil_checkfmt(system(cmd), "command failed: %s", cmd); }
/* * subtest_main -- * The main program for the subtest */ static void subtest_main(int argc, char *argv[], bool close_test) { struct rlimit rlim; TEST_OPTS *opts, _opts; WT_SESSION *session; char config[1024], filename[1024]; opts = &_opts; memset(opts, 0, sizeof(*opts)); memset(&rlim, 0, sizeof(rlim)); /* No core files during fault injection tests. */ testutil_check(setrlimit(RLIMIT_CORE, &rlim)); testutil_check(testutil_parse_opts(argc, argv, opts)); testutil_make_work_dir(opts->home); /* Redirect stderr, stdout. */ testutil_check(__wt_snprintf( filename, sizeof(filename), "%s/%s", opts->home, STDERR_FILE)); testutil_assert(freopen(filename, "a", stderr) != NULL); testutil_check(__wt_snprintf( filename, sizeof(filename), "%s/%s", opts->home, STDOUT_FILE)); testutil_assert(freopen(filename, "a", stdout) != NULL); testutil_check(__wt_snprintf(config, sizeof(config), "create,cache_size=250M,log=(enabled)," "transaction_sync=(enabled,method=none),extensions=(" WT_FAIL_FS_LIB "=(early_load,config={environment=true,verbose=true})]")); testutil_check( wiredtiger_open(opts->home, &event_handler, config, &opts->conn)); testutil_check( opts->conn->open_session(opts->conn, NULL, NULL, &session)); testutil_check(session->create(session, "table:subtest", "key_format=i,value_format=iiiS," "columns=(id,v0,v1,v2,big)")); testutil_check(session->create(session, "table:subtest2", "key_format=i,value_format=i")); testutil_check(session->create(session, "index:subtest:v0", "columns=(v0)")); testutil_check(session->create(session, "index:subtest:v1", "columns=(v1)")); testutil_check(session->create(session, "index:subtest:v2", "columns=(v2)")); testutil_check(session->close(session, NULL)); subtest_populate(opts, close_test); testutil_cleanup(opts); }
/* * enable_failures -- * Enable failures in the fail file system. */ static void enable_failures(uint64_t allow_writes, uint64_t allow_reads) { char value[100]; testutil_check(setenv("WT_FAIL_FS_ENABLE", "1", 1)); testutil_check(__wt_snprintf( value, sizeof(value), "%" PRIu64, allow_writes)); testutil_check(setenv("WT_FAIL_FS_WRITE_ALLOW", value, 1)); testutil_check(__wt_snprintf( value, sizeof(value), "%" PRIu64, allow_reads)); testutil_check(setenv("WT_FAIL_FS_READ_ALLOW", value, 1)); }
/* * __bloom_init -- * Allocate a WT_BLOOM handle. */ static int __bloom_init(WT_SESSION_IMPL *session, const char *uri, const char *config, WT_BLOOM **bloomp) { WT_BLOOM *bloom; WT_DECL_RET; size_t len; *bloomp = NULL; WT_RET(__wt_calloc_one(session, &bloom)); WT_ERR(__wt_strdup(session, uri, &bloom->uri)); len = strlen(WT_BLOOM_TABLE_CONFIG) + 2; if (config != NULL) len += strlen(config); WT_ERR(__wt_calloc_def(session, len, &bloom->config)); /* Add the standard config at the end, so it overrides user settings. */ WT_ERR(__wt_snprintf(bloom->config, len, "%s,%s", config == NULL ? "" : config, WT_BLOOM_TABLE_CONFIG)); bloom->session = session; *bloomp = bloom; return (0); err: __wt_free(session, bloom->uri); __wt_free(session, bloom->config); __wt_free(session, bloom->bitstring); __wt_free(session, bloom); return (ret); }
/* * __wt_thread_str -- * Fill in a printable version of the process and thread IDs. */ int __wt_thread_str(char *buf, size_t buflen) { return (__wt_snprintf(buf, buflen, "%" PRIu64 ":%" PRIu64, (uint64_t)GetCurrentProcessId(), (uint64_t)GetCurrentThreadId)); }
void setup(void) { WT_CONNECTION *conn; WT_SESSION *session; int ret; char config[512]; if ((ret = system("rm -f WiredTiger* *.bf")) != 0) testutil_die(ret, "system cleanup call failed"); /* * This test doesn't test public Wired Tiger functionality, it still * needs connection and session handles. */ /* * Open configuration -- put command line configuration options at the * end so they can override "standard" configuration. */ testutil_check(__wt_snprintf(config, sizeof(config), "create,error_prefix=\"%s\",cache_size=%" PRIu32 "MB,%s", progname, g.c_cache, g.config_open == NULL ? "" : g.config_open)); testutil_check(wiredtiger_open(NULL, NULL, config, &conn)); testutil_check(conn->open_session(conn, NULL, NULL, &session)); g.wt_conn = conn; g.wt_session = session; populate_entries(); }
void obj_create_unique(int force) { WT_SESSION *session; int ret; char new_uri[64]; if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) testutil_die(ret, "conn.session"); /* Generate a unique object name. */ if ((ret = pthread_rwlock_wrlock(&single)) != 0) testutil_die(ret, "pthread_rwlock_wrlock single"); testutil_check(__wt_snprintf( new_uri, sizeof(new_uri), "%s.%u", uri, ++uid)); if ((ret = pthread_rwlock_unlock(&single)) != 0) testutil_die(ret, "pthread_rwlock_unlock single"); if ((ret = session->create(session, new_uri, config)) != 0) testutil_die(ret, "session.create"); __wt_yield(); while ((ret = session->drop( session, new_uri, force ? "force" : NULL)) != 0) if (ret != EBUSY) testutil_die(ret, "session.drop: %s", new_uri); if ((ret = session->close(session, NULL)) != 0) testutil_die(ret, "session.close"); }
/* * __wt_strerror -- * WT_SESSION.strerror and wiredtiger_strerror. */ const char * __wt_strerror(WT_SESSION_IMPL *session, int error, char *errbuf, size_t errlen) { const char *p; /* * Check for a WiredTiger or POSIX constant string, no buffer needed. */ if ((p = __wt_wiredtiger_error(error)) != NULL) return (p); /* * When called from wiredtiger_strerror, write a passed-in buffer. * When called from WT_SESSION.strerror, write the session's buffer. * * Fallback to a generic message. */ if (session == NULL && __wt_snprintf(errbuf, errlen, "error return: %d", error) == 0) return (errbuf); if (session != NULL && __wt_buf_fmt( session, &session->err, "error return: %d", error) == 0) return (session->err.data); /* Defeated. */ return ("Unable to return error string"); }
int util_downgrade(WT_SESSION *session, WT_CONNECTION *conn, int argc, char *argv[]) { WT_DECL_RET; int ch; char config_str[128], *release; release = NULL; while ((ch = __wt_getopt(progname, argc, argv, "V:")) != EOF) switch (ch) { case 'V': release = __wt_optarg; break; case '?': default: return (usage()); } argc -= __wt_optind; /* * The release argument is required. * There should not be any more arguments. */ if (argc != 0 || release == NULL) return (usage()); if ((ret = __wt_snprintf(config_str, sizeof(config_str), "compatibility=(release=%s)", release)) != 0) return (util_err(session, ret, NULL)); if ((ret = conn->reconfigure(conn, config_str)) != 0) return (util_err(session, ret, "conn.downgrade")); return (0); }
static void open_normal(const char *sfx, TABLE_INFO *table_data) { WT_CONNECTION *conn; char buf[1024]; printf("=== wt_open normal ===\n"); if (sfx != NULL) testutil_check(__wt_snprintf(buf, sizeof(buf), "%s.%s", home, sfx)); else testutil_check(__wt_snprintf(buf, sizeof(buf), "%s", home)); testutil_check(wiredtiger_open(buf, &event_handler, NULL, &conn)); verify_metadata(conn, &table_data[0]); testutil_check(conn->close(conn, NULL)); }
static void file_create(SHARED_CONFIG *cfg, const char *name) { WT_CONNECTION *conn; WT_SESSION *session; int ret; char config[128]; conn = cfg->conn; testutil_check(conn->open_session(conn, NULL, NULL, &session)); testutil_check(__wt_snprintf(config, sizeof(config), "key_format=%s," "internal_page_max=%d," "split_deepen_min_child=200," "leaf_page_max=%d," "%s", cfg->ftype == ROW ? "S" : "r", 16 * 1024, 128 * 1024, cfg->ftype == FIX ? ",value_format=3t" : "")); if ((ret = session->create(session, name, config)) != 0) if (ret != EEXIST) testutil_die(ret, "session.create"); testutil_check(session->close(session, NULL)); }
static void page_init(uint64_t n) { WT_CONNECTION *conn; WT_CURSOR *cursor; WT_SESSION *session; uint64_t recno, vrecno; char buf[64]; conn = opts->conn; testutil_check(conn->open_session(conn, NULL, NULL, &session)); testutil_check( session->open_cursor(session, opts->uri, NULL, "append", &cursor)); vrecno = 0; buf[0] = '\2'; for (recno = 1;; ++recno) { if (opts->table_type == TABLE_FIX) cursor->set_value(cursor, buf[0]); else { if (recno % 3 == 0) ++vrecno; testutil_check(__wt_snprintf(buf, sizeof(buf), "%" PRIu64 " VALUE ------", vrecno)); cursor->set_value(cursor, buf); } testutil_check(cursor->insert(cursor)); testutil_check(cursor->get_key(cursor, &opts->max_inserted_id)); if (opts->max_inserted_id >= n) break; } }
/* * __wt_nfilename -- * Build a file name in a scratch buffer. If the name is already an * absolute path duplicate it, otherwise generate a path relative to the * connection home directory. */ int __wt_nfilename( WT_SESSION_IMPL *session, const char *name, size_t namelen, char **path) { WT_DECL_RET; size_t len; char *buf; *path = NULL; /* * Needs to work with a NULL session handle - since this is called via * the exists API which is used by the test utilities. */ if (session == NULL || __wt_absolute_path(name)) return (__wt_strndup(session, name, namelen, path)); len = strlen(S2C(session)->home) + 1 + namelen + 1; WT_RET(__wt_calloc(session, 1, len, &buf)); WT_ERR(__wt_snprintf(buf, len, "%s%s%.*s", S2C(session)->home, __wt_path_separator(), (int)namelen, name)); *path = buf; return (0); err: __wt_free(session, buf); return (ret); }
/* * cursor_insert -- * Insert some data into a table. */ static void cursor_insert(const char *uri, uint64_t i) { WT_CURSOR *cursor; WT_ITEM vu; char keybuf[100], valuebuf[100]; bool recno; memset(&vu, 0, sizeof(vu)); /* Open a cursor. */ testutil_check(wt_session->open_cursor( wt_session, uri, NULL, NULL, &cursor)); /* Operations change based on the key/value formats. */ recno = strcmp(cursor->key_format, "r") == 0; if (recno) cursor->set_key(cursor, i); else { testutil_check(__wt_snprintf(keybuf, sizeof(keybuf), "%s-%" PRIu64, KEY, i)); cursor->set_key(cursor, keybuf); } strcpy(valuebuf, VALUE); cursor->set_value(cursor, valuebuf); testutil_check(cursor->insert(cursor)); testutil_check(cursor->close(cursor)); }
/* Setup the logging output mechanism. */ int setup_log_file(WTPERF *wtperf) { CONFIG_OPTS *opts; size_t len; int ret; char *fname; opts = wtperf->opts; ret = 0; if (opts->verbose < 1) return (0); len = strlen(wtperf->monitor_dir) + strlen(opts->table_name) + strlen(".stat") + 2; fname = dmalloc(len); testutil_check(__wt_snprintf(fname, len, "%s/%s.stat", wtperf->monitor_dir, opts->table_name)); if ((wtperf->logf = fopen(fname, "w")) == NULL) { ret = errno; fprintf(stderr, "%s: %s\n", fname, strerror(ret)); } free(fname); if (wtperf->logf == NULL) return (ret); /* Use line buffering for the log file. */ __wt_stream_set_line_buffer(wtperf->logf); return (0); }
/* * run_check_subtest -- * Run the subtest with the given parameters and check the results. */ static void run_check_subtest(TEST_OPTS *opts, const char *debugger, uint64_t nops, bool close_test, uint64_t *nresultsp) { int estatus, narg; char rarg[20], sarg[20], *subtest_args[MAX_ARGS]; narg = 0; if (debugger != NULL) { subtest_args[narg++] = (char *)debugger; subtest_args[narg++] = (char *)"--"; } subtest_args[narg++] = (char *)opts->progname; /* "subtest" must appear before arguments */ if (close_test) subtest_args[narg++] = (char *)"subtest_close"; else subtest_args[narg++] = (char *)"subtest"; subtest_args[narg++] = (char *)"-h"; subtest_args[narg++] = opts->home; subtest_args[narg++] = (char *)"-v"; /* subtest is always verbose */ subtest_args[narg++] = (char *)"-p"; subtest_args[narg++] = (char *)"-o"; testutil_check(__wt_snprintf(sarg, sizeof(sarg), "%" PRIu64, nops)); subtest_args[narg++] = sarg; /* number of operations */ subtest_args[narg++] = (char *)"-n"; testutil_check(__wt_snprintf( rarg, sizeof(rarg), "%" PRIu64, opts->nrecords)); subtest_args[narg++] = rarg; /* number of records */ subtest_args[narg++] = NULL; testutil_assert(narg <= MAX_ARGS); if (opts->verbose) printf("running a separate process with %" PRIu64 " operations until fail...\n", nops); testutil_clean_work_dir(opts->home); testutil_check(run_process( opts, debugger != NULL ? debugger : opts->progname, subtest_args, &estatus)); if (opts->verbose) printf("process exited %d\n", estatus); /* * Verify results in parent process. */ testutil_check(check_results(opts, nresultsp)); }
static void run(bool config_cache) { pthread_t idlist[1000]; u_int i, j; char buf[256], home[256]; done = false; testutil_work_dir_from_path( home, sizeof(home), "WT_TEST.wt4333_handle_locks"); testutil_make_work_dir(home); testutil_check(__wt_snprintf(buf, sizeof(buf), "create" ", cache_cursors=%s" ", cache_size=5GB" ", checkpoint_sync=true" ", eviction=(threads_max=5)" ", file_manager=(" "close_handle_minimum=1,close_idle_time=1,close_scan_interval=1)" ", mmap=true" ", session_max=%u" ", statistics=(all)", config_cache ? "true" : "false", workers + 100)); testutil_check(wiredtiger_open(home, NULL, buf, &conn)); printf("%s: %d seconds, cache_cursors=%s, %u workers, %u files\n", progname, PERIOD, config_cache ? "true" : "false", workers, uris); uri_init(); /* 75% readers, 25% writers. */ for (i = 0; i < workers; ++i) testutil_check(pthread_create(&idlist[i], NULL, wthread, NULL)); testutil_check(pthread_create(&idlist[i], NULL, vthread, NULL)); ++i; (void)alarm(PERIOD); for (j = 0; j < i; ++j) testutil_check(pthread_join(idlist[j], NULL)); printf( "\t" "worker %" PRIu64 ", worker_busy %" PRIu64 ", verify %" PRIu64 ", verify_busy %" PRIu64 "\n", worker, worker_busy, verify, verify_busy); if (verbose) sweep_stats(); testutil_check(conn->close(conn, NULL)); }
/* * start_workers -- * Setup the configuration for the tables being populated, then start * the worker thread(s) and wait for them to finish. */ int start_workers(table_type type) { struct timeval start, stop; WT_SESSION *session; wt_thread_t *tids; double seconds; int i, ret; ret = 0; /* Create statistics and thread structures. */ if ((tids = calloc((size_t)(g.nworkers), sizeof(*tids))) == NULL) return (log_print_err("calloc", errno, 1)); if ((ret = g.conn->open_session(g.conn, NULL, NULL, &session)) != 0) { (void)log_print_err("conn.open_session", ret, 1); goto err; } /* Setup the cookies */ for (i = 0; i < g.ntables; ++i) { g.cookies[i].id = i; if (type == MIX) g.cookies[i].type = (table_type)((i % MAX_TABLE_TYPE) + 1); else g.cookies[i].type = type; testutil_check(__wt_snprintf( g.cookies[i].uri, sizeof(g.cookies[i].uri), "%s%04d", URI_BASE, g.cookies[i].id)); /* Should probably be atomic to avoid races. */ if ((ret = create_table(session, &g.cookies[i])) != 0) goto err; } (void)gettimeofday(&start, NULL); /* Create threads. */ for (i = 0; i < g.nworkers; ++i) testutil_check(__wt_thread_create( NULL, &tids[i], worker, &g.cookies[i])); /* Wait for the threads. */ for (i = 0; i < g.nworkers; ++i) testutil_check(__wt_thread_join(NULL, tids[i])); (void)gettimeofday(&stop, NULL); seconds = (stop.tv_sec - start.tv_sec) + (stop.tv_usec - start.tv_usec) * 1e-6; printf("Ran workers for: %f seconds\n", seconds); err: free(tids); return (ret); }
/* * __wt_debug_set_verbose -- * Set verbose flags from the debugger. */ int __wt_debug_set_verbose(WT_SESSION_IMPL *session, const char *v) { char buf[256]; const char *cfg[2] = { NULL, NULL }; WT_RET(__wt_snprintf(buf, sizeof(buf), "verbose=[%s]", v)); cfg[0] = buf; return (__wt_verbose_config(session, cfg)); }
static void op(WT_SESSION *session, WT_RAND_STATE *rnd, WT_CURSOR **cpp) { WT_CURSOR *cursor; WT_DECL_RET; u_int i, key; char buf[128]; bool readonly; /* Close any open cursor in the slot we're about to reuse. */ if (*cpp != NULL) { testutil_check((*cpp)->close(*cpp)); *cpp = NULL; } cursor = NULL; readonly = __wt_random(rnd) % 2 == 0; /* Loop to open an object handle. */ for (i = __wt_random(rnd) % uris; !done; __wt_yield()) { /* Use a checkpoint handle for 50% of reads. */ ret = session->open_cursor(session, uri_list[i], NULL, readonly && (i % 2 == 0) ? "checkpoint=WiredTigerCheckpoint" : NULL, &cursor); if (ret != EBUSY) { testutil_check(ret); break; } (void)__wt_atomic_add64(&worker_busy, 1); } if (cursor == NULL) return; /* Operate on some number of key/value pairs. */ for (key = 1; !done && key < MAXKEY; key += __wt_random(rnd) % 37, __wt_yield()) { testutil_check( __wt_snprintf(buf, sizeof(buf), "key:%020u", key)); cursor->set_key(cursor, buf); if (readonly) testutil_check(cursor->search(cursor)); else { cursor->set_value(cursor, buf); testutil_check(cursor->insert(cursor)); } } /* Close the cursor half the time, otherwise cache it. */ if (__wt_random(rnd) % 2 == 0) testutil_check(cursor->close(cursor)); else *cpp = cursor; (void)__wt_atomic_add64(&worker, 1); }
/* * __curjoin_open_main -- * For the given index, open the main file with a projection * that is the index keys. */ static int __curjoin_open_main(WT_SESSION_IMPL *session, WT_CURSOR_JOIN *cjoin, WT_CURSOR_JOIN_ENTRY *entry) { WT_DECL_RET; WT_INDEX *idx; size_t len, newsize; char *main_uri, *newformat; const char *raw_cfg[] = { WT_CONFIG_BASE( session, WT_SESSION_open_cursor), "raw", NULL }; main_uri = newformat = NULL; idx = entry->index; newsize = strlen(cjoin->table->iface.name) + idx->colconf.len + 1; WT_ERR(__wt_calloc(session, 1, newsize, &main_uri)); WT_ERR(__wt_snprintf(main_uri, newsize, "%s%.*s", cjoin->table->iface.name, (int)idx->colconf.len, idx->colconf.str)); WT_ERR(__wt_open_cursor(session, main_uri, (WT_CURSOR *)cjoin, raw_cfg, &entry->main)); if (idx->extractor == NULL) { /* * Add no-op padding so trailing 'u' formats are not * transformed to 'U'. This matches what happens in * the index. We don't do this when we have an * extractor, extractors already use the padding * byte trick. */ len = strlen(entry->main->value_format) + 3; WT_ERR(__wt_calloc(session, len, 1, &newformat)); WT_ERR(__wt_snprintf( newformat, len, "%s0x", entry->main->value_format)); __wt_free(session, entry->main->value_format); entry->main->value_format = newformat; newformat = NULL; } err: __wt_free(session, main_uri); __wt_free(session, newformat); return (ret); }
static void setup_database(const char *src, const char *turtle_dir, const char *meta_dir) { int ret; char buf[1024]; /* * Remove the test home directory and copy the source to it. * Then copy the saved turtle and/or metadata file from the * given args. */ testutil_check(__wt_snprintf(buf, sizeof(buf), "rm -rf ./%s.%s; mkdir ./%s.%s; " "cp -p %s.%s/* ./%s.%s", home, TEST, home, TEST, home, src, home, TEST)); printf("copy: %s\n", buf); if ((ret = system(buf)) < 0) testutil_die(ret, "system: %s", buf); /* Copy turtle if given. */ if (turtle_dir != NULL) { testutil_check(__wt_snprintf(buf, sizeof(buf), "cp -p %s.%s/%s.%s %s.%s/%s", home, turtle_dir, WT_METADATA_TURTLE, SAVE, home, TEST, WT_METADATA_TURTLE)); printf("copy: %s\n", buf); if ((ret = system(buf)) < 0) testutil_die(ret, "system: %s", buf); } /* Copy metadata if given. */ if (meta_dir != NULL) { testutil_check(__wt_snprintf(buf, sizeof(buf), "cp -p %s.%s/%s.%s %s.%s/%s", home, meta_dir, WT_METAFILE, SAVE, home, TEST, WT_METAFILE)); printf("copy: %s\n", buf); if ((ret = system(buf)) < 0) testutil_die(ret, "system: %s", buf); } }
static void uri_init(void) { WT_CURSOR *cursor; WT_SESSION *session; u_int i, key; char buf[128]; for (i = 0; i < uris; ++i) if (uri_list[i] == NULL) { testutil_check( __wt_snprintf(buf, sizeof(buf), "table:%u", i)); uri_list[i] = dstrdup(buf); } testutil_check(conn->open_session(conn, NULL, NULL, &session)); /* Initialize the file contents. */ for (i = 0; i < uris; ++i) { testutil_check(__wt_snprintf(buf, sizeof(buf), "key_format=S,value_format=S," "allocation_size=4K,leaf_page_max=32KB,")); testutil_check(session->create(session, uri_list[i], buf)); testutil_check(session->open_cursor( session, uri_list[i], NULL, NULL, &cursor)); for (key = 1; key < MAXKEY; ++key) { testutil_check(__wt_snprintf( buf, sizeof(buf), "key:%020u", key)); cursor->set_key(cursor, buf); cursor->set_value(cursor, buf); testutil_check(cursor->insert(cursor)); } testutil_check(cursor->close(cursor)); } /* Create a checkpoint we can use for readonly handles. */ testutil_check(session->checkpoint(session, NULL)); testutil_check(session->close(session, NULL)); }
/* * Create a guaranteed unique table and open and close a bulk cursor on it. */ void op_bulk_unique(void *arg) { TEST_OPTS *opts; TEST_PER_THREAD_OPTS *args; WT_CURSOR *c; WT_RAND_STATE rnd; WT_SESSION *session; int ret; char new_uri[64]; args = (TEST_PER_THREAD_OPTS *)arg; opts = args->testopts; __wt_random_init_seed(NULL, &rnd); testutil_check( opts->conn->open_session(opts->conn, NULL, NULL, &session)); /* Generate a unique object name. */ testutil_check(__wt_snprintf( new_uri, sizeof(new_uri), "%s.%" PRIu64, opts->uri, __wt_atomic_add64(&opts->unique_id, 1))); testutil_check(session->create(session, new_uri, DEFAULT_TABLE_SCHEMA)); __wt_yield(); /* * Opening a bulk cursor may have raced with a forced checkpoint * which created a checkpoint of the empty file, and triggers an EINVAL. */ if ((ret = session->open_cursor( session, new_uri, NULL, "bulk,checkpoint_wait=false", &c)) == 0) { testutil_check(c->close(c)); } else if (ret != EINVAL && ret != EBUSY) testutil_die(ret, "session.open_cursor bulk unique: %s", new_uri); while ((ret = session->drop(session, new_uri, __wt_random(&rnd) & 1 ? "force,checkpoint_wait=false" : "checkpoint_wait=false")) != 0) if (ret != EBUSY) testutil_die(ret, "session.drop: %s", new_uri); else /* * The EBUSY is expected when we run with * checkpoint_wait set to false, so we increment the * counter while in this loop to avoid false positives. */ args->thread_counter++; testutil_check(session->close(session, NULL)); args->thread_counter++; }
static void open_with_salvage(const char *sfx, TABLE_INFO *table_data) { WT_CONNECTION *conn; char buf[1024]; printf("=== wt_open with salvage ===\n"); /* * Then call wiredtiger_open with the salvage configuration setting. * That should succeed. We should be able to then verify the contents * of the metadata file. */ test_abort = true; if (sfx != NULL) testutil_check(__wt_snprintf(buf, sizeof(buf), "%s.%s", home, sfx)); else testutil_check(__wt_snprintf(buf, sizeof(buf), "%s", home)); testutil_check(wiredtiger_open(buf, &event_handler, "salvage=true", &conn)); testutil_assert(conn != NULL); if (sfx != NULL) testutil_check(__wt_snprintf(buf, sizeof(buf), "%s.%s/%s", home, sfx, WT_METAFILE_SLVG)); else testutil_check(__wt_snprintf(buf, sizeof(buf), "%s/%s", home, WT_METAFILE_SLVG)); testutil_assert(file_exists(buf)); /* * Confirm we salvaged the metadata file by looking for the saved * copy of the original metadata. */ printf("verify with salvaged connection\n"); verify_metadata(conn, &table_data[0]); testutil_check(conn->close(conn, NULL)); }
/* * create_data -- * Create a table and insert a piece of data. */ static void create_data(TABLE_INFO *t) { size_t len; uint64_t i; char buf[APP_BUF_SIZE], cfg[APP_MD_SIZE]; memset(buf, 0, sizeof(buf)); memset(cfg, 0, sizeof(cfg)); /* * Create an app-specific metadata string that fills most of page * so that each table in the metadata has its own page. */ len = strlen(APP_STR); for (i = 0; i + len < APP_BUF_SIZE; i += len) testutil_check(__wt_snprintf( &buf[i], APP_BUF_SIZE - i, "%s", APP_STR)); testutil_check(__wt_snprintf(cfg, sizeof(cfg), "%s,app_metadata=\"%s\"", t->kvformat, buf)); testutil_check(wt_session->create(wt_session, t->name, cfg)); data_val = 1; cursor_insert(t->name, data_val); }
/* * util_uri -- * Build a name. */ char * util_uri(WT_SESSION *session, const char *s, const char *type) { WT_DECL_RET; size_t len; char *name; if (WT_PREFIX_MATCH(s, "backup:") || WT_PREFIX_MATCH(s, "config:") || WT_PREFIX_MATCH(s, "statistics:")) { fprintf(stderr, "%s: %s: unsupported object type: %s\n", progname, command, s); return (NULL); } len = strlen(type) + strlen(s) + 2; if ((name = calloc(len, 1)) == NULL) { (void)util_err(session, errno, NULL); return (NULL); } /* * If the string has a URI prefix, use it verbatim, otherwise prepend * the default type for the operation. */ if (strchr(s, ':') != NULL) WT_ERR(__wt_snprintf(name, len, "%s", s)); else WT_ERR(__wt_snprintf(name, len, "%s:%s", type, s)); return (name); err: free(name); (void)util_err(session, ret, NULL); return (NULL); }
void load(SHARED_CONFIG *cfg, const char *name) { WT_CONNECTION *conn; WT_CURSOR *cursor; WT_ITEM *value, _value; WT_SESSION *session; size_t len; uint64_t keyno; char keybuf[64], valuebuf[64]; conn = cfg->conn; file_create(cfg, name); testutil_check(conn->open_session(conn, NULL, NULL, &session)); testutil_check( session->open_cursor(session, name, NULL, "bulk", &cursor)); value = &_value; for (keyno = 1; keyno <= cfg->nkeys; ++keyno) { if (cfg->ftype == ROW) { testutil_check(__wt_snprintf( keybuf, sizeof(keybuf), "%016" PRIu64, keyno)); cursor->set_key(cursor, keybuf); } else cursor->set_key(cursor, (uint32_t)keyno); value->data = valuebuf; if (cfg->ftype == FIX) cursor->set_value(cursor, 0x01); else { testutil_check(__wt_snprintf_len_set( valuebuf, sizeof(valuebuf), &len, "%37" PRIu64, keyno)); value->size = (uint32_t)len; cursor->set_value(cursor, value); } testutil_check(cursor->insert(cursor)); } /* Setup the starting key range for the workload phase. */ cfg->key_range = cfg->nkeys; testutil_check(cursor->close(cursor)); testutil_check(session->checkpoint(session, NULL)); testutil_check(session->close(session, NULL)); }