1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# 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
|