From 35005a19d59c064d362e83ab8acaa8af4ac82a06 Mon Sep 17 00:00:00 2001 From: Michael Vrable Date: Mon, 5 Apr 2010 20:59:41 -0700 Subject: [PATCH] Initial work to use Berkeley DB for locally logging FS changes. Not yet hooked up to anything else, but commit this now so the file doesn't get lost. --- bluesky/localstore.c | 128 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 bluesky/localstore.c diff --git a/bluesky/localstore.c b/bluesky/localstore.c new file mode 100644 index 0000000..0ce6c6a --- /dev/null +++ b/bluesky/localstore.c @@ -0,0 +1,128 @@ +/* Blue Sky: File Systems in the Cloud + * + * Copyright (C) 2009 The Regents of the University of California + * Written by Michael Vrable + * + * TODO: Licensing + */ + +#include +#include +#include +#include + +#include "bluesky-private.h" + +/* Management of the filesystem log/cache stored on local disk. This is used + * as a buffer for queueing writes to the cloud, a cache for satisfying reads, + * and is also used to provide durability for the filesystem across crashes + * even if data has not been flushed to the cloud. + * + * We use Berkeley DB since it provides durability of writes after a crash. */ + +void bluesky_localstore_init() +{ + int res; + DB_ENV *env; + DB *db; + + res = db_env_create(&env, 0); + + if (res != 0) + { + cerr << db_strerror(res) << endl; + throw std::runtime_error("db_env_create fail"); + } + + /* Set Cache Size To Total Memory */ + if (true) + { + double use_fraction = 0.1; + uint64_t pages = sysconf(_SC_PHYS_PAGES); + uint64_t page_size = sysconf(_SC_PAGE_SIZE); + + uint64_t bytes = pages * page_size * use_fraction / num_dbs; + + uint32_t gbytes = bytes / (1024uLL * 1024uLL * 1024uLL); + uint32_t nbytes = bytes % (1024uLL * 1024uLL * 1024uLL); + uint32_t ncache = bytes / (1024uLL * 1024uLL * 1024uLL * 4uLL) + 1; + + res = env->set_cachesize(env, gbytes, nbytes, ncache); + + if (res != 0) + { + cerr << db_strerror(res) << endl; + throw std::runtime_error("set_cachesize"); + } + } + + if (log_in_memory) + { + res = env->set_flags(env, DB_LOG_IN_MEMORY, 1); + + if (res != 0) + { + cerr << db_strerror(res) << endl; + throw std::runtime_error("BDB ENV DB_LOG_IN_MEMORY"); + } + + } + + res = env->set_flags(env, DB_LOG_AUTO_REMOVE, 1); + + if (res != 0) + { + cerr << db_strerror(res) << endl; + throw std::runtime_error("BDB ENV DB_LOG_AUTO_REMOVE"); + } + + res = env->open(env, _path.c_str(), + DB_CREATE | DB_RECOVER | DB_INIT_LOCK | DB_INIT_LOG + | DB_INIT_MPOOL | DB_INIT_TXN | DB_THREAD, + 0644); + + if (res != 0) + { + cerr << db_strerror(res) << endl; + throw std::runtime_error("BDB ENV Open Fail"); + } + + string dbfilename = _path + "/test.db"; + + /* Flush */ + if (flush) + { + res = env->dbremove(env, NULL, dbfilename.c_str(), "test", 0); + + if (res != 0 && res != ENOENT) + { + cerr << db_strerror(res) << endl; + throw std::runtime_error("db remove failed"); + } + } + + res = db_create(&_db, env, 0); + + if (res != 0) + { + cerr << db_strerror(res) << endl; + throw std::runtime_error("db_create fail"); + } + + uint32_t flags = DB_CREATE | DB_THREAD | DB_AUTO_COMMIT; + + res = _db->open(_db, + NULL, /* TXN */ + dbfilename.c_str(), + "test", + DB_BTREE, + flags, + 0644); + + if (res != 0) + { + cerr << db_strerror(res) << endl; + throw std::runtime_error("BDB Open Fail"); + } + +} -- 2.20.1