summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorSimon Rettberg2017-11-02 13:41:35 +0100
committerSimon Rettberg2017-11-02 13:41:35 +0100
commit1587f73c38c9228a1a93889aae6351eff891cbe8 (patch)
tree4a43804793d1c5c3a1d0566c827e7cde8bac3c6b /src/server
parent[FUSE] Fix printf warning for logadd call (diff)
downloaddnbd3-1587f73c38c9228a1a93889aae6351eff891cbe8.tar.gz
dnbd3-1587f73c38c9228a1a93889aae6351eff891cbe8.tar.xz
dnbd3-1587f73c38c9228a1a93889aae6351eff891cbe8.zip
[SERVER] Support finer control over replication when a proxy connects to a proxy
Introduce new flag in "select image" message to tell the uplink server whether we have background replication enabled or not. Also reject a connecting proxy if the connecting proxy uses BGR but we don't, as this would basically force the image to be replicated locally too.
Diffstat (limited to 'src/server')
-rw-r--r--src/server/altservers.c2
-rw-r--r--src/server/globals.c2
-rw-r--r--src/server/globals.h7
-rw-r--r--src/server/image.c2
-rw-r--r--src/server/net.c24
5 files changed, 33 insertions, 4 deletions
diff --git a/src/server/altservers.c b/src/server/altservers.c
index 28ea91e..2ae0d16 100644
--- a/src/server/altservers.c
+++ b/src/server/altservers.c
@@ -437,7 +437,7 @@ static void *altservers_main(void *data UNUSED)
int sock = sock_connect( &servers[itAlt], 750, _uplinkTimeout );
if ( sock < 0 ) continue;
// Select image ++++++++++++++++++++++++++++++
- if ( !dnbd3_select_image( sock, image->name, image->rid, FLAGS8_SERVER ) ) {
+ if ( !dnbd3_select_image( sock, image->name, image->rid, SI_SERVER_FLAGS ) ) {
goto server_failed;
}
// See if selecting the image succeeded ++++++++++++++++++++++++++++++
diff --git a/src/server/globals.c b/src/server/globals.c
index d6f077b..50d7885 100644
--- a/src/server/globals.c
+++ b/src/server/globals.c
@@ -14,6 +14,7 @@ bool _removeMissingImages = true;
bool _isProxy = false;
bool _proxyPrivateOnly = false;
bool _backgroundReplication = true;
+bool _lookupMissingForProxy = true;
int _listenPort = PORT;
int _uplinkTimeout = SOCKET_TIMEOUT_UPLINK;
int _clientTimeout = SOCKET_TIMEOUT_CLIENT;
@@ -32,6 +33,7 @@ static int ini_handler(void *custom UNUSED, const char* section, const char* key
SAVE_TO_VAR_BOOL( dnbd3, isProxy );
SAVE_TO_VAR_BOOL( dnbd3, proxyPrivateOnly );
SAVE_TO_VAR_BOOL( dnbd3, backgroundReplication );
+ SAVE_TO_VAR_BOOL( dnbd3, lookupMissingForProxy );
SAVE_TO_VAR_BOOL( dnbd3, removeMissingImages );
SAVE_TO_VAR_BOOL( dnbd3, closeUnusedFd );
SAVE_TO_VAR_INT( dnbd3, serverPenalty );
diff --git a/src/server/globals.h b/src/server/globals.h
index 2dbabd5..1475981 100644
--- a/src/server/globals.h
+++ b/src/server/globals.h
@@ -207,6 +207,13 @@ extern bool _closeUnusedFd;
extern bool _backgroundReplication;
/**
+ * (In proxy mode): If connecting client is a proxy, and the requested image
+ * is not known locally, should we ask our known alt servers for it?
+ * Otherwise the request is rejected.
+ */
+extern bool _lookupMissingForProxy;
+
+/**
* Port to listen on (default: #define PORT (5003))
*/
extern int _listenPort;
diff --git a/src/server/image.c b/src/server/image.c
index e356dbf..91d7572 100644
--- a/src/server/image.c
+++ b/src/server/image.c
@@ -1236,7 +1236,7 @@ static dnbd3_image_t *loadImageProxy(char * const name, const uint16_t revision,
bool ok = false;
int sock = sock_connect( &servers[i], 750, _uplinkTimeout );
if ( sock == -1 ) continue;
- if ( !dnbd3_select_image( sock, name, revision, FLAGS8_SERVER ) ) goto server_fail;
+ if ( !dnbd3_select_image( sock, name, revision, SI_SERVER_FLAGS ) ) goto server_fail;
if ( !dnbd3_select_image_reply( &serialized, sock, &remoteProtocolVersion, &remoteName, &remoteRid, &remoteImageSize ) ) goto server_fail;
if ( remoteProtocolVersion < MIN_SUPPORTED_SERVER || remoteRid == 0 ) goto server_fail;
if ( revision != 0 && remoteRid != revision ) goto server_fail; // Want specific revision but uplink supplied different rid
diff --git a/src/server/net.c b/src/server/net.c
index 5866f25..1e484ac 100644
--- a/src/server/net.c
+++ b/src/server/net.c
@@ -27,6 +27,7 @@
#include "../shared/sockhelper.h"
#include "../shared/timing.h"
+#include "../shared/protocol.h"
#include "../serialize.h"
#include <assert.h>
@@ -251,7 +252,8 @@ void* net_handleNewConnection(void *clientPtr)
client_version = serializer_get_uint16( &payload );
image_name = serializer_get_string( &payload );
rid = serializer_get_uint16( &payload );
- client->isServer = serializer_get_uint8( &payload );
+ const uint8_t flags = serializer_get_uint8( &payload );
+ client->isServer = ( flags & FLAGS8_SERVER );
if ( request.size < 3 || !image_name || client_version < MIN_SUPPORTED_CLIENT ) {
if ( client_version < MIN_SUPPORTED_CLIENT ) {
logadd( LOG_DEBUG1, "Client %s too old", client->hostName );
@@ -259,7 +261,25 @@ void* net_handleNewConnection(void *clientPtr)
logadd( LOG_DEBUG1, "Incomplete handshake received from %s", client->hostName );
}
} else {
- image = image_getOrLoad( image_name, rid );
+ if ( !client->isServer || !_isProxy ) {
+ // Is a normal client, or we're not proxy
+ image = image_getOrLoad( image_name, rid );
+ } else if ( !_backgroundReplication && ( flags & FLAGS8_BG_REP ) ) {
+ // We're a proxy, client is another proxy, we don't do BGR, but connecting proxy does...
+ // Reject, as this would basically force this proxy to do BGR too.
+ image = image_get( image_name, rid, true );
+ if ( image != NULL && image->cache_map != NULL ) {
+ // Only exception is if the image is complete locally
+ image = image_release( image );
+ }
+ } else if ( _lookupMissingForProxy ) {
+ // No BGR mismatch and we're told to lookup missing images on a known uplink server
+ // if the requesting client is a proxy
+ image = image_getOrLoad( image_name, rid );
+ } else {
+ // No BGR mismatch, but don't lookup if image is unknown locally
+ image = image_get( image_name, rid, true );
+ }
spin_lock( &client->lock );
client->image = image;
spin_unlock( &client->lock );