Commit 6edcb18a authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

closes[t:2639] recover from translation table realloc failures in the allocate...

closes[t:2639] recover from translation table realloc failures in the allocate block function of the brtloader. merge -r 20450:head from tokudb.2639

git-svn-id: file:///svn/toku/tokudb@20466 c7de825b-a66e-492c-adef-691d508d4ae1
parent 73c323a8
...@@ -473,6 +473,7 @@ serialize_uncompressed_block_to_memory(char * uncompressed_buf, ...@@ -473,6 +473,7 @@ serialize_uncompressed_block_to_memory(char * uncompressed_buf,
int int
toku_serialize_brtnode_to_memory (BRTNODE node, int UU(n_workitems), int UU(n_threads), /*out*/ size_t *n_bytes_to_write, /*out*/ char **bytes_to_write) { toku_serialize_brtnode_to_memory (BRTNODE node, int UU(n_workitems), int UU(n_threads), /*out*/ size_t *n_bytes_to_write, /*out*/ char **bytes_to_write) {
int result = 0;
// get the size of the serialized node // get the size of the serialized node
size_t calculated_size = toku_serialize_brtnode_size(node); size_t calculated_size = toku_serialize_brtnode_size(node);
...@@ -492,6 +493,9 @@ toku_serialize_brtnode_to_memory (BRTNODE node, int UU(n_workitems), int UU(n_th ...@@ -492,6 +493,9 @@ toku_serialize_brtnode_to_memory (BRTNODE node, int UU(n_workitems), int UU(n_th
// allocate space for the serialized node // allocate space for the serialized node
char *MALLOC_N(calculated_size, buf); char *MALLOC_N(calculated_size, buf);
if (buf == NULL)
result = errno;
else {
//toku_verify_counts(node); //toku_verify_counts(node);
//assert(size>0); //assert(size>0);
//printf("%s:%d serializing %lld w height=%d p0=%p\n", __FILE__, __LINE__, off, node->height, node->mdicts[0]); //printf("%s:%d serializing %lld w height=%d p0=%p\n", __FILE__, __LINE__, off, node->height, node->mdicts[0]);
...@@ -503,7 +507,8 @@ toku_serialize_brtnode_to_memory (BRTNODE node, int UU(n_workitems), int UU(n_th ...@@ -503,7 +507,8 @@ toku_serialize_brtnode_to_memory (BRTNODE node, int UU(n_workitems), int UU(n_th
serialize_uncompressed_block_to_memory(buf, n_sub_blocks, sub_block, serialize_uncompressed_block_to_memory(buf, n_sub_blocks, sub_block,
n_bytes_to_write, bytes_to_write); n_bytes_to_write, bytes_to_write);
toku_free(buf); toku_free(buf);
return 0; }
return result;
} }
int int
......
...@@ -261,9 +261,13 @@ int brtloader_open_temp_file (BRTLOADER bl, FIDX *file_idx) ...@@ -261,9 +261,13 @@ int brtloader_open_temp_file (BRTLOADER bl, FIDX *file_idx)
*/ */
{ {
int result = 0; int result = 0;
char *fname = toku_strdup(bl->temp_file_template);
FILE *f = NULL; FILE *f = NULL;
int fd = mkstemp(fname); int fd = -1;
char *fname = toku_strdup(bl->temp_file_template);
if (fname == NULL)
result = errno;
else {
fd = mkstemp(fname);
if (fd < 0) { if (fd < 0) {
result = errno; result = errno;
} else { } else {
...@@ -273,6 +277,7 @@ int brtloader_open_temp_file (BRTLOADER bl, FIDX *file_idx) ...@@ -273,6 +277,7 @@ int brtloader_open_temp_file (BRTLOADER bl, FIDX *file_idx)
else else
result = open_file_add(&bl->file_infos, f, fname, file_idx); result = open_file_add(&bl->file_infos, f, fname, file_idx);
} }
}
if (result != 0) { if (result != 0) {
if (fd >= 0) { if (fd >= 0) {
toku_os_close(fd); toku_os_close(fd);
...@@ -1865,7 +1870,10 @@ static inline void dbout_init(struct dbout *out) { ...@@ -1865,7 +1870,10 @@ static inline void dbout_init(struct dbout *out) {
} }
static inline void dbout_destroy(struct dbout *out) { static inline void dbout_destroy(struct dbout *out) {
invariant(out->fd == -1); if (out->fd >= 0) {
toku_os_close(out->fd);
out->fd = -1;
}
toku_free(out->translation); toku_free(out->translation);
out->translation = NULL; out->translation = NULL;
} }
...@@ -1918,21 +1926,31 @@ static void dbuf_destroy (struct dbuf *dbuf) { ...@@ -1918,21 +1926,31 @@ static void dbuf_destroy (struct dbuf *dbuf) {
toku_free(dbuf->buf); dbuf->buf = NULL; toku_free(dbuf->buf); dbuf->buf = NULL;
} }
static int64_t allocate_block (struct dbout *out) static int allocate_block (struct dbout *out, int64_t *ret_block_number)
// Return the new block number // Return the new block number
{ {
int result = 0;
dbout_lock(out); dbout_lock(out);
int64_t result = out->n_translations; int64_t block_number = out->n_translations;
if (result >= out->n_translations_limit) { if (block_number >= out->n_translations_limit) {
int64_t old_n_translations_limit = out->n_translations_limit;
struct translation *old_translation = out->translation;
if (out->n_translations_limit==0) { if (out->n_translations_limit==0) {
out->n_translations_limit = 1; out->n_translations_limit = 1;
} else { } else {
out->n_translations_limit *= 2; out->n_translations_limit *= 2;
} }
REALLOC_N(out->n_translations_limit, out->translation); REALLOC_N(out->n_translations_limit, out->translation);
lazy_assert(out->translation); if (out->translation == NULL) {
result = errno;
out->n_translations_limit = old_n_translations_limit;
out->translation = old_translation;
} }
}
if (result == 0) {
out->n_translations++; out->n_translations++;
*ret_block_number = block_number;
}
dbout_unlock(out); dbout_unlock(out);
return result; return result;
} }
...@@ -2130,7 +2148,9 @@ static int toku_loader_write_brt_from_q (BRTLOADER bl, ...@@ -2130,7 +2148,9 @@ static int toku_loader_write_brt_from_q (BRTLOADER bl,
out.translation[1].off = -1; // block 1 is the block translation, filled in later out.translation[1].off = -1; // block 1 is the block translation, filled in later
out.translation[2].off = -1; // block 2 is the descriptor out.translation[2].off = -1; // block 2 is the descriptor
seek_align(&out); seek_align(&out);
int64_t lblock = allocate_block(&out); int64_t lblock;
result = allocate_block(&out, &lblock);
lazy_assert(result == 0); // can not fail since translations reserved above
struct leaf_buf *lbuf = start_leaf(&out, descriptor, lblock); struct leaf_buf *lbuf = start_leaf(&out, descriptor, lblock);
struct subtree_estimates est = zero_estimates; struct subtree_estimates est = zero_estimates;
est.exact = TRUE; est.exact = TRUE;
...@@ -2153,6 +2173,7 @@ static int toku_loader_write_brt_from_q (BRTLOADER bl, ...@@ -2153,6 +2173,7 @@ static int toku_loader_write_brt_from_q (BRTLOADER bl,
} }
struct rowset *output_rowset = (struct rowset *)item; struct rowset *output_rowset = (struct rowset *)item;
if (result == 0)
for (unsigned int i = 0; i < output_rowset->n_rows; i++) { for (unsigned int i = 0; i < output_rowset->n_rows; i++) {
DBT key = make_dbt(output_rowset->data+output_rowset->rows[i].off, output_rowset->rows[i].klen); DBT key = make_dbt(output_rowset->data+output_rowset->rows[i].off, output_rowset->rows[i].klen);
DBT val = make_dbt(output_rowset->data+output_rowset->rows[i].off + output_rowset->rows[i].klen, output_rowset->rows[i].vlen); DBT val = make_dbt(output_rowset->data+output_rowset->rows[i].off + output_rowset->rows[i].klen, output_rowset->rows[i].vlen);
...@@ -2183,12 +2204,19 @@ static int toku_loader_write_brt_from_q (BRTLOADER bl, ...@@ -2183,12 +2204,19 @@ static int toku_loader_write_brt_from_q (BRTLOADER bl,
if ((r = bl_write_dbt(&key, pivots_stream, NULL, bl))) { if ((r = bl_write_dbt(&key, pivots_stream, NULL, bl))) {
brt_loader_set_panic(bl, r); // error after cilk sync brt_loader_set_panic(bl, r); // error after cilk sync
if (result == 0) result = r;
break; break;
} }
cilk_spawn finish_leafnode(&out, lbuf, progress_this_node, bl); cilk_spawn finish_leafnode(&out, lbuf, progress_this_node, bl);
lbuf = NULL;
lblock = allocate_block(&out); r = allocate_block(&out, &lblock);
if (r != 0) {
brt_loader_set_panic(bl, r);
if (result == 0) result = r;
break;
}
lbuf = start_leaf(&out, descriptor, lblock); lbuf = start_leaf(&out, descriptor, lblock);
} }
...@@ -2203,12 +2231,14 @@ static int toku_loader_write_brt_from_q (BRTLOADER bl, ...@@ -2203,12 +2231,14 @@ static int toku_loader_write_brt_from_q (BRTLOADER bl,
toku_free(output_rowset); toku_free(output_rowset);
} }
if (lbuf) {
allocate_node(&sts, lblock, est, lbuf->local_fingerprint); allocate_node(&sts, lblock, est, lbuf->local_fingerprint);
{ {
int p = progress_allocation/2; int p = progress_allocation/2;
finish_leafnode(&out, lbuf, p, bl); finish_leafnode(&out, lbuf, p, bl);
progress_allocation -= p; progress_allocation -= p;
} }
}
cilk_sync; cilk_sync;
...@@ -2704,8 +2734,11 @@ static int write_translation_table (struct dbout *out, long long *off_of_transla ...@@ -2704,8 +2734,11 @@ static int write_translation_table (struct dbout *out, long long *off_of_transla
} }
unsigned int checksum = x1764_memory(ttable.buf, ttable.off); unsigned int checksum = x1764_memory(ttable.buf, ttable.off);
putbuf_int32(&ttable, checksum); putbuf_int32(&ttable, checksum);
int result = ttable.error;
if (result == 0) {
invariant(bt_size_on_disk==ttable.off); invariant(bt_size_on_disk==ttable.off);
int result = toku_os_pwrite(out->fd, ttable.buf, ttable.off, off_of_translation); result = toku_os_pwrite(out->fd, ttable.buf, ttable.off, off_of_translation);
}
dbuf_destroy(&ttable); dbuf_destroy(&ttable);
*off_of_translation_p = off_of_translation; *off_of_translation_p = off_of_translation;
return result; return result;
...@@ -2794,20 +2827,16 @@ static int setup_nonleaf_block (int n_children, ...@@ -2794,20 +2827,16 @@ static int setup_nonleaf_block (int n_children,
if (result == 0) { if (result == 0) {
int r = read_some_pivots(pivots_file, n_children, bl, pivots); int r = read_some_pivots(pivots_file, n_children, bl, pivots);
if (r) { if (r)
delete_pivots(pivots, n_children);
result = r; result = r;
} }
}
if (result == 0) { if (result == 0) {
FILE *next_pivots_stream = toku_bl_fidx2file(bl, next_pivots_file); FILE *next_pivots_stream = toku_bl_fidx2file(bl, next_pivots_file);
int r = bl_write_dbt(&pivots[n_children-1], next_pivots_stream, NULL, bl); int r = bl_write_dbt(&pivots[n_children-1], next_pivots_stream, NULL, bl);
if (r) { if (r)
delete_pivots(pivots, n_children);
result = r; result = r;
} }
}
if (result == 0) { if (result == 0) {
// The last pivot was written to the next_pivots file, so we free it now instead of returning it. // The last pivot was written to the next_pivots file, so we free it now instead of returning it.
...@@ -2827,12 +2856,23 @@ static int setup_nonleaf_block (int n_children, ...@@ -2827,12 +2856,23 @@ static int setup_nonleaf_block (int n_children,
fingerprint += subtrees->subtrees[from_blocknum].fingerprint; fingerprint += subtrees->subtrees[from_blocknum].fingerprint;
} }
*blocknum = allocate_block(out); int r = allocate_block(out, blocknum);
if (r) {
toku_free(subtrees_array);
result = r;
} else {
allocate_node(next_subtrees, *blocknum, new_subtree_estimates, fingerprint); allocate_node(next_subtrees, *blocknum, new_subtree_estimates, fingerprint);
*pivots_p = pivots; *pivots_p = pivots;
*subtrees_info_p = subtrees_array; *subtrees_info_p = subtrees_array;
} }
}
if (result != 0) {
if (pivots) {
delete_pivots(pivots, n_children); pivots = NULL;
}
}
return result; return result;
} }
...@@ -2860,10 +2900,15 @@ static void write_nonleaf_node (BRTLOADER bl, struct dbout *out, int64_t blocknu ...@@ -2860,10 +2900,15 @@ static void write_nonleaf_node (BRTLOADER bl, struct dbout *out, int64_t blocknu
node->rand4fingerprint = loader_random(); node->rand4fingerprint = loader_random();
XMALLOC_N(n_children-1, node->u.n.childkeys); XMALLOC_N(n_children-1, node->u.n.childkeys);
for (int i=0; i<n_children-1; i++)
node->u.n.childkeys[i] = NULL;
unsigned int totalchildkeylens = 0; unsigned int totalchildkeylens = 0;
for (int i=0; i<n_children-1; i++) { for (int i=0; i<n_children-1; i++) {
struct kv_pair *childkey = kv_pair_malloc(pivots[i].data, pivots[i].size, NULL, 0); struct kv_pair *childkey = kv_pair_malloc(pivots[i].data, pivots[i].size, NULL, 0);
lazy_assert(childkey); if (childkey == NULL) {
result = errno;
break;
}
node->u.n.childkeys[i] = childkey; node->u.n.childkeys[i] = childkey;
totalchildkeylens += kv_pair_keylen(childkey); totalchildkeylens += kv_pair_keylen(childkey);
} }
...@@ -2882,6 +2927,7 @@ static void write_nonleaf_node (BRTLOADER bl, struct dbout *out, int64_t blocknu ...@@ -2882,6 +2927,7 @@ static void write_nonleaf_node (BRTLOADER bl, struct dbout *out, int64_t blocknu
ci->n_bytes_in_buffer = 0; ci->n_bytes_in_buffer = 0;
} }
if (result == 0) {
size_t n_bytes; size_t n_bytes;
char *bytes; char *bytes;
int r; int r;
...@@ -2900,9 +2946,10 @@ static void write_nonleaf_node (BRTLOADER bl, struct dbout *out, int64_t blocknu ...@@ -2900,9 +2946,10 @@ static void write_nonleaf_node (BRTLOADER bl, struct dbout *out, int64_t blocknu
else else
seek_align_locked(out); seek_align_locked(out);
dbout_unlock(out); dbout_unlock(out);
toku_free(bytes);
}
} }
toku_free(bytes);
for (int i=0; i<n_children-1; i++) { for (int i=0; i<n_children-1; i++) {
toku_free(pivots[i].data); toku_free(pivots[i].data);
toku_free(node->u.n.childkeys[i]); toku_free(node->u.n.childkeys[i]);
......
...@@ -101,7 +101,7 @@ check_brtloader-test-bad-generate$(BINSUF): EXTRA_ARGS=dir.$@ ...@@ -101,7 +101,7 @@ check_brtloader-test-bad-generate$(BINSUF): EXTRA_ARGS=dir.$@
check_brtloader-test-extractor-errors$(BINSUF): $(patsubst %,check_brtloader-test-extractor-errors-%, 1 2) check_brtloader-test-extractor-errors$(BINSUF): $(patsubst %,check_brtloader-test-extractor-errors-%, 1 2)
true $(SUMMARIZE_CMD) true $(SUMMARIZE_CMD)
check_brtloader-test-extractor-errors-1: brtloader-test-extractor-errors$(BINSUF) check_brtloader-test-extractor-errors-1: brtloader-test-extractor-errors$(BINSUF)
$(VGRIND) ./$< -q -f -m -u -r 1 dir.$@ $(SUMMARIZE_CMD) $(VGRIND) ./$< -q -w -m -u -r 1 dir.$@ $(SUMMARIZE_CMD)
check_brtloader-test-extractor-errors-2: brtloader-test-extractor-errors$(BINSUF) check_brtloader-test-extractor-errors-2: brtloader-test-extractor-errors$(BINSUF)
$(VGRIND) ./$< -q -m -r 10000 dir.$@ $(SUMMARIZE_CMD) $(VGRIND) ./$< -q -m -r 10000 dir.$@ $(SUMMARIZE_CMD)
...@@ -114,12 +114,14 @@ check_brtloader-test-writer-1: brtloader-test-writer$(BINSUF) ...@@ -114,12 +114,14 @@ check_brtloader-test-writer-1: brtloader-test-writer$(BINSUF)
check_brtloader-test-writer-2: brtloader-test-writer$(BINSUF) check_brtloader-test-writer-2: brtloader-test-writer$(BINSUF)
$(VGRIND) ./$< -q -r 10000000 dir.$@ $(SUMMARIZE_CMD) $(VGRIND) ./$< -q -r 10000000 dir.$@ $(SUMMARIZE_CMD)
check_brtloader-test-writer-errors$(BINSUF): $(patsubst %,check_brtloader-test-writer-errors-%, 1 2) check_brtloader-test-writer-errors$(BINSUF): $(patsubst %,check_brtloader-test-writer-errors-%, 1 2 3)
true $(SUMMARIZE_CMD) true $(SUMMARIZE_CMD)
check_brtloader-test-writer-errors-1: brtloader-test-writer-errors$(BINSUF) check_brtloader-test-writer-errors-1: brtloader-test-writer-errors$(BINSUF)
$(VGRIND) ./$< -q -f -m -u -r 1000000 dir.$@ $(SUMMARIZE_CMD) $(VGRIND) ./$< -q -w -m -u -r 1000000 dir.$@ $(SUMMARIZE_CMD)
check_brtloader-test-writer-errors-2: brtloader-test-writer-errors$(BINSUF) check_brtloader-test-writer-errors-2: brtloader-test-writer-errors$(BINSUF)
$(VGRIND) ./$< -q -s -f -m -u -r 10000 dir.$@ $(SUMMARIZE_CMD) $(VGRIND) ./$< -q -s -w -m -u -r 10000 dir.$@ $(SUMMARIZE_CMD)
check_brtloader-test-writer-errors-3: brtloader-test-writer-errors$(BINSUF)
$(VGRIND) ./$< -q -s -r 10000 --malloc_limit 0 --realloc_errors dir.$@ $(SUMMARIZE_CMD)
brtloader-%$(BINSUF): brtloader-%.$(OEXT) brtloader-%$(BINSUF): brtloader-%.$(OEXT)
ifeq ($(BRTLOADER),cilk) ifeq ($(BRTLOADER),cilk)
......
...@@ -82,6 +82,7 @@ static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) { ...@@ -82,6 +82,7 @@ static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) {
static int do_malloc_errors = 0; static int do_malloc_errors = 0;
static int my_malloc_count = 0, my_big_malloc_count = 0; static int my_malloc_count = 0, my_big_malloc_count = 0;
static int my_realloc_count = 0, my_big_realloc_count = 0; static int my_realloc_count = 0, my_big_realloc_count = 0;
static size_t my_big_malloc_limit = 64*1024;
static void reset_my_malloc_counts(void) { static void reset_my_malloc_counts(void) {
my_malloc_count = my_big_malloc_count = 0; my_malloc_count = my_big_malloc_count = 0;
...@@ -93,7 +94,7 @@ static void *my_malloc(size_t n) { ...@@ -93,7 +94,7 @@ static void *my_malloc(size_t n) {
if (!((void*)toku_malloc <= caller && caller <= (void*)toku_free)) if (!((void*)toku_malloc <= caller && caller <= (void*)toku_free))
goto skip; goto skip;
my_malloc_count++; my_malloc_count++;
if (n >= 64*1024) { if (n >= my_big_malloc_limit) {
my_big_malloc_count++; my_big_malloc_count++;
if (do_malloc_errors) { if (do_malloc_errors) {
caller = __builtin_return_address(1); caller = __builtin_return_address(1);
...@@ -116,7 +117,7 @@ static void *my_realloc(void *p, size_t n) { ...@@ -116,7 +117,7 @@ static void *my_realloc(void *p, size_t n) {
if (!((void*)toku_realloc <= caller && caller <= (void*)toku_free)) if (!((void*)toku_realloc <= caller && caller <= (void*)toku_free))
goto skip; goto skip;
my_realloc_count++; my_realloc_count++;
if (n >= 64*1024) { if (n >= my_big_malloc_limit) {
my_big_realloc_count++; my_big_realloc_count++;
if (do_malloc_errors) { if (do_malloc_errors) {
caller = __builtin_return_address(1); caller = __builtin_return_address(1);
...@@ -254,7 +255,8 @@ static int usage(const char *progname) { ...@@ -254,7 +255,8 @@ static int usage(const char *progname) {
fprintf(stderr, "[--rowsets %d] set the number of rowsets\n", nrowsets); fprintf(stderr, "[--rowsets %d] set the number of rowsets\n", nrowsets);
fprintf(stderr, "[-s] set the small loader size factor\n"); fprintf(stderr, "[-s] set the small loader size factor\n");
fprintf(stderr, "[-m] inject big malloc and realloc errors\n"); fprintf(stderr, "[-m] inject big malloc and realloc errors\n");
fprintf(stderr, "[-f] inject write errors\n"); fprintf(stderr, "[--malloc_limit %u] set the threshold for failing malloc and realloc\n", (unsigned) my_big_malloc_limit);
fprintf(stderr, "[-w] inject write errors\n");
fprintf(stderr, "[-u] inject user errors\n"); fprintf(stderr, "[-u] inject user errors\n");
return 1; return 1;
} }
...@@ -278,12 +280,15 @@ int test_main (int argc, const char *argv[]) { ...@@ -278,12 +280,15 @@ int test_main (int argc, const char *argv[]) {
nrowsets = atoi(argv[0]); nrowsets = atoi(argv[0]);
} else if (strcmp(argv[0],"-s") == 0) { } else if (strcmp(argv[0],"-s") == 0) {
toku_brtloader_set_size_factor(1); toku_brtloader_set_size_factor(1);
} else if (strcmp(argv[0],"-f") == 0) { } else if (strcmp(argv[0],"-w") == 0) {
do_write_errors = 1; do_write_errors = 1;
} else if (strcmp(argv[0],"-m") == 0) { } else if (strcmp(argv[0],"-m") == 0) {
do_malloc_errors = 1; do_malloc_errors = 1;
} else if (strcmp(argv[0],"-u") == 0) { } else if (strcmp(argv[0],"-u") == 0) {
do_user_errors = 1; do_user_errors = 1;
} else if (strcmp(argv[0],"--malloc_limit") == 0 && argc > 1) {
argc--; argv++;
my_big_malloc_limit = atoi(argv[0]);
} else if (strcmp(argv[0],"--max_error_limit") == 0 && argc >= 1) { } else if (strcmp(argv[0],"--max_error_limit") == 0 && argc >= 1) {
argc--; argv++; argc--; argv++;
max_error_limit = atoi(argv[0]); max_error_limit = atoi(argv[0]);
......
...@@ -82,6 +82,7 @@ static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) { ...@@ -82,6 +82,7 @@ static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) {
static int do_malloc_errors = 0; static int do_malloc_errors = 0;
static int my_malloc_count = 0, my_big_malloc_count = 0; static int my_malloc_count = 0, my_big_malloc_count = 0;
static int my_realloc_count = 0, my_big_realloc_count = 0; static int my_realloc_count = 0, my_big_realloc_count = 0;
static size_t my_big_malloc_limit = 64*1024;
static void reset_my_malloc_counts(void) { static void reset_my_malloc_counts(void) {
my_malloc_count = my_big_malloc_count = 0; my_malloc_count = my_big_malloc_count = 0;
...@@ -93,7 +94,7 @@ static void *my_malloc(size_t n) { ...@@ -93,7 +94,7 @@ static void *my_malloc(size_t n) {
if (!((void*)toku_malloc <= caller && caller <= (void*)toku_free)) if (!((void*)toku_malloc <= caller && caller <= (void*)toku_free))
goto skip; goto skip;
my_malloc_count++; my_malloc_count++;
if (n >= 64*1024) { if (n >= my_big_malloc_limit) {
my_big_malloc_count++; my_big_malloc_count++;
if (do_malloc_errors) { if (do_malloc_errors) {
caller = __builtin_return_address(1); caller = __builtin_return_address(1);
...@@ -111,14 +112,16 @@ static void *my_malloc(size_t n) { ...@@ -111,14 +112,16 @@ static void *my_malloc(size_t n) {
return malloc(n); return malloc(n);
} }
static int do_realloc_errors = 0;
static void *my_realloc(void *p, size_t n) { static void *my_realloc(void *p, size_t n) {
void *caller = __builtin_return_address(0); void *caller = __builtin_return_address(0);
if (!((void*)toku_realloc <= caller && caller <= (void*)toku_free)) if (!((void*)toku_realloc <= caller && caller <= (void*)toku_free))
goto skip; goto skip;
my_realloc_count++; my_realloc_count++;
if (n >= 64*1024) { if (n >= my_big_malloc_limit) {
my_big_realloc_count++; my_big_realloc_count++;
if (do_malloc_errors) { if (do_realloc_errors) {
caller = __builtin_return_address(1); caller = __builtin_return_address(1);
if ((void*)toku_xrealloc <= caller && caller <= (void*)toku_malloc_report) if ((void*)toku_xrealloc <= caller && caller <= (void*)toku_malloc_report)
goto skip; goto skip;
...@@ -155,8 +158,8 @@ static void err_cb(DB *db UU(), int dbn UU(), int err UU(), DBT *key UU(), DBT * ...@@ -155,8 +158,8 @@ static void err_cb(DB *db UU(), int dbn UU(), int err UU(), DBT *key UU(), DBT *
abort(); abort();
} }
static void write_dbfile (char *template, int n, char *output_name, BOOL expect_error) { static void write_dbfile (char *template, int n, char *output_name, BOOL expect_error, int testno) {
if (verbose) printf("test start %d %d\n", n, expect_error); if (verbose) printf("test start %d %d testno=%d\n", n, expect_error, testno);
DB *dest_db = NULL; DB *dest_db = NULL;
struct brtloader_s bl = { struct brtloader_s bl = {
...@@ -271,7 +274,8 @@ static int usage(const char *progname, int n) { ...@@ -271,7 +274,8 @@ static int usage(const char *progname, int n) {
fprintf(stderr, "[-r %d] set the number of rows\n", n); fprintf(stderr, "[-r %d] set the number of rows\n", n);
fprintf(stderr, "[-s] set the small loader size factor\n"); fprintf(stderr, "[-s] set the small loader size factor\n");
fprintf(stderr, "[-m] inject big malloc and realloc errors\n"); fprintf(stderr, "[-m] inject big malloc and realloc errors\n");
fprintf(stderr, "[-f] inject write errors\n"); fprintf(stderr, "[--malloc_limit %u] set the threshold for failing malloc and realloc\n", (unsigned) my_big_malloc_limit);
fprintf(stderr, "[-w] inject write errors\n");
fprintf(stderr, "[-u] inject user errors\n"); fprintf(stderr, "[-u] inject user errors\n");
return 1; return 1;
} }
...@@ -292,12 +296,18 @@ int test_main (int argc, const char *argv[]) { ...@@ -292,12 +296,18 @@ int test_main (int argc, const char *argv[]) {
n = atoi(argv[0]); n = atoi(argv[0]);
} else if (strcmp(argv[0],"-s") == 0) { } else if (strcmp(argv[0],"-s") == 0) {
toku_brtloader_set_size_factor(1); toku_brtloader_set_size_factor(1);
} else if (strcmp(argv[0],"-f") == 0) { } else if (strcmp(argv[0],"-w") == 0) {
do_write_errors = 1; do_write_errors = 1;
} else if (strcmp(argv[0],"-m") == 0) { } else if (strcmp(argv[0],"-m") == 0) {
do_malloc_errors = 1; do_malloc_errors = 1;
do_realloc_errors = 1;
} else if (strcmp(argv[0],"-u") == 0) { } else if (strcmp(argv[0],"-u") == 0) {
do_user_errors = 1; do_user_errors = 1;
} else if (strcmp(argv[0],"--realloc_errors") == 0) {
do_realloc_errors = 1;
} else if (strcmp(argv[0],"--malloc_limit") == 0 && argc > 1) {
argc--; argv++;
my_big_malloc_limit = atoi(argv[0]);
} else if (argc!=1) { } else if (argc!=1) {
return usage(progname, n); return usage(progname, n);
} }
...@@ -324,7 +334,7 @@ int test_main (int argc, const char *argv[]) { ...@@ -324,7 +334,7 @@ int test_main (int argc, const char *argv[]) {
int r; int r;
r = system(unlink_all); CKERR(r); r = system(unlink_all); CKERR(r);
r = toku_os_mkdir(directory, 0755); CKERR(r); r = toku_os_mkdir(directory, 0755); CKERR(r);
write_dbfile(template, n, output_name, FALSE); write_dbfile(template, n, output_name, FALSE, 0);
if (verbose) printf("my_malloc_count=%d big_count=%d\n", my_malloc_count, my_big_malloc_count); if (verbose) printf("my_malloc_count=%d big_count=%d\n", my_malloc_count, my_big_malloc_count);
if (verbose) printf("my_realloc_count=%d big_count=%d\n", my_realloc_count, my_big_realloc_count); if (verbose) printf("my_realloc_count=%d big_count=%d\n", my_realloc_count, my_big_realloc_count);
...@@ -333,12 +343,13 @@ int test_main (int argc, const char *argv[]) { ...@@ -333,12 +343,13 @@ int test_main (int argc, const char *argv[]) {
if (verbose) printf("event_limit=%d\n", event_limit); if (verbose) printf("event_limit=%d\n", event_limit);
for (int i = 1; i <= event_limit; i++) { for (int i = 1; i <= event_limit; i++) {
// if (i == 62 || i == 63 || i == 64 || i == 65 || i == 66 || i == 67) continue;
reset_event_counts(); reset_event_counts();
reset_my_malloc_counts(); reset_my_malloc_counts();
event_count_trigger = i; event_count_trigger = i;
r = system(unlink_all); CKERR(r); r = system(unlink_all); CKERR(r);
r = toku_os_mkdir(directory, 0755); CKERR(r); r = toku_os_mkdir(directory, 0755); CKERR(r);
write_dbfile(template, n, output_name, TRUE); write_dbfile(template, n, output_name, TRUE, i);
} }
return 0; return 0;
......
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