Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfe27009

Browse files
committed
Recognize network-failure errnos as indicating hard connection loss.
Up to now, only ECONNRESET (and EPIPE, in most but not quite all places)received special treatment in our error handling logic. This patchchanges things so that related error codes such as ECONNABORTED arealso recognized as indicating that the connection's dead and unlikelyto come back.We continue to think, however, that only ECONNRESET and EPIPE should bereported as probable server crashes; the other cases indicate networkconnectivity problems but prove little about the server's state. Thus,there's no change in the error message texts that are output for suchcases. The key practical effect is that errcode_for_socket_access()will report ERRCODE_CONNECTION_FAILURE rather thanERRCODE_INTERNAL_ERROR for a network failure. It's expected that thiswill fix buildfarm member lorikeet's failures since commit32a9c0b,as that seems to be due to not treating ECONNABORTED equivalently toECONNRESET.The set of errnos treated this way now includes ECONNABORTED, EHOSTDOWN,EHOSTUNREACH, ENETDOWN, ENETRESET, and ENETUNREACH. Several of thesewere second-class citizens in terms of their handling in places likeget_errno_symbol(), so upgrade the infrastructure where necessary.As committed, this patch assumes that all these symbols are definedeverywhere. POSIX specifies all of them except EHOSTDOWN, but thatseems to exist on all platforms of interest; we'll see what thebuildfarm says about that.Probably this should be back-patched, but let's see what the buildfarmthinks of it first.Fujii Masao and Tom LaneDiscussion:https://postgr.es/m/2621622.1602184554@sss.pgh.pa.us
1 parented30b1a commitfe27009

File tree

9 files changed

+96
-58
lines changed

9 files changed

+96
-58
lines changed

‎src/backend/port/win32/socket.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,21 @@ TranslateSocketError(void)
120120
caseWSAEADDRNOTAVAIL:
121121
errno=EADDRNOTAVAIL;
122122
break;
123-
caseWSAEHOSTUNREACH:
124123
caseWSAEHOSTDOWN:
124+
errno=EHOSTDOWN;
125+
break;
126+
caseWSAEHOSTUNREACH:
125127
caseWSAHOST_NOT_FOUND:
128+
errno=EHOSTUNREACH;
129+
break;
126130
caseWSAENETDOWN:
131+
errno=ENETDOWN;
132+
break;
127133
caseWSAENETUNREACH:
134+
errno=ENETUNREACH;
135+
break;
128136
caseWSAENETRESET:
129-
errno=EHOSTUNREACH;
137+
errno=ENETRESET;
130138
break;
131139
caseWSAENOTCONN:
132140
caseWSAESHUTDOWN:

‎src/backend/utils/error/elog.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -711,10 +711,7 @@ errcode_for_socket_access(void)
711711
switch (edata->saved_errno)
712712
{
713713
/* Loss of connection */
714-
caseEPIPE:
715-
#ifdefECONNRESET
716-
caseECONNRESET:
717-
#endif
714+
caseALL_CONNECTION_FAILURE_ERRNOS:
718715
edata->sqlerrcode=ERRCODE_CONNECTION_FAILURE;
719716
break;
720717

‎src/bin/pg_dump/parallel.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,10 +1825,15 @@ piperead(int s, char *buf, int len)
18251825
{
18261826
intret=recv(s,buf,len,0);
18271827

1828-
if (ret<0&&WSAGetLastError()==WSAECONNRESET)
1828+
if (ret<0)
18291829
{
1830-
/* EOF on the pipe! */
1831-
ret=0;
1830+
switch (TranslateSocketError())
1831+
{
1832+
caseALL_CONNECTION_FAILURE_ERRNOS:
1833+
/* Treat connection loss as EOF on the pipe */
1834+
ret=0;
1835+
break;
1836+
}
18321837
}
18331838
returnret;
18341839
}

‎src/include/port.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,28 @@ extern void pgfnames_cleanup(char **filenames);
9999
)
100100
#endif
101101

102+
/*
103+
* This macro provides a centralized list of all errnos that identify
104+
* hard failure of a previously-established network connection.
105+
* The macro is intended to be used in a switch statement, in the form
106+
* "case ALL_CONNECTION_FAILURE_ERRNOS:".
107+
*
108+
* Note: this groups EPIPE and ECONNRESET, which we take to indicate a
109+
* probable server crash, with other errors that indicate loss of network
110+
* connectivity without proving much about the server's state. Places that
111+
* are actually reporting errors typically single out EPIPE and ECONNRESET,
112+
* while allowing the network failures to be reported generically.
113+
*/
114+
#defineALL_CONNECTION_FAILURE_ERRNOS \
115+
EPIPE: \
116+
case ECONNRESET: \
117+
case ECONNABORTED: \
118+
case EHOSTDOWN: \
119+
case EHOSTUNREACH: \
120+
case ENETDOWN: \
121+
case ENETRESET: \
122+
case ENETUNREACH
123+
102124
/* Portable locale initialization (in exec.c) */
103125
externvoidset_pglocale_pgservice(constchar*argv0,constchar*app);
104126

‎src/include/port/win32_port.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,16 @@ extern int_pgstat64(const char *name, struct stat *buf);
369369
#defineEADDRINUSE WSAEADDRINUSE
370370
#undef EADDRNOTAVAIL
371371
#defineEADDRNOTAVAIL WSAEADDRNOTAVAIL
372+
#undef EHOSTDOWN
373+
#defineEHOSTDOWN WSAEHOSTDOWN
372374
#undef EHOSTUNREACH
373375
#defineEHOSTUNREACH WSAEHOSTUNREACH
376+
#undef ENETDOWN
377+
#defineENETDOWN WSAENETDOWN
378+
#undef ENETRESET
379+
#defineENETRESET WSAENETRESET
380+
#undef ENETUNREACH
381+
#defineENETUNREACH WSAENETUNREACH
374382
#undef ENOTCONN
375383
#defineENOTCONN WSAENOTCONN
376384

‎src/interfaces/libpq/fe-misc.c

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -668,24 +668,29 @@ pqReadData(PGconn *conn)
668668
conn->inBufSize-conn->inEnd);
669669
if (nread<0)
670670
{
671-
if (SOCK_ERRNO==EINTR)
672-
gotoretry3;
673-
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
671+
switch (SOCK_ERRNO)
672+
{
673+
caseEINTR:
674+
gotoretry3;
675+
676+
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
674677
#ifdefEAGAIN
675-
if (SOCK_ERRNO==EAGAIN)
676-
returnsomeread;
678+
caseEAGAIN:
679+
returnsomeread;
677680
#endif
678681
#if defined(EWOULDBLOCK)&& (!defined(EAGAIN)|| (EWOULDBLOCK!=EAGAIN))
679-
if (SOCK_ERRNO==EWOULDBLOCK)
680-
returnsomeread;
682+
caseEWOULDBLOCK:
683+
returnsomeread;
681684
#endif
682-
/* We might get ECONNRESET here if using TCP and backend died */
683-
#ifdefECONNRESET
684-
if (SOCK_ERRNO==ECONNRESET)
685-
gotodefinitelyFailed;
686-
#endif
687-
/* pqsecure_read set the error message for us */
688-
return-1;
685+
686+
/* We might get ECONNRESET etc here if connection failed */
687+
caseALL_CONNECTION_FAILURE_ERRNOS:
688+
gotodefinitelyFailed;
689+
690+
default:
691+
/* pqsecure_read set the error message for us */
692+
return-1;
693+
}
689694
}
690695
if (nread>0)
691696
{
@@ -758,24 +763,29 @@ pqReadData(PGconn *conn)
758763
conn->inBufSize-conn->inEnd);
759764
if (nread<0)
760765
{
761-
if (SOCK_ERRNO==EINTR)
762-
gotoretry4;
763-
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
766+
switch (SOCK_ERRNO)
767+
{
768+
caseEINTR:
769+
gotoretry4;
770+
771+
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
764772
#ifdefEAGAIN
765-
if (SOCK_ERRNO==EAGAIN)
766-
return0;
773+
caseEAGAIN:
774+
return0;
767775
#endif
768776
#if defined(EWOULDBLOCK)&& (!defined(EAGAIN)|| (EWOULDBLOCK!=EAGAIN))
769-
if (SOCK_ERRNO==EWOULDBLOCK)
770-
return0;
777+
caseEWOULDBLOCK:
778+
return0;
771779
#endif
772-
/* We might get ECONNRESET here if using TCP and backend died */
773-
#ifdefECONNRESET
774-
if (SOCK_ERRNO==ECONNRESET)
775-
gotodefinitelyFailed;
776-
#endif
777-
/* pqsecure_read set the error message for us */
778-
return-1;
780+
781+
/* We might get ECONNRESET etc here if connection failed */
782+
caseALL_CONNECTION_FAILURE_ERRNOS:
783+
gotodefinitelyFailed;
784+
785+
default:
786+
/* pqsecure_read set the error message for us */
787+
return-1;
788+
}
779789
}
780790
if (nread>0)
781791
{

‎src/interfaces/libpq/fe-secure.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,13 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
261261
/* no error message, caller is expected to retry */
262262
break;
263263

264-
#ifdefECONNRESET
264+
caseEPIPE:
265265
caseECONNRESET:
266266
printfPQExpBuffer(&conn->errorMessage,
267267
libpq_gettext("server closed the connection unexpectedly\n"
268268
"\tThis probably means the server terminated abnormally\n"
269269
"\tbefore or while processing the request.\n"));
270270
break;
271-
#endif
272271

273272
default:
274273
printfPQExpBuffer(&conn->errorMessage,
@@ -374,11 +373,9 @@ pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
374373
/* Set flag for EPIPE */
375374
REMEMBER_EPIPE(spinfo, true);
376375

377-
#ifdefECONNRESET
378376
/* FALL THRU */
379377

380378
caseECONNRESET:
381-
#endif
382379
printfPQExpBuffer(&conn->errorMessage,
383380
libpq_gettext("server closed the connection unexpectedly\n"
384381
"\tThis probably means the server terminated abnormally\n"

‎src/interfaces/libpq/win32.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,6 @@
1414
#definewrite(a,b,c) _write(a,b,c)
1515

1616
#undef EAGAIN/* doesn't apply on sockets */
17-
#undef EINTR
18-
#defineEINTR WSAEINTR
19-
#ifndefEWOULDBLOCK
20-
#defineEWOULDBLOCK WSAEWOULDBLOCK
21-
#endif
22-
#ifndefECONNRESET
23-
#defineECONNRESET WSAECONNRESET
24-
#endif
25-
#ifndefEINPROGRESS
26-
#defineEINPROGRESS WSAEINPROGRESS
27-
#endif
2817

2918
/*
3019
* support for handling Windows Socket errors

‎src/port/strerror.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,16 +146,12 @@ get_errno_symbol(int errnum)
146146
return"EBUSY";
147147
caseECHILD:
148148
return"ECHILD";
149-
#ifdefECONNABORTED
150149
caseECONNABORTED:
151150
return"ECONNABORTED";
152-
#endif
153151
caseECONNREFUSED:
154152
return"ECONNREFUSED";
155-
#ifdefECONNRESET
156153
caseECONNRESET:
157154
return"ECONNRESET";
158-
#endif
159155
caseEDEADLK:
160156
return"EDEADLK";
161157
caseEDOM:
@@ -166,10 +162,10 @@ get_errno_symbol(int errnum)
166162
return"EFAULT";
167163
caseEFBIG:
168164
return"EFBIG";
169-
#ifdefEHOSTUNREACH
165+
caseEHOSTDOWN:
166+
return"EHOSTDOWN";
170167
caseEHOSTUNREACH:
171168
return"EHOSTUNREACH";
172-
#endif
173169
caseEIDRM:
174170
return"EIDRM";
175171
caseEINPROGRESS:
@@ -198,6 +194,12 @@ get_errno_symbol(int errnum)
198194
return"EMSGSIZE";
199195
caseENAMETOOLONG:
200196
return"ENAMETOOLONG";
197+
caseENETDOWN:
198+
return"ENETDOWN";
199+
caseENETRESET:
200+
return"ENETRESET";
201+
caseENETUNREACH:
202+
return"ENETUNREACH";
201203
caseENFILE:
202204
return"ENFILE";
203205
caseENOBUFS:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp