Close the mirror client socket on rejection
If the mirror attempt connects ok, but is rejected (say, for reporting the wrong size), the client socket needs to be closed. The destination end can't close its socket and accept another connection attempt unless it does.
This commit is contained in:
11
src/mirror.c
11
src/mirror.c
@@ -312,6 +312,8 @@ void mirror_cleanup( struct server * serve,
|
|||||||
int mirror_connect( struct mirror * mirror, off64_t local_size )
|
int mirror_connect( struct mirror * mirror, off64_t local_size )
|
||||||
{
|
{
|
||||||
struct sockaddr * connect_from = NULL;
|
struct sockaddr * connect_from = NULL;
|
||||||
|
int connected = 0;
|
||||||
|
|
||||||
if ( mirror->connect_from ) {
|
if ( mirror->connect_from ) {
|
||||||
connect_from = &mirror->connect_from->generic;
|
connect_from = &mirror->connect_from->generic;
|
||||||
}
|
}
|
||||||
@@ -332,6 +334,7 @@ int mirror_connect( struct mirror * mirror, off64_t local_size )
|
|||||||
off64_t remote_size;
|
off64_t remote_size;
|
||||||
if ( socket_nbd_read_hello( mirror->client, &remote_size ) ) {
|
if ( socket_nbd_read_hello( mirror->client, &remote_size ) ) {
|
||||||
if( remote_size == local_size ){
|
if( remote_size == local_size ){
|
||||||
|
connected = 1;
|
||||||
mirror_set_state( mirror, MS_GO );
|
mirror_set_state( mirror, MS_GO );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -349,13 +352,15 @@ int mirror_connect( struct mirror * mirror, off64_t local_size )
|
|||||||
warn( "No NBD Hello received." );
|
warn( "No NBD Hello received." );
|
||||||
mirror_set_state( mirror, MS_FAIL_NO_HELLO );
|
mirror_set_state( mirror, MS_FAIL_NO_HELLO );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !connected ) { close( mirror->client ); }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
warn( "Mirror failed to connect.");
|
warn( "Mirror failed to connect.");
|
||||||
mirror_set_state( mirror, MS_FAIL_CONNECT );
|
mirror_set_state( mirror, MS_FAIL_CONNECT );
|
||||||
}
|
}
|
||||||
|
|
||||||
return MS_GO == mirror_get_state(mirror);
|
return connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -574,9 +579,9 @@ void * mirror_super_runner( void * serve_uncast )
|
|||||||
should_retry = 0;
|
should_retry = 0;
|
||||||
}
|
}
|
||||||
else if (should_retry){
|
else if (should_retry){
|
||||||
warn( "Mirror failed, retrying" );
|
info( "Mirror failed, retrying" );
|
||||||
}
|
}
|
||||||
else { warn( "Mirror failed before commit, giving up" ); }
|
else { info( "Mirror failed before commit, giving up" ); }
|
||||||
}
|
}
|
||||||
while ( should_retry && !success );
|
while ( should_retry && !success );
|
||||||
|
|
||||||
|
@@ -21,4 +21,9 @@ client.write_hello( :size => :wrong )
|
|||||||
|
|
||||||
t.join
|
t.join
|
||||||
|
|
||||||
|
# Now check that the source closed the first socket (yes, this was an
|
||||||
|
# actual bug)
|
||||||
|
|
||||||
|
fail "Didn't close socket" unless client.disconnected?
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@@ -62,6 +62,15 @@ module FlexNBD
|
|||||||
write_reply( handle, 1 )
|
write_reply( handle, 1 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def disconnected?
|
||||||
|
begin
|
||||||
|
Timeout.timeout(2) do
|
||||||
|
@sock.read(1) == nil
|
||||||
|
end
|
||||||
|
rescue Timeout::Error
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def write_reply( handle, err=0, opts={} )
|
def write_reply( handle, err=0, opts={} )
|
||||||
if opts[:magic] == :wrong
|
if opts[:magic] == :wrong
|
||||||
|
Reference in New Issue
Block a user