-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
152 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ qemu/bzImage | |
|
||
subprojects/liburing-* | ||
subprojects/packagecache | ||
subprojects/nlohmann_json* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Configuring LSVD | ||
|
||
LSVD is configured using a JSON file. When creating an image, we will | ||
try to read the following paths and parse them for configuration options: | ||
|
||
- Default built-in configuration | ||
- `/usr/local/etc/lsvd.json` | ||
- `./lsvd.json` | ||
- user supplied path | ||
|
||
The file read last has highest priority. | ||
|
||
We will also first try to parse the user-supplied path as a JSON object, and if | ||
that fails try treat it as a path and read it from a file. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"rcache_dir": "/tmp/lsvd", | ||
"rcache_size": 524288000, | ||
"rcache_fetch_window": 12, | ||
"wlog_dir": "/tmp/lsvd", | ||
"wlog_bytes": 524288000, | ||
"wlog_write_window": 8, | ||
"wlog_chunk_bytes": 2097152, | ||
"antithrash_ratio": 67, | ||
"backend_obj_bytes": 8388608, | ||
"backend_write_window": 8, | ||
"checkpoint_interval_objs": 500, | ||
"flush_timeout_ms": 2000, | ||
"flush_interval_ms": 1000, | ||
"gc_threshold_pc": 60, | ||
"gc_write_window": 4, | ||
"no_gc": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,153 +1,91 @@ | ||
/* | ||
* file: config.cc | ||
* description: quick and dirty config file parser | ||
* env var overrides modeled on github.com/spf13/viper | ||
* | ||
* author: Peter Desnoyers, Northeastern University | ||
* Copyright 2021, 2022 Peter Desnoyers | ||
* license: GNU LGPL v2.1 or newer | ||
* LGPL-2.1-or-later | ||
*/ | ||
|
||
#include "src/utils.h" | ||
#include <ctype.h> | ||
#include <nlohmann/json.hpp> | ||
#include <stdlib.h> | ||
#include <string> | ||
#include <unistd.h> | ||
#include <uuid/uuid.h> | ||
|
||
#include <filesystem> | ||
#include <fstream> | ||
#include <map> | ||
#include <string> | ||
#include <vector> | ||
namespace fs = std::filesystem; | ||
|
||
#include "config.h" | ||
#include "config_macros.h" | ||
#include "utils.h" | ||
|
||
vec<std::string> cfg_path({"lsvd.conf", "/usr/local/etc/lsvd.conf"}); | ||
|
||
static void split(std::string s, vec<std::string> &words) | ||
{ | ||
std::string w = ""; | ||
for (auto c : s) { | ||
if (!isspace(c)) | ||
w = w + c; | ||
else { | ||
words.push_back(w); | ||
w = ""; | ||
} | ||
} | ||
if (w.size() > 0) | ||
words.push_back(w); | ||
} | ||
|
||
static std::map<std::string, cfg_backend> m = {{"file", BACKEND_FILE}, | ||
{"rados", BACKEND_RADOS}}; | ||
|
||
/* fancy-ass macros to parse config file lines. | ||
* config keyword = field name | ||
* environment var = LSVD_ + uppercase(field name) | ||
* skips blank lines and lines that don't match a keyword | ||
*/ | ||
|
||
int lsvd_config::read() | ||
opt<lsvd_config> lsvd_config::from_file(str path) | ||
{ | ||
auto explicit_cfg = getenv("LSVD_CONFIG_FILE"); | ||
if (explicit_cfg) { | ||
std::string f(explicit_cfg); | ||
cfg_path.insert(cfg_path.begin(), f); | ||
} | ||
for (auto f : cfg_path) { | ||
std::ifstream fp(f); | ||
if (!fp.is_open()) | ||
continue; | ||
std::string line; | ||
while (getline(fp, line)) { | ||
if (line[0] == '#') | ||
continue; | ||
vec<std::string> words; | ||
split(line, words); | ||
if (words.size() != 2) | ||
continue; | ||
F_CONFIG_H_INT(words[0], words[1], backend_obj_size); | ||
F_CONFIG_INT(words[0], words[1], wcache_batch); | ||
F_CONFIG_H_INT(words[0], words[1], wcache_chunk); | ||
F_CONFIG_STR(words[0], words[1], rcache_dir); | ||
F_CONFIG_STR(words[0], words[1], wcache_dir); | ||
F_CONFIG_INT(words[0], words[1], num_parallel_writes); | ||
F_CONFIG_TABLE(words[0], words[1], backend, m); | ||
F_CONFIG_H_INT(words[0], words[1], cache_size); | ||
F_CONFIG_H_INT(words[0], words[1], wlog_size); | ||
F_CONFIG_INT(words[0], words[1], hard_sync); | ||
F_CONFIG_INT(words[0], words[1], ckpt_interval); | ||
F_CONFIG_INT(words[0], words[1], flush_timeout_msec); | ||
F_CONFIG_INT(words[0], words[1], gc_threshold); | ||
F_CONFIG_INT(words[0], words[1], fetch_window); | ||
F_CONFIG_INT(words[0], words[1], fetch_ratio); | ||
F_CONFIG_INT(words[0], words[1], no_gc); | ||
F_CONFIG_INT(words[0], words[1], gc_window); | ||
} | ||
fp.close(); | ||
break; | ||
} | ||
// write just a simple braindead parser | ||
// syntax: lines of `key = value` | ||
|
||
ENV_CONFIG_H_INT(backend_obj_size); | ||
ENV_CONFIG_INT(wcache_batch); | ||
ENV_CONFIG_H_INT(wcache_chunk); | ||
ENV_CONFIG_STR(rcache_dir); | ||
ENV_CONFIG_STR(wcache_dir); | ||
ENV_CONFIG_INT(num_parallel_writes); | ||
ENV_CONFIG_TABLE(backend, m); | ||
ENV_CONFIG_H_INT(cache_size); | ||
ENV_CONFIG_H_INT(wlog_size); | ||
ENV_CONFIG_INT(hard_sync); | ||
ENV_CONFIG_INT(ckpt_interval); | ||
ENV_CONFIG_INT(flush_timeout_msec); | ||
ENV_CONFIG_INT(gc_threshold); | ||
ENV_CONFIG_INT(fetch_window); | ||
ENV_CONFIG_INT(fetch_ratio); | ||
ENV_CONFIG_INT(no_gc); | ||
ENV_CONFIG_INT(gc_window); | ||
|
||
return 0; // success | ||
UNIMPLEMENTED(); | ||
} | ||
|
||
opt<lsvd_config> lsvd_config::from_file(str path) { UNIMPLEMENTED(); } | ||
|
||
std::string lsvd_config::cache_filename(uuid_t &uuid, const char *name, | ||
cfg_cache_type type) | ||
lsvd_config lsvd_config::get_default() { return lsvd_config(); } | ||
|
||
#define JSON_GET_BOOL(key) \ | ||
do { \ | ||
if (js.contains(#key)) { \ | ||
auto v = js[#key]; \ | ||
if (v.is_boolean()) { \ | ||
cfg.key = js[#key]; \ | ||
} else { \ | ||
log_error("Invalid value for key (must be bool): {}", #key); \ | ||
} \ | ||
} \ | ||
} while (0) | ||
|
||
#define JSON_GET_UINT(key) \ | ||
do { \ | ||
if (js.contains(#key)) { \ | ||
auto v = js[#key]; \ | ||
if (v.is_number_unsigned()) { \ | ||
cfg.key = js[#key]; \ | ||
} else { \ | ||
log_error("Invalid value for key (must be uint): {}", #key); \ | ||
} \ | ||
} \ | ||
} while (0) | ||
|
||
#define JSON_GET_STR(key) \ | ||
do { \ | ||
if (js.contains(#key)) { \ | ||
auto v = js[#key]; \ | ||
if (v.is_string()) { \ | ||
cfg.key = js[#key]; \ | ||
} else { \ | ||
log_error("Invalid value for key (must be str): {}", #key); \ | ||
} \ | ||
} \ | ||
} while (0) | ||
|
||
opt<lsvd_config> lsvd_config::from_json(str json) | ||
{ | ||
char buf[256]; // PATH_MAX | ||
std::string file(name); | ||
file = fs::path(file).filename(); | ||
const char *dir; | ||
const char *f_ext; | ||
nlohmann::json js; | ||
|
||
dir = (type == LSVD_CFG_READ) ? rcache_dir.c_str() : wcache_dir.c_str(); | ||
f_ext = (type == LSVD_CFG_READ) ? "rcache" : "wcache"; | ||
try { | ||
js = nlohmann::json::parse(json); | ||
} catch (nlohmann::json::parse_error &e) { | ||
log_error("Failed to parse JSON: {}", e.what()); | ||
return std::nullopt; | ||
} | ||
|
||
sprintf(buf, "%s/%s.%s", dir, file.c_str(), f_ext); | ||
if (access(buf, R_OK | W_OK) == 0) | ||
return std::string((const char *)buf); | ||
lsvd_config cfg; | ||
JSON_GET_STR(rcache_dir); | ||
JSON_GET_UINT(rcache_bytes); | ||
JSON_GET_UINT(rcache_fetch_window); | ||
|
||
char uuid_s[64]; | ||
uuid_unparse(uuid, uuid_s); | ||
sprintf(buf, "%s/%s.%s", dir, uuid_s, f_ext); | ||
return std::string((const char *)buf); | ||
} | ||
JSON_GET_STR(wlog_dir); | ||
JSON_GET_UINT(wlog_bytes); | ||
JSON_GET_UINT(wlog_write_window); | ||
JSON_GET_UINT(wlog_chunk_bytes); | ||
|
||
#if 0 | ||
int main(int argc, char **argv) { | ||
auto cfg = new lsvd_config; | ||
cfg->read(); | ||
JSON_GET_UINT(antithrash_ratio); | ||
JSON_GET_UINT(backend_obj_bytes); | ||
JSON_GET_UINT(backend_write_window); | ||
JSON_GET_UINT(checkpoint_interval_objs); | ||
JSON_GET_UINT(flush_timeout_ms); | ||
JSON_GET_UINT(flush_interval_ms); | ||
|
||
printf("batch: %d\n", cfg->batch_size); // h_int | ||
printf("wc batch %d\n", cfg->wcache_batch); // int | ||
printf("cache: %s\n", cfg->cache_dir.c_str()); // str | ||
printf("backend: %d\n", (int)cfg->backend); // table | ||
JSON_GET_UINT(gc_threshold_pc); | ||
JSON_GET_UINT(gc_write_window); | ||
JSON_GET_BOOL(no_gc); | ||
|
||
uuid_t uu; | ||
std::cout << cfg->cache_filename(uu, "foobar") << "\n"; | ||
return cfg; | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,48 @@ | ||
#pragma once | ||
|
||
/* | ||
* file: config.h | ||
* description: quick and dirty config file parser | ||
* env var overrides modeled on github.com/spf13/viper | ||
* | ||
* author: Peter Desnoyers, Northeastern University | ||
* Copyright 2021, 2022 Peter Desnoyers | ||
* license: GNU LGPL v2.1 or newer | ||
* LGPL-2.1-or-later | ||
*/ | ||
|
||
#include <string> | ||
#include <uuid/uuid.h> | ||
|
||
#include "utils.h" | ||
|
||
enum cfg_backend { BACKEND_FILE = 1, BACKEND_RADOS = 2 }; | ||
|
||
enum cfg_cache_type { LSVD_CFG_READ = 1, LSVD_CFG_WRITE = 2 }; | ||
|
||
class lsvd_config | ||
{ | ||
public: | ||
int backend_obj_size = 8 * 1024 * 1024; // in bytes | ||
int wcache_batch = 8; // requests | ||
int wcache_chunk = 2 * 1024 * 1024; // bytes | ||
std::string rcache_dir = "/tmp/lsvd/"; | ||
std::string wcache_dir = "/tmp/lsvd/"; | ||
u32 num_parallel_writes = 8; | ||
int hard_sync = 0; | ||
enum cfg_backend backend = BACKEND_RADOS; | ||
long cache_size = 500 * 1024 * 1024; // in bytes | ||
long wlog_size = 500 * 1024 * 1024; // in bytes | ||
int ckpt_interval = 500; // objects | ||
int flush_timeout_msec = 2000; // flush timeout | ||
int flush_interval_msec = 1000; // flush interval | ||
int gc_threshold = 60; // GC threshold, percent | ||
int gc_window = 4; // max GC writes outstanding | ||
int fetch_window = 12; // read cache fetches | ||
int fetch_ratio = 67; // anti-thrash served:backend ratio | ||
int no_gc = 0; // turn off GC | ||
// read cache | ||
str rcache_dir = "/tmp/lsvd/"; // directory to store read cache files | ||
u64 rcache_bytes = 500 * 1024 * 1024; // in bytes | ||
u64 rcache_fetch_window = 12; // read cache fetches | ||
|
||
// write log | ||
str wlog_dir = "/tmp/lsvd/"; | ||
u64 wlog_bytes = 500 * 1024 * 1024; // in bytes | ||
u64 wlog_write_window = 8; // requests | ||
u64 wlog_chunk_bytes = 2 * 1024 * 1024; // bytes | ||
|
||
// backend | ||
u64 antithrash_ratio = 67; // anti-thrash served:backend ratio | ||
u64 backend_obj_bytes = 8 * 1024 * 1024; // in bytes | ||
u64 backend_write_window = 8; // backend parallel writes | ||
|
||
u64 checkpoint_interval_objs = 500; // objects | ||
u64 flush_timeout_ms = 2000; // flush timeout | ||
u64 flush_interval_ms = 1000; // flush interval | ||
|
||
// GC | ||
u64 gc_threshold_pc = 60; // GC threshold, percent | ||
u64 gc_write_window = 4; // max GC writes outstanding | ||
bool no_gc = false; // turn off GC | ||
|
||
lsvd_config() {} | ||
~lsvd_config() {} | ||
int read(); | ||
str cache_filename(uuid_t &uuid, const char *name, cfg_cache_type type); | ||
|
||
inline fspath wlog_path(str imgname) | ||
{ | ||
auto filename = imgname + ".wlog"; | ||
return fspath(wcache_dir) / filename; | ||
return fspath(wlog_dir) / filename; | ||
} | ||
|
||
static opt<lsvd_config> from_json(str json); | ||
static opt<lsvd_config> from_file(str path); | ||
static lsvd_config get_default(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.