flexnbd: Move building the allocation map to before server socket bind()

Building the allocation map takes time, which scales with the size of the disc
being presented. By building that map in the space between bind() and accept(),
we leave the process in a useless state after the only good signal we have for
"we are ready" and the state where it is actually ready. This was breaking
migrations of large files.
This commit is contained in:
nick
2012-09-25 11:47:44 +01:00
parent ccbfce1075
commit 32cae67a75
3 changed files with 43 additions and 8 deletions

View File

@@ -816,8 +816,8 @@ int do_serve(struct server* params)
int has_control;
error_set_handler((cleanup_handler*) serve_cleanup, params);
serve_open_server_socket(params);
serve_init_allocation_map(params);
serve_open_server_socket(params);
serve_accept_loop(params);
has_control = params->has_control;
serve_cleanup(params, 0);

View File

@@ -314,9 +314,16 @@ module FlexNBD
while !File.socket?(ctrl)
pid, status = Process.wait2(@pid, Process::WNOHANG)
raise "server did not start (#{cmd})" if pid
raise "server did not start (#{cmd}) - UNIX socket didn't appear" if pid
sleep 0.1
end
while !socket_open?
pid, status = Process.wait2(@pid, Process::WNOHANG)
raise "server did not start (#{cmd}) - TCP socket didn't appear" if pid
sleep 0.1
end
at_exit { kill }
end
private :run_serve_cmd
@@ -511,7 +518,15 @@ module FlexNBD
hsh
end
def socket_open?
sock = (TCPSocket.new(@ip, @port) rescue nil)
!!sock
ensure
sock.close rescue nil if sock
end
end
end

View File

@@ -8,16 +8,35 @@ module FlexNBD
class FakeSource
def initialize( addr, port, err_msg, source_addr=nil, source_port=0 )
timing_out( 2, err_msg ) do
@sock = if source_addr
TCPSocket.new( addr, port, source_addr, source_port )
timing_out( 10, err_msg ) {
@sock = wait_for_server_socket( addr, port, source_addr, source_port )
}
end
def wait_for_server_socket(addr, port, saddr = nil, sport = 0)
sock = nil
loop do
sock = try_get_server_socket( addr, port, saddr, sport )
break if sock
sleep 0.1
end
sock
end
def try_get_server_socket(addr, port, saddr = nil, sport = 0)
if saddr
TCPSocket.new( addr, port, saddr, sport ) rescue nil
else
TCPSocket.new( addr, port )
end
TCPSocket.new( addr, port ) rescue nil
end
end
def close
@sock.close
end
@@ -137,3 +156,4 @@ module FlexNBD
end # class FakeSource
end # module FlexNBD