2012-06-27 17:28:24 +01:00
|
|
|
require 'socket'
|
2018-02-02 21:34:14 +00:00
|
|
|
require 'timeout'
|
2012-06-27 17:28:24 +01:00
|
|
|
require 'flexnbd/constants'
|
|
|
|
|
|
|
|
module FlexNBD
|
2012-07-03 14:39:05 +01:00
|
|
|
class FakeSource
|
2018-02-02 21:34:14 +00:00
|
|
|
def initialize(addr, port, err_msg, source_addr = nil, source_port = 0)
|
|
|
|
timing_out(2, err_msg) do
|
2012-10-09 17:35:20 +01:00
|
|
|
begin
|
|
|
|
@sock = if source_addr
|
2018-02-02 21:34:14 +00:00
|
|
|
TCPSocket.new(addr, port, source_addr, source_port)
|
2012-10-09 17:35:20 +01:00
|
|
|
else
|
2018-02-02 21:34:14 +00:00
|
|
|
TCPSocket.new(addr, port)
|
2012-10-09 17:35:20 +01:00
|
|
|
end
|
|
|
|
rescue Errno::ECONNREFUSED
|
2018-02-02 21:34:14 +00:00
|
|
|
warn 'Connection refused, retrying'
|
2012-10-09 17:35:20 +01:00
|
|
|
sleep(0.2)
|
|
|
|
retry
|
2012-10-08 16:01:25 +01:00
|
|
|
end
|
2012-06-27 17:28:24 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-07-03 14:39:05 +01:00
|
|
|
def close
|
|
|
|
@sock.close
|
|
|
|
end
|
|
|
|
|
2018-02-02 21:27:12 +00:00
|
|
|
def read_hello
|
|
|
|
timing_out(::FlexNBD::MS_HELLO_TIME_SECS,
|
|
|
|
'Timed out waiting for hello.') do
|
2018-02-02 21:34:14 +00:00
|
|
|
raise 'No hello.' unless (hello = @sock.read(152)) &&
|
|
|
|
hello.length == 152
|
2018-02-02 21:27:12 +00:00
|
|
|
|
|
|
|
passwd_s = hello[0..7]
|
|
|
|
magic = hello[8..15].unpack('Q>').first
|
|
|
|
size = hello[16..23].unpack('Q>').first
|
|
|
|
flags = hello[24..27].unpack('L>').first
|
|
|
|
reserved = hello[28..-1]
|
|
|
|
|
|
|
|
return { passwd: passwd_s, magic: magic, size: size, flags: flags, reserved: reserved }
|
2012-06-27 17:28:24 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-02-03 20:29:15 +00:00
|
|
|
def send_request(type, handle = 'myhandle', from = 0, len = 0, magic = REQUEST_MAGIC, flags = 0)
|
2018-02-02 21:34:14 +00:00
|
|
|
raise 'Bad handle' unless handle.length == 8
|
2012-06-27 17:28:24 +01:00
|
|
|
|
2018-02-02 21:34:14 +00:00
|
|
|
@sock.write(magic)
|
2018-02-03 20:29:15 +00:00
|
|
|
@sock.write([flags].pack('n'))
|
|
|
|
@sock.write([type].pack('n'))
|
2018-02-02 21:34:14 +00:00
|
|
|
@sock.write(handle)
|
|
|
|
@sock.write([n64(from)].pack('q'))
|
|
|
|
@sock.write([len].pack('N'))
|
2012-07-02 15:37:52 +01:00
|
|
|
end
|
|
|
|
|
2018-02-02 21:34:14 +00:00
|
|
|
def write_write_request(from, len, handle = 'myhandle')
|
|
|
|
send_request(1, handle, from, len)
|
2012-07-11 15:19:50 +01:00
|
|
|
end
|
2018-02-03 20:29:15 +00:00
|
|
|
|
|
|
|
def write_write_request_with_fua(from, len, handle = 'myhandle')
|
|
|
|
send_request(1, handle, from, len, REQUEST_MAGIC, 1)
|
|
|
|
end
|
|
|
|
|
2018-02-03 20:10:47 +00:00
|
|
|
def write_flush_request(handle = 'myhandle')
|
|
|
|
send_request(3, handle, 0, 0)
|
|
|
|
end
|
2012-07-11 15:19:50 +01:00
|
|
|
|
2018-02-02 21:34:14 +00:00
|
|
|
def write_entrust_request(handle = 'myhandle')
|
|
|
|
send_request(65_536, handle)
|
2012-07-11 15:19:50 +01:00
|
|
|
end
|
|
|
|
|
2018-02-02 21:34:14 +00:00
|
|
|
def write_disconnect_request(handle = 'myhandle')
|
|
|
|
send_request(2, handle)
|
2012-07-12 09:39:39 +01:00
|
|
|
end
|
|
|
|
|
2018-02-02 21:34:14 +00:00
|
|
|
def write_read_request(from, len, _handle = 'myhandle')
|
|
|
|
send_request(0, 'myhandle', from, len)
|
2012-07-12 14:14:46 +01:00
|
|
|
end
|
|
|
|
|
2018-02-02 21:34:14 +00:00
|
|
|
def write_data(data)
|
|
|
|
@sock.write(data)
|
2012-07-03 15:33:00 +01:00
|
|
|
end
|
|
|
|
|
2012-07-12 14:14:46 +01:00
|
|
|
# Handy utility
|
2018-02-02 21:34:14 +00:00
|
|
|
def read(from, len)
|
|
|
|
timing_out(2, 'Timed out reading') do
|
|
|
|
send_request(0, 'myhandle', from, len)
|
|
|
|
read_raw(len)
|
2012-07-12 14:14:46 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-02-02 21:34:14 +00:00
|
|
|
def read_raw(len)
|
|
|
|
@sock.read(len)
|
2012-07-12 14:14:46 +01:00
|
|
|
end
|
|
|
|
|
2012-07-12 09:39:39 +01:00
|
|
|
def send_mirror
|
2018-02-02 21:34:14 +00:00
|
|
|
read_hello
|
|
|
|
write(0, '12345678')
|
|
|
|
read_response
|
|
|
|
write_disconnect_request
|
|
|
|
close
|
2012-07-12 09:39:39 +01:00
|
|
|
end
|
|
|
|
|
2018-02-02 21:34:14 +00:00
|
|
|
def write(from, data)
|
|
|
|
write_write_request(from, data.length)
|
|
|
|
write_data(data)
|
2012-09-13 12:21:43 +01:00
|
|
|
end
|
|
|
|
|
2018-02-03 20:29:15 +00:00
|
|
|
def write_with_fua(from, data)
|
|
|
|
write_write_request_with_fua(from, data.length)
|
|
|
|
write_data(data)
|
|
|
|
end
|
|
|
|
|
2018-02-03 20:10:47 +00:00
|
|
|
def flush
|
|
|
|
write_flush_request
|
|
|
|
end
|
|
|
|
|
2012-07-03 14:39:05 +01:00
|
|
|
def read_response
|
|
|
|
magic = @sock.read(4)
|
|
|
|
error_s = @sock.read(4)
|
|
|
|
handle = @sock.read(8)
|
2012-07-02 15:37:52 +01:00
|
|
|
|
|
|
|
{
|
2018-02-02 21:34:14 +00:00
|
|
|
magic: magic,
|
|
|
|
error: error_s.unpack('N').first,
|
|
|
|
handle: handle
|
2012-07-02 15:37:52 +01:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2013-02-15 16:51:28 +00:00
|
|
|
def disconnected?
|
|
|
|
result = nil
|
2018-02-02 21:34:14 +00:00
|
|
|
Timeout.timeout(2) { result = @sock.read(1).nil? }
|
2013-02-15 16:51:28 +00:00
|
|
|
result
|
2012-07-03 14:39:05 +01:00
|
|
|
end
|
|
|
|
|
2018-02-02 21:34:14 +00:00
|
|
|
def timing_out(time, msg)
|
|
|
|
Timeout.timeout(time) do
|
|
|
|
yield
|
2012-06-27 17:28:24 +01:00
|
|
|
end
|
2018-02-02 21:34:14 +00:00
|
|
|
rescue Timeout::Error
|
|
|
|
warn msg
|
|
|
|
exit 1
|
2012-06-27 17:28:24 +01:00
|
|
|
end
|
|
|
|
|
2013-02-15 16:51:28 +00:00
|
|
|
private
|
|
|
|
|
|
|
|
# take a 64-bit number, turn it upside down (due to :
|
|
|
|
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/11920
|
|
|
|
# )
|
|
|
|
def n64(b)
|
|
|
|
((b & 0xff00000000000000) >> 56) |
|
2018-02-02 21:34:14 +00:00
|
|
|
((b & 0x00ff000000000000) >> 40) |
|
|
|
|
((b & 0x0000ff0000000000) >> 24) |
|
|
|
|
((b & 0x000000ff00000000) >> 8) |
|
|
|
|
((b & 0x00000000ff000000) << 8) |
|
|
|
|
((b & 0x0000000000ff0000) << 24) |
|
|
|
|
((b & 0x000000000000ff00) << 40) |
|
|
|
|
((b & 0x00000000000000ff) << 56)
|
2013-02-15 16:51:28 +00:00
|
|
|
end
|
2012-07-03 14:39:05 +01:00
|
|
|
end # class FakeSource
|
2012-06-27 17:28:24 +01:00
|
|
|
end # module FlexNBD
|