diff options
Diffstat (limited to 'database/engine/rrdenginelib.c')
-rw-r--r-- | database/engine/rrdenginelib.c | 119 |
1 files changed, 106 insertions, 13 deletions
diff --git a/database/engine/rrdenginelib.c b/database/engine/rrdenginelib.c index 0606dd938..287b86be8 100644 --- a/database/engine/rrdenginelib.c +++ b/database/engine/rrdenginelib.c @@ -60,7 +60,7 @@ int check_file_properties(uv_file file, uint64_t *file_size, size_t min_size) if (ret < 0) { fatal("uv_fs_fstat: %s\n", uv_strerror(ret)); } - assert(req.result == 0); + fatal_assert(req.result == 0); s = req.ptr; if (!(s->st_mode & S_IFREG)) { error("Not a regular file.\n"); @@ -78,17 +78,22 @@ int check_file_properties(uv_file file, uint64_t *file_size, size_t min_size) return 0; } -/* - * Tries to open a file in direct I/O mode, falls back to buffered mode if not possible. - * Returns UV error number that is < 0 on failure. - * On success sets (*file) to be the uv_file that was opened. +/** + * Open file for I/O. + * + * @param path The full path of the file. + * @param flags Same flags as the open() system call uses. + * @param file On success sets (*file) to be the uv_file that was opened. + * @param direct Tries to open a file in direct I/O mode when direct=1, falls back to buffered mode if not possible. + * @return Returns UV error number that is < 0 on failure. 0 on success. */ -int open_file_direct_io(char *path, int flags, uv_file *file) +int open_file_for_io(char *path, int flags, uv_file *file, int direct) { uv_fs_t req; - int fd, current_flags, direct; + int fd = -1, current_flags; - for (direct = 1 ; direct >= 0 ; --direct) { + fatal_assert(0 == direct || 1 == direct); + for ( ; direct >= 0 ; --direct) { #ifdef __APPLE__ /* Apple OS does not support O_DIRECT */ direct = 0; @@ -106,7 +111,7 @@ int open_file_direct_io(char *path, int flags, uv_file *file) --direct; /* break the loop */ } } else { - assert(req.result >= 0); + fatal_assert(req.result >= 0); *file = req.result; #ifdef __APPLE__ info("Disabling OS X caching for file \"%s\".", path); @@ -159,8 +164,10 @@ char *get_rrdeng_statistics(struct rrdengine_instance *ctx, char *str, size_t si "global_io_errors: %ld\n" "global_fs_errors: %ld\n" "rrdeng_reserved_file_descriptors: %ld\n" - "flushing_errors: %ld\n" - "global_flushing_errors: %ld\n", + "pg_cache_over_half_dirty_events: %ld\n" + "global_pg_cache_over_half_dirty_events: %ld\n" + "flushing_pressure_page_deletions: %ld\n" + "global_flushing_pressure_page_deletions: %ld\n", (long)ctx->stats.metric_API_producers, (long)ctx->stats.metric_API_consumers, (long)pg_cache->page_descriptors, @@ -194,8 +201,94 @@ char *get_rrdeng_statistics(struct rrdengine_instance *ctx, char *str, size_t si (long)global_io_errors, (long)global_fs_errors, (long)rrdeng_reserved_file_descriptors, - (long)ctx->stats.flushing_errors, - (long)global_flushing_errors + (long)ctx->stats.pg_cache_over_half_dirty_events, + (long)global_pg_cache_over_half_dirty_events, + (long)ctx->stats.flushing_pressure_page_deletions, + (long)global_flushing_pressure_page_deletions ); return str; } + +int is_legacy_child(const char *machine_guid) +{ + uuid_t uuid; + char dbengine_file[FILENAME_MAX+1]; + + if (unlikely(!strcmp(machine_guid, "unittest-dbengine") || !strcmp(machine_guid, "dbengine-dataset") || + !strcmp(machine_guid, "dbengine-stress-test"))) { + return 1; + } + if (!uuid_parse(machine_guid, uuid)) { + uv_fs_t stat_req; + snprintfz(dbengine_file, FILENAME_MAX, "%s/%s/dbengine", netdata_configured_cache_dir, machine_guid); + int rc = uv_fs_stat(NULL, &stat_req, dbengine_file, NULL); + if (likely(rc == 0 && ((stat_req.statbuf.st_mode & S_IFMT) == S_IFDIR))) { + //info("Found legacy engine folder \"%s\"", dbengine_file); + return 1; + } + } + return 0; +} + +int count_legacy_children(char *dbfiles_path) +{ + int ret; + uv_fs_t req; + uv_dirent_t dent; + int legacy_engines = 0; + + ret = uv_fs_scandir(NULL, &req, dbfiles_path, 0, NULL); + if (ret < 0) { + uv_fs_req_cleanup(&req); + error("uv_fs_scandir(%s): %s", dbfiles_path, uv_strerror(ret)); + return ret; + } + + while(UV_EOF != uv_fs_scandir_next(&req, &dent)) { + if (dent.type == UV_DIRENT_DIR) { + if (is_legacy_child(dent.name)) + legacy_engines++; + } + } + uv_fs_req_cleanup(&req); + return legacy_engines; +} + +int compute_multidb_diskspace() +{ + char multidb_disk_space_file[FILENAME_MAX + 1]; + FILE *fp; + int computed_multidb_disk_quota_mb = -1; + + snprintfz(multidb_disk_space_file, FILENAME_MAX, "%s/dbengine_multihost_size", netdata_configured_varlib_dir); + fp = fopen(multidb_disk_space_file, "r"); + if (likely(fp)) { + int rc = fscanf(fp, "%d", &computed_multidb_disk_quota_mb); + fclose(fp); + if (unlikely(rc != 1 || computed_multidb_disk_quota_mb < RRDENG_MIN_DISK_SPACE_MB)) { + errno = 0; + error("File '%s' contains invalid input, it will be rebuild", multidb_disk_space_file); + computed_multidb_disk_quota_mb = -1; + } + } + + if (computed_multidb_disk_quota_mb == -1) { + int rc = count_legacy_children(netdata_configured_cache_dir); + if (likely(rc >= 0)) { + computed_multidb_disk_quota_mb = (rc + 1) * default_rrdeng_disk_quota_mb; + info("Found %d legacy dbengines, setting multidb diskspace to %dMB", rc, computed_multidb_disk_quota_mb); + + fp = fopen(multidb_disk_space_file, "w"); + if (likely(fp)) { + fprintf(fp, "%d", computed_multidb_disk_quota_mb); + info("Created file '%s' to store the computed value", multidb_disk_space_file); + fclose(fp); + } else + error("Failed to store the default multidb disk quota size on '%s'", multidb_disk_space_file); + } + else + computed_multidb_disk_quota_mb = default_rrdeng_disk_quota_mb; + } + + return computed_multidb_disk_quota_mb; +} |