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:
Alex Young
2012-07-15 18:30:20 +01:00
parent e0a61e91e6
commit e77234c6b1
3 changed files with 22 additions and 3 deletions

View File

@@ -312,6 +312,8 @@ void mirror_cleanup( struct server * serve,
int mirror_connect( struct mirror * mirror, off64_t local_size )
{
struct sockaddr * connect_from = NULL;
int connected = 0;
if ( mirror->connect_from ) {
connect_from = &mirror->connect_from->generic;
}
@@ -332,6 +334,7 @@ int mirror_connect( struct mirror * mirror, off64_t local_size )
off64_t remote_size;
if ( socket_nbd_read_hello( mirror->client, &remote_size ) ) {
if( remote_size == local_size ){
connected = 1;
mirror_set_state( mirror, MS_GO );
}
else {
@@ -349,13 +352,15 @@ int mirror_connect( struct mirror * mirror, off64_t local_size )
warn( "No NBD Hello received." );
mirror_set_state( mirror, MS_FAIL_NO_HELLO );
}
if ( !connected ) { close( mirror->client ); }
}
else {
warn( "Mirror failed to 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;
}
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 );

View File

@@ -21,4 +21,9 @@ client.write_hello( :size => :wrong )
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

View File

@@ -62,6 +62,15 @@ module FlexNBD
write_reply( handle, 1 )
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={} )
if opts[:magic] == :wrong