68 Commits

Author SHA1 Message Date
Patrick J Cherry
e7e99b099c Updated debian packaging, adding in new build-deps. 2016-10-06 16:02:15 +01:00
Patrick J Cherry
b2edd0734a Merge branch 'master' of gitlab.bytemark.co.uk:open-source/flexnbd-c into debian 2016-10-06 16:00:14 +01:00
James Carter
e19d005636 Merge branch '26-fix-function-definition' into 'master'
OK removed the cast and fixed the function def in the test

This should definitely clear the warning.

Closes #26

See merge request !21
2016-10-06 15:59:57 +01:00
Patrick J Cherry
d1e6e835c4 OK removed the cast and fixed the function def in the test
This should definitely clear the warning.
2016-10-06 15:56:57 +01:00
Patrick J Cherry
8fed794fe7 Merge branch 'master' of gitlab.bytemark.co.uk:open-source/flexnbd-c into debian 2016-10-06 15:47:25 +01:00
James Carter
e24efa9864 Merge branch '26-fix-compiler-warning' into 'master'
Resolve "tests/unit/check_readwrite.c causes compiler warnings"

Closes #26

See merge request !20
2016-10-06 15:46:41 +01:00
James Carter
3134d619ef Merge branch '27-fix-make-test' into 'master'
Update Makefile to specify dependencies properly for tests

Closes #27

See merge request !19
2016-10-06 15:44:46 +01:00
Patrick J Cherry
898f3f6c7e Reinstated char * cast to remove compiler warning 2016-10-06 15:43:20 +01:00
Patrick J Cherry
5a1bc21088 Update Makefile to specify dependencies properly for tests 2016-10-06 15:40:15 +01:00
James Carter
deb8f2c53b Merge branch 'fix-check-nbdtypes' into 'master'
Fix up nbdtypes test to correctly use htobe64

Previous change hadn't taken this into account, and hopefully this makes
our test a little clearer.

See merge request !18
2016-10-06 14:50:03 +01:00
Patrick J Cherry
1338d9e910 Fix up nbdtypes test to correctly use htobe64
Previous change hadn't taken this into account, and hopefully this makes
our test a little clearer.
2016-10-06 14:46:29 +01:00
James Carter
47c05174b6 Merge branch 'fix-check-readwrite' into 'master'
Fix check readwrite segfault

Little slip corrected :)

See merge request !17
2016-10-06 14:10:22 +01:00
Patrick J Cherry
191b3bc72c Merge branch 'master' of gitlab.bytemark.co.uk:open-source/flexnbd-c into fix-check-readwrite 2016-10-06 14:06:21 +01:00
James Carter
770ca0d0e5 Merge branch 'fix-test-names' into 'master'
Fixed up internal test names (copy/pasta?)

The test names output by `make check` now reflect reality.

See merge request !16
2016-10-06 14:04:54 +01:00
Patrick J Cherry
6505588f25 Fixed check_readwrite test to pass correct handle to fd_write_reply
The (char*) cast to resp->received.handle.b was causing a segfault
2016-10-06 14:01:47 +01:00
Patrick J Cherry
957707bcfc Fixed up internal test names (copy/pasta?)
The test names output by `make check` now reflect reality.
2016-10-06 13:44:20 +01:00
James Carter
3f01b77221 Merge branch 'update-manpages-again' into 'master'
Updated manpages, replaces a2x with txt2man

This simplifies the build-deps for Debian packages a little, and brings
the docs up to date.

See merge request !15
2016-10-06 13:43:53 +01:00
Patrick J Cherry
0dbea7f8fe Removed extra tabs
Oops
2016-10-06 13:11:07 +01:00
Patrick J Cherry
091aacd16d Updated manpages, replaces a2x with txt2man
This simplifies the build-deps for Debian packages a little, and brings
the docs up to date.
2016-10-06 12:55:05 +01:00
Patrick J Cherry
04b6637451 Merge branch 'failed-tests-cause-error' into 'master'
failures in make check now result in an error



See merge request !13
2016-10-05 17:20:43 +01:00
James F. Carter
7d2eda6cea failures in make check now result in an error 2016-10-05 16:28:27 +01:00
Patrick J Cherry
7e152ca4f2 Merge branch '24-tests-in-gitlab' into 'master'
Resolve "tests should be run in gitlab-ci"

Closes #24

See merge request !12
2016-10-05 15:08:22 +01:00
James F. Carter
fe0125efbc Merge branch 'master' into 24-tests-in-gitlab 2016-10-05 14:27:56 +01:00
James Carter
ebaaa6d671 Merge branch '25-retire-rake' into 'master'
Moved tasks from Rake to Make

The rake file was obsolete, apart from one invocation of ruby in a shell!

Closes #25

See merge request !11
2016-10-05 14:26:06 +01:00
James F. Carter
8cc8588744 Merge branch '24-tests-in-gitlab' of gitlab.bytemark.co.uk:open-source/flexnbd-c into 24-tests-in-gitlab 2016-10-05 13:06:36 +01:00
James F. Carter
5da77ea39a remove unnecessary step in gitlab-ci 2016-10-05 12:52:32 +01:00
James F. Carter
a744965c67 add missing deps on server object files when building check binaries 2016-10-05 12:51:58 +01:00
Patrick J Cherry
d07659f694 Merge branch '24-tests-in-gitlab' of gitlab.bytemark.co.uk:open-source/flexnbd-c into 25-retire-rake 2016-10-05 12:49:53 +01:00
Patrick J Cherry
30562ed900 Added dpkg-dev to requirements
Allows dpkg-architecture to run.
2016-10-05 12:49:25 +01:00
Patrick J Cherry
93c0fa2e92 Merged in gitlab-ci.yml and fixed to use Make
The CI should now use Make instead of Rake
2016-10-05 12:47:24 +01:00
Patrick J Cherry
8dc491fb89 Merge branch '24-tests-in-gitlab' of gitlab.bytemark.co.uk:open-source/flexnbd-c into 25-retire-rake 2016-10-05 12:46:47 +01:00
Patrick J Cherry
ea7cd64fc2 Moved tasks from Rake to Make
The rake file was obsolete, apart from one invocation of ruby in a
shell!
2016-10-05 12:36:06 +01:00
James F. Carter
35d3340708 avoid need for slow-to-install asciidoc in gitlab-ci 2016-10-05 12:10:21 +01:00
James F. Carter
d47a44a204 install asciidoc in gitlab-ci 2016-10-05 12:07:24 +01:00
James F. Carter
d6968d8242 explicitly compile before running tests in gitlab-ci 2016-10-05 12:06:11 +01:00
James F. Carter
bf85e329a0 clean build environment before running tests in gitlab-ci 2016-10-05 12:03:23 +01:00
James F. Carter
edcaef532c revert gitlab-ci to ruby2.1 2016-10-05 11:58:50 +01:00
James F. Carter
cb920e4e9d Merge branch 'master' into 24-tests-in-gitlab 2016-10-05 11:58:21 +01:00
Patrick J Cherry
91d85633b6 Merge branch 'force-encoding-for-ruby21' into 'master'
force binary encoding in a ruby2.1-compatible way



See merge request !10
2016-10-05 11:57:14 +01:00
James Carter
7c516b85a6 Merge branch 'makefile-fixes' into 'master'
Makefile fixes



See merge request !2
2016-10-05 11:55:54 +01:00
James F. Carter
679fa6dbf8 force binary encoding in a ruby2.1-compatible way 2016-10-05 11:54:09 +01:00
James F. Carter
50708326ec try ruby2.3 in gitlab-ci 2016-10-05 11:42:32 +01:00
James F. Carter
d907025d71 try a newer version of ruby in gitlab-ci 2016-10-05 11:39:56 +01:00
James F. Carter
e4d398a078 install net-tools in gitlab-ci 2016-10-05 11:29:42 +01:00
James F. Carter
8de0780125 install libev-dev in gitlab-ci 2016-10-05 11:26:46 +01:00
James F. Carter
0fd16822ea run tests in gitlab-ci 2016-10-05 11:12:39 +01:00
Patrick J Cherry
1e3c61b541 Merge branch '23-fix-unit-tests' into 'master'
update tests to reflect changes in handle storage

Closes #23

See merge request !9
2016-10-05 11:08:21 +01:00
James F. Carter
a09e14b2d4 whitespace fix 2016-10-05 11:06:39 +01:00
James F. Carter
a6710b6c32 update tests to reflect changes in handle storage 2016-10-05 10:57:52 +01:00
Patrick J Cherry
ed3995303f Reinstate doc to all 2016-10-05 10:41:23 +01:00
James Carter
f5de8fb12b Merge branch '20-fix-encoding-failures' into 'master'
Use a BINARY encoded string when doing read/write comparisons.

This is a bit of a cheat really, but `#read` returns an ASCII encoded
string, where as our ruby generates UTF-8 encoded strings, causing
assertion failures.

Closes #20

See merge request !8
2016-10-05 10:32:05 +01:00
James F. Carter
99a5f79a52 fixed typo 2016-10-05 10:30:44 +01:00
Patrick J Cherry
356e1fd6a1 Use a BINARY encoded string when doing read/write comparisons.
This is a bit of a cheat really, but `#read` returns an ASCII encoded
string, where as our ruby generates UTF-8 encoded strings, causing
assertion failures.

Fixes #20
2016-10-05 10:01:15 +01:00
James Carter
67dcea207d Merge branch '19-fix-double-definition-warnings' into 'master'
Fixes "double-definition of constants" warning

Looks like `#constants.include?` doesn't work as well as `#const_defined?`.

Closes #19

See merge request !6
2016-10-05 10:00:50 +01:00
Patrick J Cherry
d3762162db Fixes "double-definition of constants" warning
Looks like `#constants.include?` doesn't work as well as
`#const_defined?`.
2016-10-05 09:29:07 +01:00
Patrick J Cherry
3571d3f82e Added net-tools to the build-deps for testing
Fixes #21
2016-10-05 09:27:10 +01:00
Patrick J Cherry
4cd7e764bb Updated changelog 2016-10-04 21:22:07 +01:00
Patrick J Cherry
4f535fbb02 Merge branch 'master' of gitlab.bytemark.co.uk:open-source/flexnbd-c into debian 2016-10-04 21:14:26 +01:00
James Carter
218c55fb63 Merge branch 'simplify-nbd-handles-part-deux' into 'master'
Simplified NBD handle comparisons

8 bytes, therefore a uing64_t to compare to, no need for memcmp()

Signed-off-by: Michel Pollet <buserror@gmail.com>

See merge request !5
2016-10-04 15:49:07 +01:00
Michel Pollet
956a602475 Simplified NBD handle comparisons
8 bytes, therefore a uing64_t to compare to, no need for memcmp()

Signed-off-by: Michel Pollet <buserror@gmail.com>
2016-10-04 15:41:48 +01:00
James Carter
26a0a82f9d Merge branch '12-fix-bind' into 'master'
Attempt at fixing bind() bug

This will prevent the bind() wrapper to loop forever in some cases. I
could nor reproduce the issue, but this removes the only infinite loop I
could find.

Closes #12

See merge request !3
2016-10-04 15:41:37 +01:00
Michel Pollet
76e0476113 Attempt at fixing bind() bug
This will prevent the bind() wrapper to loop forever in some cases. I
could nor reproduc the issue, but this removes the only infinite loop I
could find.

Signed-off-by: Michel Pollet <buserror@gmail.com>
2016-10-04 15:36:46 +01:00
Michel Pollet
d9651a038c Makefile: don't include *.d's before 'all'
Include any .d file from the build directory, and do that after all the
other targets

Signed-off-by: Michel Pollet <buserror@gmail.com>
2016-10-04 15:32:56 +01:00
Michel Pollet
fcd3d33498 Simplified Makefile
gcc and clang can generate dep files as well as compiling in a single
pass, no need for two.

Signed-off-by: Michel Pollet <buserror@gmail.com>
2016-10-04 15:32:49 +01:00
James Carter
e3360a3a1b Merge branch 'cherry-pick-41f25408' into 'master'
Close socket fix, might relate to migration crashing

This was listed as a bug, and was immediatelly picked the static
analyzer anyway, this is very likely the cause for the
migration-cancel-crash bug.

closes #10 and possibly closes #11

See merge request !1
2016-09-14 11:29:12 +01:00
Michel Pollet
1fefe1a669 Close socket fix, might relate to migration crashing
This was listed as a bug, and was immediatelly picked the static
analyzer anyway, this is very likely the cause for the
migration-cancel-crash bug.

Signed-off-by: Michel Pollet <buserror@gmail.com>
2016-09-14 10:45:49 +01:00
Patrick J Cherry
4ed8d49b2c Updated rules to skip ruby tests, and just use the normal make check 2016-08-31 10:06:07 +01:00
Patrick J Cherry
3af0e84f5f Updated Debian packaging to be in a separate branch.
This should allow us to use git-buildpackage to build our packages.
2016-08-30 21:57:00 +01:00
27 changed files with 3241 additions and 390 deletions

10
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,10 @@
image: "ruby:2.1"
before_script:
- apt-get update; apt-get install -y check libev-dev net-tools dpkg-dev
unit_test:
script:
- make clean
- make build
- make test

View File

@@ -50,15 +50,11 @@ CC?=gcc
LIBS=-lpthread LIBS=-lpthread
INC=-I/usr/include/libev -Isrc/common -Isrc/server -Isrc/proxy INC=-I/usr/include/libev -Isrc/common -Isrc/server -Isrc/proxy
COMPILE=$(CC) $(INC) -c $(CCFLAGS) COMPILE=$(CC) -MMD $(INC) -c $(CCFLAGS)
SAVEDEP=$(CC) $(INC) -MM $(CCFLAGS)
LINK=$(CC) $(LLDFLAGS) -Isrc $(LIBS) LINK=$(CC) $(LLDFLAGS) -Isrc $(LIBS)
LIB=build/ LIB=build/
EXISTING_OBJS := $(wildcard build/*.o)
-include $(EXISTING_OBJS:.o=.d)
COMMON_SRC := $(wildcard src/common/*.c) COMMON_SRC := $(wildcard src/common/*.c)
SERVER_SRC := $(wildcard src/server/*.c) SERVER_SRC := $(wildcard src/server/*.c)
PROXY_SRC := $(wildcard src/proxy/*.c) PROXY_SRC := $(wildcard src/proxy/*.c)
@@ -71,12 +67,13 @@ SRCS := $(COMMON_SRC) $(SERVER_SRC) $(PROXY_SRC)
OBJS := $(COMMON_OBJ) $(SERVER_OBJ) $(PROXY_OBJ) OBJS := $(COMMON_OBJ) $(SERVER_OBJ) $(PROXY_OBJ)
all: build/flexnbd build/flexnbd-proxy doc all: build doc
build: server proxy
build/%.o: %.c build/%.o: %.c
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(COMPILE) $< -o $@ $(COMPILE) $< -o $@
$(SAVEDEP) $< > build/$*.d
objs: $(OBJS) objs: $(OBJS)
@@ -87,41 +84,42 @@ build/flexnbd-proxy: $(COMMON_OBJ) $(PROXY_OBJ) build/proxy-main.o
$(LINK) $^ -o $@ $(LINK) $^ -o $@
server: build/flexnbd server: build/flexnbd
proxy: build/flexnbd-proxy proxy: build/flexnbd-proxy
CHECK_SRC := $(wildcard tests/unit/*.c) CHECK_SRC := $(wildcard tests/unit/*.c)
CHECK_OBJ := $(CHECK_SRC:tests/unit/%.c=build/tests/%.o) CHECK_OBJ := $(CHECK_SRC:tests/unit/%.c=build/%.o)
# Why can't we reuse the build/%.o rule above? Not sure. # Why can't we reuse the build/%.o rule above? Not sure.
build/tests/%.o: tests/unit/%.c
mkdir -p $(dir $@)
$(COMPILE) $< -o $@
$(SAVEDEP) $< > build/tests/$*.d
CHECK_BINS := $(CHECK_OBJ:build/tests/%.o=build/tests/%) CHECK_BINS := $(CHECK_SRC:tests/unit/%.c=build/%)
build/tests/%: build/tests/%.o $(OBJS)
$(LINK) $^ -o $@ -lcheck build/check_%: build/check_%.o
$(LINK) $^ -o $@ $(COMMON_OBJ) $(SERVER_OBJ) -lcheck
check_objs: $(CHECK_OBJ) check_objs: $(CHECK_OBJ)
check_bins: $(CHECK_BINS) check_bins: $(CHECK_BINS)
check: $(CHECK_BINS)
for bin in $^; do $$bin; done check: $(OBJS) $(CHECK_BINS)
r=true ; for bin in $(CHECK_BINS); do $$bin || r=false; done ; $$r
acceptance: build
cd tests/acceptance && RUBYOPT='-I.' ruby nbd_scenarios -v
test: check acceptance
build/flexnbd.1: README.txt build/flexnbd.1: README.txt
a2x --destination-dir build --format manpage $< txt2man -t flexnbd -s 1 $< > $@
build/flexnbd-proxy.1: README.proxy.txt build/flexnbd-proxy.1: README.proxy.txt
a2x --destination-dir build --format manpage $< txt2man -t flexnbd-proxy -s 1 $< > $@
# If we don't pipe to file, gzip clobbers the original, causing make # If we don't pipe to file, gzip clobbers the original, causing make
# to rebuild each time # to rebuild each time
%.1.gz: %.1 %.1.gz: %.1
gzip -c -f $< > $@ gzip -c -f $< > $@
doc: build/flexnbd.1.gz build/flexnbd-proxy.1.gz
server-man: build/flexnbd.1.gz
proxy-man: build/flexnbd-proxy.1.gz
doc: server-man proxy-man
install: install:
mkdir -p $(INSTALLDIR) mkdir -p $(INSTALLDIR)
@@ -131,4 +129,7 @@ clean:
rm -rf build/* rm -rf build/*
.PHONY: clean objs check_objs all server proxy check_bins check server-man proxy-man doc .PHONY: clean objs check_objs all server proxy check_bins check doc build test acceptance
# Include extra dependencies at the end, NOT before 'all'
-include $(wildcard build/*.d)

View File

@@ -1,19 +1,14 @@
FLEXNBD-PROXY(1)
================
:doctype: manpage
NAME NAME
----
flexnbd-proxy - A simple NBD proxy flexnbd-proxy - A simple NBD proxy
SYNOPSIS SYNOPSIS
--------
*flexnbd-proxy* ['OPTIONS'] flexnbd-proxy --addr ADDR [--port PORT] --conn-addr ADDR
--conn-port PORT [--bind ADDR] [--cache[=CACHE_BYTES]]
[--help] [--verbose] [--quiet]
DESCRIPTION DESCRIPTION
-----------
flexnbd-proxy is a simple NBD proxy server that implements resilient flexnbd-proxy is a simple NBD proxy server that implements resilient
connection logic for the client. It connects to an upstream NBD server connection logic for the client. It connects to an upstream NBD server
@@ -25,11 +20,6 @@ of view of the client) reconnects and retransmits the request, before
returning the response to the client. returning the response to the client.
USAGE USAGE
-----
$ flexnbd-proxy --addr <ADDR> [ --port <PORT> ]
--conn-addr <ADDR> --conn-port <PORT>
[--bind <ADDR>] [--cache[=<CACHE_BYTES>]] [option]*
Proxy requests from an NBD client to an NBD server, resiliently. Only one Proxy requests from an NBD client to an NBD server, resiliently. Only one
client can be connected at a time, and ACLs cannot be applied to the client, as they client can be connected at a time, and ACLs cannot be applied to the client, as they
@@ -58,40 +48,39 @@ 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 doesn't seem to slow things down much relative to alternative options, but may
be changed in the future if it becomes an issue. be changed in the future if it becomes an issue.
Options OPTIONS
~~~~~~~
*--addr, -l ADDR*: --addr, -l ADDR
The address to listen on. If this begins with a '/', it is assumed to be The address to listen on. If this begins with a '/', it is assumed to be
a UNIX domain socket to create. Otherwise, it should be an IPv4 or IPv6 a UNIX domain socket to create. Otherwise, it should be an IPv4 or IPv6
address. address.
*--port, -p PORT*:
--port, -p PORT
The port to listen on, if --addr is not a UNIX socket. The port to listen on, if --addr is not a UNIX socket.
*--conn-addr, -C ADDR*: --conn-addr, -C ADDR
The address of the NBD server to connect to. Required. The address of the NBD server to connect to. Required.
*--conn-port, -P PORT*: --conn-port, -P PORT
The port of the NBD server to connect to. Required. The port of the NBD server to connect to. Required.
*--cache, -c=CACHE_BYTES*: --cache, -c=CACHE_BYTES
If given, the size in bytes of read cache to use. CACHE_BYTES If given, the size in bytes of read cache to use. CACHE_BYTES
defaults to 4096. defaults to 4096.
*--help, -h* : --help, -h
Show command or global help. Show command or global help.
*--verbose, -v* : --verbose, -v
Output all available log information to STDERR. Output all available log information to STDERR.
*--quiet, -q* : --quiet, -q
Output as little log information as possible to STDERR. Output as little log information as possible to STDERR.
LOGGING LOGGING
-------
Log output is sent to STDERR. If --quiet is set, no output will be seen Log output is sent to STDERR. If --quiet is set, no output will be
unless the program termintes abnormally. If neither --quiet nor seen unless the program termintes abnormally. If neither --quiet nor
--verbose are set, no output will be seen unless something goes wrong --verbose are set, no output will be seen unless something goes wrong
with a specific request. If --verbose is given, every available log 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 message will be seen (which, for a debug build, is many). It is not an
@@ -101,32 +90,31 @@ The log line format is:
<TIMESTAMP>:<LEVEL>:<PID> <THREAD> <SOURCEFILE>:<SOURCELINE>: <MSG> <TIMESTAMP>:<LEVEL>:<PID> <THREAD> <SOURCEFILE>:<SOURCELINE>: <MSG>
*TIMESTAMP*: <TIMESTAMP>
Time the log entry was made. This is expressed in terms of monotonic ms Time the log entry was made. This is expressed in terms of monotonic ms
*LEVEL*: <LEVEL>
This will be one of 'D', 'I', 'W', 'E', 'F' in increasing order of 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 severity. If flexnbd is started with the --quiet flag, only 'F' will
seen. If it is started with the --verbose flag, any from 'I' upwards be seen. If it is started with the --verbose flag, any from 'I'
will be seen. Only if you have a debug build and start it with upwards will be seen. Only if you have a debug build and start it
--verbose will you see 'D' entries. with --verbose will you see 'D' entries.
*PID*: <PID>
This is the process ID. This is the process ID.
*THREAD*: <THREAD>
flexnbd-proxy is currently single-threaded, so this should be the same flexnbd-proxy is currently single-threaded, so this should be the
for all lines. That may not be the case in the future. same for all lines. That may not be the case in the future.
*SOURCEFILE:SOURCELINE*: <SOURCEFILE:SOURCELINE>
Identifies where in the source code this log line can be found. Identifies where in the source code this log line can be found.
*MSG*: <MSG>
A short message describing what's happening, how it's being done, or A short message describing what's happening, how it's being done, or
if you're very lucky *why* it's going on. if you're very lucky why it's going on.
Proxying EXAMPLES
~~~~~~~~
The main point of the proxy mode is to allow clients that would otherwise break 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 when the NBD server goes away (during a migration, for instance) to see a
@@ -160,7 +148,6 @@ The data in myfile has been moved between physical servers without the nbd
client process having to be disturbed at all. client process having to be disturbed at all.
READ CACHE READ CACHE
----------
If the --cache option is given at the command line, either without an If the --cache option is given at the command line, either without an
argument or with an argument greater than 0, flexnbd-proxy will use a argument or with an argument greater than 0, flexnbd-proxy will use a
@@ -173,7 +160,7 @@ cache without making a request to the server.
This pattern is designed to match sequential reads, such as those This pattern is designed to match sequential reads, such as those
performed by a booting virtual machine. performed by a booting virtual machine.
Note: If specifying a cache size, you *must* use this form: Note: If specifying a cache size, you must use this form:
nbd-client$ flexnbd-proxy --cache=XXXX nbd-client$ flexnbd-proxy --cache=XXXX
@@ -183,30 +170,37 @@ If no cache size is given, a size of 4096 bytes is assumed. Caching can
be explicitly disabled by setting a size of 0. be explicitly disabled by setting a size of 0.
BUGS BUGS
----
Should be reported to nick@bytemark.co.uk. Should be reported via GitHub.
* https://github.com/BytemarkHosting/flexnbd-c/issues
Current issues include: Current issues include:
* Only old-style NBD negotiation is supported * only old-style NBD negotiation is supported;
* Only one request may be in-flight at a time * only one request may be in-flight at a time;
* All I/O is blocking, and signals terminate the process immediately * all I/O is blocking, and signals terminate the process immediately;
* UNIX socket support is limited to the listen address * UNIX socket support is limited to the listen address;
* FLUSH and TRIM commands, and the FUA flag, are not supported * FLUSH and TRIM commands, and the FUA flag, are not supported;
* DISCONNECT requests do not get passed through to the NBD server * 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 * no active timeout-retry of requests - we trust the kernel's idea of
failure.
AUTHOR AUTHOR
------
Written by Alex Young <alex@bytemark.co.uk>. Originally written by Alex Young <alex@blackkettle.org>.
Original concept and core code by Matthew Bloch <matthew@bytemark.co.uk>. Original concept and core code by Matthew Bloch <matthew@bytemark.co.uk>.
Proxy mode written by Nick Thomas <nick@bytemark.co.uk> Proxy mode written by Nick Thomas <me@ur.gs>.
COPYING The full commit history is available on GitHub.
-------
Copyright (c) 2012 Bytemark Hosting Ltd. Free use of this software is SEE ALSO
granted under the terms of the GNU General Public License version 3 or
later. flexnbd(1), nbd-client(8), xnbd-server(8), xnbd-client(8)
COPYRIGHT
Copyright (c) 2012-2016 Bytemark Hosting Ltd. Free use of this
software is granted under the terms of the GNU General Public License
version 3 or later.

View File

@@ -1,17 +1,36 @@
FLEXNBD(1)
==========
:doctype: manpage
NAME NAME
----
flexnbd - A fast NBD server flexnbd - A fast NBD server
SYNOPSIS SYNOPSIS
--------
*flexnbd* 'COMMAND' ['OPTIONS'] flexnbd MODE [ ARGS ]
flexnbd serve --addr ADDR --port PORT --file FILE [--sock SOCK]
[--default-deny] [--killswitch] [global_option]* [acl_entry]*
flexnbd listen --addr ADDR --port PORT --file FILE [--sock SOCK]
[--default-deny] [global_option]* [acl_entry]*
flexnbd mirror --addr ADDR --port PORT --sock SOCK [--unlink]
[--bind BIND_ADDR] [global_option]*
flexnbd acl --sock SOCK [acl_entry]+ [global_option]*
flexnbd break --sock SOCK [global_option]*
flexnbd status --sock SOCK [global_option]*
flexnbd read --addr ADDR --port PORT --from OFFSET --size SIZE
[--bind BIND_ADDR] [global_option]*
flexnbd write --addr ADDR --port PORT --from OFFSET --size SIZE
[--bind BIND_ADDR] [global_option]*
flexnbd help [mode] [global_option]*
DESCRIPTION DESCRIPTION
-----------
Flexnbd is a fast NBD server which supports live migration. Live Flexnbd is a fast NBD server which supports live migration. Live
migration is performed by writing the data to a new server. A failed migration is performed by writing the data to a new server. A failed
migration will be invisible to any connected clients. migration will be invisible to any connected clients.
@@ -19,57 +38,56 @@ migration will be invisible to any connected clients.
Flexnbd tries quite hard to preserve sparsity of files it is serving, Flexnbd tries quite hard to preserve sparsity of files it is serving,
even across migrations. even across migrations.
COMMANDS SERVE MODE
--------
Serve a file.
serve
~~~~~
$ flexnbd serve --addr <ADDR> --port <PORT> --file <FILE> $ flexnbd serve --addr <ADDR> --port <PORT> --file <FILE>
[--sock <SOCK>] [--default-deny] [-k] [global option]* [acl entry]* [--sock <SOCK>] [--default-deny] [-k] [global_option]*
[acl_entry]*
Serve a file. If any ACL entries are given (which should be IP If any ACL entries are given (which should be IP
addresses), only those clients listed will be permitted to connect. addresses), only those clients listed will be permitted to connect.
flexnbd will continue to serve until a SIGINT, SIGQUIT, or a successful flexnbd will continue to serve until a SIGINT, SIGQUIT, or a successful
migration. migration.
Options OPTIONS
^^^^^^^
*--addr, -l ADDR*: --addr, -l ADDR
The address to listen on. Required. The address to listen on. Required.
*--port, -p PORT*: --port, -p PORT
The port to listen on. Required. The port to listen on. Required.
*--file, -f FILE*: --file, -f FILE
The file to serve. Must already exist. Required. The file to serve. Must already exist. Required.
*--sock, -s SOCK*: --sock, -s SOCK
Path to a control socket to open. You will need this if you want to Path to a control socket to open. You will need this if you want to
migrate, get the current status, or manipulate the access control migrate, get the current status, or manipulate the access control
list. list.
*--default-deny, -d*: --default-deny, -d
How to interpret an empty ACL. If --default-deny is given, an How to interpret an empty ACL. If --default-deny is given, an
empty ACL will let no clients connect. If it is not given, an empty ACL will let no clients connect. If it is not given, an
empty ACL will let any client connect. empty ACL will let any client connect.
*--killswitch, -k*: --killswitch, -k
If set, we implement a 2-minute timeout on NBD requests and If set, we implement a 2-minute timeout on NBD requests and
responses. If a request takes longer than that to complete, responses. If a request takes longer than that to complete,
the client is disconnected. This is useful to keep broken the client is disconnected. This is useful to keep broken
clients from breaking migrations, among other things. clients from breaking migrations, among other things.
listen LISTEN MODE
~~~~~~
$ flexnbd listen --addr <ADDR> --port <PORT> --file <FILE>
[--sock <SOCK>] [--default-deny] [global option]* [acl entry]*
Listen for an inbound migration, and quit with a status of 0 on Listen for an inbound migration, and quit with a status of 0 on
completion. completion.
$ flexnbd listen --addr ADDR --port PORT --file FILE
[--sock SOCK] [--default-deny] [global_option]*
[acl_entry]*
flexnbd will wait for a successful migration, and then quit. The file flexnbd will wait for a successful migration, and then quit. The file
to write the inbound migration data to must already exist before you to write the inbound migration data to must already exist before you
run 'flexnbd listen'. run 'flexnbd listen'.
@@ -81,25 +99,24 @@ to assume that a partial migration can be resumed because the
destination has no knowledge of whether a client has made a write to destination has no knowledge of whether a client has made a write to
the source in the interim. the source in the interim.
If the migration fails for a reason which the `flexnbd listen` process If the migration fails for a reason which the 'flexnbd listen' process
can't fix (say, a failed local write), it will exit with an error can't fix (say, a failed local write), it will exit with an error
status. In this case, the sender will continually retry the migration status. In this case, the sender will continually retry the migration
until it succeeds, and you will need to restart the `flexnbd listen` until it succeeds, and you will need to restart the 'flexnbd listen'
process to allow that to happen. process to allow that to happen.
Options OPTIONS
^^^^^^^
As for 'serve'.
mirror As for serve.
~~~~~~
$ flexnbd mirror --addr <ADDR> --port <PORT> --sock SOCK MIRROR MODE
[--unlink] [--bind <BIND-ADDR>] [global option]*
Start a migration from the server with control socket SOCK to the server Start a migration from the server with control socket SOCK to the server
listening at ADDR:PORT. listening at ADDR:PORT.
$ flexnbd mirror --addr ADDR --port PORT --sock SOCK [--unlink]
[--bind BIND_ADDR] [global_option]*
Migration can be a slow process. Rather than block the 'flexnbd mirror' Migration can be a slow process. Rather than block the 'flexnbd mirror'
process until it completes, it will exit with a message of "Migration process until it completes, it will exit with a message of "Migration
started" once it has confirmation that the local server was able to started" once it has confirmation that the local server was able to
@@ -112,7 +129,7 @@ again. It is not safe to resume the migration from where it left off
because the source can't see that the backing store behind the because the source can't see that the backing store behind the
destination is intact, or even on the same machine. destination is intact, or even on the same machine.
If the `--unlink` option is given, the local file will be deleted If the --unlink option is given, the local file will be deleted
immediately before the mirror connection is terminated. This allows immediately before the mirror connection is terminated. This allows
an otherwise-ambiguous situation to be resolved: if you don't unlink an otherwise-ambiguous situation to be resolved: if you don't unlink
the file and the flexnbd process at either end is terminated, it's not the file and the flexnbd process at either end is terminated, it's not
@@ -122,161 +139,150 @@ the data, there can be no ambiguity.
Note: files smaller than 4096 bytes cannot be mirrored. Note: files smaller than 4096 bytes cannot be mirrored.
Options OPTIONS
^^^^^^^
*--addr, -l ADDR*: --addr, -l ADDR
The address of the remote server to migrate to. Required. The address of the remote server to migrate to. Required.
*--port, -p PORT*: --port, -p PORT
The port of the remote server to migrate to. Required. The port of the remote server to migrate to. Required.
*--sock, -s SOCK*: --sock, -s SOCK
The control socket of the local server to migrate from. Required. The control socket of the local server to migrate from. Required.
*--unlink, -u*: --unlink, -u
Unlink the served file from the local filesystem after successfully Unlink the served file from the local filesystem after
mirroring. successfully mirroring.
*--bind, -b BIND-ADDR*: --bind, -b BIND_ADDR
The local address to bind to. You may need this if the remote server The local address to bind to. You may need this if the remote
is using an access control list. server is using an access control list.
break BREAK MODE
~~~~~
$ flexnbd mirror --sock SOCK [global option]*
Stop a running migration. Stop a running migration.
Options $ flexnbd break --sock SOCK [global_option]*
^^^^^^^
*--sock, -s SOCK*: OPTIONS
The control socket of the local server whose emigration to stop.
--sock, -s SOCK
The control socket of the local server whose migration to stop.
Required. Required.
ACL MODE
acl
~~~
$ flexnbd acl --sock <SOCK> [acl entry]+ [global option]*
Set the access control list of the server with the control socket SOCK Set the access control list of the server with the control socket SOCK
to the given access control list entries. to the given access control list entries.
$ flexnbd acl --sock SOCK [acl_entry]+ [global_option]*
ACL entries are given as IP addresses. ACL entries are given as IP addresses.
Options OPTIONS
^^^^^^^
*--sock, -s SOCK*: --sock, -s SOCK
The control socket of the server whose ACL to replace. The control socket of the server whose ACL to replace. Required
status STATUS MODE
~~~~~~
$ flexnbd status --sock <SOCK> [global option]*
Get the current status of the server with control socket SOCK. Get the current status of the server with control socket SOCK.
$ flexnbd status --sock SOCK [global_option]*
The status will be printed to STDOUT. It is a space-separated list of The status will be printed to STDOUT. It is a space-separated list of
key=value pairs. The space character will never appear in a key or key=value pairs. The space character will never appear in a key or
value. Currently reported values are: value. Currently reported values are:
*pid*: pid
The process id of the server listening on SOCK. The process id of the server listening on SOCK.
*is_mirroring*: is_mirroring
'true' if this server is sending migration data, 'false' otherwise. 'true' if this server is sending migration data, 'false' otherwise.
*has_control*: has_control
'false' if this server was started in 'listen' mode. 'true' otherwise. 'false' if this server was started in 'listen' mode. 'true' otherwise.
read OPTIONS
~~~~
$ flexnbd read --addr <ADDR> --port <PORT> --from <OFFSET> --sock, -s SOCK
--size <SIZE> [--bind BIND-ADDR] [global option]* The control socket of the server of interest. Required.
READ MODE
Connect to the server at ADDR:PORT, and read SIZE bytes starting at Connect to the server at ADDR:PORT, and read SIZE bytes starting at
OFFSET in a single NBD query. The returned data will be echoed to OFFSET in a single NBD query.
STDOUT. In case of a remote ACL, set the local source address to
BIND-ADDR.
Options $ flexnbd read --addr ADDR --port PORT --from OFFSET --size SIZE
^^^^^^^ [--bind BIND_ADDR] [global_option]*
*--addr, -l ADDR*: The returned data will be echoed to STDOUT. In case of a remote ACL,
set the local source address to BIND_ADDR.
OPTIONS
--addr, -l ADDR
The address of the remote server. Required. The address of the remote server. Required.
*--port, -p PORT*: --port, -p PORT
The port of the remote server. Required. The port of the remote server. Required.
*--from, -F OFFSET*: --from, -F OFFSET
The byte offset to start reading from. Required. Maximum 2^62. The byte offset to start reading from. Required. Maximum 2^62.
*--size, -S SIZE*: --size, -S SIZE
The number of bytes to read. Required. Maximum 2^30. The number of bytes to read. Required. Maximum 2^30.
*--bind, -b BIND-ADDR*: --bind, -b BIND_ADDR
The local address to bind to. You may need this if the remote server The local address to bind to. You may need this if the remote
is using an access control list. server is using an access control list.
write WRITE MODE
~~~~~
$ cat ... | flexnbd write --addr <ADDR> --port <PORT> --from <OFFSET>
--size <SIZE> [--bind BIND-ADDR] [global option]*
Connect to the server at ADDR:PORT, and write SIZE bytes from STDIN Connect to the server at ADDR:PORT, and write SIZE bytes from STDIN
starting at OFFSET in a single NBD query. In case of a remote ACL, set starting at OFFSET in a single NBD query.
the local source address to BIND-ADDR.
Options $ cat ... | flexnbd write --addr ADDR --port PORT --from OFFSET
^^^^^^^ --size SIZE [--bind BIND_ADDR] [global_option]*
*--addr, -l ADDR*: In case of a remote ACL, set the local source address to BIND_ADDR.
OPTIONS
--addr, -l ADDR
The address of the remote server. Required. The address of the remote server. Required.
*--port, -p PORT*: --port, -p PORT
The port of the remote server. Required. The port of the remote server. Required.
*--from, -F OFFSET*: --from, -F OFFSET
The byte offset to start writing from. Required. Maximum 2^62. The byte offset to start writing from. Required. Maximum 2^62.
*--size, -S SIZE*: --size, -S SIZE
The number of bytes to write. Required. Maximum 2^30. The number of bytes to write. Required. Maximum 2^30.
*--bind, -b BIND-ADDR*: --bind, -b BIND_ADDR
The local address to bind to. You may need this if the remote server The local address to bind to. You may need this if the remote
is using an access control list. server is using an access control list.
help HELP MODE
~~~~
$ flexnbd help [command] [global option]* $ flexnbd help [mode] [global_option]*
Without 'command', show the list of available commands. With 'command', Without mode, show the list of available modes. With mode, show help for that mode.
show help for that command.
GLOBAL OPTIONS GLOBAL OPTIONS
--------------
*--help, -h* : --help, -h Show mode or global help.
Show command or global help.
*--verbose, -v* : --verbose, -v Output all available log information to STDERR.
Output all available log information to STDERR.
*--quiet, -q* :
Output as little log information as possible to STDERR.
--quiet, -q Output as little log information as possible to STDERR.
LOGGING LOGGING
-------
Log output is sent to STDERR. If --quiet is set, no output will be seen Log output is sent to STDERR. If --quiet is set, no output will be
unless the program termintes abnormally. If neither --quiet nor seen unless the program termintes abnormally. If neither --quiet nor
--verbose are set, no output will be seen unless something goes wrong --verbose are set, no output will be seen unless something goes wrong
with a specific request. If --verbose is given, every available log 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 message will be seen (which, for a debug build, is many). It is not an
@@ -284,39 +290,38 @@ error to set both --verbose and --quiet. The last one wins.
The log line format is: The log line format is:
<TIMESTAMP>:<LEVEL>:<PID> <THREAD> <SOURCEFILE>:<SOURCELINE>: <MSG> <TIMESTAMP>:<LEVEL>:<PID> <THREAD> <SOURCEFILE:SOURCELINE>: <MSG>
*TIMESTAMP*: <TIMESTAMP>
Time the log entry was made. This is expressed in terms of monotonic ms. Time the log entry was made. This is expressed in terms of monotonic
ms.
*LEVEL*: <LEVEL>
This will be one of 'D', 'I', 'W', 'E', 'F' in increasing order of 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 severity. If flexnbd is started with the --quiet flag, only 'F'
seen. If it is started with the --verbose flag, any from 'I' upwards will be seen. If it is started with the --verbose flag, any from 'I'
will be seen. Only if you have a debug build and start it with upwards will be seen. Only if you have a debug build and start it
--verbose will you see 'D' entries. with --verbose will you see 'D' entries.
*PID*: <PID>
This is the process ID. This is the process ID.
*THREAD*: <THREAD>
There are several pthreads per flexnbd process: a main thread, a serve There are several pthreads per flexnbd process: a main thread, a
thread, a thread per client, and possibly a pair of mirror threads and a serve thread, a thread per client, and possibly a pair of mirror
control thread. This field identifies which thread was responsible for threads and a control thread. This field identifies which thread was
the log line. responsible for the log line.
*SOURCEFILE:SOURCELINE*: <SOURCEFILE:SOURCELINE>
Identifies where in the source code this log line can be found. Identifies where in the source code this log line can be found.
*MSG*: <MSG>
A short message describing what's happening, how it's being done, or A short message describing what's happening, how it's being done, or
if you're very lucky *why* it's going on. if you're very lucky why it's going on.
EXAMPLES EXAMPLES
--------
Serving a file SERVING A FILE
~~~~~~~~~~~~~~
The simplest case is serving a file on the default nbd port: The simplest case is serving a file on the default nbd port:
@@ -326,8 +331,7 @@ The simplest case is serving a file on the default nbd port:
root:x: root:x:
$ $
Reading server status READING SERVER STATUS
~~~~~~~~~~~~~~~~~~~~~
In order to read a server's status, we need it to open a control socket. In order to read a server's status, we need it to open a control socket.
@@ -340,8 +344,7 @@ In order to read a server's status, we need it to open a control socket.
Note that the status output is newline-terminated. Note that the status output is newline-terminated.
Migrating MIGRATING
~~~~~~~~~
To migrate, we need to provide a destination file of the right size. To migrate, we need to provide a destination file of the right size.
@@ -367,8 +370,8 @@ With this knowledge in hand, we can start the migration:
$ flexnbd mirror --addr 127.0.0.1 --port 4779 \ $ flexnbd mirror --addr 127.0.0.1 --port 4779 \
--sock /tmp/flex-source.sock --sock /tmp/flex-source.sock
Migration started Migration started
[1] + 9648 done build/flexnbd serve --addr 0.0.0.0 --port 4778 [1] + 9648 done flexnbd serve --addr 0.0.0.0 --port 4778
[2] + 9651 done build/flexnbd listen --addr 0.0.0.0 --port 4779 [2] + 9651 done flexnbd listen --addr 0.0.0.0 --port 4779
$ $
Note that because the file is so small in this case, we see the source Note that because the file is so small in this case, we see the source
@@ -376,21 +379,25 @@ server quit soon after we start the migration, and the destination
exited at roughly the same time. exited at roughly the same time.
BUGS BUGS
----
Should be reported to alex@bytemark.co.uk. Should be reported on GitHub at
* https://github.com/BytemarkHosting/flexnbd-c/issues
AUTHOR AUTHOR
------
Written by Alex Young <alex@bytemark.co.uk>. Originally written by Alex Young <alex@blackkettle.org>.
Original concept and core code by Matthew Bloch <matthew@bytemark.co.uk>. Original concept and core code by Matthew Bloch <matthew@bytemark.co.uk>.
Some additions by Nick Thomas <nick@bytemark.co.uk> Proxy mode written by Nick Thomas <me@ur.gs>.
COPYING The full commit history is available on GitHub.
-------
Copyright (c) 2012 Bytemark Hosting Ltd. Free use of this software is SEE ALSO
granted under the terms of the GNU General Public License version 3 or
later.
flexnbd-proxy(1), nbd-client(8), xnbd-server(8), xnbd-client(8)
COPYRIGHT
Copyright (c) 2012-2016 Bytemark Hosting Ltd. Free use of this
software is granted under the terms of the GNU General Public License
version 3 or later.

View File

@@ -1,60 +0,0 @@
# encoding: utf-8
def make(*targets)
sh "make #{targets.map{|t| t.to_s}.join(" ")}"
end
def maketask( opts )
case opts
when Symbol
maketask opts => opts
else
opts.each do |name, targets|
task( name ){make *[*targets]}
end
end
end
desc "Build the binary and man page"
maketask :build => [:all, :doc]
desc "Build just the flexnbd binary"
maketask :flexnbd => [:server]
file "build/flexnbd" => :flexnbd
desc "Build just the flexnbd-proxy binary"
maketask :flexnbd_proxy => [:proxy]
file "build/flexnbd-proxy" => :flexnbd_proxy
desc "Build just the man page"
maketask :man => :doc
namespace "test" do
desc "Run all tests"
task 'run' => ["unit", "scenarios"]
desc "Build C tests"
maketask :build => :check_bins
desc "Run C tests"
maketask :unit => :check
desc "Run NBD test scenarios"
task 'scenarios' => ["build/flexnbd", "build/flexnbd-proxy"] do
sh "cd tests/acceptance && RUBYOPT='-I.' ruby nbd_scenarios -v"
end
end
desc "Remove all build targets, binaries and temporary files"
maketask :clean
file "debian/changelog" do
FileUtils.mkdir_p "debian"
sh "hg log --style=changelog.template > debian/changelog"
end
desc "Generate the changelog"
task :changelog => "debian/changelog"

2783
debian/changelog vendored Normal file

File diff suppressed because it is too large Load Diff

1
debian/compat vendored Normal file
View File

@@ -0,0 +1 @@
7

25
debian/control vendored Normal file
View File

@@ -0,0 +1,25 @@
Source: flexnbd
Section: web
Priority: extra
Maintainer: Patrick J Cherry <patrick@bytemark.co.uk>
Build-Depends: debhelper (>= 7.0.50), ruby, gcc, libev-dev, txt2man, check, net-tools
Standards-Version: 3.8.1
Homepage: https://github.com/BytemarkHosting/flexnbd-c
Package: flexnbd
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libev4 | libev3
Description: FlexNBD server
An NBD server offering push-mirroring and intelligent sparse file handling
Package: flexnbd-dbg
Architecture: any
Section: debug
Priority: extra
Depends:
flexnbd (= ${binary:Version}),
${misc:Depends}
Description: debugging symbols for flexnbd
An NBD server offering push-mirroring and intelligent sparse file handling
.
This package contains the debugging symbols for flexnbd.

53
debian/copyright vendored Normal file
View File

@@ -0,0 +1,53 @@
This work was packaged for Debian by:
Alex Young <alex@bytemark.co.uk> on Wed, 30 May 2012 16:46:58 +0100
It was downloaded from:
<url://example.com>
Upstream Author(s):
<put author's name and email here>
<likewise for another author>
Copyright:
<Copyright (C) YYYY Firstname Lastname>
<likewise for another author>
License:
### SELECT: ###
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
### OR ###
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
##########
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
The Debian packaging is:
Copyright (C) 2012 Alex Young <alex@bytemark.co.uk>
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
# Please also look if there are files or directories which have a
# different copyright/license attached and list them here.

3
debian/flexnbd.install vendored Normal file
View File

@@ -0,0 +1,3 @@
build/flexnbd usr/bin
build/flexnbd-proxy usr/bin

2
debian/flexnbd.manpages vendored Normal file
View File

@@ -0,0 +1,2 @@
build/flexnbd.1.gz
build/flexnbd-proxy.1.gz

19
debian/rules vendored Executable file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@
override_dh_strip:
dh_strip --dbg-package=flexnbd-dbg
#
# TODO: The ruby test suites don't work during buiding in a chroot, so leave
# them out for now.
#
#override_dh_auto_test:
# rake test:run

1
debian/source/format vendored Normal file
View File

@@ -0,0 +1 @@
3.0 (quilt)

View File

@@ -27,7 +27,7 @@ void nbd_r2h_request( struct nbd_request_raw *from, struct nbd_request * to )
{ {
to->magic = htobe32( from->magic ); to->magic = htobe32( from->magic );
to->type = htobe32( from->type ); to->type = htobe32( from->type );
memcpy( to->handle, from->handle, 8 ); to->handle.w = from->handle.w;
to->from = htobe64( from->from ); to->from = htobe64( from->from );
to->len = htobe32( from->len ); to->len = htobe32( from->len );
} }
@@ -36,7 +36,7 @@ void nbd_h2r_request( struct nbd_request * from, struct nbd_request_raw * to )
{ {
to->magic = be32toh( from->magic ); to->magic = be32toh( from->magic );
to->type = be32toh( from->type ); to->type = be32toh( from->type );
memcpy( to->handle, from->handle, 8 ); to->handle.w = from->handle.w;
to->from = be64toh( from->from ); to->from = be64toh( from->from );
to->len = be32toh( from->len ); to->len = be32toh( from->len );
} }
@@ -46,13 +46,13 @@ void nbd_r2h_reply( struct nbd_reply_raw * from, struct nbd_reply * to )
{ {
to->magic = htobe32( from->magic ); to->magic = htobe32( from->magic );
to->error = htobe32( from->error ); to->error = htobe32( from->error );
memcpy( to->handle, from->handle, 8 ); to->handle.w = from->handle.w;
} }
void nbd_h2r_reply( struct nbd_reply * from, struct nbd_reply_raw * to ) void nbd_h2r_reply( struct nbd_reply * from, struct nbd_reply_raw * to )
{ {
to->magic = be32toh( from->magic ); to->magic = be32toh( from->magic );
to->error = be32toh( from->error ); to->error = be32toh( from->error );
memcpy( to->handle, from->handle, 8 ); to->handle.w = from->handle.w;
} }

View File

@@ -24,6 +24,11 @@
#include <linux/types.h> #include <linux/types.h>
#include <inttypes.h> #include <inttypes.h>
typedef union nbd_handle_t {
uint8_t b[8];
uint64_t w;
} nbd_handle_t;
/* The _raw types are the types as they appear on the wire. Non-_raw /* The _raw types are the types as they appear on the wire. Non-_raw
* types are in host-format. * types are in host-format.
* Conversion functions are _r2h_ for converting raw to host, and _h2r_ * Conversion functions are _r2h_ for converting raw to host, and _h2r_
@@ -39,7 +44,7 @@ struct nbd_init_raw {
struct nbd_request_raw { struct nbd_request_raw {
__be32 magic; __be32 magic;
__be32 type; /* == READ || == WRITE */ __be32 type; /* == READ || == WRITE */
char handle[8]; nbd_handle_t handle;
__be64 from; __be64 from;
__be32 len; __be32 len;
} __attribute__((packed)); } __attribute__((packed));
@@ -47,7 +52,7 @@ struct nbd_request_raw {
struct nbd_reply_raw { struct nbd_reply_raw {
__be32 magic; __be32 magic;
__be32 error; /* 0 = ok, else error */ __be32 error; /* 0 = ok, else error */
char handle[8]; /* handle you got from request */ nbd_handle_t handle; /* handle you got from request */
}; };
@@ -62,7 +67,7 @@ struct nbd_init {
struct nbd_request { struct nbd_request {
uint32_t magic; uint32_t magic;
uint32_t type; /* == READ || == WRITE || == DISCONNECT */ uint32_t type; /* == READ || == WRITE || == DISCONNECT */
char handle[8]; nbd_handle_t handle;
uint64_t from; uint64_t from;
uint32_t len; uint32_t len;
} __attribute__((packed)); } __attribute__((packed));
@@ -70,7 +75,7 @@ struct nbd_request {
struct nbd_reply { struct nbd_reply {
uint32_t magic; uint32_t magic;
uint32_t error; /* 0 = ok, else error */ uint32_t error; /* 0 = ok, else error */
char handle[8]; /* handle you got from request */ nbd_handle_t handle; /* handle you got from request */
}; };
void nbd_r2h_init( struct nbd_init_raw * from, struct nbd_init * to ); void nbd_r2h_init( struct nbd_init_raw * from, struct nbd_init * to );

View File

@@ -105,9 +105,7 @@ void fill_request(struct nbd_request *request, int type, uint64_t from, uint32_t
{ {
request->magic = htobe32(REQUEST_MAGIC); request->magic = htobe32(REQUEST_MAGIC);
request->type = htobe32(type); request->type = htobe32(type);
uint32_t * randa = (uint32_t*)request->handle; request->handle.w = (((uint64_t)rand()) << 32) | ((uint64_t)rand());
randa[0] = rand();
randa[1] = rand();
request->from = htobe64(from); request->from = htobe64(from);
request->len = htobe32(len); request->len = htobe32(len);
} }
@@ -127,7 +125,7 @@ void read_reply(int fd, struct nbd_request *request, struct nbd_reply *reply)
if (reply->error != 0) { if (reply->error != 0) {
error("Server replied with error %d", reply->error); error("Server replied with error %d", reply->error);
} }
if (strncmp(request->handle, reply->handle, 8) != 0) { if (request->handle.w != reply->handle.w) {
error("Did not reply with correct handle"); error("Did not reply with correct handle");
} }
} }

View File

@@ -100,7 +100,7 @@ int sock_try_bind( int fd, const struct sockaddr* sa )
{ {
int bind_result; int bind_result;
char s_address[256]; char s_address[256];
int retry = 1; int retry = 10;
sockaddr_address_string( sa, &s_address[0], 256 ); sockaddr_address_string( sa, &s_address[0], 256 );
@@ -126,8 +126,11 @@ int sock_try_bind( int fd, const struct sockaddr* sa )
* will cope with it. * will cope with it.
*/ */
case EADDRNOTAVAIL: case EADDRNOTAVAIL:
retry--;
if (retry) {
debug( "retrying" ); debug( "retrying" );
sleep( 1 ); sleep( 1 );
}
continue; continue;
case EADDRINUSE: case EADDRINUSE:
warn( "%s in use, giving up.", s_address ); warn( "%s in use, giving up.", s_address );

View File

@@ -709,7 +709,7 @@ void proxy_session( struct proxier* proxy )
state_started = monotonic_time_ms(); state_started = monotonic_time_ms();
debug( debug(
"State transitition from %s to %s", "State transition from %s to %s",
proxy_session_state_names[old_state], proxy_session_state_names[old_state],
proxy_session_state_names[state] proxy_session_state_names[state]
); );

View File

@@ -252,14 +252,14 @@ int client_read_request( struct client * client , struct nbd_request *out_reques
return 1; return 1;
} }
int fd_write_reply( int fd, char *handle, int error ) int fd_write_reply( int fd, uint64_t handle, int error )
{ {
struct nbd_reply reply; struct nbd_reply reply;
struct nbd_reply_raw reply_raw; struct nbd_reply_raw reply_raw;
reply.magic = REPLY_MAGIC; reply.magic = REPLY_MAGIC;
reply.error = error; reply.error = error;
memcpy( reply.handle, handle, 8 ); reply.handle.w = handle;
nbd_h2r_reply( &reply, &reply_raw ); nbd_h2r_reply( &reply, &reply_raw );
debug( "Replying with handle=0x%08X, error=%"PRIu32, handle, error ); debug( "Replying with handle=0x%08X, error=%"PRIu32, handle, error );
@@ -291,7 +291,7 @@ int fd_write_reply( int fd, char *handle, int error )
*/ */
int client_write_reply( struct client * client, struct nbd_request *request, int error ) int client_write_reply( struct client * client, struct nbd_request *request, int error )
{ {
return fd_write_reply( client->socket, request->handle, error); return fd_write_reply( client->socket, request->handle.w, error);
} }

View File

@@ -412,7 +412,7 @@ int mirror_setup_next_xfer( struct mirror_ctrl *ctrl )
struct nbd_request req = { struct nbd_request req = {
.magic = REQUEST_MAGIC, .magic = REQUEST_MAGIC,
.type = REQUEST_WRITE, .type = REQUEST_WRITE,
.handle = ".MIRROR.", .handle.b = ".MIRROR.",
.from = current, .from = current,
.len = run .len = run
}; };
@@ -568,7 +568,7 @@ static void mirror_read_cb( struct ev_loop *loop, ev_io *w, int revents )
return; return;
} }
if ( memcmp( ".MIRROR.", &rsp.handle[0], 8 ) != 0 ) { if ( memcmp( ".MIRROR.", rsp.handle.b, 8 ) != 0 ) {
warn( "Bad handle returned from listener" ); warn( "Bad handle returned from listener" );
ev_break( loop, EVBREAK_ONE ); ev_break( loop, EVBREAK_ONE );
return; return;
@@ -922,7 +922,7 @@ void* mirror_runner(void* serve_params_uncast)
* for us ). But if we've failed and are going to retry on the next run, we * for us ). But if we've failed and are going to retry on the next run, we
* must close this socket here to have any chance of it succeeding. * must close this socket here to have any chance of it succeeding.
*/ */
if ( !mirror->client < 0 ) { if ( !(mirror->client < 0) ) {
sock_try_close( mirror->client ); sock_try_close( mirror->client );
mirror->client = -1; mirror->client = -1;
} }

View File

@@ -32,7 +32,7 @@ module FlexNBD
txt_lines.each do |line| txt_lines.each do |line|
if line =~ /^#\s*define\s+([A-Z0-9_]+)\s+(\d+)\s*$/ if line =~ /^#\s*define\s+([A-Z0-9_]+)\s+(\d+)\s*$/
# Bodge until I can figure out what to do with #ifdefs # Bodge until I can figure out what to do with #ifdefs
const_set($1, $2.to_i) unless constants.include?( $1 ) const_set($1, $2.to_i) unless const_defined?( $1 )
end end
end end
end end

View File

@@ -3,6 +3,10 @@ require 'flexnbd/fake_source'
require 'flexnbd/fake_dest' require 'flexnbd/fake_dest'
module ProxyTests module ProxyTests
def b
"\xFF".b
end
def with_proxied_client( override_size = nil ) def with_proxied_client( override_size = nil )
@env.serve1 unless @server_up @env.serve1 unless @server_up
@env.proxy2 unless @proxy_up @env.proxy2 unless @proxy_up
@@ -51,7 +55,7 @@ module ProxyTests
with_proxied_client do |client| with_proxied_client do |client|
(0..3).each do |n| (0..3).each do |n|
offset = n * 4096 offset = n * 4096
client.write(offset, "\xFF" * 4096) client.write(offset, b * 4096)
rsp = client.read_response rsp = client.read_response
assert_equal FlexNBD::REPLY_MAGIC, rsp[:magic] assert_equal FlexNBD::REPLY_MAGIC, rsp[:magic]
@@ -60,7 +64,7 @@ module ProxyTests
data = @env.file1.read(offset, 4096) data = @env.file1.read(offset, 4096)
assert_equal( ( "\xFF" * 4096 ), data, "Data not written correctly (offset is #{n})" ) assert_equal( ( b * 4096 ), data, "Data not written correctly (offset is #{n})" )
end end
end end
end end
@@ -107,7 +111,7 @@ module ProxyTests
# The reply should be proxied back to the client. # The reply should be proxied back to the client.
sc2.write_reply( req2[:handle] ) sc2.write_reply( req2[:handle] )
sc2.write_data( "\xFF" * 4096 ) sc2.write_data( b * 4096 )
# Check it to make sure it's correct # Check it to make sure it's correct
rsp = timeout(15) { client.read_response } rsp = timeout(15) { client.read_response }
@@ -116,7 +120,7 @@ module ProxyTests
assert_equal req1[:handle], rsp[:handle] assert_equal req1[:handle], rsp[:handle]
data = client.read_raw( 4096 ) data = client.read_raw( 4096 )
assert_equal( ("\xFF" * 4096), data, "Wrong data returned" ) assert_equal( (b * 4096), data, "Wrong data returned" )
sc2.close sc2.close
server.close server.close
@@ -131,7 +135,7 @@ module ProxyTests
server, sc1 = maker.value server, sc1 = maker.value
# Send the read request to the proxy # Send the read request to the proxy
client.write( 0, ( "\xFF" * 4096 ) ) client.write( 0, ( b * 4096 ) )
# ensure we're given the read request # ensure we're given the read request
req1 = sc1.read_request req1 = sc1.read_request
@@ -140,7 +144,7 @@ module ProxyTests
assert_equal 0, req1[:from] assert_equal 0, req1[:from]
assert_equal 4096, req1[:len] assert_equal 4096, req1[:len]
data1 = sc1.read_data( 4096 ) data1 = sc1.read_data( 4096 )
assert_equal( ( "\xFF" * 4096 ), data1, "Data not proxied successfully" ) assert_equal( ( b * 4096 ), data1, "Data not proxied successfully" )
# Kill the server again, now we're sure the read request has been sent once # Kill the server again, now we're sure the read request has been sent once
sc1.close sc1.close

View File

@@ -6,6 +6,7 @@ class TestServeMode < Test::Unit::TestCase
def setup def setup
super super
@b = "\xFF".b
@env = Environment.new @env = Environment.new
@env.writefile1( "0" ) @env.writefile1( "0" )
@env.serve1 @env.serve1
@@ -53,18 +54,18 @@ class TestServeMode < Test::Unit::TestCase
assert_equal FlexNBD::REPLY_MAGIC, rsp[:magic] assert_equal FlexNBD::REPLY_MAGIC, rsp[:magic]
assert_equal 0, rsp[:error] assert_equal 0, rsp[:error]
client.write( 0, "\xFF" ) client.write( 0, @b )
rsp = client.read_response rsp = client.read_response
assert_equal FlexNBD::REPLY_MAGIC, rsp[:magic] assert_equal FlexNBD::REPLY_MAGIC, rsp[:magic]
assert_equal 0, rsp[:error] assert_equal 0, rsp[:error]
client.write( 0, "\xFF\xFF" ) client.write( 0, @b * 2 )
rsp = client.read_response rsp = client.read_response
assert_equal FlexNBD::REPLY_MAGIC, rsp[:magic] assert_equal FlexNBD::REPLY_MAGIC, rsp[:magic]
assert_equal 0, rsp[:error] assert_equal 0, rsp[:error]
end end
assert_equal "\xFF\xFF", @env.file1.read( 0, 2 ) assert_equal @b * 2, @env.file1.read( 0, 2 )
end end

View File

@@ -66,9 +66,9 @@ START_TEST( test_receive_blocks_until_post )
END_TEST END_TEST
Suite* acl_suite(void) Suite* mbox_suite(void)
{ {
Suite *s = suite_create("acl"); Suite *s = suite_create("mbox");
TCase *tc_create = tcase_create("create"); TCase *tc_create = tcase_create("create");
TCase *tc_post = tcase_create("post"); TCase *tc_post = tcase_create("post");
@@ -93,7 +93,7 @@ int main(void)
log_level = 2; log_level = 2;
#endif #endif
int number_failed; int number_failed;
Suite *s = acl_suite(); Suite *s = mbox_suite();
SRunner *sr = srunner_create(s); SRunner *sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL); srunner_run_all(sr, CK_NORMAL);
log_level = 0; log_level = 0;

View File

@@ -88,14 +88,14 @@ START_TEST(test_request_handle)
struct nbd_request_raw request_raw; struct nbd_request_raw request_raw;
struct nbd_request request; struct nbd_request request;
memcpy( request_raw.handle, "MYHANDLE", 8 ); memcpy( request_raw.handle.b, "MYHANDLE", 8 );
nbd_r2h_request( &request_raw, &request ); nbd_r2h_request( &request_raw, &request );
memset( request_raw.handle, 0, 8 ); request_raw.handle.w = 0;
nbd_h2r_request( &request, &request_raw ); nbd_h2r_request( &request, &request_raw );
fail_unless( memcmp( request.handle, "MYHANDLE", 8 ) == 0, "The handle was not copied." ); fail_unless( memcmp( request.handle.b, "MYHANDLE", 8 ) == 0, "The handle was not copied." );
fail_unless( memcmp( request_raw.handle, "MYHANDLE", 8 ) == 0, "The handle was not copied back." ); fail_unless( memcmp( request_raw.handle.b, "MYHANDLE", 8 ) == 0, "The handle was not copied back." );
} }
END_TEST END_TEST
@@ -170,14 +170,14 @@ START_TEST(test_reply_handle)
struct nbd_reply_raw reply_raw; struct nbd_reply_raw reply_raw;
struct nbd_reply reply; struct nbd_reply reply;
memcpy( reply_raw.handle, "MYHANDLE", 8 ); memcpy( reply_raw.handle.b, "MYHANDLE", 8 );
nbd_r2h_reply( &reply_raw, &reply ); nbd_r2h_reply( &reply_raw, &reply );
memset( reply_raw.handle, 0, 8 ); reply_raw.handle.w = 0;
nbd_h2r_reply( &reply, &reply_raw ); nbd_h2r_reply( &reply, &reply_raw );
fail_unless( memcmp( reply.handle, "MYHANDLE", 8 ) == 0, "The handle was not copied." ); fail_unless( memcmp( reply.handle.b, "MYHANDLE", 8 ) == 0, "The handle was not copied." );
fail_unless( memcmp( reply_raw.handle, "MYHANDLE", 8 ) == 0, "The handle was not copied back." ); fail_unless( memcmp( reply_raw.handle.b, "MYHANDLE", 8 ) == 0, "The handle was not copied back." );
} }
END_TEST END_TEST
@@ -188,14 +188,15 @@ START_TEST( test_convert_from )
* nbd_request_raw */ * nbd_request_raw */
struct nbd_request_raw request_raw; struct nbd_request_raw request_raw;
struct nbd_request request; struct nbd_request request;
char readbuf[] = {0x80, 0, 0, 0, 0, 0, 0, 0};
memcpy( &request_raw.from, readbuf, 8 ); uint64_t target = 0x8000000000000000;
/* this is stored big-endian */
request_raw.from = htobe64(target);
/* We expect this to convert big-endian to the host format */
nbd_r2h_request( &request_raw, &request ); nbd_r2h_request( &request_raw, &request );
uint64_t target = 1;
target <<= 63;
fail_unless( target == request.from, "from was wrong" ); fail_unless( target == request.from, "from was wrong" );
} }
END_TEST END_TEST

View File

@@ -22,7 +22,7 @@
int fd_read_request( int, struct nbd_request_raw *); int fd_read_request( int, struct nbd_request_raw *);
int fd_write_reply( int, char *, int ); int fd_write_reply( int, uint64_t, int );
int marker; int marker;
@@ -57,7 +57,7 @@ void * responder( void *respond_uncast )
fd_write_reply( sock_fd, wrong_handle, 0 ); fd_write_reply( sock_fd, wrong_handle, 0 );
} }
else { else {
fd_write_reply( sock_fd, resp->received.handle, 0 ); fd_write_reply( sock_fd, resp->received.handle.w, 0 );
} }
write( sock_fd, "12345678", 8 ); write( sock_fd, "12345678", 8 );
} }
@@ -150,7 +150,7 @@ END_TEST
Suite* readwrite_suite(void) Suite* readwrite_suite(void)
{ {
Suite *s = suite_create("acl"); Suite *s = suite_create("readwrite");
TCase *tc_transfer = tcase_create("entrust"); TCase *tc_transfer = tcase_create("entrust");
TCase *tc_disconnect = tcase_create("disconnect"); TCase *tc_disconnect = tcase_create("disconnect");

View File

@@ -141,9 +141,9 @@ START_TEST( test_fatal_doesnt_call_handler )
END_TEST END_TEST
Suite* error_suite(void) Suite* util_suite(void)
{ {
Suite *s = suite_create("error"); Suite *s = suite_create("util");
TCase *tc_process = tcase_create("process"); TCase *tc_process = tcase_create("process");
TCase *tc_handler = tcase_create("handler"); TCase *tc_handler = tcase_create("handler");
@@ -163,7 +163,7 @@ Suite* error_suite(void)
int main(void) int main(void)
{ {
int number_failed; int number_failed;
Suite *s = error_suite(); Suite *s = util_suite();
SRunner *sr = srunner_create(s); SRunner *sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL); srunner_run_all(sr, CK_NORMAL);
number_failed = srunner_ntests_failed(sr); number_failed = srunner_ntests_failed(sr);