From 39b235fa430f9abad9f7562ff883517befe4cee7 Mon Sep 17 00:00:00 2001 From: Rich Prohaska <prohaska@tokutek.com> Date: Fri, 12 Mar 2010 14:06:45 +0000 Subject: [PATCH] merge -c 18380 from 3.0.5 to main refs[t:2436] git-svn-id: file:///svn/toku/tokudb@18382 c7de825b-a66e-492c-adef-691d508d4ae1 --- linux/file.c | 93 +++++++++++++++++++++--------------------- src/export.map | 1 + src/tests/diskfull.c | 1 + toku_include/toku_os.h | 3 ++ 4 files changed, 52 insertions(+), 46 deletions(-) diff --git a/linux/file.c b/linux/file.c index 1cea316324..febd9c0e25 100644 --- a/linux/file.c +++ b/linux/file.c @@ -8,20 +8,17 @@ #include <string.h> #include <time.h> -static uint64_t get_tnow(void) { - struct timeval tv; - int r = gettimeofday(&tv, NULL); assert(r == 0); - return tv.tv_sec * 1000000ULL + tv.tv_usec; -} - -#define DO_ASSERT_ON_ENOSPC 1 - +static int toku_assert_on_write_enospc = 0; static const int toku_write_enospc_sleep = 1; static uint64_t toku_write_enospc_last_report; static uint64_t toku_write_enospc_last_time; static uint32_t toku_write_enospc_current; static uint64_t toku_write_enospc_total; +void toku_set_assert_on_write_enospc(int do_assert) { + toku_assert_on_write_enospc = do_assert; +} + void toku_fs_get_write_info(uint64_t *enospc_last_time, uint64_t *enospc_current, uint64_t *enospc_total) { *enospc_last_time = toku_write_enospc_last_time; @@ -48,46 +45,45 @@ try_again_after_handling_write_error(int fd, size_t len, ssize_t r_write) { break; } case ENOSPC: { -#if DO_ASSERT_ON_ENOSPC - toku_write_enospc_last_report = get_tnow(); - char err_msg[sizeof("Failed write of [] bytes to fd=[].") + 20+10]; //64 bit is 20 chars, 32 bit is 10 chars - snprintf(err_msg, sizeof(err_msg), "Failed write of [%"PRIu64"] bytes to fd=[%d].", (uint64_t)len, fd); - perror(err_msg); - fflush(stderr); - int out_of_disk_space = 1; - assert(!out_of_disk_space); //Give an error message that might be useful if this is the only one that survives. -#else - toku_sync_fetch_and_increment_uint64(&toku_write_enospc_total); - toku_sync_fetch_and_increment_uint32(&toku_write_enospc_current); - - uint64_t tnow = get_tnow(); - toku_write_enospc_last_time = tnow; - if (toku_write_enospc_last_report == 0 || tnow - toku_write_enospc_last_report >= 60*1000000) { - toku_write_enospc_last_report = tnow; - - const int tstr_length = 26; - char tstr[tstr_length]; - time_t t = time(0); - ctime_r(&t, tstr); - - const int MY_MAX_PATH = 256; - char fname[MY_MAX_PATH], symname[MY_MAX_PATH]; - sprintf(fname, "/proc/%d/fd/%d", getpid(), fd); - ssize_t n = readlink(fname, symname, MY_MAX_PATH); - - if ((int)n == -1) - fprintf(stderr, "%.24s Tokudb No space when writing %"PRIu64" bytes to fd=%d ", tstr, (uint64_t) len, fd); - else - fprintf(stderr, "%.24s Tokudb No space when writing %"PRIu64" bytes to %*s ", tstr, (uint64_t) len, (int) n, symname); - fprintf(stderr, "retry in %d second%s\n", toku_write_enospc_sleep, toku_write_enospc_sleep > 1 ? "s" : ""); + if (toku_assert_on_write_enospc) { + char err_msg[sizeof("Failed write of [] bytes to fd=[].") + 20+10]; //64 bit is 20 chars, 32 bit is 10 chars + snprintf(err_msg, sizeof(err_msg), "Failed write of [%"PRIu64"] bytes to fd=[%d].", (uint64_t)len, fd); + perror(err_msg); fflush(stderr); + int out_of_disk_space = 1; + assert(!out_of_disk_space); //Give an error message that might be useful if this is the only one that survives. + } else { + toku_sync_fetch_and_increment_uint64(&toku_write_enospc_total); + toku_sync_fetch_and_increment_uint32(&toku_write_enospc_current); + + time_t tnow = time(0); + toku_write_enospc_last_time = tnow; + if (toku_write_enospc_last_report == 0 || tnow - toku_write_enospc_last_report >= 60) { + toku_write_enospc_last_report = tnow; + + const int tstr_length = 26; + char tstr[tstr_length]; + time_t t = time(0); + ctime_r(&t, tstr); + + const int MY_MAX_PATH = 256; + char fname[MY_MAX_PATH], symname[MY_MAX_PATH]; + sprintf(fname, "/proc/%d/fd/%d", getpid(), fd); + ssize_t n = readlink(fname, symname, MY_MAX_PATH); + + if ((int)n == -1) + fprintf(stderr, "%.24s Tokudb No space when writing %"PRIu64" bytes to fd=%d ", tstr, (uint64_t) len, fd); + else + fprintf(stderr, "%.24s Tokudb No space when writing %"PRIu64" bytes to %*s ", tstr, (uint64_t) len, (int) n, symname); + fprintf(stderr, "retry in %d second%s\n", toku_write_enospc_sleep, toku_write_enospc_sleep > 1 ? "s" : ""); + fflush(stderr); + } + sleep(toku_write_enospc_sleep); + try_again = 1; + toku_sync_fetch_and_decrement_uint32(&toku_write_enospc_current); + break; } - sleep(toku_write_enospc_sleep); - try_again = 1; - toku_sync_fetch_and_decrement_uint32(&toku_write_enospc_current); - break; -#endif - } + } default: break; } @@ -197,6 +193,11 @@ toku_file_fsync_without_accounting (int fd) { return r; } +static uint64_t get_tnow(void) { + struct timeval tv; + int r = gettimeofday(&tv, NULL); assert(r == 0); + return tv.tv_sec * 1000000ULL + tv.tv_usec; +} // keep trying if fsync fails because of EINTR int diff --git a/src/export.map b/src/export.map index 0dc165cf11..ea36218620 100644 --- a/src/export.map +++ b/src/export.map @@ -62,6 +62,7 @@ toku_os_get_phys_memory_size; toku_do_assert_fail; + toku_set_assert_on_write_enospc; test_db_redirect_dictionary; local: *; diff --git a/src/tests/diskfull.c b/src/tests/diskfull.c index 6b03226cad..50204b3cd8 100644 --- a/src/tests/diskfull.c +++ b/src/tests/diskfull.c @@ -163,6 +163,7 @@ write_counting_and_failing (int fd, const void *buf, size_t size) static void do_writes_that_fail (void) { + toku_set_assert_on_write_enospc(TRUE); db_env_set_func_pwrite(pwrite_counting_and_failing); db_env_set_func_write (write_counting_and_failing); write_count=0; diff --git a/toku_include/toku_os.h b/toku_include/toku_os.h index a982533bc8..b21f855967 100644 --- a/toku_include/toku_os.h +++ b/toku_include/toku_os.h @@ -67,6 +67,9 @@ int toku_os_initialize_settings(int verbosity) __attribute__((__visibility__("d // int toku_os_is_absolute_name(const char* path) __attribute__((__visibility__("default"))); +// Set whether or not writes assert when ENOSPC is returned or they wait for space +void toku_set_assert_on_write_enospc(int do_assert) __attribute__((__visibility__("default"))); + // Get file system write information // *enospc_last_time is the last time ENOSPC was returned by write or pwrite // *enospc_current is the number of threads waiting on space -- 2.30.9