Initial work to use Berkeley DB for locally logging FS changes.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 6 Apr 2010 03:59:41 +0000 (20:59 -0700)
committerMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 6 Apr 2010 03:59:41 +0000 (20:59 -0700)
Not yet hooked up to anything else, but commit this now so the file doesn't
get lost.

bluesky/localstore.c [new file with mode: 0644]

diff --git a/bluesky/localstore.c b/bluesky/localstore.c
new file mode 100644 (file)
index 0000000..0ce6c6a
--- /dev/null
@@ -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 <mvrable@cs.ucsd.edu>
+ *
+ * TODO: Licensing
+ */
+
+#include <stdint.h>
+#include <glib.h>
+#include <string.h>
+#include <db.h>
+
+#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");
+    }
+
+}