proxy: Deal with close() failures (and EINTR errnos) comprehensively
This commit is contained in:
27
src/proxy.c
27
src/proxy.c
@@ -90,8 +90,9 @@ int proxy_connect_to_upstream( struct proxier* proxy )
|
||||
}
|
||||
|
||||
if( !socket_nbd_read_hello( fd, &size ) ) {
|
||||
FATAL_IF_NEGATIVE(
|
||||
close( fd ), SHOW_ERRNO( "FIXME: shouldn't be fatal" )
|
||||
WARN_IF_NEGATIVE(
|
||||
sock_try_close( fd ),
|
||||
"Couldn't close() after failed read of NBD hello on fd %i", fd
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
@@ -114,10 +115,10 @@ void proxy_disconnect_from_upstream( struct proxier* proxy )
|
||||
debug(" Closing upstream connection" );
|
||||
|
||||
/* TODO: An NBD disconnect would be pleasant here */
|
||||
|
||||
FATAL_IF_NEGATIVE(
|
||||
close( proxy->upstream_fd ),
|
||||
SHOW_ERRNO( "FIXME: shouldn't be fatal" )
|
||||
WARN_IF_NEGATIVE(
|
||||
sock_try_close( proxy->upstream_fd ),
|
||||
"Failed to close() fd %i when disconnecting from upstream",
|
||||
proxy->upstream_fd
|
||||
);
|
||||
proxy->upstream_fd = -1;
|
||||
}
|
||||
@@ -442,10 +443,11 @@ int proxy_accept( struct proxier* params )
|
||||
params->downstream_fd = client_fd;
|
||||
proxy_session( params );
|
||||
|
||||
if ( close( params->downstream_fd ) == -1 ) {
|
||||
warn( SHOW_ERRNO( "FIXME: close returned" ) );
|
||||
}
|
||||
|
||||
WARN_IF_NEGATIVE(
|
||||
sock_try_close( params->downstream_fd ),
|
||||
"Couldn't close() downstram fd %i after proxy session",
|
||||
params->downstream_fd
|
||||
);
|
||||
params->downstream_fd = -1;
|
||||
}
|
||||
|
||||
@@ -467,7 +469,10 @@ void proxy_cleanup( struct proxier* params )
|
||||
info( "cleaning up" );
|
||||
|
||||
if ( -1 != params->listen_fd ) {
|
||||
close( params->listen_fd );
|
||||
WARN_IF_NEGATIVE(
|
||||
sock_try_close( params->listen_fd ),
|
||||
"Failed to close() listen_fd %i", params->listen_fd
|
||||
);
|
||||
}
|
||||
|
||||
debug( "Cleanup done" );
|
||||
|
@@ -216,3 +216,24 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
int sock_try_close( int fd )
|
||||
{
|
||||
int result;
|
||||
|
||||
do {
|
||||
result = close( fd );
|
||||
|
||||
if ( result == -1 ) {
|
||||
if ( EINTR == errno ) {
|
||||
continue; /* retry EINTR */
|
||||
} else {
|
||||
warn( SHOW_ERRNO( "Failed to close() fd %i", fd ) );
|
||||
break; /* Other errors get reported */
|
||||
}
|
||||
}
|
||||
|
||||
} while( 0 );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -34,5 +34,8 @@ int sock_try_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptf
|
||||
/* Try to call connect(), timing out after wait seconds */
|
||||
int sock_try_connect( int fd, struct sockaddr* to, socklen_t addrlen, int wait );
|
||||
|
||||
/* Try to call close(), retrying EINTR */
|
||||
int sock_try_close( int fd );
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -150,5 +150,7 @@ void mylog(int line_level, const char* format, ...);
|
||||
|
||||
#define SHOW_ERRNO( msg, ... ) msg ": %s (%i)", ##__VA_ARGS__, ( errno == 0 ? "EOF" : strerror(errno) ), errno
|
||||
|
||||
#define WARN_IF_NEGATIVE( value, msg, ... ) if ( value < 0 ) { warn( msg, ##__VA_ARGS__ ); }
|
||||
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user