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 ) ) {
|
if( !socket_nbd_read_hello( fd, &size ) ) {
|
||||||
FATAL_IF_NEGATIVE(
|
WARN_IF_NEGATIVE(
|
||||||
close( fd ), SHOW_ERRNO( "FIXME: shouldn't be fatal" )
|
sock_try_close( fd ),
|
||||||
|
"Couldn't close() after failed read of NBD hello on fd %i", fd
|
||||||
);
|
);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -114,10 +115,10 @@ void proxy_disconnect_from_upstream( struct proxier* proxy )
|
|||||||
debug(" Closing upstream connection" );
|
debug(" Closing upstream connection" );
|
||||||
|
|
||||||
/* TODO: An NBD disconnect would be pleasant here */
|
/* TODO: An NBD disconnect would be pleasant here */
|
||||||
|
WARN_IF_NEGATIVE(
|
||||||
FATAL_IF_NEGATIVE(
|
sock_try_close( proxy->upstream_fd ),
|
||||||
close( proxy->upstream_fd ),
|
"Failed to close() fd %i when disconnecting from upstream",
|
||||||
SHOW_ERRNO( "FIXME: shouldn't be fatal" )
|
proxy->upstream_fd
|
||||||
);
|
);
|
||||||
proxy->upstream_fd = -1;
|
proxy->upstream_fd = -1;
|
||||||
}
|
}
|
||||||
@@ -442,10 +443,11 @@ int proxy_accept( struct proxier* params )
|
|||||||
params->downstream_fd = client_fd;
|
params->downstream_fd = client_fd;
|
||||||
proxy_session( params );
|
proxy_session( params );
|
||||||
|
|
||||||
if ( close( params->downstream_fd ) == -1 ) {
|
WARN_IF_NEGATIVE(
|
||||||
warn( SHOW_ERRNO( "FIXME: close returned" ) );
|
sock_try_close( params->downstream_fd ),
|
||||||
}
|
"Couldn't close() downstram fd %i after proxy session",
|
||||||
|
params->downstream_fd
|
||||||
|
);
|
||||||
params->downstream_fd = -1;
|
params->downstream_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,7 +469,10 @@ void proxy_cleanup( struct proxier* params )
|
|||||||
info( "cleaning up" );
|
info( "cleaning up" );
|
||||||
|
|
||||||
if ( -1 != params->listen_fd ) {
|
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" );
|
debug( "Cleanup done" );
|
||||||
|
@@ -216,3 +216,24 @@ out:
|
|||||||
return result;
|
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 */
|
/* Try to call connect(), timing out after wait seconds */
|
||||||
int sock_try_connect( int fd, struct sockaddr* to, socklen_t addrlen, int wait );
|
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
|
#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 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
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user