flexnbd: Split the proxy mode out into its own binary.
"flexnbd-proxy ..." should be identical in operation to "flexnbd proxy ..."
This commit is contained in:
182
README.proxy.txt
Normal file
182
README.proxy.txt
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
FLEXNBD-PROXY(1)
|
||||||
|
================
|
||||||
|
:doctype: manpage
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
|
||||||
|
flexnbd-proxy - A simple NBD proxy
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
|
||||||
|
*flexnbd-proxy* ['OPTIONS']
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
-----------
|
||||||
|
|
||||||
|
flexnbd-proxy is a simple NBD proxy server that implements resilient
|
||||||
|
connection logic for the client. It connects to an upstream NBD server
|
||||||
|
and allows a single client to connect to it. All server properties are
|
||||||
|
proxied to the client, and the client connection is kept alive across
|
||||||
|
reconnections to the upstream server. If the upstream goes away while
|
||||||
|
an NBD request is in-flight then the proxy (silently, from the point
|
||||||
|
of view of the client) reconnects and retransmits the request, before
|
||||||
|
returning the response to the client.
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
-----
|
||||||
|
|
||||||
|
$ flexnbd-proxy --addr <ADDR> --port <PORT>
|
||||||
|
--conn-addr <ADDR> --conn-port <PORT> [--bind <ADDR>] [option]*
|
||||||
|
|
||||||
|
Proxy requests from an NBD client to an NBD server, resiliently. Only one
|
||||||
|
client can be connected (to the address specified by --addr and --port) at a
|
||||||
|
time, and ACLs cannot be applied to the client, as they can be to clients
|
||||||
|
connecting directly to a flexnbd in serve mode.
|
||||||
|
|
||||||
|
On starting up, the proxy will attempt to connect to the server specified by
|
||||||
|
--conn-addr and --conn-port (from the address specified by --bind, if given). If
|
||||||
|
it fails, then the process will die with an error exit status.
|
||||||
|
|
||||||
|
Assuming a successful connection to the `upstream` server is made, the proxy
|
||||||
|
will then start listening on the address specified by --addr and --port, waiting
|
||||||
|
for `downstream` to connect to it (this will be your NBD client). The client
|
||||||
|
will be given the same hello message as the proxy was given by the server.
|
||||||
|
|
||||||
|
When connected, any request the client makes will be read by the proxy and sent
|
||||||
|
to the server. If the server goes away for any reason, the proxy will remember
|
||||||
|
the request and regularly (~ every 5 seconds) try to reconnect to the server.
|
||||||
|
Upon reconnection, the request is sent and a reply is waited for. When a reply
|
||||||
|
is received, it is sent back to the client.
|
||||||
|
|
||||||
|
When the client disconnects, cleanly or otherwise, the proxy goes back to
|
||||||
|
waiting for a new client to connect. The connection to the server is maintained
|
||||||
|
at that point, in case it is needed again.
|
||||||
|
|
||||||
|
Only one request may be in-flight at a time under the current architecture; that
|
||||||
|
doesn't seem to slow things down much relative to alternative options, but may
|
||||||
|
be changed in the future if it becomes an issue.
|
||||||
|
|
||||||
|
Options
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
*--addr, -l ADDR*:
|
||||||
|
The address to listen on. Required.
|
||||||
|
|
||||||
|
*--port, -p PORT*:
|
||||||
|
The port to listen on. Required.
|
||||||
|
|
||||||
|
*--conn-addr, -C ADDR*:
|
||||||
|
The address of the NBD server to connect to. Required.
|
||||||
|
|
||||||
|
*--conn-port, -P PORT*:
|
||||||
|
The port of the NBD server to connect to. Required.
|
||||||
|
|
||||||
|
*--help, -h* :
|
||||||
|
Show command or global help.
|
||||||
|
|
||||||
|
*--verbose, -v* :
|
||||||
|
Output all available log information to STDERR.
|
||||||
|
|
||||||
|
*--quiet, -q* :
|
||||||
|
Output as little log information as possible to STDERR.
|
||||||
|
|
||||||
|
|
||||||
|
LOGGING
|
||||||
|
-------
|
||||||
|
Log output is sent to STDERR. If --quiet is set, no output will be seen
|
||||||
|
unless the program termintes abnormally. If neither --quiet nor
|
||||||
|
--verbose are set, no output will be seen unless something goes wrong
|
||||||
|
with a specific request. If --verbose is given, every available log
|
||||||
|
message will be seen (which, for a debug build, is many). It is not an
|
||||||
|
error to set both --verbose and --quiet. The last one wins.
|
||||||
|
|
||||||
|
The log line format is:
|
||||||
|
|
||||||
|
<LEVEL>:<PID> <THREAD> <SOURCEFILE>:<SOURCELINE>: <MSG>
|
||||||
|
|
||||||
|
*LEVEL*:
|
||||||
|
This will be one of 'D', 'I', 'W', 'E', 'F' in increasing order of
|
||||||
|
severity. If flexnbd is started with the --quiet flag, only 'F' will be
|
||||||
|
seen. If it is started with the --verbose flag, any from 'I' upwards
|
||||||
|
will be seen. Only if you have a debug build and start it with
|
||||||
|
--verbose will you see 'D' entries.
|
||||||
|
|
||||||
|
*PID*:
|
||||||
|
This is the process ID.
|
||||||
|
|
||||||
|
*THREAD*:
|
||||||
|
flexnbd-proxy is currently single-threaded, so this should be the same
|
||||||
|
for all lines. That may not be the case in the future.
|
||||||
|
|
||||||
|
*SOURCEFILE:SOURCELINE*:
|
||||||
|
Identifies where in the source code this log line can be found.
|
||||||
|
|
||||||
|
*MSG*:
|
||||||
|
A short message describing what's happening, how it's being done, or
|
||||||
|
if you're very lucky *why* it's going on.
|
||||||
|
|
||||||
|
Proxying
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
The main point of the proxy mode is to allow clients that would otherwise break
|
||||||
|
when the NBD server goes away (during a migration, for instance) to see a
|
||||||
|
persistent TCP connection throughout the process, instead of needing its own
|
||||||
|
reconnection logic.
|
||||||
|
|
||||||
|
For maximum reliability, the proxy process would be run on the same machine as
|
||||||
|
the actual NBD client; an example might look like:
|
||||||
|
|
||||||
|
nbd-server-1$ flexnbd serve -l 10.0.0.1 -p 4777 myfile [...]
|
||||||
|
|
||||||
|
nbd-client-1$ flexnbd-proxy -l 127.0.0.1 -p 4777 -C 10.0.0.1 -P 4777
|
||||||
|
nbd-client-1$ nbd-client -c 127.0.0.1 4777 /dev/nbd0
|
||||||
|
|
||||||
|
nbd-server-2$ flexnbd listen -l 10.0.0.2 -p 4777 -f myfile [...]
|
||||||
|
|
||||||
|
nbd-server-1$ flexnbd mirror --addr 10.0.0.2 -p 4777 [...]
|
||||||
|
|
||||||
|
Upon completing the migration, the mirroring and listening flexnbd servers will
|
||||||
|
both exit. With the proxy mediating requests, this does not break the TCP
|
||||||
|
connection that nbd-client is holding open. If no requests are in-flight, it
|
||||||
|
will not notice anything at all; if requests are in-flight, then the reply may
|
||||||
|
take longer than usual to be returned.
|
||||||
|
|
||||||
|
When flexnbd is restarted in serve mode on the second server:
|
||||||
|
|
||||||
|
nbd-server-2$ flexnbd serve -l 10.0.0.1 -p 4777 -f myfile [...]
|
||||||
|
|
||||||
|
The proxy notices and reconnects, fulfiling any request it has in its buffer.
|
||||||
|
The data in myfile has been moved between physical servers without the nbd
|
||||||
|
client process having to be disturbed at all.
|
||||||
|
|
||||||
|
BUGS
|
||||||
|
----
|
||||||
|
|
||||||
|
Should be reported to nick@bytemark.co.uk.
|
||||||
|
|
||||||
|
Current issues include:
|
||||||
|
|
||||||
|
* Only old-style NBD negotiation is supported
|
||||||
|
* Only one request may be in-flight at a time
|
||||||
|
* All I/O is blocking, and signals terminate the process immediately
|
||||||
|
* No UNIX socket support
|
||||||
|
* FLUSH and TRIM commands, and the FUA flag, are not supported
|
||||||
|
* DISCONNECT requests do not get passed through to the NBD server
|
||||||
|
* No active timeout-retry of requests - we trust the kernel's idea of failure
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
------
|
||||||
|
|
||||||
|
Written by Alex Young <alex@bytemark.co.uk>.
|
||||||
|
Original concept and core code by Matthew Bloch <matthew@bytemark.co.uk>.
|
||||||
|
Some additions by Nick Thomas <nick@bytemark.co.uk>
|
||||||
|
|
||||||
|
COPYING
|
||||||
|
-------
|
||||||
|
|
||||||
|
Copyright (c) 2012 Bytemark Hosting Ltd. Free use of this software is
|
||||||
|
granted under the terms of the GNU General Public License version 3 or
|
||||||
|
later.
|
||||||
|
|
83
README.txt
83
README.txt
@@ -85,55 +85,6 @@ Options
|
|||||||
^^^^^^^
|
^^^^^^^
|
||||||
As for 'serve'.
|
As for 'serve'.
|
||||||
|
|
||||||
proxy
|
|
||||||
~~~~~
|
|
||||||
|
|
||||||
$ flexnbd proxy --addr <ADDR> --port <PORT>
|
|
||||||
--conn-addr <ADDR> --conn-port <PORT> [--bind <ADDR>] [global option]*
|
|
||||||
|
|
||||||
Proxy requests from an NBD client to an NBD server, resiliently. Only one
|
|
||||||
client can be connected (to the address specified by --addr and --port) at a
|
|
||||||
time, and ACLs cannot be applied to the client, as they can be to clients
|
|
||||||
connecting directly to a flexnbd in serve mode.
|
|
||||||
|
|
||||||
On starting up, the proxy will attempt to connect to the server specified by
|
|
||||||
--conn-addr and --conn-port (from the address specified by --bind, if given). If
|
|
||||||
it fails, then the process will die with an error exit status.
|
|
||||||
|
|
||||||
Assuming a successful connection to the `upstream` server is made, the proxy
|
|
||||||
will then start listening on the address specified by --addr and --port, waiting
|
|
||||||
for `downstream` to connect to it (this will be your NBD client). The client
|
|
||||||
will be given the same hello message as the proxy was given by the server.
|
|
||||||
|
|
||||||
When connected, any request the client makes will be read by the proxy and sent
|
|
||||||
to the server. If the server goes away for any reason, the proxy will remember
|
|
||||||
the request and regularly (~ every 5 seconds) try to reconnect to the server.
|
|
||||||
Upon reconnection, the request is sent and a reply is waited for. When a reply
|
|
||||||
is received, it is sent back to the client.
|
|
||||||
|
|
||||||
When the client disconnects, cleanly or otherwise, the proxy goes back to
|
|
||||||
waiting for a new client to connect. The connection to the server is maintained
|
|
||||||
at that point, in case it is needed again.
|
|
||||||
|
|
||||||
Only one request may be in-flight at a time under the current architecture; that
|
|
||||||
doesn't seem to slow things down much relative to alternative options, but may
|
|
||||||
be changed in the future if it becomes an issue.
|
|
||||||
|
|
||||||
Options
|
|
||||||
^^^^^^^
|
|
||||||
|
|
||||||
*--addr, -l ADDR*:
|
|
||||||
The address to listen on. Required.
|
|
||||||
|
|
||||||
*--port, -p PORT*:
|
|
||||||
The port to listen on. Required.
|
|
||||||
|
|
||||||
*--conn-addr, -C ADDR*:
|
|
||||||
The address of the NBD server to connect to. Required.
|
|
||||||
|
|
||||||
*--conn-port, -P PORT*:
|
|
||||||
The port of the NBD server to connect to. Required.
|
|
||||||
|
|
||||||
mirror
|
mirror
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
@@ -415,40 +366,6 @@ Note that because the file is so small in this case, we see the source
|
|||||||
server quit soon after we start the migration, and the destination
|
server quit soon after we start the migration, and the destination
|
||||||
exited at roughly the same time.
|
exited at roughly the same time.
|
||||||
|
|
||||||
Proxying
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
The main point of the proxy mode is to allow clients that would otherwise break
|
|
||||||
when the NBD server goes away (during a migration, for instance) to see a
|
|
||||||
persistent TCP connection throughout the process, instead of needing its own
|
|
||||||
reconnection logic.
|
|
||||||
|
|
||||||
For maximum reliability, the proxy process would be run on the same machine as
|
|
||||||
the actual NBD client; an example might look like:
|
|
||||||
|
|
||||||
nbd-server-1$ flexnbd serve -l 10.0.0.1 -p 4777 myfile [...]
|
|
||||||
|
|
||||||
nbd-client-1$ flexnbd proxy -l 127.0.0.1 -p 4777 -C 10.0.0.1 -P 4777
|
|
||||||
nbd-client-1$ nbd-client -c 127.0.0.1 4777 /dev/nbd0
|
|
||||||
|
|
||||||
nbd-server-2$ flexnbd listen -l 10.0.0.2 -p 4777 -f myfile [...]
|
|
||||||
|
|
||||||
nbd-server-1$ flexnbd mirror --addr 10.0.0.2 -p 4777 [...]
|
|
||||||
|
|
||||||
Upon completing the migration, the mirroring and listening flexnbd servers will
|
|
||||||
both exit. With the proxy mediating requests, this does not break the TCP
|
|
||||||
connection that nbd-client is holding open. If no requests are in-flight, it
|
|
||||||
will not notice anything at all; if requests are in-flight, then the reply will
|
|
||||||
take longer than usual to be returned.
|
|
||||||
|
|
||||||
When flexnbd is restarted in serve mode on the second server:
|
|
||||||
|
|
||||||
nbd-server-2$ flexnbd serve -l 10.0.0.1 -p 4777 -f myfile [...]
|
|
||||||
|
|
||||||
The proxy notices and reconnects, fulfiling any request it has in its buffer.
|
|
||||||
The data in myfile has been moved between physical servers without the nbd
|
|
||||||
client process having to be disturbed at all.
|
|
||||||
|
|
||||||
BUGS
|
BUGS
|
||||||
----
|
----
|
||||||
|
|
||||||
|
62
Rakefile
62
Rakefile
@@ -7,9 +7,17 @@ CC=ENV['CC'] || "gcc"
|
|||||||
DEBUG = ENV.has_key?('DEBUG') &&
|
DEBUG = ENV.has_key?('DEBUG') &&
|
||||||
%w|yes y ok 1 true t|.include?(ENV['DEBUG'])
|
%w|yes y ok 1 true t|.include?(ENV['DEBUG'])
|
||||||
|
|
||||||
ALL_SOURCES =FileList['src/*']
|
ALL_SOURCES = FileList['src/*']
|
||||||
SOURCES = ALL_SOURCES.select { |c| c =~ /\.c$/ }
|
|
||||||
OBJECTS = SOURCES.pathmap( "%{^src,build}X.o" )
|
PROXY_ONLY_SOURCES = FileList['src/{proxy-main,proxy}.c']
|
||||||
|
PROXY_ONLY_OBJECTS = PROXY_ONLY_SOURCES.pathmap( "%{^src,build}X.o" )
|
||||||
|
|
||||||
|
SOURCES = ALL_SOURCES.select { |c| c =~ /\.c$/ } - PROXY_ONLY_SOURCES
|
||||||
|
OBJECTS = SOURCES.pathmap( "%{^src,build}X.o" ) - PROXY_ONLY_OBJECTS
|
||||||
|
|
||||||
|
PROXY_SOURCES = FileList['src/{ioutil,nbdtypes,readwrite,sockutil,util,parse}.c'] + PROXY_ONLY_SOURCES
|
||||||
|
PROXY_OBJECTS = PROXY_SOURCES.pathmap( "%{^src,build}X.o" )
|
||||||
|
|
||||||
TEST_SOURCES = FileList['tests/unit/*.c']
|
TEST_SOURCES = FileList['tests/unit/*.c']
|
||||||
TEST_OBJECTS = TEST_SOURCES.pathmap( "%{^tests/unit,build/tests}X.o" )
|
TEST_OBJECTS = TEST_SOURCES.pathmap( "%{^tests/unit,build/tests}X.o" )
|
||||||
|
|
||||||
@@ -38,26 +46,38 @@ if DEBUG
|
|||||||
end
|
end
|
||||||
|
|
||||||
desc "Build the binary and man page"
|
desc "Build the binary and man page"
|
||||||
task :build => ['build/flexnbd', 'build/flexnbd.1.gz']
|
task :build => [:flexnbd, :flexnbd_proxy, :man]
|
||||||
task :default => :build
|
task :default => :build
|
||||||
|
|
||||||
desc "Build just the binary"
|
desc "Build just the flexnbd binary"
|
||||||
task :flexnbd => "build/flexnbd"
|
task :flexnbd => "build/flexnbd"
|
||||||
|
|
||||||
|
desc "Build just the flexnbd-proxy binary"
|
||||||
|
task :flexnbd_proxy => "build/flexnbd-proxy"
|
||||||
|
|
||||||
def check(m)
|
def check(m)
|
||||||
"build/tests/check_#{m}"
|
"build/tests/check_#{m}"
|
||||||
end
|
end
|
||||||
|
|
||||||
file "README.txt"
|
file "README.txt"
|
||||||
|
file "README.proxy.txt"
|
||||||
|
|
||||||
|
def manpage(name, src)
|
||||||
|
FileUtils.mkdir_p( "build" )
|
||||||
|
sh "a2x --destination-dir build --format manpage #{src}"
|
||||||
|
sh "gzip -f build/#{name}"
|
||||||
|
end
|
||||||
|
|
||||||
file "build/flexnbd.1.gz" => "README.txt" do
|
file "build/flexnbd.1.gz" => "README.txt" do
|
||||||
FileUtils.mkdir_p( "build" )
|
manpage("flexnbd.1", "README.txt")
|
||||||
sh "a2x --destination-dir build --format manpage README.txt"
|
end
|
||||||
sh "gzip -f build/flexnbd.1"
|
|
||||||
|
file "build/flexnbd-proxy.1.gz" => "README.proxy.txt" do
|
||||||
|
manpage("flexnbd-proxy.1", "README.proxy.txt")
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Build just the man page"
|
desc "Build just the man page"
|
||||||
task :man => "build/flexnbd.1.gz"
|
task :man => ["build/flexnbd.1.gz", "build/flexnbd-proxy.1.gz"]
|
||||||
|
|
||||||
|
|
||||||
namespace "test" do
|
namespace "test" do
|
||||||
@@ -83,7 +103,7 @@ namespace "test" do
|
|||||||
end
|
end
|
||||||
|
|
||||||
desc "Run NBD test scenarios"
|
desc "Run NBD test scenarios"
|
||||||
task 'scenarios' => 'flexnbd' do
|
task 'scenarios' => ['build/flexnbd', 'build/flexnbd-proxy'] do
|
||||||
sh "cd tests/acceptance; ruby nbd_scenarios -v"
|
sh "cd tests/acceptance; ruby nbd_scenarios -v"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -109,6 +129,10 @@ def headers(c)
|
|||||||
`#{CC} -Isrc -MM #{c}`.gsub("\\\n", " ").split(" ")[2..-1]
|
`#{CC} -Isrc -MM #{c}`.gsub("\\\n", " ").split(" ")[2..-1]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
rule 'build/flexnbd-proxy' => PROXY_OBJECTS do |t|
|
||||||
|
gcc_link(t.name, t.sources)
|
||||||
|
end
|
||||||
|
|
||||||
rule 'build/flexnbd' => OBJECTS do |t|
|
rule 'build/flexnbd' => OBJECTS do |t|
|
||||||
gcc_link(t.name, t.sources)
|
gcc_link(t.name, t.sources)
|
||||||
end
|
end
|
||||||
@@ -125,7 +149,6 @@ file check("client") =>
|
|||||||
build/parse.o
|
build/parse.o
|
||||||
build/client.o
|
build/client.o
|
||||||
build/serve.o
|
build/serve.o
|
||||||
build/proxy.o
|
|
||||||
build/acl.o
|
build/acl.o
|
||||||
build/ioutil.o
|
build/ioutil.o
|
||||||
build/mbox.o
|
build/mbox.o
|
||||||
@@ -161,7 +184,6 @@ file check("serve") =>
|
|||||||
build/client.o
|
build/client.o
|
||||||
build/flexthread.o
|
build/flexthread.o
|
||||||
build/serve.o
|
build/serve.o
|
||||||
build/proxy.o
|
|
||||||
build/flexnbd.o
|
build/flexnbd.o
|
||||||
build/mirror.o
|
build/mirror.o
|
||||||
build/status.o
|
build/status.o
|
||||||
@@ -179,7 +201,6 @@ file check("readwrite") =>
|
|||||||
build/client.o
|
build/client.o
|
||||||
build/self_pipe.o
|
build/self_pipe.o
|
||||||
build/serve.o
|
build/serve.o
|
||||||
build/proxy.o
|
|
||||||
build/parse.o
|
build/parse.o
|
||||||
build/acl.o
|
build/acl.o
|
||||||
build/flexthread.o
|
build/flexthread.o
|
||||||
@@ -213,22 +234,20 @@ file check("flexnbd") =>
|
|||||||
build/nbdtypes.o
|
build/nbdtypes.o
|
||||||
build/readwrite.o
|
build/readwrite.o
|
||||||
build/mirror.o
|
build/mirror.o
|
||||||
build/serve.o
|
build/serve.o} do |t|
|
||||||
build/proxy.o} do |t|
|
|
||||||
gcc_link t.name, t.prerequisites + [LIBCHECK]
|
gcc_link t.name, t.prerequisites + [LIBCHECK]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
file check("control") =>
|
file check("control") =>
|
||||||
%w{build/tests/check_control.o} + OBJECTS - ["build/main.o"] do |t|
|
%w{build/tests/check_control.o} + OBJECTS - ["build/main.o", 'build/proxy-main.o', 'build/proxy.o'] do |t|
|
||||||
gcc_link t.name, t.prerequisites + [LIBCHECK]
|
gcc_link t.name, t.prerequisites + [LIBCHECK]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
(TEST_MODULES- %w{control flexnbd acl client serve readwrite util}).each do |m|
|
(TEST_MODULES- %w{control flexnbd acl client serve readwrite util}).each do |m|
|
||||||
tgt = "build/tests/check_#{m}.o"
|
tgt = "build/tests/check_#{m}.o"
|
||||||
maybe_obj_name = "build/#{m}.o"
|
maybe_obj_name = "build/#{m}.o"
|
||||||
# Take it out in case we're testing util.o or ioutil.o
|
# Take it out in case we're testing one of the utils
|
||||||
deps = ["build/ioutil.o", "build/util.o", "build/sockutil.o"] - [maybe_obj_name]
|
deps = ["build/ioutil.o", "build/util.o", "build/sockutil.o"] - [maybe_obj_name]
|
||||||
|
|
||||||
# Add it back in if it's something we need to compile
|
# Add it back in if it's something we need to compile
|
||||||
@@ -244,6 +263,10 @@ OBJECTS.zip( SOURCES ).each do |o,c|
|
|||||||
file o => [c]+headers(c) do |t| gcc_compile( o, c ) end
|
file o => [c]+headers(c) do |t| gcc_compile( o, c ) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
PROXY_ONLY_OBJECTS.zip( PROXY_ONLY_SOURCES).each do |o, c|
|
||||||
|
file o => [c]+headers(c) do |t| gcc_compile( o, c ) end
|
||||||
|
end
|
||||||
|
|
||||||
TEST_OBJECTS.zip( TEST_SOURCES ).each do |o,c|
|
TEST_OBJECTS.zip( TEST_SOURCES ).each do |o,c|
|
||||||
file o => [c] + headers(c) do |t| gcc_compile( o, c ) end
|
file o => [c] + headers(c) do |t| gcc_compile( o, c ) end
|
||||||
end
|
end
|
||||||
@@ -255,10 +278,9 @@ end
|
|||||||
|
|
||||||
namespace :pkg do
|
namespace :pkg do
|
||||||
deb do |t|
|
deb do |t|
|
||||||
t.code_files = ALL_SOURCES + ["Rakefile", "README.txt"]
|
t.code_files = ALL_SOURCES + ["Rakefile", "README.txt", "README.proxy.txt"]
|
||||||
t.pkg_name = "flexnbd"
|
t.pkg_name = "flexnbd"
|
||||||
t.generate_changelog!
|
t.generate_changelog!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
7
debian/flexnbd.install
vendored
7
debian/flexnbd.install
vendored
@@ -1,2 +1,5 @@
|
|||||||
build/flexnbd usr/bin
|
build/flexnbd usr/bin
|
||||||
build/flexnbd.1.gz usr/share/man/man1
|
build/flexnbd-proxy usr/bin
|
||||||
|
build/flexnbd.1.gz usr/share/man/man1
|
||||||
|
build/flexnbd-proxy.1.gz usr/share/man/man1
|
||||||
|
|
||||||
|
@@ -128,27 +128,6 @@ struct flexnbd * flexnbd_create_listening(
|
|||||||
return flexnbd;
|
return flexnbd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct flexnbd * flexnbd_create_proxying(
|
|
||||||
char* s_downstream_address,
|
|
||||||
char* s_downstream_port,
|
|
||||||
char* s_upstream_address,
|
|
||||||
char* s_upstream_port,
|
|
||||||
char* s_upstream_bind
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct flexnbd * flexnbd = xmalloc( sizeof( struct flexnbd ) );
|
|
||||||
flexnbd->proxy = proxy_create(
|
|
||||||
flexnbd,
|
|
||||||
s_downstream_address,
|
|
||||||
s_downstream_port,
|
|
||||||
s_upstream_address,
|
|
||||||
s_upstream_port,
|
|
||||||
s_upstream_bind);
|
|
||||||
flexnbd_create_shared( flexnbd, NULL );
|
|
||||||
return flexnbd;
|
|
||||||
}
|
|
||||||
|
|
||||||
void flexnbd_spawn_control(struct flexnbd * flexnbd )
|
void flexnbd_spawn_control(struct flexnbd * flexnbd )
|
||||||
{
|
{
|
||||||
NULLCHECK( flexnbd );
|
NULLCHECK( flexnbd );
|
||||||
@@ -274,14 +253,3 @@ int flexnbd_serve( struct flexnbd * flexnbd )
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flexnbd_proxy( struct flexnbd * flexnbd )
|
|
||||||
{
|
|
||||||
NULLCHECK( flexnbd );
|
|
||||||
int success;
|
|
||||||
|
|
||||||
success = do_proxy( flexnbd->proxy );
|
|
||||||
debug("do_proxy success is %d", success );
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -17,9 +17,6 @@ struct flexnbd {
|
|||||||
*/
|
*/
|
||||||
struct server * serve;
|
struct server * serve;
|
||||||
|
|
||||||
/* In proxy mode, this is filled instead of serve, above */
|
|
||||||
struct proxier * proxy;
|
|
||||||
|
|
||||||
/* We only have a control object if a control socket name was
|
/* We only have a control object if a control socket name was
|
||||||
* passed on the command line.
|
* passed on the command line.
|
||||||
*/
|
*/
|
||||||
@@ -50,14 +47,6 @@ struct flexnbd * flexnbd_create_listening(
|
|||||||
int acl_entries,
|
int acl_entries,
|
||||||
char** s_acl_entries );
|
char** s_acl_entries );
|
||||||
|
|
||||||
struct flexnbd * flexnbd_create_proxying(
|
|
||||||
char* s_downstream_address,
|
|
||||||
char* s_downstream_port,
|
|
||||||
char* s_upstream_address,
|
|
||||||
char* s_upstream_port,
|
|
||||||
char* s_upstream_bind
|
|
||||||
);
|
|
||||||
|
|
||||||
void flexnbd_destroy( struct flexnbd * );
|
void flexnbd_destroy( struct flexnbd * );
|
||||||
enum mirror_state;
|
enum mirror_state;
|
||||||
enum mirror_state flexnbd_get_mirror_state( struct flexnbd * );
|
enum mirror_state flexnbd_get_mirror_state( struct flexnbd * );
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
signal(SIGPIPE, SIG_IGN); /* calls to splice() unhelpfully throw this */
|
signal(SIGPIPE, SIG_IGN); /* calls to splice() unhelpfully throw this */
|
||||||
|
119
src/mode.c
119
src/mode.c
@@ -56,30 +56,6 @@ static char listen_help_text[] =
|
|||||||
VERBOSE_LINE
|
VERBOSE_LINE
|
||||||
QUIET_LINE;
|
QUIET_LINE;
|
||||||
|
|
||||||
static struct option proxy_options[] = {
|
|
||||||
GETOPT_HELP,
|
|
||||||
GETOPT_ADDR,
|
|
||||||
GETOPT_PORT,
|
|
||||||
GETOPT_CONNECT_ADDR,
|
|
||||||
GETOPT_CONNECT_PORT,
|
|
||||||
GETOPT_BIND,
|
|
||||||
GETOPT_QUIET,
|
|
||||||
GETOPT_VERBOSE,
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
static char proxy_short_options[] = "hl:p:C:P:b:" SOPT_QUIET SOPT_VERBOSE;
|
|
||||||
static char proxy_help_text[] =
|
|
||||||
"Usage: flexnbd " CMD_PROXY " <options>\n\n"
|
|
||||||
"Resiliently proxy an NBD connection between client and server\n\n"
|
|
||||||
HELP_LINE
|
|
||||||
"\t--" OPT_ADDR ",-l <ADDR>\tThe address we will bind to as a proxy.\n"
|
|
||||||
"\t--" OPT_PORT ",-p <PORT>\tThe port we will bind to as a proxy.\n"
|
|
||||||
"\t--" OPT_CONNECT_ADDR ",-C <ADDR>\tAddress of the proxied server.\n"
|
|
||||||
"\t--" OPT_CONNECT_PORT ",-P <PORT>\tPort of the proxied server.\n"
|
|
||||||
"\t--" OPT_BIND ",-b <ADDR>\tThe address we connect from, as a proxy.\n"
|
|
||||||
QUIET_LINE
|
|
||||||
VERBOSE_LINE;
|
|
||||||
|
|
||||||
static struct option read_options[] = {
|
static struct option read_options[] = {
|
||||||
GETOPT_HELP,
|
GETOPT_HELP,
|
||||||
GETOPT_ADDR,
|
GETOPT_ADDR,
|
||||||
@@ -197,7 +173,6 @@ char help_help_text_arr[] =
|
|||||||
"Commands:\n"
|
"Commands:\n"
|
||||||
"\tflexnbd serve\n"
|
"\tflexnbd serve\n"
|
||||||
"\tflexnbd listen\n"
|
"\tflexnbd listen\n"
|
||||||
"\tflexnbd proxy\n"
|
|
||||||
"\tflexnbd read\n"
|
"\tflexnbd read\n"
|
||||||
"\tflexnbd write\n"
|
"\tflexnbd write\n"
|
||||||
"\tflexnbd acl\n"
|
"\tflexnbd acl\n"
|
||||||
@@ -416,46 +391,6 @@ void read_break_param( int c, char **sock )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void read_proxy_param(
|
|
||||||
int c,
|
|
||||||
char **downstream_addr,
|
|
||||||
char **downstream_port,
|
|
||||||
char **upstream_addr,
|
|
||||||
char **upstream_port,
|
|
||||||
char **bind_addr )
|
|
||||||
{
|
|
||||||
switch( c ) {
|
|
||||||
case 'h' :
|
|
||||||
fprintf( stdout, "%s\n", proxy_help_text );
|
|
||||||
exit( 0 );
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
*downstream_addr = optarg;
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
*downstream_port = optarg;
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
*upstream_addr = optarg;
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
*upstream_port = optarg;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
*bind_addr = optarg;
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
log_level = QUIET_LOG_LEVEL;
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
log_level = VERBOSE_LOG_LEVEL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
exit_err( proxy_help_text );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_status_param( int c, char **sock )
|
void read_status_param( int c, char **sock )
|
||||||
{
|
{
|
||||||
read_sock_param( c, sock, status_help_text );
|
read_sock_param( c, sock, status_help_text );
|
||||||
@@ -799,56 +734,6 @@ int mode_status( int argc, char *argv[] )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mode_proxy( int argc, char *argv[] )
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
struct flexnbd * flexnbd;
|
|
||||||
char *downstream_addr = NULL;
|
|
||||||
char *downstream_port = NULL;
|
|
||||||
char *upstream_addr = NULL;
|
|
||||||
char *upstream_port = NULL;
|
|
||||||
char *bind_addr = NULL;
|
|
||||||
int success;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
c = getopt_long( argc, argv, proxy_short_options, proxy_options, NULL );
|
|
||||||
if ( -1 == c ) { break; }
|
|
||||||
read_proxy_param( c,
|
|
||||||
&downstream_addr,
|
|
||||||
&downstream_port,
|
|
||||||
&upstream_addr,
|
|
||||||
&upstream_port,
|
|
||||||
&bind_addr
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( NULL == downstream_addr || NULL == downstream_port ){
|
|
||||||
fprintf( stderr, "both --addr and --port are required.\n" );
|
|
||||||
exit_err( proxy_help_text );
|
|
||||||
} else if ( NULL == upstream_addr || NULL == upstream_port ){
|
|
||||||
fprintf( stderr, "both --conn-addr and --conn-port are required.\n" );
|
|
||||||
exit_err( proxy_help_text );
|
|
||||||
}
|
|
||||||
|
|
||||||
flexnbd = flexnbd_create_proxying(
|
|
||||||
downstream_addr,
|
|
||||||
downstream_port,
|
|
||||||
upstream_addr,
|
|
||||||
upstream_port,
|
|
||||||
bind_addr
|
|
||||||
);
|
|
||||||
|
|
||||||
info(
|
|
||||||
"Proxying between %s %s (downstream) and %s %s (upstream)",
|
|
||||||
downstream_addr, downstream_port, upstream_addr, upstream_port
|
|
||||||
);
|
|
||||||
|
|
||||||
success = flexnbd_proxy( flexnbd );
|
|
||||||
flexnbd_destroy( flexnbd );
|
|
||||||
|
|
||||||
return success ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mode_help( int argc, char *argv[] )
|
int mode_help( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
char *cmd;
|
char *cmd;
|
||||||
@@ -872,8 +757,6 @@ int mode_help( int argc, char *argv[] )
|
|||||||
help_text = mirror_help_text;
|
help_text = mirror_help_text;
|
||||||
} else if ( IS_CMD( CMD_STATUS, cmd ) ) {
|
} else if ( IS_CMD( CMD_STATUS, cmd ) ) {
|
||||||
help_text = status_help_text;
|
help_text = status_help_text;
|
||||||
} else if ( IS_CMD( CMD_PROXY, cmd ) ) {
|
|
||||||
help_text = proxy_help_text;
|
|
||||||
} else { exit_err( help_help_text ); }
|
} else { exit_err( help_help_text ); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,8 +790,6 @@ void mode(char* mode, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else if ( IS_CMD( CMD_STATUS, mode ) ) {
|
else if ( IS_CMD( CMD_STATUS, mode ) ) {
|
||||||
mode_status( argc, argv );
|
mode_status( argc, argv );
|
||||||
} else if ( IS_CMD( CMD_PROXY, mode ) ) {
|
|
||||||
mode_proxy( argc, argv );
|
|
||||||
}
|
}
|
||||||
else if ( IS_CMD( CMD_HELP, mode ) ) {
|
else if ( IS_CMD( CMD_HELP, mode ) ) {
|
||||||
mode_help( argc-1, argv+1 );
|
mode_help( argc-1, argv+1 );
|
||||||
|
@@ -25,7 +25,6 @@ void mode(char* mode, int argc, char **argv);
|
|||||||
|
|
||||||
#define CMD_SERVE "serve"
|
#define CMD_SERVE "serve"
|
||||||
#define CMD_LISTEN "listen"
|
#define CMD_LISTEN "listen"
|
||||||
#define CMD_PROXY "proxy"
|
|
||||||
#define CMD_READ "read"
|
#define CMD_READ "read"
|
||||||
#define CMD_WRITE "write"
|
#define CMD_WRITE "write"
|
||||||
#define CMD_ACL "acl"
|
#define CMD_ACL "acl"
|
||||||
|
172
src/proxy-main.c
Normal file
172
src/proxy-main.c
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
#include <signal.h>
|
||||||
|
#include <sys/signalfd.h>
|
||||||
|
|
||||||
|
#include "mode.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "sockutil.h"
|
||||||
|
#include "proxy.h"
|
||||||
|
|
||||||
|
|
||||||
|
static struct option proxy_options[] = {
|
||||||
|
GETOPT_HELP,
|
||||||
|
GETOPT_ADDR,
|
||||||
|
GETOPT_PORT,
|
||||||
|
GETOPT_CONNECT_ADDR,
|
||||||
|
GETOPT_CONNECT_PORT,
|
||||||
|
GETOPT_BIND,
|
||||||
|
GETOPT_QUIET,
|
||||||
|
GETOPT_VERBOSE,
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
static char proxy_short_options[] = "hl:p:C:P:b:" SOPT_QUIET SOPT_VERBOSE;
|
||||||
|
static char proxy_help_text[] =
|
||||||
|
"Usage: flexnbd-proxy <options>\n\n"
|
||||||
|
"Resiliently proxy an NBD connection between client and server\n\n"
|
||||||
|
HELP_LINE
|
||||||
|
"\t--" OPT_ADDR ",-l <ADDR>\tThe address we will bind to as a proxy.\n"
|
||||||
|
"\t--" OPT_PORT ",-p <PORT>\tThe port we will bind to as a proxy.\n"
|
||||||
|
"\t--" OPT_CONNECT_ADDR ",-C <ADDR>\tAddress of the proxied server.\n"
|
||||||
|
"\t--" OPT_CONNECT_PORT ",-P <PORT>\tPort of the proxied server.\n"
|
||||||
|
"\t--" OPT_BIND ",-b <ADDR>\tThe address we connect from, as a proxy.\n"
|
||||||
|
QUIET_LINE
|
||||||
|
VERBOSE_LINE;
|
||||||
|
|
||||||
|
void read_proxy_param(
|
||||||
|
int c,
|
||||||
|
char **downstream_addr,
|
||||||
|
char **downstream_port,
|
||||||
|
char **upstream_addr,
|
||||||
|
char **upstream_port,
|
||||||
|
char **bind_addr )
|
||||||
|
{
|
||||||
|
switch( c ) {
|
||||||
|
case 'h' :
|
||||||
|
fprintf( stdout, "%s\n", proxy_help_text );
|
||||||
|
exit( 0 );
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
*downstream_addr = optarg;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
*downstream_port = optarg;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
*upstream_addr = optarg;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
*upstream_port = optarg;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
*bind_addr = optarg;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
log_level = QUIET_LOG_LEVEL;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
log_level = VERBOSE_LOG_LEVEL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit_err( proxy_help_text );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stolen from flexnbd.c, wil change in the near future so no point DRYing */
|
||||||
|
int build_signal_fd(void)
|
||||||
|
{
|
||||||
|
sigset_t mask;
|
||||||
|
int sfd;
|
||||||
|
|
||||||
|
sigemptyset( &mask );
|
||||||
|
sigaddset( &mask, SIGTERM );
|
||||||
|
sigaddset( &mask, SIGQUIT );
|
||||||
|
sigaddset( &mask, SIGINT );
|
||||||
|
|
||||||
|
FATAL_UNLESS( 0 == pthread_sigmask( SIG_BLOCK, &mask, NULL ),
|
||||||
|
"Signal blocking failed" );
|
||||||
|
|
||||||
|
sfd = signalfd( -1, &mask, 0 );
|
||||||
|
FATAL_IF( -1 == sfd, "Failed to get a signal fd" );
|
||||||
|
|
||||||
|
return sfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct proxier* flexnbd_create_proxying(
|
||||||
|
int signal_fd,
|
||||||
|
char* s_downstream_address,
|
||||||
|
char* s_downstream_port,
|
||||||
|
char* s_upstream_address,
|
||||||
|
char* s_upstream_port,
|
||||||
|
char* s_upstream_bind
|
||||||
|
)
|
||||||
|
{
|
||||||
|
struct proxier* proxy = proxy_create(
|
||||||
|
signal_fd,
|
||||||
|
s_downstream_address,
|
||||||
|
s_downstream_port,
|
||||||
|
s_upstream_address,
|
||||||
|
s_upstream_port,
|
||||||
|
s_upstream_bind
|
||||||
|
);
|
||||||
|
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main( int argc, char *argv[] )
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
struct proxier * proxy;
|
||||||
|
char *downstream_addr = NULL;
|
||||||
|
char *downstream_port = NULL;
|
||||||
|
char *upstream_addr = NULL;
|
||||||
|
char *upstream_port = NULL;
|
||||||
|
char *bind_addr = NULL;
|
||||||
|
int signal_fd;
|
||||||
|
int success;
|
||||||
|
|
||||||
|
signal(SIGPIPE, SIG_IGN); /* calls to splice() unhelpfully throw this */
|
||||||
|
error_init();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
c = getopt_long( argc, argv, proxy_short_options, proxy_options, NULL );
|
||||||
|
if ( -1 == c ) { break; }
|
||||||
|
read_proxy_param( c,
|
||||||
|
&downstream_addr,
|
||||||
|
&downstream_port,
|
||||||
|
&upstream_addr,
|
||||||
|
&upstream_port,
|
||||||
|
&bind_addr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( NULL == downstream_addr || NULL == downstream_port ){
|
||||||
|
fprintf( stderr, "both --addr and --port are required.\n" );
|
||||||
|
exit_err( proxy_help_text );
|
||||||
|
} else if ( NULL == upstream_addr || NULL == upstream_port ){
|
||||||
|
fprintf( stderr, "both --conn-addr and --conn-port are required.\n" );
|
||||||
|
exit_err( proxy_help_text );
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_fd = build_signal_fd();
|
||||||
|
|
||||||
|
proxy = flexnbd_create_proxying(
|
||||||
|
signal_fd,
|
||||||
|
downstream_addr,
|
||||||
|
downstream_port,
|
||||||
|
upstream_addr,
|
||||||
|
upstream_port,
|
||||||
|
bind_addr
|
||||||
|
);
|
||||||
|
|
||||||
|
info(
|
||||||
|
"Proxying between %s %s (downstream) and %s %s (upstream)",
|
||||||
|
downstream_addr, downstream_port, upstream_addr, upstream_port
|
||||||
|
);
|
||||||
|
|
||||||
|
success = do_proxy( proxy );
|
||||||
|
sock_try_close( signal_fd );
|
||||||
|
|
||||||
|
return success ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
15
src/proxy.c
15
src/proxy.c
@@ -11,18 +11,16 @@
|
|||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
struct proxier* proxy_create(
|
struct proxier* proxy_create(
|
||||||
struct flexnbd* flexnbd,
|
int signal_fd,
|
||||||
char* s_downstream_address,
|
char* s_downstream_address,
|
||||||
char* s_downstream_port,
|
char* s_downstream_port,
|
||||||
char* s_upstream_address,
|
char* s_upstream_address,
|
||||||
char* s_upstream_port,
|
char* s_upstream_port,
|
||||||
char* s_upstream_bind )
|
char* s_upstream_bind )
|
||||||
{
|
{
|
||||||
NULLCHECK( flexnbd );
|
|
||||||
|
|
||||||
struct proxier* out;
|
struct proxier* out;
|
||||||
out = xmalloc( sizeof( struct proxier ) );
|
out = xmalloc( sizeof( struct proxier ) );
|
||||||
out->flexnbd = flexnbd;
|
out->signal_fd = signal_fd;
|
||||||
|
|
||||||
FATAL_IF_NULL(s_downstream_address, "Listen address not specified");
|
FATAL_IF_NULL(s_downstream_address, "Listen address not specified");
|
||||||
NULLCHECK( s_downstream_address );
|
NULLCHECK( s_downstream_address );
|
||||||
@@ -172,13 +170,11 @@ int proxy_should_exit( struct proxier* params, fd_set *check_fds, int wait )
|
|||||||
fd_set internal_fds;
|
fd_set internal_fds;
|
||||||
fd_set* fds = check_fds;
|
fd_set* fds = check_fds;
|
||||||
|
|
||||||
int signal_fd = flexnbd_signal_fd( params->flexnbd );
|
|
||||||
|
|
||||||
if ( NULL == check_fds ) {
|
if ( NULL == check_fds ) {
|
||||||
fds = &internal_fds;
|
fds = &internal_fds;
|
||||||
|
|
||||||
FD_ZERO( fds );
|
FD_ZERO( fds );
|
||||||
FD_SET( signal_fd, fds );
|
FD_SET( params->signal_fd, fds );
|
||||||
|
|
||||||
FATAL_IF_NEGATIVE(
|
FATAL_IF_NEGATIVE(
|
||||||
sock_try_select(FD_SETSIZE, fds, NULL, NULL, &tv),
|
sock_try_select(FD_SETSIZE, fds, NULL, NULL, &tv),
|
||||||
@@ -186,7 +182,7 @@ int proxy_should_exit( struct proxier* params, fd_set *check_fds, int wait )
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( FD_ISSET( signal_fd, fds ) ) {
|
if ( FD_ISSET( params->signal_fd, fds ) ) {
|
||||||
info( "Stop signal received" );
|
info( "Stop signal received" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -410,7 +406,6 @@ int proxy_accept( struct proxier* params )
|
|||||||
NULLCHECK( params );
|
NULLCHECK( params );
|
||||||
|
|
||||||
int client_fd;
|
int client_fd;
|
||||||
int signal_fd = flexnbd_signal_fd( params->flexnbd );
|
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
int should_continue = 1;
|
int should_continue = 1;
|
||||||
|
|
||||||
@@ -421,7 +416,7 @@ int proxy_accept( struct proxier* params )
|
|||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(params->listen_fd, &fds);
|
FD_SET(params->listen_fd, &fds);
|
||||||
FD_SET(signal_fd, &fds);
|
FD_SET(params->signal_fd, &fds);
|
||||||
|
|
||||||
FATAL_IF_NEGATIVE(
|
FATAL_IF_NEGATIVE(
|
||||||
sock_try_select(FD_SETSIZE, &fds, NULL, NULL, NULL),
|
sock_try_select(FD_SETSIZE, &fds, NULL, NULL, NULL),
|
||||||
|
@@ -55,10 +55,13 @@ struct proxier {
|
|||||||
|
|
||||||
/* We transform the raw reply header into here */
|
/* We transform the raw reply header into here */
|
||||||
struct nbd_reply rsp_hdr;
|
struct nbd_reply rsp_hdr;
|
||||||
|
|
||||||
|
/* File descriptor that signal handlers write to */
|
||||||
|
int signal_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct proxier* proxy_create(
|
struct proxier* proxy_create(
|
||||||
struct flexnbd * flexnbd,
|
int signal_fd,
|
||||||
char* s_downstream_address,
|
char* s_downstream_address,
|
||||||
char* s_downstream_port,
|
char* s_downstream_port,
|
||||||
char* s_upstream_address,
|
char* s_upstream_address,
|
||||||
|
@@ -242,7 +242,7 @@ module FlexNBD
|
|||||||
end
|
end
|
||||||
|
|
||||||
def proxy_cmd( connect_ip, connect_port )
|
def proxy_cmd( connect_ip, connect_port )
|
||||||
"#{bin} proxy "\
|
"#{bin}-proxy "\
|
||||||
"--addr #{ip} "\
|
"--addr #{ip} "\
|
||||||
"--port #{port} "\
|
"--port #{port} "\
|
||||||
"--conn-addr #{connect_ip} "\
|
"--conn-addr #{connect_ip} "\
|
||||||
|
Reference in New Issue
Block a user