Compare commits
43 Commits
0.1.5
...
take-reque
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cc69752394 | ||
![]() |
af2bee79fc | ||
![]() |
c37627a5b9 | ||
![]() |
ceb3328261 | ||
![]() |
61940bdfc5 | ||
![]() |
6d96d751d8 | ||
![]() |
fa75de0a8b | ||
![]() |
1cb11bfd38 | ||
![]() |
2702e73a26 | ||
![]() |
dbf50046a8 | ||
![]() |
d62b069ce4 | ||
![]() |
884a714744 | ||
![]() |
0c668f1776 | ||
![]() |
1d5b315f17 | ||
![]() |
24f1e62a73 | ||
![]() |
5c37cba39b | ||
![]() |
59f264184b | ||
![]() |
42d206cfb7 | ||
![]() |
ab3106202a | ||
![]() |
e04dead5ce | ||
![]() |
88bc5f0643 | ||
![]() |
e89c87e2b9 | ||
![]() |
9d2ac3f403 | ||
![]() |
67823bf85b | ||
![]() |
17d30b86ad | ||
![]() |
b97bcd6f51 | ||
![]() |
4d3c15a4d0 | ||
![]() |
83d6872a8d | ||
![]() |
ab8470aef3 | ||
![]() |
716df32fd6 | ||
![]() |
1a768d5e9c | ||
![]() |
72992c76ac | ||
![]() |
cace8123f4 | ||
![]() |
c3b241464a | ||
![]() |
4f956e4b9d | ||
![]() |
e7e99b099c | ||
![]() |
b2edd0734a | ||
![]() |
8fed794fe7 | ||
![]() |
3571d3f82e | ||
![]() |
4cd7e764bb | ||
![]() |
4f535fbb02 | ||
![]() |
4ed8d49b2c | ||
![]() |
3af0e84f5f |
@@ -1,10 +1,27 @@
|
||||
image: "ruby:2.1"
|
||||
|
||||
before_script:
|
||||
- apt-get update; apt-get install -y check libev-dev net-tools dpkg-dev
|
||||
|
||||
unit_test:
|
||||
stages:
|
||||
- package
|
||||
- publish
|
||||
|
||||
package:jessie: &package
|
||||
stage: package
|
||||
image: $CI_REGISTRY/docker-images/layers:$DISTRO-deb
|
||||
variables:
|
||||
DISTRO: jessie
|
||||
script:
|
||||
- make clean
|
||||
- make build
|
||||
- make test
|
||||
- package
|
||||
artifacts:
|
||||
paths:
|
||||
- pkg/
|
||||
|
||||
package:stretch:
|
||||
<<: *package
|
||||
variables:
|
||||
DISTRO: stretch
|
||||
|
||||
publish:
|
||||
stage: publish
|
||||
tags:
|
||||
- shell
|
||||
script:
|
||||
- publish
|
||||
|
||||
|
27
Makefile
27
Makefile
@@ -11,28 +11,9 @@ ifdef DEBUG
|
||||
else
|
||||
CFLAGS_EXTRA=-O2
|
||||
endif
|
||||
|
||||
CFLAGS_EXTRA += -fPIC --std=gnu99
|
||||
LDFLAGS_EXTRA += -Wl,--relax,--gc-sections
|
||||
|
||||
TOOLCHAIN := $(shell $(CC) --version|awk '/Debian/ {print "debian";exit;}')
|
||||
#
|
||||
# This bit adds extra flags depending of the distro, and the
|
||||
# architecture. To make sure debian packages have the right
|
||||
# set of 'native' flags on them
|
||||
#
|
||||
ifeq ($(TOOLCHAIN),debian)
|
||||
DEBARCH := $(shell dpkg-architecture -qDEB_BUILD_ARCH)
|
||||
ifeq ($(DEBARCH),$(filter $(DEBARCH),amd64 i386))
|
||||
CFLAGS_EXTRA += -march=native
|
||||
endif
|
||||
ifeq ($(DEBARCH),armhf)
|
||||
CFLAGS_EXTRA += -march=armv7-a -mtune=cortex-a8 -mfpu=neon
|
||||
endif
|
||||
LDFLAGS_EXTRA += -L$(LIB) -Wl,-rpath,${shell readlink -f ${LIB}}
|
||||
else
|
||||
LDFLAGS_EXTRA += -L$(LIB) -Wl,-rpath-link,$(LIB)
|
||||
endif
|
||||
|
||||
LDFLAGS_EXTRA += -Wl,--relax,--gc-sections -L$(LIB) -Wl,-rpath-link,$(LIB)
|
||||
|
||||
# The -Wunreachable-code warning is only implemented in clang, but it
|
||||
# doesn't break anything for gcc to see it.
|
||||
@@ -42,10 +23,10 @@ WARNINGS=-Wall \
|
||||
-Wstrict-prototypes \
|
||||
-Wno-missing-field-initializers \
|
||||
-Wunreachable-code
|
||||
|
||||
CCFLAGS=-D_GNU_SOURCE=1 $(WARNINGS) $(CFLAGS_EXTRA) $(CFLAGS)
|
||||
LLDFLAGS=-lm -lrt -lev $(LDFLAGS_EXTRA) $(LDFLAGS)
|
||||
|
||||
|
||||
CC?=gcc
|
||||
|
||||
LIBS=-lpthread
|
||||
@@ -94,7 +75,7 @@ CHECK_OBJ := $(CHECK_SRC:tests/unit/%.c=build/%.o)
|
||||
CHECK_BINS := $(CHECK_SRC:tests/unit/%.c=build/%)
|
||||
|
||||
build/check_%: build/check_%.o
|
||||
$(LINK) $^ -o $@ $(COMMON_OBJ) $(SERVER_OBJ) -lcheck
|
||||
$(LINK) $^ -o $@ $(COMMON_OBJ) $(SERVER_OBJ) -lcheck -lsubunit
|
||||
|
||||
check_objs: $(CHECK_OBJ)
|
||||
|
||||
|
2817
debian/changelog
vendored
Normal file
2817
debian/changelog
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
||||
7
|
25
debian/control
vendored
Normal file
25
debian/control
vendored
Normal 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, libsubunit-dev, ruby-test-unit
|
||||
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
53
debian/copyright
vendored
Normal 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
3
debian/flexnbd.install
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
build/flexnbd usr/bin
|
||||
build/flexnbd-proxy usr/bin
|
||||
|
2
debian/flexnbd.manpages
vendored
Normal file
2
debian/flexnbd.manpages
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
build/flexnbd.1.gz
|
||||
build/flexnbd-proxy.1.gz
|
19
debian/rules
vendored
Executable file
19
debian/rules
vendored
Executable 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
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (native)
|
@@ -16,7 +16,7 @@
|
||||
|
||||
|
||||
/* 1MiB is the de-facto standard for maximum size of header + data */
|
||||
#define NBD_MAX_SIZE ( 1024 * 1024 )
|
||||
#define NBD_MAX_SIZE ( 32 * 1024 * 1024 )
|
||||
|
||||
#define NBD_REQUEST_SIZE ( sizeof( struct nbd_request_raw ) )
|
||||
#define NBD_REPLY_SIZE ( sizeof( struct nbd_reply_raw ) )
|
||||
|
@@ -68,6 +68,37 @@ int sock_set_reuseaddr( int fd, int optval )
|
||||
return setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval) );
|
||||
}
|
||||
|
||||
int sock_set_keepalive_params( int fd, int time, int intvl, int probes)
|
||||
{
|
||||
if (sock_set_keepalive(fd, 1) ||
|
||||
sock_set_tcp_keepidle(fd, time) ||
|
||||
sock_set_tcp_keepintvl(fd, intvl) ||
|
||||
sock_set_tcp_keepcnt(fd, probes)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sock_set_keepalive( int fd, int optval )
|
||||
{
|
||||
return setsockopt( fd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval) );
|
||||
}
|
||||
|
||||
int sock_set_tcp_keepidle( int fd, int optval )
|
||||
{
|
||||
return setsockopt( fd, IPPROTO_TCP, TCP_KEEPIDLE, &optval, sizeof(optval) );
|
||||
}
|
||||
|
||||
int sock_set_tcp_keepintvl( int fd, int optval )
|
||||
{
|
||||
return setsockopt( fd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, sizeof(optval) );
|
||||
}
|
||||
|
||||
int sock_set_tcp_keepcnt( int fd, int optval )
|
||||
{
|
||||
return setsockopt( fd, IPPROTO_TCP, TCP_KEEPCNT, &optval, sizeof(optval) );
|
||||
}
|
||||
|
||||
/* Set the tcp_nodelay option */
|
||||
int sock_set_tcp_nodelay( int fd, int optval )
|
||||
{
|
||||
|
@@ -14,9 +14,24 @@ size_t sockaddr_size(const struct sockaddr* sa);
|
||||
*/
|
||||
const char* sockaddr_address_string(const struct sockaddr* sa, char* dest, size_t len);
|
||||
|
||||
/* Configure TCP keepalive on a socket */
|
||||
int sock_set_keepalive_params( int fd, int time, int intvl, int probes);
|
||||
|
||||
/* Set the SOL_KEEPALIVE otion */
|
||||
int sock_set_keepalive(int fd, int optval);
|
||||
|
||||
/* Set the SOL_REUSEADDR otion */
|
||||
int sock_set_reuseaddr(int fd, int optval);
|
||||
|
||||
/* Set the tcp_keepidle option */
|
||||
int sock_set_tcp_keepidle(int fd, int optval);
|
||||
|
||||
/* Set the tcp_keepintvl option */
|
||||
int sock_set_tcp_keepintvl(int fd, int optval);
|
||||
|
||||
/* Set the tcp_keepcnt option */
|
||||
int sock_set_tcp_keepcnt(int fd, int optval);
|
||||
|
||||
/* Set the tcp_nodelay option */
|
||||
int sock_set_tcp_nodelay(int fd, int optval);
|
||||
|
||||
|
@@ -13,6 +13,7 @@
|
||||
pthread_key_t cleanup_handler_key;
|
||||
|
||||
int log_level = 2;
|
||||
char *log_context = "";
|
||||
|
||||
void error_init(void)
|
||||
{
|
||||
|
@@ -21,6 +21,9 @@ extern int log_level;
|
||||
/* set up the error globals */
|
||||
void error_init(void);
|
||||
|
||||
/* some context for the overall process that appears on each log line */
|
||||
extern char *log_context;
|
||||
|
||||
|
||||
void exit_err( const char * );
|
||||
|
||||
@@ -92,7 +95,7 @@ uint64_t monotonic_time_ms(void);
|
||||
|
||||
#define levstr(i) (i==0?'D':(i==1?'I':(i==2?'W':(i==3?'E':'F'))))
|
||||
|
||||
#define myloglev(level, msg, ...) mylog( level, "%"PRIu64":%c:%d %p %s:%d: "msg"\n", monotonic_time_ms(), levstr(level), getpid(),pthread_self(), __FILE__, __LINE__, ##__VA_ARGS__ )
|
||||
#define myloglev(level, msg, ...) mylog( level, "%"PRIu64":%c:%d %p %s %s:%d: "msg"\n", monotonic_time_ms(), levstr(level), getpid(),pthread_self(), log_context, __FILE__, __LINE__, ##__VA_ARGS__ )
|
||||
|
||||
#ifdef DEBUG
|
||||
# define debug(msg, ...) myloglev(0, msg, ##__VA_ARGS__)
|
||||
|
@@ -76,8 +76,15 @@ struct proxier* proxy_create(
|
||||
}
|
||||
|
||||
out->init.buf = xmalloc( sizeof( struct nbd_init_raw ) );
|
||||
out->req.buf = xmalloc( NBD_MAX_SIZE );
|
||||
out->rsp.buf = xmalloc( NBD_MAX_SIZE );
|
||||
|
||||
/* Add on the request / reply size to our malloc to accommodate both
|
||||
* the struct and the data
|
||||
*/
|
||||
out->req.buf = xmalloc( NBD_MAX_SIZE + NBD_REQUEST_SIZE );
|
||||
out->rsp.buf = xmalloc( NBD_MAX_SIZE + NBD_REPLY_SIZE );
|
||||
|
||||
log_context = xmalloc( strlen(s_upstream_address) + strlen(s_upstream_port) + 2 );
|
||||
sprintf(log_context, "%s:%s", s_upstream_address, s_upstream_port);
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -437,15 +444,18 @@ int proxy_read_from_downstream( struct proxier *proxy, int state )
|
||||
return EXIT;
|
||||
}
|
||||
|
||||
/* Simple validations */
|
||||
/* Simple validations -- the request / reply size have already
|
||||
* been taken into account in the xmalloc, so no need to worry
|
||||
* about them here
|
||||
*/
|
||||
if ( ( request->type & REQUEST_MASK ) == REQUEST_READ ) {
|
||||
if (request->len > ( NBD_MAX_SIZE - NBD_REPLY_SIZE ) ) {
|
||||
if ( request->len > NBD_MAX_SIZE ) {
|
||||
warn( "NBD read request size %"PRIu32" too large", request->len );
|
||||
return EXIT;
|
||||
}
|
||||
}
|
||||
if ( (request->type & REQUEST_MASK ) == REQUEST_WRITE ) {
|
||||
if (request->len > ( NBD_MAX_SIZE - NBD_REQUEST_SIZE ) ) {
|
||||
if ( request->len > NBD_MAX_SIZE ) {
|
||||
warn( "NBD write request size %"PRIu32" too large", request->len );
|
||||
return EXIT;
|
||||
}
|
||||
|
@@ -78,6 +78,8 @@ struct server * server_create (
|
||||
NULLCHECK( out->close_signal );
|
||||
NULLCHECK( out->acl_updated_signal );
|
||||
|
||||
log_context = s_file;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -422,6 +424,9 @@ void accept_nbd_client(
|
||||
int slot;
|
||||
char s_client_address[64] = {0};
|
||||
|
||||
FATAL_IF_NEGATIVE( sock_set_keepalive_params( client_fd, CLIENT_KEEPALIVE_TIME, CLIENT_KEEPALIVE_INTVL, CLIENT_KEEPALIVE_PROBES),
|
||||
"Error setting keepalive parameters on client socket fd %d", client_fd );
|
||||
|
||||
|
||||
if ( !server_should_accept_client( params, client_address, s_client_address, 64 ) ) {
|
||||
FATAL_IF_NEGATIVE( close( client_fd ),
|
||||
|
@@ -21,6 +21,9 @@ struct client_tbl_entry {
|
||||
|
||||
|
||||
#define MAX_NBD_CLIENTS 16
|
||||
#define CLIENT_KEEPALIVE_TIME 30
|
||||
#define CLIENT_KEEPALIVE_INTVL 10
|
||||
#define CLIENT_KEEPALIVE_PROBES 3
|
||||
struct server {
|
||||
/* The flexnbd wrapper this server is attached to */
|
||||
struct flexnbd * flexnbd;
|
||||
|
@@ -31,6 +31,7 @@ struct status * status_create( struct server * serve )
|
||||
status->migration_speed_limit = serve->mirror->max_bytes_per_second;
|
||||
|
||||
status->migration_seconds_left = server_mirror_eta( serve );
|
||||
status->migration_bytes_left = server_mirror_bytes_remaining( serve );
|
||||
}
|
||||
|
||||
server_unlock_start_mirror( serve );
|
||||
@@ -60,6 +61,7 @@ int status_write( struct status * status, int fd )
|
||||
PRINT_UINT64( migration_speed );
|
||||
PRINT_UINT64( migration_duration );
|
||||
PRINT_UINT64( migration_seconds_left );
|
||||
PRINT_UINT64( migration_bytes_left );
|
||||
if ( status->migration_speed_limit < UINT64_MAX ) {
|
||||
PRINT_UINT64( migration_speed_limit );
|
||||
};
|
||||
|
@@ -64,6 +64,8 @@
|
||||
* Our current best estimate of how many seconds are left before the migration
|
||||
* migration is finished.
|
||||
*
|
||||
* migration_bytes_left:
|
||||
* The number of bytes remaining to migrate.
|
||||
*/
|
||||
|
||||
|
||||
@@ -84,6 +86,7 @@ struct status {
|
||||
uint64_t migration_speed;
|
||||
uint64_t migration_speed_limit;
|
||||
uint64_t migration_seconds_left;
|
||||
uint64_t migration_bytes_left;
|
||||
};
|
||||
|
||||
/** Create a status object for the given server. */
|
||||
|
@@ -308,6 +308,7 @@ START_TEST( test_renders_migration_statistics )
|
||||
status.migration_speed = 40000000;
|
||||
status.migration_speed_limit = 40000001;
|
||||
status.migration_seconds_left = 1;
|
||||
status.migration_bytes_left = 5000;
|
||||
|
||||
status_write( &status, fds[1] );
|
||||
fail_if_rendered( fds[0], "migration_duration" );
|
||||
@@ -335,6 +336,9 @@ START_TEST( test_renders_migration_statistics )
|
||||
status_write( &status, fds[1] );
|
||||
fail_unless_rendered( fds[0], "migration_seconds_left=1" );
|
||||
|
||||
status_write( &status, fds[1] );
|
||||
fail_unless_rendered( fds[0], "migration_bytes_left=5000" );
|
||||
|
||||
status.migration_speed_limit = UINT64_MAX;
|
||||
|
||||
status_write( &status, fds[1] );
|
||||
|
Reference in New Issue
Block a user