From e4b81e35c86b21b2c88db8223025d7dde2821fd8 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 29 Dec 2014 16:38:16 +0100 Subject: [SERVER] Add setting to enable/disable background replication, add comments to config and code --- server.config.example/server.conf | 8 ++++++++ src/server/globals.c | 2 ++ src/server/globals.h | 6 ++++++ src/server/uplink.c | 16 ++++++++++++---- 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... -- cgit v1.2.3-55-g7522