
If the sender disconnects its socket before sending the disconnect message, the destination should restart the migration process. This patch makes sure that happens.
109 lines
2.1 KiB
Ruby
109 lines
2.1 KiB
Ruby
# encoding: utf-8
|
|
|
|
require 'socket'
|
|
require "timeout"
|
|
require 'flexnbd/constants'
|
|
|
|
module FlexNBD
|
|
class FakeSource
|
|
|
|
def initialize( addr, port, err_msg, source_addr=nil, source_port=0 )
|
|
timing_out( 2, err_msg ) do
|
|
@sock = TCPSocket.new( addr, port, source_addr, source_port )
|
|
end
|
|
end
|
|
|
|
|
|
def close
|
|
@sock.close
|
|
end
|
|
|
|
|
|
def read_hello()
|
|
timing_out( FlexNBD::MS_HELLO_TIME_SECS,
|
|
"Timed out waiting for hello." ) do
|
|
fail "No hello." unless (hello = @sock.read( 152 )) &&
|
|
hello.length==152
|
|
hello
|
|
end
|
|
end
|
|
|
|
|
|
def send_request( type, handle="myhandle", from=0, len=0 )
|
|
fail "Bad handle" unless handle.length == 8
|
|
|
|
@sock.write( "\x25\x60\x95\x13" )
|
|
@sock.write( [type].pack( 'N' ) )
|
|
@sock.write( handle )
|
|
@sock.write( "\x0"*4 )
|
|
@sock.write( [from].pack( 'N' ) )
|
|
@sock.write( [len ].pack( 'N' ) )
|
|
end
|
|
|
|
|
|
def write_write_request( from, len, handle="myhandle" )
|
|
send_request( 1, handle, from, len )
|
|
end
|
|
|
|
|
|
def write_entrust_request( handle="myhandle" )
|
|
send_request( 65536, handle )
|
|
end
|
|
|
|
def write_disconnect_request( handle="myhandle" )
|
|
send_request( 2, handle )
|
|
end
|
|
|
|
|
|
def write_data( data )
|
|
@sock.write( data )
|
|
end
|
|
|
|
|
|
def send_mirror
|
|
read_hello()
|
|
write_write_request( 0, 8 )
|
|
write_data( "12345678" )
|
|
read_response()
|
|
write_entrust_request()
|
|
read_response()
|
|
write_disconnect_request()
|
|
close()
|
|
end
|
|
|
|
|
|
def read_response
|
|
magic = @sock.read(4)
|
|
error_s = @sock.read(4)
|
|
handle = @sock.read(8)
|
|
|
|
{
|
|
:magic => magic,
|
|
:error => error_s.unpack("N"),
|
|
:handle => handle
|
|
}
|
|
end
|
|
|
|
|
|
def ensure_disconnected
|
|
Timeout.timeout( 2 ) do
|
|
@sock.read(1)
|
|
end
|
|
end
|
|
|
|
|
|
def timing_out( time, msg )
|
|
begin
|
|
Timeout.timeout( time ) do
|
|
yield
|
|
end
|
|
rescue Timeout::Error
|
|
$stderr.puts msg
|
|
exit 1
|
|
end
|
|
end
|
|
|
|
|
|
end # class FakeSource
|
|
end # module FlexNBD
|