proxy: Deal with close() failures (and EINTR errnos) comprehensively

This commit is contained in:
nick
2013-03-15 12:07:16 +00:00
parent f89352aa28
commit 21ac3cd0ed
4 changed files with 42 additions and 11 deletions

View File

@@ -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" );

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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