Commit 5b194861 authored by Bradley C. Kuszmaul's avatar Bradley C. Kuszmaul Committed by Yoni Fogel

Merge 1767 into main line (including 1768 and 1627 fixes) and delete 1767...

Merge 1767 into main line (including 1768 and 1627 fixes) and delete 1767 branch.  Fixes #1767.  Refs #1768, 1627.

git-svn-id: file:///svn/toku/tokudb@12140 c7de825b-a66e-492c-adef-691d508d4ae1
parent 9f98364e
......@@ -29,11 +29,10 @@ int cmp(DB *db, const DBT *dbt1, const DBT *dbt2) {
void test_db(void) {
DbEnv env(DB_CXX_NO_EXCEPTIONS);
env.open(NULL, DB_PRIVATE, 0666);
int r = env.open(NULL, DB_CREATE|DB_PRIVATE, 0666);
assert(r==0);
Db db(&env, 0);
int r;
r = db.set_bt_compare(cmp); assert(r == 0);
r = db.remove("DoesNotExist.db", NULL, 0); assert(r == ENOENT);
// The db is closed
......
......@@ -12,7 +12,7 @@ int cmp(DB *db, const DBT *dbt1, const DBT *dbt2) {
void test_db(void) {
DbEnv env(0);
env.open(NULL, DB_PRIVATE, 0666);
env.open(NULL, DB_CREATE|DB_PRIVATE, 0666);
Db db(&env, 0);
int r;
......
......@@ -327,7 +327,7 @@ enum brt_layout_version_e {
};
void toku_brtheader_free (struct brt_header *h);
int toku_brtheader_close (CACHEFILE cachefile, void *header_v, char **error_string);
int toku_brtheader_close (CACHEFILE cachefile, void *header_v, char **error_string, LSN);
int toku_brtheader_begin_checkpoint (CACHEFILE cachefile, LSN checkpoint_lsn, void *header_v);
int toku_brtheader_checkpoint (CACHEFILE cachefile, void *header_v);
int toku_brtheader_end_checkpoint (CACHEFILE cachefile, void *header_v);
......
......@@ -628,6 +628,7 @@ brtheader_copy_for_checkpoint(struct brt_header *h, LSN checkpoint_lsn) {
struct brt_header* XMALLOC(ch);
*ch = *h; //Do a shallow copy
ch->type = BRTHEADER_CHECKPOINT_INPROGRESS; //Different type
//printf("checkpoint_lsn=%" PRIu64 "\n", checkpoint_lsn.lsn);
ch->checkpoint_lsn = checkpoint_lsn;
ch->panic_string = NULL;
......@@ -2976,7 +2977,7 @@ int toku_brt_open(BRT t, const char *fname, const char *fname_in_env, int is_cre
BOOL did_create = FALSE;
r = brt_open_file(t, fname, is_create, &fd, &did_create);
if (r != 0) goto died00;
r=toku_cachetable_openfd(&t->cf, cachetable, fd, fname);
r=toku_cachetable_openfd(&t->cf, cachetable, fd, fname_in_env);
if (r != 0) goto died00;
if (did_create) {
mode_t mode = S_IRWXU|S_IRWXG|S_IRWXO;
......@@ -2989,7 +2990,7 @@ int toku_brt_open(BRT t, const char *fname, const char *fname_in_env, int is_cre
}
if (r!=0) {
died_after_open:
toku_cachefile_close(&t->cf, toku_txn_logger(txn), 0);
toku_cachefile_close(&t->cf, toku_txn_logger(txn), 0, ZERO_LSN);
goto died00;
}
assert(t->nodesize>0);
......@@ -3198,7 +3199,7 @@ toku_brtheader_end_checkpoint (CACHEFILE cachefile, void *header_v) {
}
int
toku_brtheader_close (CACHEFILE cachefile, void *header_v, char **malloced_error_string)
toku_brtheader_close (CACHEFILE cachefile, void *header_v, char **malloced_error_string, LSN lsn)
{
struct brt_header *h = header_v;
assert(h->type == BRTHEADER_CURRENT);
......@@ -3208,9 +3209,9 @@ toku_brtheader_close (CACHEFILE cachefile, void *header_v, char **malloced_error
toku_brtheader_unlock(h);
int r = 0;
if (h->dirty) { // this is the only place this bit is tested (in currentheader)
//TODO: #1627 put meaningful LSN in for begin_checkpoint
int r2;
r2 = toku_brtheader_begin_checkpoint(cachefile, ZERO_LSN, header_v);
//assert(lsn.lsn!=0);
r2 = toku_brtheader_begin_checkpoint(cachefile, lsn, header_v);
if (r==0) r = r2;
r2 = toku_brtheader_checkpoint(cachefile, h);
if (r==0) r = r2;
......@@ -3283,10 +3284,10 @@ int toku_close_brt (BRT brt, TOKULOGGER logger, char **error_string) {
brtheader_note_brt_close(brt);
if (brt->cf) {
LSN lsn = ZERO_LSN; // if there is no logger, we use zero for the lsn
if (logger) {
assert(brt->fname);
BYTESTRING bs = {.len=strlen(brt->fname), .data=brt->fname};
LSN lsn;
r = toku_log_brtclose(logger, &lsn, 1, bs, toku_cachefile_filenum(brt->cf)); // flush the log on close, otherwise it might not make it out.
if (r!=0) return r;
}
......@@ -3295,7 +3296,7 @@ int toku_close_brt (BRT brt, TOKULOGGER logger, char **error_string) {
//printf("%s:%d closing cachetable\n", __FILE__, __LINE__);
// printf("%s:%d brt=%p ,brt->h=%p\n", __FILE__, __LINE__, brt, brt->h);
if (error_string) assert(*error_string == 0);
r = toku_cachefile_close(&brt->cf, logger, error_string);
r = toku_cachefile_close(&brt->cf, logger, error_string, lsn);
if (r==0 && error_string) assert(*error_string == 0);
}
if (brt->fname) toku_free(brt->fname);
......
......@@ -188,10 +188,10 @@ struct cachefile {
CACHETABLE cachetable;
struct fileid fileid;
FILENUM filenum;
char *fname;
char *fname_relative_to_env; /* Used for logging */
void *userdata;
int (*close_userdata)(CACHEFILE cf, void *userdata, char **error_string); // when closing the last reference to a cachefile, first call this function.
int (*close_userdata)(CACHEFILE cf, void *userdata, char **error_string, LSN); // when closing the last reference to a cachefile, first call this function.
int (*begin_checkpoint_userdata)(CACHEFILE cf, LSN lsn_of_checkpoint, void *userdata); // before checkpointing cachefiles call this function.
int (*checkpoint_userdata)(CACHEFILE cf, void *userdata); // when checkpointing a cachefile, call this function.
int (*end_checkpoint_userdata)(CACHEFILE cf, void *userdata); // after checkpointing cachefiles call this function.
......@@ -267,11 +267,11 @@ int toku_cachefile_of_filenum (CACHETABLE ct, FILENUM filenum, CACHEFILE *cf) {
static FILENUM next_filenum_to_use={0};
static void cachefile_init_filenum(CACHEFILE cf, int fd, const char *fname, struct fileid fileid) \
static void cachefile_init_filenum(CACHEFILE cf, int fd, const char *fname_relative_to_env, struct fileid fileid) \
{
cf->fd = fd;
cf->fileid = fileid;
cf->fname = fname ? toku_strdup(fname) : 0;
cf->fname_relative_to_env = fname_relative_to_env ? toku_strdup(fname_relative_to_env) : 0;
}
//
// Increment the reference count
......@@ -283,7 +283,7 @@ cachefile_refup (CACHEFILE cf) {
// If something goes wrong, close the fd. After this, the caller shouldn't close the fd, but instead should close the cachefile.
int toku_cachetable_openfd (CACHEFILE *cfptr, CACHETABLE ct, int fd, const char *fname) {
int toku_cachetable_openfd (CACHEFILE *cfptr, CACHETABLE ct, int fd, const char *fname_relative_to_env) {
int r;
CACHEFILE extant;
struct fileid fileid;
......@@ -327,7 +327,7 @@ int toku_cachetable_openfd (CACHEFILE *cfptr, CACHETABLE ct, int fd, const char
CACHEFILE XCALLOC(newcf);
newcf->cachetable = ct;
newcf->filenum.fileid = next_filenum_to_use.fileid++;
cachefile_init_filenum(newcf, fd, fname, fileid);
cachefile_init_filenum(newcf, fd, fname_relative_to_env, fileid);
newcf->refcount = 1;
newcf->next = ct->cachefiles;
ct->cachefiles = newcf;
......@@ -345,10 +345,10 @@ int toku_cachetable_openfd (CACHEFILE *cfptr, CACHETABLE ct, int fd, const char
}
//TEST_ONLY_FUNCTION
int toku_cachetable_openf (CACHEFILE *cfptr, CACHETABLE ct, const char *fname, int flags, mode_t mode) {
int toku_cachetable_openf (CACHEFILE *cfptr, CACHETABLE ct, const char *fname, const char *fname_relative_to_env, int flags, mode_t mode) {
int fd = open(fname, flags+O_BINARY, mode);
if (fd<0) return errno;
return toku_cachetable_openfd (cfptr, ct, fd, fname);
return toku_cachetable_openfd (cfptr, ct, fd, fname_relative_to_env);
}
WORKQUEUE toku_cachetable_get_workqueue(CACHETABLE ct) {
......@@ -361,14 +361,14 @@ void toku_cachefile_get_workqueue_load (CACHEFILE cf, int *n_in_queue, int *n_th
*n_threads = threadpool_get_current_threads(ct->threadpool);
}
int toku_cachefile_set_fd (CACHEFILE cf, int fd, const char *fname) {
int toku_cachefile_set_fd (CACHEFILE cf, int fd, const char *fname_relative_to_env) {
int r;
struct fileid fileid;
r=toku_os_get_unique_file_id(fd, &fileid);
if (r != 0) {
r=errno; close(fd); return r;
}
if (cf->close_userdata && (r = cf->close_userdata(cf, cf->userdata, 0))) {
if (cf->close_userdata && (r = cf->close_userdata(cf, cf->userdata, 0, ZERO_LSN))) {
return r;
}
cf->close_userdata = NULL;
......@@ -379,11 +379,11 @@ int toku_cachefile_set_fd (CACHEFILE cf, int fd, const char *fname) {
close(cf->fd);
cf->fd = -1;
if (cf->fname) {
toku_free(cf->fname);
cf->fname = 0;
if (cf->fname_relative_to_env) {
toku_free(cf->fname_relative_to_env);
cf->fname_relative_to_env = 0;
}
cachefile_init_filenum(cf, fd, fname, fileid);
cachefile_init_filenum(cf, fd, fname_relative_to_env, fileid);
return 0;
}
......@@ -393,13 +393,13 @@ int toku_cachefile_fd (CACHEFILE cf) {
BOOL
toku_cachefile_is_dev_null (CACHEFILE cf) {
return cf->fname==NULL;
return cf->fname_relative_to_env==NULL;
}
int
toku_cachefile_truncate (CACHEFILE cf, toku_off_t new_size) {
int r;
if (cf->fname==NULL) r = 0; //Don't truncate /dev/null
if (cf->fname_relative_to_env==NULL) r = 0; //Don't truncate /dev/null
else {
r = ftruncate(cf->fd, new_size);
if (r != 0)
......@@ -420,7 +420,7 @@ static CACHEFILE remove_cf_from_list (CACHEFILE cf, CACHEFILE list) {
static int cachetable_flush_cachefile (CACHETABLE, CACHEFILE cf);
int toku_cachefile_close (CACHEFILE *cfp, TOKULOGGER logger, char **error_string) {
int toku_cachefile_close (CACHEFILE *cfp, TOKULOGGER logger, char **error_string, LSN lsn) {
CACHEFILE cf = *cfp;
CACHETABLE ct = cf->cachetable;
......@@ -451,7 +451,7 @@ int toku_cachefile_close (CACHEFILE *cfp, TOKULOGGER logger, char **error_string
int rd = toku_pthread_cond_destroy(&cf->openfd_wait);
assert(rd == 0);
}
if (cf->fname) toku_free(cf->fname);
if (cf->fname_relative_to_env) toku_free(cf->fname_relative_to_env);
int r2 = close(cf->fd);
if (r2!=0) fprintf(stderr, "%s:%d During error handling, could not close file r=%d errno=%d\n", __FILE__, __LINE__, r2, errno);
//assert(r == 0);
......@@ -460,7 +460,7 @@ int toku_cachefile_close (CACHEFILE *cfp, TOKULOGGER logger, char **error_string
cachetable_unlock(ct);
return r;
}
if (cf->close_userdata && (r = cf->close_userdata(cf, cf->userdata, error_string))) {
if (cf->close_userdata && (r = cf->close_userdata(cf, cf->userdata, error_string, lsn))) {
goto error;
}
cf->close_userdata = NULL;
......@@ -490,7 +490,8 @@ int toku_cachefile_close (CACHEFILE *cfp, TOKULOGGER logger, char **error_string
//BYTESTRING bs = {.len=strlen(cf->fname), .data=cf->fname};
//r = toku_log_cfclose(logger, 0, 0, bs, cf->filenum);
}
if (cf->fname) toku_free(cf->fname);
if (cf->fname_relative_to_env) toku_free(cf->fname_relative_to_env);
toku_free(cf);
*cfp=NULL;
return r;
......@@ -1575,7 +1576,7 @@ toku_cachetable_begin_checkpoint (CACHETABLE ct, TOKULOGGER logger) {
if (logger) {
// The checkpoint must be performed after the lock is acquired.
{
LSN begin_lsn;
LSN begin_lsn; // we'll need to store the lsn of the checkpoint begin in all the trees that are checkpointed.
int r = toku_log_begin_checkpoint(logger, &begin_lsn, 0);
ct->lsn_of_checkpoint_in_progress = begin_lsn;
assert(r==0);
......@@ -1590,8 +1591,8 @@ toku_cachetable_begin_checkpoint (CACHETABLE ct, TOKULOGGER logger) {
//Must loop through ALL open files (even if not included in checkpoint).
CACHEFILE cf;
for (cf = ct->cachefiles; cf; cf=cf->next) {
BYTESTRING bs = { strlen(cf->fname), // don't include the NUL
cf->fname };
BYTESTRING bs = { strlen(cf->fname_relative_to_env), // don't include the NUL
cf->fname_relative_to_env };
int r = toku_log_fassociate(logger, NULL, 0, cf->filenum, bs);
assert(r==0);
}
......@@ -1700,7 +1701,7 @@ toku_cachetable_end_checkpoint(CACHETABLE ct, TOKULOGGER logger, char **error_st
ct->cachefiles_in_checkpoint = cf->next_in_checkpoint;
cf->next_in_checkpoint = NULL;
cf->for_checkpoint = FALSE;
int r = toku_cachefile_close(&cf, logger, error_string);
int r = toku_cachefile_close(&cf, logger, error_string, ct->lsn_of_checkpoint_in_progress);
if (r!=0) {
retval = r;
goto panic;
......@@ -1855,7 +1856,7 @@ int toku_cachetable_get_key_state (CACHETABLE ct, CACHEKEY key, CACHEFILE cf, vo
void
toku_cachefile_set_userdata (CACHEFILE cf,
void *userdata,
int (*close_userdata)(CACHEFILE, void*, char**),
int (*close_userdata)(CACHEFILE, void*, char**, LSN),
int (*checkpoint_userdata)(CACHEFILE, void*),
int (*begin_checkpoint_userdata)(CACHEFILE, LSN, void*),
int (*end_checkpoint_userdata)(CACHEFILE, void*)) {
......@@ -1874,7 +1875,7 @@ int
toku_cachefile_fsync(CACHEFILE cf) {
int r;
if (cf->fname==NULL) r = 0; //Don't fsync /dev/null
if (cf->fname_relative_to_env==NULL) r = 0; //Don't fsync /dev/null
else r = fsync(cf->fd);
return r;
}
......@@ -1888,9 +1889,9 @@ int toku_cachefile_redirect_nullfd (CACHEFILE cf) {
toku_os_get_unique_file_id(null_fd, &fileid);
close(cf->fd);
cf->fd = null_fd;
if (cf->fname) {
toku_free(cf->fname);
cf->fname = 0;
if (cf->fname_relative_to_env) {
toku_free(cf->fname_relative_to_env);
cf->fname_relative_to_env = 0;
}
cachefile_init_filenum(cf, null_fd, NULL, fileid);
return 0;
......
......@@ -63,10 +63,10 @@ void toku_cachetable_minicron_shutdown(CACHETABLE ct);
int toku_cachetable_close (CACHETABLE*); /* Flushes everything to disk, and destroys the cachetable. */
// Open a file and bind the file to a new cachefile object.
int toku_cachetable_openf (CACHEFILE *,CACHETABLE, const char */*fname*/, int flags, mode_t mode);
int toku_cachetable_openf (CACHEFILE *,CACHETABLE, const char */*fname*/, const char */*fname_relative_to_env*/,int flags, mode_t mode);
// Bind a file to a new cachefile object.
int toku_cachetable_openfd (CACHEFILE *,CACHETABLE, int /*fd*/, const char */*fname (used for logging)*/);
int toku_cachetable_openfd (CACHEFILE *,CACHETABLE, int /*fd*/, const char *fname_relative_to_env /*(used for logging)*/);
// Get access to the asynchronous work queue
// Returns: a pointer to the work queue
......@@ -87,7 +87,7 @@ typedef void (*CACHETABLE_FLUSH_CALLBACK)(CACHEFILE, CACHEKEY key, void *value,
// associated with the key are returned.
typedef int (*CACHETABLE_FETCH_CALLBACK)(CACHEFILE, CACHEKEY key, u_int32_t fullhash, void **value, long *sizep, void *extraargs, LSN *written_lsn);
void toku_cachefile_set_userdata(CACHEFILE cf, void *userdata, int (*close_userdata)(CACHEFILE, void*, char **/*error_string*/), int (*checkpoint_userdata)(CACHEFILE, void*), int (*begin_checkpoint_userdata)(CACHEFILE, LSN, void*), int (*end_checkpoint_userdata)(CACHEFILE, void*));
void toku_cachefile_set_userdata(CACHEFILE cf, void *userdata, int (*close_userdata)(CACHEFILE, void*, char **/*error_string*/, LSN), int (*checkpoint_userdata)(CACHEFILE, void*), int (*begin_checkpoint_userdata)(CACHEFILE, LSN, void*), int (*end_checkpoint_userdata)(CACHEFILE, void*));
// Effect: Store some cachefile-specific user data. When the last reference to a cachefile is closed, we call close_userdata().
// Before starting a checkpoint, we call checkpoint_prepare_userdata().
// When the cachefile needs to be checkpointed, we call checkpoint_userdata().
......@@ -165,7 +165,7 @@ int toku_cachetable_rename (CACHEFILE cachefile, CACHEKEY oldkey, CACHEKEY newke
// close function does not return until all of the objects are evicted. The cachefile
// object is freed.
// Returns: 0 if success, otherwise returns an error number.
int toku_cachefile_close (CACHEFILE*, TOKULOGGER, char **error_string);
int toku_cachefile_close (CACHEFILE*, TOKULOGGER, char **error_string, LSN);
// Flush the cachefile.
// Effect: Flush everything owned by the cachefile from the cachetable. All dirty
......@@ -184,7 +184,7 @@ int toku_cachefile_fd (CACHEFILE);
// Set the cachefile's fd and fname.
// Effect: Bind the cachefile to a new fd and fname. The old fd is closed.
// Returns: 0 if success, otherwise an error number
int toku_cachefile_set_fd (CACHEFILE cf, int fd, const char *fname);
int toku_cachefile_set_fd (CACHEFILE cf, int fd, const char *fname_relative_to_env);
// Equivalent to toku_cachefile_set_fd to /dev/null but without
// closing the user data.
......
......@@ -80,7 +80,7 @@ struct tokulogger {
};
int toku_logger_find_next_unused_log_file(const char *directory, long long *result);
int toku_logger_find_logfiles (const char *directory, char ***resultp);
int toku_logger_find_logfiles (const char *directory, char ***resultp, int *n_logfiles);
struct brtcachefile_pair {
BRT brt;
......
......@@ -58,7 +58,9 @@ logfilenamecompare (const void *ap, const void *bp) {
return strcmp(a,b);
}
int toku_logger_find_logfiles (const char *directory, char ***resultp) {
// Return the log files in sorted order
// Return a null_terminated array of strings, and also return the number of strings in the array.
int toku_logger_find_logfiles (const char *directory, char ***resultp, int *n_logfiles) {
int result_limit=2;
int n_results=0;
char **MALLOC_N(result_limit, result);
......@@ -85,6 +87,7 @@ int toku_logger_find_logfiles (const char *directory, char ***resultp) {
// Return them in increasing order.
qsort(result, n_results, sizeof(result[0]), logfilenamecompare);
*resultp = result;
*n_logfiles = n_results;
result[n_results]=0; // make a trailing null
return d ? closedir(d) : 0;
}
......@@ -953,7 +956,8 @@ int toku_logger_log_archive (TOKULOGGER logger, char ***logs_p, int flags) {
int all_n_logs;
int i;
char **all_logs;
int r = toku_logger_find_logfiles (logger->directory, &all_logs);
int n_logfiles;
int r = toku_logger_find_logfiles (logger->directory, &all_logs, &n_logfiles);
if (r!=0) return r;
for (i=0; all_logs[i]; i++);
......
......@@ -364,6 +364,24 @@ generate_log_reader (void) {
fprintf(cf, " };\n");
fprintf(cf, " return DB_BADFORMAT;\n"); // Should read past the record using the len field.
fprintf(cf, "}\n\n");
fprintf2(cf, hf, "// Return 0 if there is something to read, return -1 if nothing to read, abort if an error.\n");
fprintf2(cf, hf, "int toku_log_fread_backward (FILE *infile, struct log_entry *le)");
fprintf(hf, ";\n");
fprintf(cf, "{\n");
fprintf(cf, " {\n long pos = ftell(infile);\n if (pos<=12) return -1;\n }\n");
fprintf(cf, " int r = fseek(infile, -4, SEEK_CUR); assert(r==0);\n");
//fprintf(cf, " if (r!=0) return errno;\n");
fprintf(cf, " u_int32_t len;\n");
fprintf(cf, " r = toku_fread_u_int32_t_nocrclen(infile, &len); assert(r==0);\n");
//fprintf(cf, " if (r!=0) return r;\n");
fprintf(cf, " r = fseek(infile, -(int)len, SEEK_CUR) ; assert(r==0);\n");
//fprintf(cf, " if (r!=0) return errno;\n");
fprintf(cf, " r = toku_log_fread(infile, le); assert(r==0);\n");
//fprintf(cf, " if (r!=0) return r;\n");
fprintf(cf, " r = fseek(infile, -(int)len, SEEK_CUR); assert(r==0);\n");
//fprintf(cf, " if (r!=0) return errno;\n");
fprintf(cf, " return 0;\n");
fprintf(cf, "}\n");
}
static void
......
......@@ -51,12 +51,29 @@ void toku_recover_cleanup (void) {
}
}
enum backward_state { BS_INIT, BS_SAW_CKPT_END, BS_SAW_CKPT };
struct backward_scan_state {
enum backward_state bs;
LSN checkpoint_lsn;
int n_live_txns;
LSN min_live_txn;
};
static struct backward_scan_state initial_bss = {0,{0},0,{0}};
static void
toku_recover_commit (LSN UU(lsn), TXNID UU(txnid)) {
}
static int toku_recover_backward_commit (struct logtype_commit *UU(l), struct backward_scan_state *UU(bs)) {
return 0;
}
static void
toku_recover_xabort (LSN UU(lsn), TXNID UU(txnid)) {
}
static int toku_recover_backward_xabort (struct logtype_xabort *UU(l), struct backward_scan_state *UU(bs)) {
return 0;
}
static void
create_dir_from_file (const char *fname) {
......@@ -109,6 +126,12 @@ static void
internal_toku_recover_fopen_or_fcreate (int flags, int mode, char *fixedfname, FILENUM filenum) {
CACHEFILE cf;
int fd = open(fixedfname, O_RDWR|O_BINARY|flags, mode);
if (fd<0) {
char org_wd[1000];
char *wd=getcwd(org_wd, sizeof(org_wd));
fprintf(stderr, "%s:%d Could not open file %s, cwd=%s, errno=%d (%s)\n",
__FILE__, __LINE__, fixedfname, wd, errno, strerror(errno));
}
assert(fd>=0);
BRT brt=0;
int r = toku_brt_create(&brt);
......@@ -135,6 +158,12 @@ toku_recover_fopen (LSN UU(lsn), TXNID UU(txnid), BYTESTRING fname, FILENUM file
internal_toku_recover_fopen_or_fcreate(0, 0, fixedfname, filenum);
}
static int toku_recover_backward_fopen (struct logtype_fopen *l, struct backward_scan_state *UU(bs)) {
toku_free_BYTESTRING(l->fname);
return 0;
}
// fcreate is like fopen except that the file must be created. Also creates the dir if needed.
static void
toku_recover_fcreate (LSN UU(lsn), TXNID UU(txnid), FILENUM filenum, BYTESTRING fname,u_int32_t mode) {
......@@ -144,6 +173,11 @@ toku_recover_fcreate (LSN UU(lsn), TXNID UU(txnid), FILENUM filenum, BYTESTRING
internal_toku_recover_fopen_or_fcreate(O_CREAT|O_TRUNC, mode, fixedfname, filenum);
}
static int toku_recover_backward_fcreate (struct logtype_fcreate *l, struct backward_scan_state *UU(bs)) {
toku_free_BYTESTRING(l->fname);
return 0;
}
static int find_cachefile (FILENUM fnum, struct cf_pair **cf_pair) {
int i;
for (i=0; i<n_cf_pairs; i++) {
......@@ -189,6 +223,10 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,
toku_cachefile_set_userdata(pair->cf, pair->brt->h, toku_brtheader_close, toku_brtheader_checkpoint, toku_brtheader_begin_checkpoint, toku_brtheader_end_checkpoint);
}
static int toku_recover_backward_fheader (struct logtype_fheader *UU(l), struct backward_scan_state *UU(bs)) {
return 0;
}
static void
toku_recover_enqrootentry (LSN lsn __attribute__((__unused__)), FILENUM filenum, TXNID xid, u_int32_t typ, BYTESTRING key, BYTESTRING val) {
struct cf_pair *pair = NULL;
......@@ -207,6 +245,13 @@ toku_recover_enqrootentry (LSN lsn __attribute__((__unused__)), FILENUM filenum,
toku_free(val.data);
}
static int toku_recover_backward_enqrootentry (struct logtype_enqrootentry *l, struct backward_scan_state *UU(bs)) {
toku_free_BYTESTRING(l->key);
toku_free_BYTESTRING(l->data);
return 0;
}
static void
toku_recover_brtclose (LSN UU(lsn), BYTESTRING UU(fname), FILENUM filenum) {
struct cf_pair *pair = NULL;
......@@ -218,12 +263,17 @@ toku_recover_brtclose (LSN UU(lsn), BYTESTRING UU(fname), FILENUM filenum) {
toku_free_BYTESTRING(fname);
}
static int toku_recover_backward_brtclose (struct logtype_brtclose *l, struct backward_scan_state *UU(bs)) {
toku_free_BYTESTRING(l->fname);
return 0;
}
static void
toku_recover_cfclose (LSN UU(lsn), BYTESTRING UU(fname), FILENUM filenum) {
int i;
for (i=0; i<n_cf_pairs; i++) {
if (filenum.fileid==cf_pairs[i].filenum.fileid) {
int r = toku_cachefile_close(&cf_pairs[i].cf, 0, 0);
int r = toku_cachefile_close(&cf_pairs[i].cf, 0, 0, ZERO_LSN);
assert(r==0);
cf_pairs[i] = cf_pairs[n_cf_pairs-1];
n_cf_pairs--;
......@@ -233,6 +283,10 @@ toku_recover_cfclose (LSN UU(lsn), BYTESTRING UU(fname), FILENUM filenum) {
toku_free_BYTESTRING(fname);
}
static int toku_recover_backward_cfclose (struct logtype_cfclose *UU(l), struct backward_scan_state *UU(bs)) {
return 0;
}
static void
toku_recover_changeunnamedroot (LSN UU(lsn), FILENUM filenum, BLOCKNUM UU(oldroot), BLOCKNUM newroot) {
struct cf_pair *pair = NULL;
......@@ -243,19 +297,68 @@ toku_recover_changeunnamedroot (LSN UU(lsn), FILENUM filenum, BLOCKNUM UU(oldroo
pair->brt->h->root = newroot;
pair->brt->h->root_hash.valid = FALSE;
}
static int toku_recover_backward_changeunnamedroot (struct logtype_changeunnamedroot *UU(l), struct backward_scan_state *UU(bs)) {
return 0;
}
static void
toku_recover_changenamedroot (LSN UU(lsn), FILENUM UU(filenum), BYTESTRING UU(name), BLOCKNUM UU(oldroot), BLOCKNUM UU(newroot)) { assert(0); }
static int toku_recover_backward_changenamedroot (struct logtype_changenamedroot *UU(l), struct backward_scan_state *UU(bs)) {
return 0;
}
static int toku_recover_begin_checkpoint (LSN UU(lsn)) {
return 0;
}
static int toku_recover_backward_begin_checkpoint (struct logtype_begin_checkpoint *l, struct backward_scan_state *bs) {
switch (bs->bs) {
case BS_INIT:
return 0; // incomplete checkpoint
case BS_SAW_CKPT_END:
assert(bs->checkpoint_lsn.lsn == l->lsn.lsn);
bs->bs = BS_SAW_CKPT;
if (bs->n_live_txns==0) {
fprintf(stderr, "Turning around at begin_checkpoint %" PRIu64 "\n", l->lsn.lsn);
return 1;
}
else return 0;
case BS_SAW_CKPT:
return 0; // ignore it
}
fprintf(stderr, "%s: %d Unknown checkpoint state %d\n", __FILE__, __LINE__, bs->bs);
abort();
}
static int toku_recover_end_checkpoint (LSN UU(lsn), TXNID UU(txnid)) {
return 0;
}
static int toku_recover_fassociate (LSN UU(lsn), FILENUM UU(filenum), BYTESTRING UU(fname)) {
static int toku_recover_backward_end_checkpoint (struct logtype_end_checkpoint *l, struct backward_scan_state *bs) {
switch (bs->bs) {
case BS_INIT:
bs->bs = BS_SAW_CKPT_END;
bs->checkpoint_lsn.lsn = l->txnid;
return 0;
case BS_SAW_CKPT_END:
fprintf(stderr, "%s:%d Should not see two end_checkpoint log entries without an intervening begin_checkpoint\n", __FILE__, __LINE__);
abort();
case BS_SAW_CKPT:
return 0;
}
fprintf(stderr, "%s: %d Unknown checkpoint state %d\n", __FILE__, __LINE__, bs->bs);
abort();
}
static int toku_recover_fassociate (LSN UU(lsn), FILENUM filenum, BYTESTRING fname) {
char *fixedfname = fixup_fname(&fname);
toku_free_BYTESTRING(fname);
internal_toku_recover_fopen_or_fcreate(0, 0, fixedfname, filenum);
return 0;
}
static int toku_recover_backward_fassociate (struct logtype_fassociate *UU(l), struct backward_scan_state *UU(bs)) {
return 0;
}
......@@ -263,10 +366,51 @@ static int toku_recover_xstillopen (LSN UU(lsn), TXNID UU(txnid)) {
return 0;
}
static int toku_recover_backward_xstillopen (struct logtype_xstillopen *l, struct backward_scan_state *bs) {
switch (bs->bs) {
case BS_INIT:
return 0; // ignore live txns from incomplete checkpoint
case BS_SAW_CKPT_END:
if (bs->n_live_txns==0) {
bs->min_live_txn = l->lsn;
} else {
if (bs->min_live_txn.lsn > l->txnid) bs->min_live_txn = l->lsn;
}
bs->n_live_txns++;
return 0;
case BS_SAW_CKPT:
return 0; // ignore live txns from older checkpoints
}
fprintf(stderr, "%s: %d Unknown checkpoint state %d\n", __FILE__, __LINE__, bs->bs);
abort();
}
static int toku_recover_xbegin (LSN UU(lsn), TXNID UU(parent)) {
return 0;
}
static int toku_recover_backward_xbegin (struct logtype_xbegin *l, struct backward_scan_state *bs) {
switch (bs->bs) {
case BS_INIT:
return 0; // ignore txns that began after checkpoint
case BS_SAW_CKPT_END:
return 0; // ignore txns that began during the checkpoint
case BS_SAW_CKPT:
assert(bs->n_live_txns > 0); // the only thing we are doing here is looking for a live txn, so there better be one
// If we got to the min, return nonzero
if (bs->min_live_txn.lsn >= l->lsn.lsn) {
fprintf(stderr, "Turning around at xbegin %" PRIu64 "\n", l->lsn.lsn);
return 1;
} else {
fprintf(stderr, "scanning back at xbegin %" PRIu64 " (looking for %" PRIu64 "\n", l->lsn.lsn, bs->min_live_txn.lsn);
return 0;
}
}
fprintf(stderr, "%s: %d Unknown checkpoint state %d\n", __FILE__, __LINE__, bs->bs);
abort();
}
static int toku_delete_rolltmp_files (const char *log_dir) {
struct dirent *de;
DIR *d = opendir(log_dir);
......@@ -321,7 +465,8 @@ int tokudb_recover(const char *data_dir, const char *log_dir) {
r = toku_delete_rolltmp_files(log_dir);
if (r!=0) { failresult=r; goto fail; }
r = toku_logger_find_logfiles(log_dir, &logfiles);
int n_logfiles;
r = toku_logger_find_logfiles(log_dir, &logfiles, &n_logfiles);
if (r!=0) { failresult=r; goto fail; }
int i;
toku_recover_init();
......@@ -338,20 +483,49 @@ int tokudb_recover(const char *data_dir, const char *log_dir) {
assert(wd!=0);
//printf("%s:%d data_wd=\"%s\"\n", __FILE__, __LINE__, data_wd);
}
for (i=0; logfiles[i]; i++) {
FILE *f = NULL;
for (i=0; i<n_logfiles; i++) {
if (f) fclose(f);
r=chdir(org_wd);
assert(r==0);
char *logfile = logfiles[n_logfiles-i-1];
f = fopen(logfile, "r");
assert(f);
//printf("Opened %s\n", logfiles[n_logfiles-i-1]);
r = fseek(f, 0, SEEK_END); assert(r==0);
struct log_entry le;
struct backward_scan_state bs = initial_bss;
while (1) {
r = toku_log_fread_backward(f, &le);
if (r==-1) break; // Ran out of file
logtype_dispatch_assign(&le, toku_recover_backward_, r, &bs);
if (r!=0) goto go_forward;
}
}
i--;
// We got to the end of the last log
if (f) { r=fclose(f); assert(r==0); }
// Now we go forward from this point
while (n_logfiles-i-1<n_logfiles) {
//fprintf(stderr, "Opening %s\n", logfiles[i]);
int j = n_logfiles-i-1;
r=chdir(org_wd);
assert(r==0);
FILE *f = fopen(logfiles[i], "r");
f = fopen(logfiles[j], "r");
assert(f);
struct log_entry le;
u_int32_t version;
//printf("Reading file %s\n", logfiles[i]);
//printf("Reading file %d: %s\n", j, logfiles[j]);
r=toku_read_and_print_logmagic(f, &version);
assert(r==0 && version==0);
go_forward: // we have an open file, so go forward.
//printf("Going forward\n");
r=chdir(data_wd);
assert(r==0);
while ((r = toku_log_fread(f, &le))==0) {
//printf("%lld: Got cmd %c\n", (long long)le.u.commit.lsn.lsn, le.cmd);
//printf("doing %c\n", le.cmd);
logtype_dispatch_args(&le, toku_recover_);
entrycount++;
}
......@@ -365,6 +539,7 @@ int tokudb_recover(const char *data_dir, const char *log_dir) {
}
}
fclose(f);
i--;
}
toku_recover_cleanup();
for (i=0; logfiles[i]; i++) {
......
......@@ -105,7 +105,7 @@ static void checkpoint_pending(void) {
r = toku_create_cachetable(&ct, test_limit*sizeof(int), ZERO_LSN, NULL_LOGGER); assert(r == 0);
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
r = toku_cachetable_openf(&cf, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&cf, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// Insert items into the cachetable. All dirty.
int i;
......@@ -147,7 +147,7 @@ static void checkpoint_pending(void) {
assert(r == 0);
assert(n_flush == 0 && n_write_me == 0 && n_keep_me == 0);
r = toku_cachefile_close(&cf, NULL_LOGGER, 0); assert(r == 0 && cf == 0);
r = toku_cachefile_close(&cf, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && cf == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -48,7 +48,7 @@ static void cachetable_checkpoint_test(int n, enum cachetable_dirty dirty) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// insert items into the cachetable. all should be dirty
int i;
......@@ -112,7 +112,7 @@ static void cachetable_checkpoint_test(int n, enum cachetable_dirty dirty) {
assert(r == 0);
assert(n_flush == 0 && n_write_me == 0 && n_keep_me == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -35,7 +35,7 @@ cachetable_count_pinned_test (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int i;
for (i=1; i<=n; i++) {
......@@ -66,7 +66,7 @@ cachetable_count_pinned_test (int n) {
assert(toku_cachefile_count_pinned(f1, 1) == 0);
toku_cachetable_verify(ct);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -35,7 +35,7 @@ cachetable_debug_test (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int num_entries, hash_size; long size_current, size_limit;
toku_cachetable_get_state(ct, &num_entries, &hash_size, &size_current, &size_limit);
......@@ -74,7 +74,7 @@ cachetable_debug_test (int n) {
if (verbose) toku_cachetable_print_hash_histogram();
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -11,7 +11,7 @@ cachetable_fd_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE cf;
r = toku_cachetable_openf(&cf, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&cf, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int fd1 = toku_cachefile_fd(cf); assert(fd1 >= 0);
......@@ -39,7 +39,7 @@ cachetable_fd_test (void) {
r = toku_cachefile_of_filenum(ct, fn, &newcf);
assert(r == ENOENT);
r = toku_cachefile_close(&cf, NULL_LOGGER, 0); assert(r == 0 && cf == 0);
r = toku_cachefile_close(&cf, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && cf == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -35,12 +35,12 @@ test_cachetable_flush (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
char fname2[] = __FILE__ "test2.dat";
unlink(fname2);
CACHEFILE f2;
r = toku_cachetable_openf(&f2, ct, fname2, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f2, ct, fname2, fname2, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// insert keys 0..n-1
int i;
......@@ -93,8 +93,8 @@ test_cachetable_flush (int n) {
assert(r == 0);
}
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f2, NULL_LOGGER, 0); assert(r == 0 && f2 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f2, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f2 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -44,7 +44,7 @@ cachetable_getandpin_test (int n) {
char fname1[] = __FILE__ "test_getandpin.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int i;
......@@ -71,7 +71,7 @@ cachetable_getandpin_test (int n) {
}
toku_cachetable_verify(ct);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -42,7 +42,7 @@ static void cachetable_prefetch_checkpoint_test(int n, enum cachetable_dirty dir
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block n+1. this will take 10 seconds.
{
......@@ -112,7 +112,7 @@ static void cachetable_prefetch_checkpoint_test(int n, enum cachetable_dirty dir
assert(r == 0);
assert(n_flush == 0 && n_write_me == 0 && n_keep_me == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -47,7 +47,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block 0. this will take 10 seconds.
CACHEKEY key = make_blocknum(0);
......@@ -57,7 +57,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
// close with the prefetch in progress. the close should block until
// all of the reads and writes are complete.
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -48,7 +48,7 @@ static void cachetable_prefetch_close_leak_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block 0. this will take 10 seconds.
CACHEKEY key = make_blocknum(0);
......@@ -58,7 +58,7 @@ static void cachetable_prefetch_close_leak_test (void) {
// close with the prefetch in progress. the close should block until
// all of the reads and writes are complete.
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -47,7 +47,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block 0. this will take 10 seconds.
CACHEKEY key = make_blocknum(0);
......@@ -57,7 +57,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
// close with the prefetch in progress. the close should block until
// all of the reads and writes are complete.
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -50,7 +50,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
struct timeval tstart;
gettimeofday(&tstart, NULL);
......@@ -74,7 +74,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
toku_cachetable_verify(ct);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -50,7 +50,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
struct timeval tstart;
gettimeofday(&tstart, NULL);
......@@ -78,7 +78,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
assert(r == 0);
toku_cachetable_verify(ct);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -44,7 +44,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block 0. this will take 10 seconds.
CACHEKEY key = make_blocknum(0);
......@@ -68,7 +68,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
assert(r == 0);
toku_cachetable_verify(ct);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -48,7 +48,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
// prefetch block 0. this will take 10 seconds.
CACHEKEY key = make_blocknum(0);
......@@ -79,7 +79,7 @@ static void cachetable_prefetch_maybegetandpin_test (void) {
assert(r == 0);
toku_cachetable_verify(ct);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -35,7 +35,7 @@ cachetable_put_test (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int i;
for (i=1; i<=n; i++) {
......@@ -78,7 +78,7 @@ cachetable_put_test (int n) {
r = toku_cachetable_unpin(f1, k, toku_cachetable_hash(f1, k), CACHETABLE_CLEAN, 1);
assert(r != 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -88,7 +88,7 @@ static void test_rename (void) {
const char fname[] = __FILE__ "rename.dat";
r=toku_create_cachetable(&t, KEYLIMIT, ZERO_LSN, NULL_LOGGER); assert(r==0);
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r==0);
for (i=0; i<TRIALLIMIT; i++) {
int ra = random()%3;
......@@ -159,7 +159,7 @@ static void test_rename (void) {
r = toku_cachetable_rename(f, okey, nkey);
assert(r != 0);
r = toku_cachefile_close(&f, 0, 0);
r = toku_cachefile_close(&f, 0, 0, ZERO_LSN);
assert(r == 0);
r = toku_cachetable_close(&t);
assert(r == 0);
......
......@@ -49,7 +49,7 @@ CACHEFILE f;
static void open_file (void ) {
int r;
r = toku_create_cachetable(&t, KEYLIMIT, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
}
static void writeit (void) {
......@@ -85,7 +85,7 @@ static void readit (void) {
r=toku_cachetable_get_and_pin(f, key, fullhash, &block, &current_size, f_flush, f_fetch, 0); assert(r==0);
r=toku_cachetable_unpin(f, key, fullhash, CACHETABLE_CLEAN, BLOCKSIZE); assert(r==0);
}
r = toku_cachefile_close(&f, 0, 0); assert(r == 0);
r = toku_cachefile_close(&f, 0, 0, ZERO_LSN); assert(r == 0);
r = toku_cachetable_close(&t); assert(r == 0);
gettimeofday(&end, 0);
toku_os_get_process_times(&end_usertime, &end_systime);
......
......@@ -173,7 +173,7 @@ static void test0 (void) {
r=toku_create_cachetable(&t, 5, ZERO_LSN, NULL_LOGGER);
assert(r==0);
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r==0);
TOKULOGGER logger = toku_cachefile_logger(f);
......@@ -288,7 +288,7 @@ static void test0 (void) {
expectN(7);
expectN(6);
expectN(1);
r=toku_cachefile_close(&f, 0, 0);
r=toku_cachefile_close(&f, 0, 0, ZERO_LSN);
assert(r==0);
r=toku_cachetable_close(&t);
assert(r==0);
......@@ -327,7 +327,7 @@ static void test_nested_pin (void) {
r = toku_create_cachetable(&t, 1, ZERO_LSN, NULL_LOGGER);
assert(r==0);
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r==0);
expect_f = f;
......@@ -354,7 +354,7 @@ static void test_nested_pin (void) {
r = toku_cachetable_unpin(f, make_blocknum(2), f2hash, CACHETABLE_CLEAN, test_object_size);
assert(r==0);
// toku_os_usleep(1*1000000);
r = toku_cachefile_close(&f, 0, 0); assert(r==0);
r = toku_cachefile_close(&f, 0, 0, ZERO_LSN); assert(r==0);
r = toku_cachetable_close(&t); assert(r==0);
}
......@@ -399,10 +399,10 @@ static void test_multi_filehandles (void) {
unlink(fname2);
r = toku_create_cachetable(&t, 4, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_cachetable_openf(&f1, t, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f1, t, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = link(fname1, fname2); assert(r==0);
r = toku_cachetable_openf(&f2, t, fname2, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f3, t, fname3, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f2, t, fname2, fname2, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f3, t, fname3, fname3, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
assert(f1==f2);
assert(f1!=f3);
......@@ -419,14 +419,14 @@ static void test_multi_filehandles (void) {
r = toku_cachetable_unpin(f1, make_blocknum(1), toku_cachetable_hash(f1, make_blocknum(1)), CACHETABLE_CLEAN, 0); assert(r==0);
r = toku_cachetable_unpin(f1, make_blocknum(2), toku_cachetable_hash(f1, make_blocknum(2)), CACHETABLE_CLEAN, 0); assert(r==0);
r = toku_cachefile_close(&f1, 0, 0); assert(r==0);
r = toku_cachefile_close(&f1, 0, 0, ZERO_LSN); assert(r==0);
r = toku_cachetable_unpin(f2, make_blocknum(1), toku_cachetable_hash(f2, make_blocknum(1)), CACHETABLE_CLEAN, 0); assert(r==0);
r = toku_cachetable_unpin(f2, make_blocknum(2), toku_cachetable_hash(f2, make_blocknum(2)), CACHETABLE_CLEAN, 0); assert(r==0);
r = toku_cachefile_close(&f2, 0, 0); assert(r==0);
r = toku_cachefile_close(&f2, 0, 0, ZERO_LSN); assert(r==0);
r = toku_cachetable_unpin(f3, make_blocknum(2), toku_cachetable_hash(f3, make_blocknum(2)), CACHETABLE_CLEAN, 0); assert(r==0);
r = toku_cachefile_close(&f3, 0, 0); assert(r==0);
r = toku_cachefile_close(&f3, 0, 0, ZERO_LSN); assert(r==0);
r = toku_cachetable_close(&t); assert(r==0);
}
......@@ -466,7 +466,7 @@ static void test_dirty() {
char *fname = __FILE__ "test.dat";
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r == 0);
key = make_blocknum(1); value = (void*)1;
......@@ -548,7 +548,7 @@ static void test_dirty() {
assert(dirty == 1);
assert(pinned == 0);
r = toku_cachefile_close(&f, 0, 0);
r = toku_cachefile_close(&f, 0, 0, ZERO_LSN);
assert(r == 0);
r = toku_cachetable_close(&t);
assert(r == 0);
......@@ -592,7 +592,7 @@ static void test_size_resize() {
char *fname = __FILE__ "test.dat";
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r == 0);
CACHEKEY key = make_blocknum(42);
......@@ -625,7 +625,7 @@ static void test_size_resize() {
r = toku_cachetable_unpin(f, key, hkey, CACHETABLE_CLEAN, new_size);
assert(r == 0);
r = toku_cachefile_close(&f, 0, 0);
r = toku_cachefile_close(&f, 0, 0, ZERO_LSN);
assert(r == 0);
r = toku_cachetable_close(&t);
assert(r == 0);
......@@ -647,7 +647,7 @@ static void test_size_flush() {
char *fname = __FILE__ "test.dat";
unlink(fname);
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
r = toku_cachetable_openf(&f, t, fname, fname, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
assert(r == 0);
/* put 2*n keys into the table, ensure flushes occur in key order */
......@@ -693,7 +693,7 @@ static void test_size_flush() {
assert(r == 0);
}
r = toku_cachefile_close(&f, 0, 0);
r = toku_cachefile_close(&f, 0, 0, ZERO_LSN);
assert(r == 0);
r = toku_cachetable_close(&t);
assert(r == 0);
......
......@@ -156,7 +156,7 @@ static void test_chaining (void) {
r = snprintf(fname[i], FILENAME_LEN, __FILE__ ".%ld.dat", i);
assert(r>0 && r<FILENAME_LEN);
unlink(fname[i]);
r = toku_cachetable_openf(&f[i], ct, fname[i], O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f[i], ct, fname[i], fname[i], O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
}
for (i=0; i<N_PRESENT_LIMIT; i++) {
int fnum = i%N_FILES;
......@@ -227,13 +227,13 @@ static void test_chaining (void) {
//printf("Close %d (%p), now n_present=%d\n", i, f[i], n_present);
//print_ints();
CACHEFILE oldcf=f[i];
r = toku_cachefile_close(&f[i], 0, 0); assert(r==0);
r = toku_cachefile_close(&f[i], 0, 0, ZERO_LSN); assert(r==0);
file_is_not_present(oldcf);
r = toku_cachetable_openf(&f[i], ct, fname[i], O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
r = toku_cachetable_openf(&f[i], ct, fname[i], fname[i], O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); assert(r==0);
}
}
for (i=0; i<N_FILES; i++) {
r = toku_cachefile_close(&f[i], 0, 0); assert(r==0);
r = toku_cachefile_close(&f[i], 0, 0, ZERO_LSN); assert(r==0);
}
r = toku_cachetable_close(&ct); assert(r==0);
}
......
......@@ -35,7 +35,7 @@ cachetable_unpin_test (int n) {
char fname1[] = __FILE__ "test1.dat";
unlink(fname1);
CACHEFILE f1;
r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
r = toku_cachetable_openf(&f1, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int i;
for (i=1; i<=n; i++) {
......@@ -68,7 +68,7 @@ cachetable_unpin_test (int n) {
r = toku_cachetable_unpin(f1, k, toku_cachetable_hash(f1, k), CACHETABLE_CLEAN, 1);
assert(r != 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0); assert(r == 0 && f1 == 0);
r = toku_cachefile_close(&f1, NULL_LOGGER, 0, ZERO_LSN); assert(r == 0 && f1 == 0);
r = toku_cachetable_close(&ct); assert(r == 0 && ct == 0);
}
......
......@@ -9,6 +9,10 @@ DB_TXN *null_txn=0;
void do_test1753 (int do_create_on_reopen) {
if (IS_TDB==0 && DB_VERSION_MAJOR==4 && DB_VERSION_MINOR<7 && do_create_on_reopen==0) {
return; // do_create_on_reopen==0 segfaults in 4.6
}
system("rm -rf " ENVDIR);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
int r;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment