mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-30 01:48:54 +00:00
Add configurable limit to ensure a minimum amount of free space is preserved
- default to 100MB of free space - currently disabled on android due to missing sys/statvfs.h
This commit is contained in:
parent
533c0be445
commit
2ef73884a1
@ -429,7 +429,8 @@ ATOM(bool_t, fetch, 1, boolean,, "If false, no new bundl
|
|||||||
ATOM(bool_t, clean_on_open, 0, boolean,, "If true, Rhizome database is cleaned at start of every command")
|
ATOM(bool_t, clean_on_open, 0, boolean,, "If true, Rhizome database is cleaned at start of every command")
|
||||||
ATOM(bool_t, clean_on_start, 1, boolean,, "If true, Rhizome database is cleaned at start of daemon")
|
ATOM(bool_t, clean_on_start, 1, boolean,, "If true, Rhizome database is cleaned at start of daemon")
|
||||||
STRING(256, datastore_path, "", str_nonempty,, "Path of rhizome storage directory, absolute or relative to instance directory")
|
STRING(256, datastore_path, "", str_nonempty,, "Path of rhizome storage directory, absolute or relative to instance directory")
|
||||||
ATOM(uint64_t, database_size, 0, uint64_scaled,, "Maximum size of database in bytes")
|
ATOM(uint64_t, database_size, UINT64_MAX, uint64_scaled,, "Maximum size of database in bytes")
|
||||||
|
ATOM(uint64_t, min_free_space, 100*1024*1024, uint64_scaled,, "Minimum free space to preserve on the disk")
|
||||||
ATOM(uint32_t, max_blob_size, 128 * 1024, uint32_scaled,, "Store payloads larger than this in files not SQLite blobs")
|
ATOM(uint32_t, max_blob_size, 128 * 1024, uint32_scaled,, "Store payloads larger than this in files not SQLite blobs")
|
||||||
|
|
||||||
ATOM(uint64_t, rhizome_mdp_block_size, 512, uint64_scaled,, "Rhizome MDP block size.")
|
ATOM(uint64_t, rhizome_mdp_block_size, 512, uint64_scaled,, "Rhizome MDP block size.")
|
||||||
|
@ -92,6 +92,8 @@ AC_CHECK_HEADERS(
|
|||||||
sys/mman.h \
|
sys/mman.h \
|
||||||
sys/time.h \
|
sys/time.h \
|
||||||
sys/ucred.h \
|
sys/ucred.h \
|
||||||
|
sys/statvfs.h \
|
||||||
|
sys/vfs.h \
|
||||||
poll.h \
|
poll.h \
|
||||||
netdb.h \
|
netdb.h \
|
||||||
linux/ioctl.h \
|
linux/ioctl.h \
|
||||||
|
@ -19,6 +19,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#ifdef HAVE_SYS_STATVFS_H
|
||||||
|
# include <sys/statvfs.h>
|
||||||
|
#endif
|
||||||
#include "serval.h"
|
#include "serval.h"
|
||||||
#include "rhizome.h"
|
#include "rhizome.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
@ -150,6 +153,43 @@ int rhizome_delete_file(const rhizome_filehash_t *hashp)
|
|||||||
return rhizome_delete_file_id(alloca_tohex_rhizome_filehash_t(*hashp));
|
return rhizome_delete_file_id(alloca_tohex_rhizome_filehash_t(*hashp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t store_get_free_space()
|
||||||
|
{
|
||||||
|
const char *fake_space = getenv("SERVALD_FREE_SPACE");
|
||||||
|
if (fake_space)
|
||||||
|
return atol(fake_space);
|
||||||
|
#ifdef HAVE_SYS_STATVFS_H
|
||||||
|
char store_path[1024];
|
||||||
|
if (!FORMF_RHIZOME_STORE_PATH(store_path, "rhizome.db"))
|
||||||
|
return UINT64_MAX;
|
||||||
|
struct statvfs stats;
|
||||||
|
if (statvfs(store_path, &stats)==-1){
|
||||||
|
WARNF_perror("statvfs(%s)", store_path);
|
||||||
|
return UINT64_MAX;
|
||||||
|
}
|
||||||
|
return stats.f_bsize * stats.f_bfree;
|
||||||
|
#else
|
||||||
|
return UINT64_MAX;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t store_space_limit(uint64_t current_size)
|
||||||
|
{
|
||||||
|
uint64_t limit = config.rhizome.database_size;
|
||||||
|
|
||||||
|
if (config.rhizome.min_free_space!=0){
|
||||||
|
uint64_t free_space = store_get_free_space();
|
||||||
|
if (free_space < config.rhizome.min_free_space){
|
||||||
|
if (current_size + free_space < config.rhizome.min_free_space)
|
||||||
|
limit = 0;
|
||||||
|
else
|
||||||
|
limit = current_size + free_space - config.rhizome.min_free_space;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO readonly version?
|
// TODO readonly version?
|
||||||
static enum rhizome_payload_status store_make_space(uint64_t bytes, struct rhizome_cleanup_report *report)
|
static enum rhizome_payload_status store_make_space(uint64_t bytes, struct rhizome_cleanup_report *report)
|
||||||
{
|
{
|
||||||
@ -157,12 +197,11 @@ static enum rhizome_payload_status store_make_space(uint64_t bytes, struct rhizo
|
|||||||
uint64_t db_page_size;
|
uint64_t db_page_size;
|
||||||
uint64_t db_page_count;
|
uint64_t db_page_count;
|
||||||
uint64_t db_free_page_count;
|
uint64_t db_free_page_count;
|
||||||
|
|
||||||
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
|
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
|
||||||
|
|
||||||
// TODO limit based on free space?
|
|
||||||
|
|
||||||
// No limit?
|
// No limit?
|
||||||
if (config.rhizome.database_size==0)
|
if (config.rhizome.database_size==UINT64_MAX && config.rhizome.min_free_space==0)
|
||||||
return RHIZOME_PAYLOAD_STATUS_NEW;
|
return RHIZOME_PAYLOAD_STATUS_NEW;
|
||||||
|
|
||||||
// TODO index external_bytes calculation and/or cache result
|
// TODO index external_bytes calculation and/or cache result
|
||||||
@ -181,13 +220,10 @@ static enum rhizome_payload_status store_make_space(uint64_t bytes, struct rhizo
|
|||||||
)
|
)
|
||||||
return WHY("Cannot measure database used bytes");
|
return WHY("Cannot measure database used bytes");
|
||||||
|
|
||||||
if (config.rhizome.database_size < db_page_size*10)
|
|
||||||
return WHYF("rhizome.database_size is too small to store anything");
|
|
||||||
|
|
||||||
const uint64_t limit = config.rhizome.database_size - db_page_size*4;
|
|
||||||
uint64_t db_used = external_bytes + db_page_size * (db_page_count - db_free_page_count);
|
uint64_t db_used = external_bytes + db_page_size * (db_page_count - db_free_page_count);
|
||||||
|
const uint64_t limit = store_space_limit(db_used);
|
||||||
|
|
||||||
if (bytes >= limit){
|
if (bytes && bytes >= limit){
|
||||||
if (config.debug.rhizome)
|
if (config.debug.rhizome)
|
||||||
DEBUGF("Not enough space for %"PRIu64". Used; %"PRIu64" = %"PRIu64" + %"PRIu64" * (%"PRIu64" - %"PRIu64"), Limit; %"PRIu64,
|
DEBUGF("Not enough space for %"PRIu64". Used; %"PRIu64" = %"PRIu64" + %"PRIu64" * (%"PRIu64" - %"PRIu64"), Limit; %"PRIu64,
|
||||||
bytes, db_used, external_bytes, db_page_size, db_page_count, db_free_page_count, limit);
|
bytes, db_used, external_bytes, db_page_size, db_page_count, db_free_page_count, limit);
|
||||||
@ -223,7 +259,7 @@ static enum rhizome_payload_status store_make_space(uint64_t bytes, struct rhizo
|
|||||||
DEBUGF("Considering dropping file %s, size %"PRId64" cost %"PRId64" vs %"PRId64" to add %"PRId64" new bytes",
|
DEBUGF("Considering dropping file %s, size %"PRId64" cost %"PRId64" vs %"PRId64" to add %"PRId64" new bytes",
|
||||||
id, length, cost, cost_existing, bytes);
|
id, length, cost, cost_existing, bytes);
|
||||||
// don't allow the new file, we've got more important things to store
|
// don't allow the new file, we've got more important things to store
|
||||||
if (cost < cost_existing)
|
if (bytes && cost < cost_existing)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// drop the existing content and recalculate used space
|
// drop the existing content and recalculate used space
|
||||||
|
@ -1291,8 +1291,30 @@ setup_evictUninteresting() {
|
|||||||
setup_rhizome
|
setup_rhizome
|
||||||
set_instance +A
|
set_instance +A
|
||||||
executeOk_servald config set rhizome.database_size 1M
|
executeOk_servald config set rhizome.database_size 1M
|
||||||
|
create_file file1 512K
|
||||||
|
create_file file2 256K
|
||||||
|
create_file file3 128K
|
||||||
|
create_file file4 128K
|
||||||
}
|
}
|
||||||
test_evictUninteresting(){
|
test_evictUninteresting(){
|
||||||
|
executeOk_servald rhizome add file $SIDA file1 file1.manifest
|
||||||
|
executeOk_servald rhizome add file $SIDA file2 file2.manifest
|
||||||
|
executeOk_servald rhizome add file $SIDA file3 file3.manifest
|
||||||
|
executeOk_servald rhizome add file $SIDA file4 file4.manifest
|
||||||
|
tfw_cat --stderr
|
||||||
|
rhizome_clean
|
||||||
|
assert [ $deleted_files = 0 ]
|
||||||
|
assert [ $deleted_fileblobs = 0 ]
|
||||||
|
assert [ $deleted_manifests = 1 ]
|
||||||
|
executeOk_servald rhizome list
|
||||||
|
assert_rhizome_list file{2,3,4}
|
||||||
|
}
|
||||||
|
|
||||||
|
doc_evictFreeSpace="Reduce database size due to insufficient free space"
|
||||||
|
setup_evictFreeSpace() {
|
||||||
|
setup_servald
|
||||||
|
setup_rhizome
|
||||||
|
set_instance +A
|
||||||
create_file file1 512K
|
create_file file1 512K
|
||||||
create_file file2 256K
|
create_file file2 256K
|
||||||
create_file file3 128K
|
create_file file3 128K
|
||||||
@ -1301,9 +1323,17 @@ test_evictUninteresting(){
|
|||||||
executeOk_servald rhizome add file $SIDA file2 file2.manifest
|
executeOk_servald rhizome add file $SIDA file2 file2.manifest
|
||||||
executeOk_servald rhizome add file $SIDA file3 file3.manifest
|
executeOk_servald rhizome add file $SIDA file3 file3.manifest
|
||||||
executeOk_servald rhizome add file $SIDA file4 file4.manifest
|
executeOk_servald rhizome add file $SIDA file4 file4.manifest
|
||||||
|
}
|
||||||
|
test_evictFreeSpace() {
|
||||||
|
executeOk_servald config \
|
||||||
|
set rhizome.min_free_space 1M
|
||||||
|
# only 640K free...
|
||||||
|
export SERVALD_FREE_SPACE=655360
|
||||||
rhizome_clean
|
rhizome_clean
|
||||||
|
assert [ $deleted_files = 0 ]
|
||||||
|
assert [ $deleted_fileblobs = 0 ]
|
||||||
|
assert [ $deleted_manifests = 1 ]
|
||||||
executeOk_servald rhizome list
|
executeOk_servald rhizome list
|
||||||
assert_rhizome_list file{2,3,4}
|
assert_rhizome_list file{2,3,4}
|
||||||
}
|
}
|
||||||
|
|
||||||
runTests "$@"
|
runTests "$@"
|
||||||
|
Loading…
Reference in New Issue
Block a user