summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorSimon Rettberg2017-09-02 18:03:15 +0200
committerSimon Rettberg2017-09-02 18:03:15 +0200
commit9858ab5bbb2fc5d1569257c0ee8f794fdae1c512 (patch)
tree7bb448cc73f852f5ed0f258daf8c9280755bb52d /src/server
parent[*] Continue splitting #defines to clientconfig.h etc. (diff)
downloaddnbd3-9858ab5bbb2fc5d1569257c0ee8f794fdae1c512.tar.gz
dnbd3-9858ab5bbb2fc5d1569257c0ee8f794fdae1c512.tar.xz
dnbd3-9858ab5bbb2fc5d1569257c0ee8f794fdae1c512.zip
[SERVER] Implement closeUnusedFd config option
This will close the readFd of images that have no active clients after some idle period (1 hour currently). Prevents deleted images from taking up space until the server is shut down.
Diffstat (limited to 'src/server')
-rw-r--r--src/server/altservers.c5
-rw-r--r--src/server/image.c26
-rw-r--r--src/server/image.h2
3 files changed, 33 insertions, 0 deletions
diff --git a/src/server/altservers.c b/src/server/altservers.c
index 4c87344..7c55ab9 100644
--- a/src/server/altservers.c
+++ b/src/server/altservers.c
@@ -345,6 +345,7 @@ static void *altservers_main(void *data UNUSED)
serialized_buffer_t serialized;
struct timespec start, end;
time_t nextCacheMapSave = time( NULL ) + 90;
+ time_t nextCloseUnusedFd = time( NULL ) + 900;
setThreadName( "altserver-check" );
blockNoncriticalSignals();
@@ -525,6 +526,10 @@ static void *altservers_main(void *data UNUSED)
nextCacheMapSave = now + SERVER_CACHE_MAP_SAVE_INTERVAL;
image_saveAllCacheMaps();
}
+ // TODO: More random crap
+ if ( _closeUnusedFd && now > nextCloseUnusedFd ) {
+ image_closeUnusedFd();
+ }
}
cleanup: ;
if ( runSignal != NULL ) signal_close( runSignal );
diff --git a/src/server/image.c b/src/server/image.c
index 5b1a582..cc5915d 100644
--- a/src/server/image.c
+++ b/src/server/image.c
@@ -1662,6 +1662,32 @@ static bool image_ensureDiskSpace(uint64_t size)
return false;
}
+void image_closeUnusedFd()
+{
+ int fd, i;
+ time_t deadline = time( NULL ) - UNUSED_FD_TIMEOUT;
+ spin_lock( &imageListLock );
+ for (i = 0; i < _num_images; ++i) {
+ dnbd3_image_t * const image = _images[i];
+ if ( image == NULL )
+ continue;
+ spin_lock( &image->lock );
+ spin_unlock( &imageListLock );
+ if ( image->users == 0 && image->atime < deadline ) {
+ fd = image->readFd;
+ image->readFd = -1;
+ } else {
+ fd = -1;
+ }
+ spin_unlock( &image->lock );
+ if ( fd != -1 ) {
+ close( fd );
+ }
+ spin_lock( &imageListLock );
+ }
+ spin_unlock( &imageListLock );
+}
+
/*
void image_find_latest()
{
diff --git a/src/server/image.h b/src/server/image.h
index d129984..40a6375 100644
--- a/src/server/image.h
+++ b/src/server/image.h
@@ -43,6 +43,8 @@ json_t* image_getListAsJson();
int image_getCompletenessEstimate(dnbd3_image_t * const image);
+void image_closeUnusedFd();
+
// one byte in the map covers 8 4kib blocks, so 32kib per byte
// "+ (1 << 15) - 1" is required to account for the last bit of
// the image that is smaller than 32kib