From 84b57000a176f676e2b70b29127455524e578f01 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 11 Oct 2017 16:00:00 +0200 Subject: [SERVER] rpc: Support querying storage size + available space --- src/server/fileutil.c | 14 ++++++++++---- src/server/fileutil.h | 2 +- src/server/image.c | 6 +++--- src/server/rpc.c | 14 +++++++++++++- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/server/fileutil.c b/src/server/fileutil.c index d68649e..d41dc85 100644 --- a/src/server/fileutil.c +++ b/src/server/fileutil.c @@ -66,13 +66,19 @@ bool file_alloc(int fd, uint64_t offset, uint64_t size) return false; } -int64_t file_freeDiskSpace(const char * const path) +bool file_freeDiskSpace(const char * const path, uint64_t *total, uint64_t *avail) { struct statvfs fiData; - if ( (statvfs( path, &fiData )) < 0 ) { - return -1; + if ( statvfs( path, &fiData ) < 0 ) { + return false; } - return ((int64_t)fiData.f_bavail * (int64_t)fiData.f_bsize); + if ( avail != NULL ) { + *avail = ((uint64_t)fiData.f_bavail * (uint64_t)fiData.f_frsize); + } + if ( total != NULL ) { + *total = ((uint64_t)fiData.f_blocks * (uint64_t)fiData.f_frsize); + } + return true; } time_t file_lastModification(const char * const file) diff --git a/src/server/fileutil.h b/src/server/fileutil.h index 36ee432..a4458a3 100644 --- a/src/server/fileutil.h +++ b/src/server/fileutil.h @@ -9,7 +9,7 @@ bool file_isReadable(char *file); bool file_isWritable(char *file); bool mkdir_p(const char* path); bool file_alloc(int fd, uint64_t offset, uint64_t size); -int64_t file_freeDiskSpace(const char * const path); +bool file_freeDiskSpace(const char * const path, uint64_t *total, uint64_t *avail); time_t file_lastModification(const char * const file); int file_loadLineBased(const char * const file, int minFields, int maxFields, void (*cb)(int argc, char **argv, void *data), void *data); diff --git a/src/server/image.c b/src/server/image.c index 1504dae..36e0f0c 100644 --- a/src/server/image.c +++ b/src/server/image.c @@ -1612,13 +1612,13 @@ static bool image_calcBlockCrc32(const int fd, const int block, const uint64_t r static bool image_ensureDiskSpace(uint64_t size) { for ( int maxtries = 0; maxtries < 20; ++maxtries ) { - const int64_t available = file_freeDiskSpace( _basePath ); - if ( available == -1 ) { + 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 ); return true; } - if ( (uint64_t)available > size ) return true; + if ( available > size ) return true; if ( 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)) ); diff --git a/src/server/rpc.c b/src/server/rpc.c index fef7f85..7f57b0a 100644 --- a/src/server/rpc.c +++ b/src/server/rpc.c @@ -105,13 +105,19 @@ void rpc_sendStatsJson(int sock, dnbd3_host_t* host, const void* data, const int static bool handleStatus(int sock, const char *request, int permissions) { bool ok; - bool stats = false, images = false, clients = false; + bool stats = false, images = false, clients = false, space = false; if ( strstr( request, "stats" ) != NULL ) { if ( !(permissions & ACL_STATS) ) { return sendReply( sock, "403 Forbidden", "text/plain", "No permission to access statistics", -1, HTTP_KEEPALIVE ); } stats = true; } + if ( strstr( request, "space" ) != NULL ) { + if ( !(permissions & ACL_STATS) ) { + return sendReply( sock, "403 Forbidden", "text/plain", "No permission to access statistics", -1, HTTP_KEEPALIVE ); + } + space = true; + } if ( strstr( request, "images" ) != NULL ) { if ( !(permissions & ACL_IMAGE_LIST) ) { return sendReply( sock, "403 Forbidden", "text/plain", "No permission to access image list", -1, HTTP_KEEPALIVE ); @@ -142,6 +148,12 @@ static bool handleStatus(int sock, const char *request, int permissions) statisticsJson = json_pack( "{sI}", "runId", randomRunId ); } + if ( space ) { + uint64_t spaceTotal = 0, spaceAvail = 0; + file_freeDiskSpace( _basePath, &spaceTotal, &spaceAvail ); + json_object_set_new( statisticsJson, "spaceTotal", json_integer( spaceTotal ) ); + json_object_set_new( statisticsJson, "spaceFree", json_integer( spaceAvail ) ); + } if ( jsonClients != NULL ) { if ( clients ) { json_object_set_new( statisticsJson, "clients", jsonClients ); -- cgit v1.2.3-55-g7522