# name : innodb_bug60788.patch # maintainer : Alexey # # Fix for MySQL bug #60788: InnoDB crashes with an assertion failure when # receiving a signal on pwrite() # # Changes InnoDB IO code so that fsync(), pread() and pwrite() are restarted # when interrupted by a signal. # diff -ruN a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c --- a/storage/innobase/os/os0file.c 2011-04-20 12:09:57.000000000 +0400 +++ b/storage/innobase/os/os0file.c 2011-04-20 12:10:04.000000000 +0400 @@ -2083,6 +2083,9 @@ failures++; retry = TRUE; + } else if (ret == -1 && errno == EINTR) { + /* Handle signal interruptions correctly */ + retry = TRUE; } else { retry = FALSE; @@ -2212,6 +2215,7 @@ off_t offs; #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD) ssize_t n_bytes; + ssize_t n_read; #endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */ ulint sec; ulint ms; @@ -2252,7 +2256,18 @@ os_n_pending_reads++; os_mutex_exit(os_file_count_mutex); - n_bytes = pread(file, buf, (ssize_t)n, offs); + /* Handle signal interruptions correctly */ + for (n_bytes = 0; n_bytes < (ssize_t) n; ) { + n_read = pread(file, buf, (ssize_t)n, offs); + if (n_read > 0) { + n_bytes += n_read; + offs += n_read; + } else if (n_read == -1 && errno == EINTR) { + continue; + } else { + break; + } + } os_mutex_enter(os_file_count_mutex); os_file_n_pending_preads--; @@ -2271,6 +2286,7 @@ { off_t ret_offset; ssize_t ret; + ssize_t n_read; #ifndef UNIV_HOTBACKUP ulint i; #endif /* !UNIV_HOTBACKUP */ @@ -2291,7 +2307,17 @@ if (ret_offset < 0) { ret = -1; } else { - ret = read(file, buf, (ssize_t)n); + /* Handle signal interruptions correctly */ + for (ret = 0; ret < (ssize_t) n; ) { + n_read = read(file, buf, (ssize_t)n); + if (n_read > 0) { + ret += n_read; + } else if (n_read == -1 && errno == EINTR) { + continue; + } else { + break; + } + } } #ifndef UNIV_HOTBACKUP @@ -2330,6 +2356,7 @@ offset */ { ssize_t ret; + ssize_t n_written; off_t offs; ut_a((offset & 0xFFFFFFFFUL) == offset); @@ -2357,7 +2384,18 @@ os_n_pending_writes++; os_mutex_exit(os_file_count_mutex); - ret = pwrite(file, buf, (ssize_t)n, offs); + /* Handle signal interruptions correctly */ + for (ret = 0; ret < (ssize_t) n; ) { + n_written = pwrite(file, buf, (ssize_t)n, offs); + if (n_written > 0) { + ret += n_written; + offs += n_written; + } else if (n_written == -1 && errno == EINTR) { + continue; + } else { + break; + } + } os_mutex_enter(os_file_count_mutex); os_file_n_pending_pwrites--; @@ -2404,7 +2442,17 @@ goto func_exit; } - ret = write(file, buf, (ssize_t)n); + /* Handle signal interruptions correctly */ + for (ret = 0; ret < (ssize_t) n; ) { + n_written = write(file, buf, (ssize_t)n); + if (n_written > 0) { + ret += n_written; + } else if (n_written == -1 && errno == EINTR) { + continue; + } else { + break; + } + } # ifdef UNIV_DO_FLUSH if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC