summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2014-12-29 16:38:16 +0100
committerSimon Rettberg2014-12-29 16:38:16 +0100
commite4b81e35c86b21b2c88db8223025d7dde2821fd8 (patch)
tree92daee508847836ab3bff902d61344d2b5e24ce3
parent[SERVER] Fix new sendfile handling, wake up uplink thread if server should be... (diff)
downloaddnbd3-e4b81e35c86b21b2c88db8223025d7dde2821fd8.tar.gz
dnbd3-e4b81e35c86b21b2c88db8223025d7dde2821fd8.tar.xz
dnbd3-e4b81e35c86b21b2c88db8223025d7dde2821fd8.zip
[SERVER] Add setting to enable/disable background replication, add comments to config and code
-rw-r--r--server.config.example/server.conf8
-rw-r--r--src/server/globals.c2
-rw-r--r--src/server/globals.h6
-rw-r--r--src/server/uplink.c16
4 files changed, 28 insertions, 4 deletions
diff --git a/server.config.example/server.conf b/server.config.example/server.conf
index 8c8bb9e..aeae8d5 100644
--- a/server.config.example/server.conf
+++ b/server.config.example/server.conf
@@ -1,8 +1,16 @@
[dnbd3]
+; relative root directory for images, ending in .r[1-9][0-9]*
basePath=/mnt/storage/dnbd3
+; artificial connection delay for connecting servers
serverPenalty=100000
+; artificial connection delay for connecting clients
clientPenalty=0
+; is this server a proxy? if true, requests for non-existing images will be relayed to known alt-servers
isProxy=true
+; if proxy is true and an image is incomplete, should idle bandwidth be used to replicate missing blocks?
+backgroundReplication=true
+; timeout in ms for send/recv on connections to uplink servers (used for replication)
uplinkTimeout=1250
+; timeout in ms for send/recv on connections to clients (using an image on this server)
clientTimeout=15000
diff --git a/src/server/globals.c b/src/server/globals.c
index a9aca77..37bbf90 100644
--- a/src/server/globals.c
+++ b/src/server/globals.c
@@ -16,6 +16,7 @@ int _isProxy = FALSE;
int _proxyPrivateOnly = FALSE;
int _uplinkTimeout = 1250;
int _clientTimeout = 15000;
+int _backgroundReplication = FALSE;
#define SAVE_TO_VAR_STR(ss, kk) do { if (strcmp(section, #ss) == 0 && strcmp(key, #kk) == 0) { if (_ ## kk != NULL) free(_ ## kk); _ ## kk = strdup(value); } } while (0)
#define SAVE_TO_VAR_BOOL(ss, kk) do { if (strcmp(section, #ss) == 0 && strcmp(key, #kk) == 0) _ ## kk = atoi(value) != 0 || strcmp(value, "true") == 0 || strcmp(value, "True") == 0 || strcmp(value, "TRUE") == 0; } while (0)
@@ -27,6 +28,7 @@ static int ini_handler(void *custom, const char* section, const char* key, const
SAVE_TO_VAR_BOOL( dnbd3, vmdkLegacyMode );
SAVE_TO_VAR_BOOL( dnbd3, isProxy );
SAVE_TO_VAR_BOOL( dnbd3, proxyPrivateOnly );
+ SAVE_TO_VAR_BOOL( dnbd3, backgroundReplication );
SAVE_TO_VAR_INT( dnbd3, serverPenalty );
SAVE_TO_VAR_INT( dnbd3, clientPenalty );
SAVE_TO_VAR_INT( dnbd3, uplinkTimeout );
diff --git a/src/server/globals.h b/src/server/globals.h
index 037cd08..d9a299d 100644
--- a/src/server/globals.h
+++ b/src/server/globals.h
@@ -177,6 +177,12 @@ extern int _uplinkTimeout;
*/
extern int _clientTimeout;
+/**
+ * Should we replicate incomplete images in the background?
+ * Otherwise, only blocks that were explicitly requested will be cached.
+ */
+extern int _backgroundReplication;
+
void globals_loadConfig();
#endif /* GLOBALS_H_ */
diff --git a/src/server/uplink.c b/src/server/uplink.c
index 2821a27..5b05873 100644
--- a/src/server/uplink.c
+++ b/src/server/uplink.c
@@ -455,16 +455,24 @@ static void uplink_send_requests(dnbd3_connection_t *link, int newOnly)
}
/**
- * Sent a block request to an uplink server without really having
- * any client that needs that data. This will be used for background replication
+ * Send a block request to an uplink server without really having
+ * any client that needs that data. This will be used for background replication.
+ *
+ * We'll go through the cache map of the image and look for bytes that don't have
+ * all bits set. We then request the corresponding 8 blocks of 4kb from the uplink
+ * server. This means we might request data we already have, but it makes
+ * the code simpler. Worst case would be only one bit is zero, which means
+ * 4kb are missing, but we will request 32kb.
*/
static void uplink_sendReplicationRequest(dnbd3_connection_t *link)
{
+ if ( !_backgroundReplication ) return; // Don't do background replication
if ( link == NULL || link->fd == -1 ) return;
dnbd3_image_t * const image = link->image;
- if ( image == NULL || image->cache_map == NULL || image->filesize < DNBD3_BLOCK_SIZE ) return;
+ if ( image->filesize < DNBD3_BLOCK_SIZE ) return;
spin_lock( &image->lock );
if ( image == NULL || image->cache_map == NULL || link->replicationHandle != 0 ) {
+ // No cache map (=image complete), or replication pending, do nothing
spin_unlock( &image->lock );
return;
}
@@ -474,7 +482,7 @@ static void uplink_sendReplicationRequest(dnbd3_connection_t *link)
for (int i = 0; i <= len; ++i) {
if ( image->cache_map == NULL || link->fd == -1 ) break;
if ( image->cache_map[i] == 0xff || (i == len && link->replicatedLastBlock) ) continue;
- if ( i == len ) link->replicatedLastBlock = TRUE;
+ if ( i == len ) link->replicatedLastBlock = TRUE; // Special treatment, last byte in map could represent less than 8 blocks
link->replicationHandle = 1; // Prevent race condition
spin_unlock( &image->lock );
// Unlocked - do not break or continue here...