From bf665f59411840c60b6e3c9ac33f28a818233c0a Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 5 Sep 2019 18:15:52 +0200 Subject: [SERVER] Introduce autoFreeDiskSpaceDelay This setting allows you to control the formerly hard-coded timeout of 10 hours before a proxy would start deleting old images in order to free up space for new images. Setting it to -1 entirely disables automatic deletion, in case you have an external process for freeing up disk space. --- conf/server.conf | 11 +++++++++++ src/server/globals.c | 12 ++++++++++++ src/server/globals.h | 7 +++++++ src/server/image.c | 14 ++++++++------ 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/conf/server.conf b/conf/server.conf index a101f34..a15092f 100644 --- a/conf/server.conf +++ b/conf/server.conf @@ -31,6 +31,17 @@ vmdkLegacyMode=false ; Don't set the server flag when connecting to alt-servers ; Intended for if the proxy is used for on-client caching pretendClient=false +; When running in proxy mode and running out of space, automatically delete oldest image(s) to make +; the newly replicated image fit. In sparse mode, this will make sure at least 2GB of free space are +; available when replicating a new image. During normal operation, it will free at least 256MB whenever +; an attempt to write more data to cache fails. In non-sparse mode, whenever a new image is replicated, +; as much space as is required to store the entire image will be made available. +; However, after startup the proxy will refuse to delete any images for the time span given below, to be +; able to gather up to date usage information for the images available. If unitless, the value is +; interpreted in seconds. Valid suffixes are m, h, d. +; Setting this to -1 disables deletion of images. If the cache partition is full, no more images will +; be replicated unless you manually free up more disk space. +autoFreeDiskSpaceDelay=10h [limits] maxClients=2000 diff --git a/src/server/globals.c b/src/server/globals.c index 46c1030..f8c3f66 100644 --- a/src/server/globals.c +++ b/src/server/globals.c @@ -28,6 +28,7 @@ atomic_bool _closeUnusedFd = false; atomic_bool _vmdkLegacyMode = false; // Not really needed anymore since we have '+' and '-' in alt-servers atomic_bool _proxyPrivateOnly = false; +atomic_int _autoFreeDiskSpaceDelay = 3600 * 10; // [limits] atomic_int _maxClients = SERVER_MAX_CLIENTS; atomic_int _maxImages = SERVER_MAX_IMAGES; @@ -83,6 +84,7 @@ static int ini_handler(void *custom UNUSED, const char* section, const char* key SAVE_TO_VAR_UINT( limits, maxPayload ); SAVE_TO_VAR_UINT64( limits, maxReplicationSize ); SAVE_TO_VAR_BOOL( dnbd3, pretendClient ); + SAVE_TO_VAR_INT( dnbd3, autoFreeDiskSpaceDelay ); if ( strcmp( section, "dnbd3" ) == 0 && strcmp( key, "backgroundReplication" ) == 0 ) { if ( strcmp( value, "hashblock" ) == 0 ) { _backgroundReplication = BGR_HASHBLOCK; @@ -229,6 +231,15 @@ static bool parse64(const char *in, atomic_int_fast64_t *out, const char *optnam while ( *end == ' ' ) end++; if ( *end == '\0' ) { exp = 0; + } else if ( *end == 'm' ) { + exp = 1; + base = 60; + } else if ( *end == 'h' ) { + exp = 1; + base = 3600; + } else if ( *end == 'd' ) { + exp = 1; + base = 24 * 3600; } else { char *pos = strchr( units, *end > 'Z' ? (*end - 32) : *end ); if ( pos == NULL ) { @@ -318,6 +329,7 @@ size_t globals_dumpConfig(char *buffer, size_t size) PBOOL(vmdkLegacyMode); PBOOL(proxyPrivateOnly); PBOOL(pretendClient); + PINT(autoFreeDiskSpaceDelay); P_ARG("[limits]\n"); PINT(maxClients); PINT(maxImages); diff --git a/src/server/globals.h b/src/server/globals.h index ebdc1c7..58b2c9d 100644 --- a/src/server/globals.h +++ b/src/server/globals.h @@ -290,6 +290,13 @@ extern atomic_uint_fast64_t _maxReplicationSize; */ extern atomic_bool _pretendClient; +/** + * Minimum uptime in seconds before proxy starts deleting old + * images if running out of space. -1 disables automatic deletion. + * Only relevant in proxy mode. + */ +extern atomic_int _autoFreeDiskSpaceDelay; + /** * Load the server configuration. */ diff --git a/src/server/image.c b/src/server/image.c index 86e6b87..9fcb866 100644 --- a/src/server/image.c +++ b/src/server/image.c @@ -1696,14 +1696,16 @@ static bool image_ensureDiskSpace(uint64_t size, bool force) for ( int maxtries = 0; maxtries < 20; ++maxtries ) { uint64_t available; if ( !file_freeDiskSpace( _basePath, NULL, &available ) ) { - const int e = errno; - logadd( LOG_WARNING, "Could not get free disk space (errno %d), will assume there is enough space left... ;-)\n", e ); + logadd( LOG_WARNING, "Could not get free disk space (errno %d), will assume there is enough space left... ;-)\n", errno ); return true; } - if ( available > size ) return true; - if ( !force && dnbd3_serverUptime() < 10 * 3600 ) { - logadd( LOG_INFO, "Only %dMiB free, %dMiB requested, but server uptime < 10 hours...", (int)(available / (1024ll * 1024ll)), - (int)(size / (1024 * 1024)) ); + if ( available > size ) + return true; // Yay + if ( !_isProxy || _autoFreeDiskSpaceDelay == -1 ) + return false; // If not in proxy mode at all, or explicitly disabled, never delete anything + if ( !force && dnbd3_serverUptime() < (uint32_t)_autoFreeDiskSpaceDelay ) { + logadd( LOG_INFO, "Only %dMiB free, %dMiB requested, but server uptime < %d minutes...", (int)(available / (1024ll * 1024ll)), + (int)(size / (1024 * 1024)), _autoFreeDiskSpaceDelay / 60 ); return false; } logadd( LOG_INFO, "Only %dMiB free, %dMiB requested, freeing an image...", (int)(available / (1024ll * 1024ll)), -- cgit v1.2.3-55-g7522