Commit a1b14101 authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

closes[t:2622] when realloc fails in the brtloader writer, mark the dbuf in...

closes[t:2622] when realloc fails in the brtloader writer, mark the dbuf in error and check the error later

git-svn-id: file:///svn/toku/tokudb@20350 c7de825b-a66e-492c-adef-691d508d4ae1
parent 84723e0f
...@@ -1752,6 +1752,7 @@ struct dbuf { ...@@ -1752,6 +1752,7 @@ struct dbuf {
unsigned char *buf; unsigned char *buf;
int buflen; int buflen;
int off; int off;
int error;
}; };
struct leaf_buf { struct leaf_buf {
...@@ -1832,10 +1833,12 @@ static void seek_align(struct dbout *out) { ...@@ -1832,10 +1833,12 @@ static void seek_align(struct dbout *out) {
} }
static void dbuf_init (struct dbuf *dbuf) { static void dbuf_init (struct dbuf *dbuf) {
dbuf->buf=0; dbuf->buf = 0;
dbuf->buflen=0; dbuf->buflen = 0;
dbuf->off=0; dbuf->off = 0;
dbuf->error = 0;
} }
static void dbuf_destroy (struct dbuf *dbuf) { static void dbuf_destroy (struct dbuf *dbuf) {
toku_free(dbuf->buf); dbuf->buf = NULL; toku_free(dbuf->buf); dbuf->buf = NULL;
} }
...@@ -1852,6 +1855,7 @@ static int64_t allocate_block (struct dbout *out) ...@@ -1852,6 +1855,7 @@ static int64_t allocate_block (struct dbout *out)
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);
} }
out->n_translations++; out->n_translations++;
dbout_unlock(out); dbout_unlock(out);
...@@ -1860,13 +1864,21 @@ static int64_t allocate_block (struct dbout *out) ...@@ -1860,13 +1864,21 @@ static int64_t allocate_block (struct dbout *out)
static void putbuf_bytes (struct dbuf *dbuf, const void *bytes, int nbytes) { static void putbuf_bytes (struct dbuf *dbuf, const void *bytes, int nbytes) {
if (dbuf->off + nbytes > dbuf->buflen) { if (dbuf->off + nbytes > dbuf->buflen) {
void *oldbuf = dbuf->buf;
int oldbuflen = dbuf->buflen;
dbuf->buflen += dbuf->off + nbytes; dbuf->buflen += dbuf->off + nbytes;
dbuf->buflen *= 2; dbuf->buflen *= 2;
REALLOC_N(dbuf->buflen, dbuf->buf); REALLOC_N(dbuf->buflen, dbuf->buf);
lazy_assert(dbuf->buf); if (dbuf->buf == NULL) {
dbuf->error = errno;
dbuf->buf = oldbuf;
dbuf->buflen = oldbuflen;
}
} }
if (!dbuf->error) {
memcpy(dbuf->buf + dbuf->off, bytes, nbytes); memcpy(dbuf->buf + dbuf->off, bytes, nbytes);
dbuf->off += nbytes; dbuf->off += nbytes;
}
} }
static void putbuf_int8 (struct dbuf *dbuf, unsigned char v) { static void putbuf_int8 (struct dbuf *dbuf, unsigned char v) {
...@@ -1876,6 +1888,7 @@ static void putbuf_int8 (struct dbuf *dbuf, unsigned char v) { ...@@ -1876,6 +1888,7 @@ static void putbuf_int8 (struct dbuf *dbuf, unsigned char v) {
static void putbuf_int32 (struct dbuf *dbuf, int v) { static void putbuf_int32 (struct dbuf *dbuf, int v) {
putbuf_bytes(dbuf, &v, 4); putbuf_bytes(dbuf, &v, 4);
} }
static void putbuf_int64 (struct dbuf *dbuf, unsigned long long v) { static void putbuf_int64 (struct dbuf *dbuf, unsigned long long v) {
putbuf_int32(dbuf, v>>32); putbuf_int32(dbuf, v>>32);
putbuf_int32(dbuf, v&0xFFFFFFFF); putbuf_int32(dbuf, v&0xFFFFFFFF);
...@@ -1884,13 +1897,21 @@ static void putbuf_int64 (struct dbuf *dbuf, unsigned long long v) { ...@@ -1884,13 +1897,21 @@ static void putbuf_int64 (struct dbuf *dbuf, unsigned long long v) {
static void putbuf_int32_at(struct dbuf *dbuf, int off, int v) { static void putbuf_int32_at(struct dbuf *dbuf, int off, int v) {
const int nbytes = 4; const int nbytes = 4;
if (off+nbytes > dbuf->buflen) { if (off+nbytes > dbuf->buflen) {
void *oldbuf = dbuf->buf;
int oldbuflen = dbuf->buflen;
dbuf->buflen += dbuf->off + nbytes; dbuf->buflen += dbuf->off + nbytes;
dbuf->buflen *= 2; dbuf->buflen *= 2;
REALLOC_N(dbuf->buflen, dbuf->buf); REALLOC_N(dbuf->buflen, dbuf->buf);
lazy_assert(dbuf->buf); if (dbuf->buf == NULL) {
dbuf->error = errno;
dbuf->buf = oldbuf;
dbuf->buflen = oldbuflen;
} }
}
if (!dbuf->error)
memcpy(dbuf->buf + off, &v, 4); memcpy(dbuf->buf + off, &v, 4);
} }
static void putbuf_int64_at(struct dbuf *dbuf, int off, unsigned long long v) { static void putbuf_int64_at(struct dbuf *dbuf, int off, unsigned long long v) {
unsigned int a = v>>32; unsigned int a = v>>32;
unsigned int b = v&0xFFFFFFFF; unsigned int b = v&0xFFFFFFFF;
...@@ -2428,6 +2449,7 @@ static void add_pair_to_leafnode (struct leaf_buf *lbuf, unsigned char *key, int ...@@ -2428,6 +2449,7 @@ static void add_pair_to_leafnode (struct leaf_buf *lbuf, unsigned char *key, int
putbuf_bytes(&lbuf->dbuf, key, keylen); putbuf_bytes(&lbuf->dbuf, key, keylen);
putbuf_bytes(&lbuf->dbuf, val, vallen); putbuf_bytes(&lbuf->dbuf, val, vallen);
int le_len = 1+4+4+keylen+vallen; int le_len = 1+4+4+keylen+vallen;
if (!lbuf->dbuf.error) {
invariant(le_off + le_len == lbuf->dbuf.off); invariant(le_off + le_len == lbuf->dbuf.off);
u_int32_t this_x = x1764_memory(lbuf->dbuf.buf + le_off, le_len); u_int32_t this_x = x1764_memory(lbuf->dbuf.buf + le_off, le_len);
u_int32_t this_prod = lbuf->rand4fingerprint * this_x; u_int32_t this_prod = lbuf->rand4fingerprint * this_x;
...@@ -2438,6 +2460,7 @@ static void add_pair_to_leafnode (struct leaf_buf *lbuf, unsigned char *key, int ...@@ -2438,6 +2460,7 @@ static void add_pair_to_leafnode (struct leaf_buf *lbuf, unsigned char *key, int
printf("%s:%d this_prod=%8x\n", __FILE__, __LINE__, this_prod); printf("%s:%d this_prod=%8x\n", __FILE__, __LINE__, this_prod);
printf("%s:%d local_fingerprint=%8x\n", __FILE__, __LINE__, lbuf->local_fingerprint); printf("%s:%d local_fingerprint=%8x\n", __FILE__, __LINE__, lbuf->local_fingerprint);
} }
}
} }
static int write_literal(struct dbout *out, void*data, size_t len) { static int write_literal(struct dbout *out, void*data, size_t len) {
...@@ -2470,6 +2493,9 @@ static void finish_leafnode (struct dbout *out, struct leaf_buf *lbuf, int progr ...@@ -2470,6 +2493,9 @@ static void finish_leafnode (struct dbout *out, struct leaf_buf *lbuf, int progr
putbuf_int32_at(&lbuf->dbuf, lbuf->n_in_buf_p, lbuf->n_in_buf); putbuf_int32_at(&lbuf->dbuf, lbuf->n_in_buf_p, lbuf->n_in_buf);
result = lbuf->dbuf.error;
if (result == 0) {
//print_bytestring(lbuf->dbuf.buf, lbuf->dbuf.off, 200); //print_bytestring(lbuf->dbuf.buf, lbuf->dbuf.off, 200);
int n_uncompressed_bytes_at_beginning = (8 // tokuleaf int n_uncompressed_bytes_at_beginning = (8 // tokuleaf
...@@ -2541,12 +2567,12 @@ static void finish_leafnode (struct dbout *out, struct leaf_buf *lbuf, int progr ...@@ -2541,12 +2567,12 @@ static void finish_leafnode (struct dbout *out, struct leaf_buf *lbuf, int progr
seek_align_locked(out); seek_align_locked(out);
} }
dbout_unlock(out); dbout_unlock(out);
} }
toku_free(sub_block); // RFP cilk++ bug toku_free(sub_block); // RFP cilk++ bug
toku_free(compressed_buf); toku_free(compressed_buf);
}
dbuf_destroy(&lbuf->dbuf); dbuf_destroy(&lbuf->dbuf);
toku_free(lbuf); toku_free(lbuf);
......
...@@ -81,9 +81,11 @@ static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) { ...@@ -81,9 +81,11 @@ static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) {
static int my_malloc_event = 0; static int my_malloc_event = 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 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;
my_realloc_count = my_big_realloc_count = 0;
} }
static void *my_malloc(size_t n) { static void *my_malloc(size_t n) {
...@@ -109,6 +111,29 @@ static void *my_malloc(size_t n) { ...@@ -109,6 +111,29 @@ static void *my_malloc(size_t n) {
return malloc(n); return malloc(n);
} }
static void *my_realloc(void *p, size_t n) {
void *caller = __builtin_return_address(0);
if (!((void*)toku_realloc <= caller && caller <= (void*)toku_free))
goto skip;
my_realloc_count++;
if (n >= 64*1024) {
my_big_realloc_count++;
if (my_malloc_event) {
caller = __builtin_return_address(1);
if ((void*)toku_xrealloc <= caller && caller <= (void*)toku_malloc_report)
goto skip;
event_count++;
if (event_count == event_count_trigger) {
event_hit();
errno = ENOMEM;
return NULL;
}
}
}
skip:
return realloc(p, n);
}
static int qsort_compare_ints (const void *a, const void *b) { static int qsort_compare_ints (const void *a, const void *b) {
int avalue = *(int*)a; int avalue = *(int*)a;
int bvalue = *(int*)b; int bvalue = *(int*)b;
...@@ -207,6 +232,7 @@ static void write_dbfile (char *template, int n, char *output_name, BOOL expect_ ...@@ -207,6 +232,7 @@ static void write_dbfile (char *template, int n, char *output_name, BOOL expect_
assert(fd>=0); assert(fd>=0);
toku_set_func_malloc(my_malloc); toku_set_func_malloc(my_malloc);
toku_set_func_realloc(my_realloc);
brtloader_set_os_fwrite(bad_fwrite); brtloader_set_os_fwrite(bad_fwrite);
toku_set_func_write(bad_write); toku_set_func_write(bad_write);
toku_set_func_pwrite(bad_pwrite); toku_set_func_pwrite(bad_pwrite);
...@@ -217,6 +243,7 @@ static void write_dbfile (char *template, int n, char *output_name, BOOL expect_ ...@@ -217,6 +243,7 @@ static void write_dbfile (char *template, int n, char *output_name, BOOL expect_
assert(expect_error ? r != 0 : r == 0); assert(expect_error ? r != 0 : r == 0);
toku_set_func_malloc(NULL); toku_set_func_malloc(NULL);
toku_set_func_realloc(NULL);
brtloader_set_os_fwrite(NULL); brtloader_set_os_fwrite(NULL);
toku_set_func_write(NULL); toku_set_func_write(NULL);
toku_set_func_pwrite(NULL); toku_set_func_pwrite(NULL);
...@@ -289,6 +316,7 @@ int test_main (int argc, const char *argv[]) { ...@@ -289,6 +316,7 @@ int test_main (int argc, const char *argv[]) {
write_dbfile(template, n, output_name, FALSE); write_dbfile(template, n, output_name, FALSE);
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);
int event_limit = event_count; int event_limit = event_count;
if (verbose) printf("event_limit=%d\n", event_limit); if (verbose) printf("event_limit=%d\n", event_limit);
......
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