[pve-devel] r5468 - in pve-cluster/trunk/data: . src

svn-commits at proxmox.com svn-commits at proxmox.com
Mon Jan 31 14:44:09 CET 2011


Author: dietmar
Date: 2011-01-31 14:44:09 +0100 (Mon, 31 Jan 2011)
New Revision: 5468

Modified:
   pve-cluster/trunk/data/ChangeLog
   pve-cluster/trunk/data/src/cfs-plug-memdb.c
   pve-cluster/trunk/data/src/cfs-utils.c
   pve-cluster/trunk/data/src/cfs-utils.h
   pve-cluster/trunk/data/src/database.c
   pve-cluster/trunk/data/src/dcdb.c
   pve-cluster/trunk/data/src/dcdb.h
   pve-cluster/trunk/data/src/dfsm.c
   pve-cluster/trunk/data/src/dfsm.h
   pve-cluster/trunk/data/src/memdb.c
   pve-cluster/trunk/data/src/memdb.h
Log:
	* src/dcdb.c (dcdb_deliver): implement a simple distributed lock
	manager for short lived locks (no fencing, see README).


Modified: pve-cluster/trunk/data/ChangeLog
===================================================================
--- pve-cluster/trunk/data/ChangeLog	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/ChangeLog	2011-01-31 13:44:09 UTC (rev 5468)
@@ -1,3 +1,8 @@
+2011-01-31  Proxmox Support Team  <support at proxmox.com>
+
+	* src/dcdb.c (dcdb_deliver): implement a simple distributed lock
+	manager for short lived locks (no fencing, see README).
+
 2011-01-19  root  <root at maui.maurer-it.com>
 
 	* perl/Cluster.pm (log_msg): fixes for taint mode (untaint $0)

Modified: pve-cluster/trunk/data/src/cfs-plug-memdb.c
===================================================================
--- pve-cluster/trunk/data/src/cfs-plug-memdb.c	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/cfs-plug-memdb.c	2011-01-31 13:44:09 UTC (rev 5468)
@@ -365,14 +365,35 @@
 
 	res = -EIO;
 
+	memdb_tree_entry_t *te = memdb_getattr(mdb->memdb, path);
 	uint32_t mtime = tv[1].tv_sec;
+
+	gboolean unlock_req = FALSE;
+
+	if (te && mtime == 0 && te->type == DT_DIR &&
+	    path_is_lockdir(path)) {
+		unlock_req = TRUE;
+	}
+
 	if (mdb->dfsm) {
+		guchar csum[32];
+		if (unlock_req && memdb_tree_entry_csum(te, csum))
+			dcdb_send_unlock(mdb->dfsm, path, csum, TRUE);
+	    
 		res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_MTIME, path, 
 					     NULL, NULL, 0, mtime, 0);
 	} else {
-		res = memdb_mtime(mdb->memdb, path, 0, mtime);
+		uint32_t ctime = time(NULL);
+		if (unlock_req && memdb_lock_expired(mdb->memdb, path)) {
+			res = memdb_delete(mdb->memdb, path, 0, ctime);
+		} else {
+			res = memdb_mtime(mdb->memdb, path, 0, mtime);
+		}
 	}
 
+	if (te)
+		g_free(te);
+
 	return res;
 }
 

Modified: pve-cluster/trunk/data/src/cfs-utils.c
===================================================================
--- pve-cluster/trunk/data/src/cfs-utils.c	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/cfs-utils.c	2011-01-31 13:44:09 UTC (rev 5468)
@@ -431,3 +431,8 @@
 	return FALSE;
 }
 
+gboolean
+path_is_lockdir(const char *path)
+{
+	return (strncmp(path, "priv/lock/", 10) == 0) && (strlen(path) > 10);
+}

Modified: pve-cluster/trunk/data/src/cfs-utils.h
===================================================================
--- pve-cluster/trunk/data/src/cfs-utils.h	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/cfs-utils.h	2011-01-31 13:44:09 UTC (rev 5468)
@@ -113,4 +113,7 @@
 gboolean
 path_is_private(const char *path);
 
+gboolean
+path_is_lockdir(const char *path);
+
 #endif /* _PVE_CFS_UTILS_H_ */

Modified: pve-cluster/trunk/data/src/database.c
===================================================================
--- pve-cluster/trunk/data/src/database.c	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/database.c	2011-01-31 13:44:09 UTC (rev 5468)
@@ -436,6 +436,7 @@
 	}
 
 	sqlite3_reset(stmt);
+
 	return TRUE;
 
 fail:
@@ -582,6 +583,9 @@
 		result = FALSE;
 		goto ret;
 	}
+
+	memdb_update_locks(memdb);
+
 	result = TRUE;
 
 ret:

Modified: pve-cluster/trunk/data/src/dcdb.c
===================================================================
--- pve-cluster/trunk/data/src/dcdb.c	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/dcdb.c	2011-01-31 13:44:09 UTC (rev 5468)
@@ -47,6 +47,64 @@
 	GList *updates;
 } dcdb_sync_info_t;
 
+void
+dcdb_send_unlock(
+	dfsm_t *dfsm,
+	const char *path,
+	const guchar csum[32],
+	gboolean request)
+{
+	g_return_if_fail(dfsm != NULL);
+	g_return_if_fail(path != NULL);
+	g_return_if_fail(csum != NULL);
+
+	struct iovec iov[2];
+
+	iov[0].iov_base = (char *)csum;
+	iov[0].iov_len = 32;
+
+	iov[1].iov_base = (char *)path;
+	iov[1].iov_len = strlen(path) + 1;
+
+	if (!cfs_is_quorate())
+		return;
+
+	dcdb_message_t msg_type = request ? 
+		DCDB_MESSAGE_CFS_UNLOCK_REQUEST : DCDB_MESSAGE_CFS_UNLOCK;
+	
+	dfsm_send_message_sync(dfsm, msg_type, iov, 2, NULL);
+}
+
+static gboolean 
+dcdb_parse_unlock_request(
+	const void *msg,
+	size_t msg_len,
+	const char **path,
+	const guchar **csum)
+
+{
+	g_return_val_if_fail(msg != NULL, FALSE);
+	g_return_val_if_fail(path != NULL, FALSE);
+	g_return_val_if_fail(csum != NULL, FALSE);
+
+	if (msg_len < 33) {
+		cfs_critical("received short unlock message (%lu < 33)", msg_len);
+		return FALSE;
+	}
+
+	*csum = msg;
+	msg += 32; msg_len -= 32;
+
+	*path = msg;
+	if ((*path)[msg_len - 1] != 0) {
+		cfs_critical("received mailformed unlock message - 'path' not terminated");
+		*path = NULL;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 int 
 dcdb_send_fuse_message(
 	dfsm_t *dfsm,
@@ -750,11 +808,43 @@
 		goto leave;
 	}
 
-	const char *path, *to, *buf;
+	const char *path, *to, *buf; 
 	guint32 size, offset, flags;
+	const guchar *csum;
 
-	if (msg_type == DCDB_MESSAGE_CFS_WRITE) {
+	if (msg_type == DCDB_MESSAGE_CFS_UNLOCK_REQUEST ||
+	    msg_type == DCDB_MESSAGE_CFS_UNLOCK) {
+		msg_result = 0; /* ignored anyways */ 
+		
+		if (!dcdb_parse_unlock_request(msg, msg_len, &path, &csum))
+			goto leave;
 
+		guchar cur_csum[32];
+		memdb_tree_entry_t *te = memdb_getattr(memdb, path);
+
+		if (te &&  te->type == DT_DIR &&
+		    path_is_lockdir(path) && memdb_tree_entry_csum(te, cur_csum) &&
+		    (memcmp(csum, cur_csum, 32) == 0)) {
+
+			if (msg_type == DCDB_MESSAGE_CFS_UNLOCK) {
+
+				cfs_debug("got valid unlock message");
+
+				msg_result = memdb_delete(memdb, path, nodeid, msg_time);
+
+			} else if (dfsm_lowest_nodeid(dfsm)) {
+
+				cfs_debug("got valid unlock request message");
+			
+				if (memdb_lock_expired(memdb, path)) {
+					cfs_debug("sending unlock message");
+					dcdb_send_unlock(dfsm, path, csum, FALSE);
+				}
+			}
+		}
+
+	} else if (msg_type == DCDB_MESSAGE_CFS_WRITE) {
+
 		if (!dcdb_parse_fuse_message(msg, msg_len, &path, &to, &buf, 
 					     &size, &offset, &flags))
 			goto leave;

Modified: pve-cluster/trunk/data/src/dcdb.h
===================================================================
--- pve-cluster/trunk/data/src/dcdb.h	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/dcdb.h	2011-01-31 13:44:09 UTC (rev 5468)
@@ -38,9 +38,11 @@
 	DCDB_MESSAGE_CFS_RENAME = 4,
 	DCDB_MESSAGE_CFS_CREATE = 5,
 	DCDB_MESSAGE_CFS_MTIME = 6,
+	DCDB_MESSAGE_CFS_UNLOCK_REQUEST = 7,
+	DCDB_MESSAGE_CFS_UNLOCK = 8,
 } dcdb_message_t;
 
-#define DCDB_VALID_MESSAGE_TYPE(mt) (mt >= DCDB_MESSAGE_CFS_WRITE && mt <= DCDB_MESSAGE_CFS_MTIME)
+#define DCDB_VALID_MESSAGE_TYPE(mt) (mt >= DCDB_MESSAGE_CFS_WRITE && mt <= DCDB_MESSAGE_CFS_UNLOCK)
 
 dfsm_t *dcdb_new(memdb_t *memdb);
 
@@ -58,5 +60,11 @@
 	guint32 offset, 
 	guint32 flags);
 
+void
+dcdb_send_unlock_request(
+	dfsm_t *dfsm,
+	const char *path,
+	const guchar csum[32],
+	gboolean request);
 
 #endif /* _PVE_DCDB_H_ */

Modified: pve-cluster/trunk/data/src/dfsm.c
===================================================================
--- pve-cluster/trunk/data/src/dfsm.c	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/dfsm.c	2011-01-31 13:44:09 UTC (rev 5468)
@@ -1278,6 +1278,17 @@
 	return NULL;
 }
 
+gboolean 
+dfsm_lowest_nodeid(dfsm_t *dfsm)
+{
+	g_return_val_if_fail(dfsm != NULL, FALSE);
+
+	if (dfsm->lowest_nodeid && (dfsm->lowest_nodeid == dfsm->nodeid))
+		return TRUE;
+
+	return FALSE;
+}
+
 cs_error_t 
 dfsm_verify_request(dfsm_t *dfsm)
 {

Modified: pve-cluster/trunk/data/src/dfsm.h
===================================================================
--- pve-cluster/trunk/data/src/dfsm.h	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/dfsm.h	2011-01-31 13:44:09 UTC (rev 5468)
@@ -174,6 +174,9 @@
 dfsm_send_update_complete(dfsm_t *dfsm);
 
 gboolean 
+dfsm_lowest_nodeid(dfsm_t *dfsm);
+
+gboolean 
 dfsm_nodeid_is_local(
 	dfsm_t *dfsm, 
 	uint32_t nodeid,

Modified: pve-cluster/trunk/data/src/memdb.c
===================================================================
--- pve-cluster/trunk/data/src/memdb.c	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/memdb.c	2011-01-31 13:44:09 UTC (rev 5468)
@@ -38,6 +38,8 @@
 #include "memdb.h"
 #include "status.h"
 
+#define CFS_LOCK_TIMEOUT (60*2)
+
 memdb_tree_entry_t *
 memdb_tree_entry_new(
 	const char *name)
@@ -97,7 +99,17 @@
 	g_free(te);
 }
 
+void 
+memdb_lock_info_free(memdb_lock_info_t *li)
+{
+	g_return_if_fail(li != NULL);
 
+	if (li->path)
+		g_free(li->path);
+
+	g_free(li);
+}
+
 static gint
 memdb_tree_compare(
 	gconstpointer v1,
@@ -327,6 +339,79 @@
 	return ret;
 }
 
+gboolean
+memdb_lock_expired(
+	memdb_t *memdb,
+	const char *path)
+{
+	g_return_val_if_fail(memdb != NULL, FALSE);
+	g_return_val_if_fail(memdb->locks != NULL, FALSE);
+	g_return_val_if_fail(path != NULL, FALSE);
+
+	memdb_lock_info_t *li;
+	uint32_t ctime = time(NULL);
+
+	if ((li = g_hash_table_lookup(memdb->locks, path))) {
+		if ((ctime > li->ltime) && ((ctime - li->ltime) > CFS_LOCK_TIMEOUT))
+			return TRUE;
+	} else {
+		li = g_new0(memdb_lock_info_t, 1);
+		li->path = g_strdup(path);
+		li->ltime = ctime;
+		g_hash_table_replace(memdb->locks, li->path, li);
+	}
+
+	return FALSE;
+}
+
+void
+memdb_update_locks(memdb_t *memdb)
+{
+	g_return_if_fail(memdb != NULL);
+	g_return_if_fail(memdb->locks != NULL);
+
+	memdb_tree_entry_t *te, *parent;
+
+	if (!(te = memdb_lookup_path(memdb, "priv/lock", &parent)))
+		return;
+		
+	if (te->type != DT_DIR)
+		return;
+
+
+	GHashTable *old =  memdb->locks;
+	memdb->locks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+					     (GDestroyNotify)memdb_lock_info_free);
+	GHashTableIter iter;
+	GHashTable *ht = te->data.entries;
+
+	gpointer key, value;
+
+	g_hash_table_iter_init (&iter, ht);
+	while (g_hash_table_iter_next (&iter, &key, &value)) {
+
+		memdb_tree_entry_t *lock_te = (memdb_tree_entry_t *)value;
+		if (lock_te->type != DT_DIR)
+			continue;
+
+		memdb_lock_info_t *li;
+		li = g_new0(memdb_lock_info_t, 1);
+		li->path = g_strdup_printf("priv/lock/%s", lock_te->name);
+
+		memdb_lock_info_t *oldli;
+		if ((oldli = g_hash_table_lookup(memdb->locks, lock_te->name))) {
+			li->ltime = oldli->ltime;
+		} else {
+			li->ltime = time(NULL);
+		}
+		g_hash_table_insert(memdb->locks, li->path, li);
+	}
+
+	if (old)
+		g_hash_table_destroy(old);
+	
+}
+
 gboolean 
 memdb_recreate_vmlist(
 	memdb_t *memdb)
@@ -395,6 +480,9 @@
 
 	g_hash_table_replace(memdb->index, &memdb->root->inode, memdb->root);
 
+	memdb->locks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+					     (GDestroyNotify)memdb_lock_info_free);
+
 	if (!(memdb->bdb = bdb_backend_open(dbfilename, memdb->root, memdb->index))) {
 		memdb_close(memdb);
 		return NULL;
@@ -407,6 +495,8 @@
 		return NULL;		
 	}
 
+	memdb_update_locks(memdb);
+
 	cfs_debug("memdb open '%s' successful (version = %016zX)", 
 		  dbfilename, memdb->root->version);
 
@@ -426,6 +516,9 @@
 	if (memdb->index)
 		g_hash_table_destroy(memdb->index);
 
+	if (memdb->locks)
+		g_hash_table_destroy(memdb->locks);
+
 	if (memdb->dbfilename)
 		g_free(memdb->dbfilename);
 
@@ -513,6 +606,11 @@
 		goto ret;
 	}
 
+	if (strcmp(dirname, "priv/lock") == 0) {
+		g_hash_table_remove(memdb->locks, path);
+		memdb_lock_expired(memdb, path); // insert a new entry
+	}
+
 	ret = 0;
 
  ret:
@@ -771,6 +869,18 @@
 		goto ret;
 	}
 
+	/* NOTE: we use utime(0,0) to trigger 'unlock', so we do not
+	 * allow to change mtime for locks (only it mtime is newer).
+	 * See README for details about locks.
+	 */
+	if (mtime < te->mtime && te->type == DT_DIR && 
+	    strcmp(dirname, "priv/lock") == 0) {
+		cfs_debug("dir is locked");
+		ret = -EACCES;		
+		goto ret;
+	}
+	
+
 	memdb->root->version++;
 	memdb->root->mtime = mtime;
 	memdb->root->writer = writer;
@@ -992,6 +1102,12 @@
 		}
 	}
 
+	/* we do not allow rename for locks */
+	if (from_te->type == DT_DIR && path_is_lockdir(from)) {
+		ret = -EACCES;
+		goto ret;
+	}
+
 	if ((to_te = memdb_lookup_path(memdb, to, &to_parent))) {
 
 		if ((ret = unlink_tree_entry(memdb, to_parent, to_te)) != 0)
@@ -1114,6 +1230,8 @@
 			ret = -ENOTEMPTY;
 			goto ret;
 		}
+
+		g_hash_table_remove(memdb->locks, path);
 	}
 
 	record_memdb_change(path);
@@ -1272,6 +1390,35 @@
 	return copy;
 }
 
+gboolean
+memdb_tree_entry_csum(
+	memdb_tree_entry_t *te,
+	guchar csum[32])
+{
+	g_return_val_if_fail(te != NULL, FALSE);
+	g_return_val_if_fail(csum != NULL, FALSE);
+
+	GChecksum *sha256 = g_checksum_new(G_CHECKSUM_SHA256); 
+
+	g_checksum_update(sha256, (unsigned char*)&te->inode, sizeof(te->inode));
+	g_checksum_update(sha256, (unsigned char*)&te->version, sizeof(te->version));
+	g_checksum_update(sha256, (unsigned char*)&te->writer, sizeof(te->writer));
+	g_checksum_update(sha256, (unsigned char*)&te->mtime, sizeof(te->mtime));
+	g_checksum_update(sha256, (unsigned char*)&te->size, sizeof(te->size));
+	g_checksum_update(sha256, (unsigned char*)&te->type, sizeof(te->type));
+	g_checksum_update(sha256, (unsigned char*)&te->parent, sizeof(te->parent));
+	g_checksum_update(sha256, (unsigned char*)te->name, strlen(te->name));
+
+	if (te->type == DT_REG && te->size) 
+		g_checksum_update(sha256, (unsigned char*)te->data.value, te->size);
+
+	size_t csum_len = 32;
+	g_checksum_get_digest(sha256, csum, &csum_len);
+	g_checksum_free(sha256);
+
+	return TRUE;
+} 
+
 gboolean 
 memdb_compute_checksum(
 	GHashTable *index, 

Modified: pve-cluster/trunk/data/src/memdb.h
===================================================================
--- pve-cluster/trunk/data/src/memdb.h	2011-01-31 07:15:15 UTC (rev 5467)
+++ pve-cluster/trunk/data/src/memdb.h	2011-01-31 13:44:09 UTC (rev 5468)
@@ -47,7 +47,7 @@
 	union {
 		GHashTable *entries;
 		gpointer value;
-	} data; 
+	} data;
 	char name[0];
 };
 
@@ -69,148 +69,183 @@
 typedef struct db_backend db_backend_t;
 
 typedef struct {
+	char *path;
+	guint32 ltime;
+} memdb_lock_info_t;
+
+typedef struct {
 	char *dbfilename;
 	gboolean errors;
 	memdb_tree_entry_t *root;
 	GHashTable *index; /* map version ==> memdb_tree_entry */
+	GHashTable *locks; /* contains memdb_lock_info_t */
 	GMutex *mutex;
 	db_backend_t *bdb;
 } memdb_t;
 
-memdb_t *memdb_open(
-	const char *dbfilename);
+memdb_t *
+memdb_open(const char *dbfilename);
 
-void memdb_close(
-	memdb_t *memdb);
+void
+memdb_close(memdb_t *memdb);
 
-gboolean memdb_checkpoint(
-	memdb_t *memdb);
+gboolean
+memdb_checkpoint(memdb_t *memdb);
 
-gboolean memdb_recreate_vmlist(
-	memdb_t *memdb);
+gboolean
+memdb_recreate_vmlist(memdb_t *memdb);
 
-int memdb_statfs(
-	memdb_t *memdb, 
+gboolean
+memdb_lock_expired(
+	memdb_t *memdb,
+	const char *path);
+
+void
+memdb_update_locks(memdb_t *memdb);
+
+int
+memdb_statfs(
+	memdb_t *memdb,
 	struct statvfs *stbuf);
 
-int memdb_mkdir(
-	memdb_t *memdb, 
-	const char *path, 
-	guint32 writer, 
+int
+memdb_mkdir(
+	memdb_t *memdb,
+	const char *path,
+	guint32 writer,
 	guint32 mtime);
 
-int 
+int
 memdb_mtime(
-	memdb_t *memdb, 
-	const char *path, 
-	guint32 writer, 
+	memdb_t *memdb,
+	const char *path,
+	guint32 writer,
 	guint32 mtime);
 
-GList *memdb_readdir(
-	memdb_t *memdb, 
+GList *
+memdb_readdir(
+	memdb_t *memdb,
 	const char *path);
 
-void memdb_dirlist_free(
-	GList *dirlist);
+void
+memdb_dirlist_free(GList *dirlist);
 
-void tree_entry_debug(
-	memdb_tree_entry_t *te);
+void
+tree_entry_debug(memdb_tree_entry_t *te);
 
-void tree_entry_print(
-	memdb_tree_entry_t *te);
+void
+tree_entry_print(memdb_tree_entry_t *te);
 
-memdb_tree_entry_t *memdb_tree_entry_new(
-	const char *name);
+memdb_tree_entry_t *
+memdb_tree_entry_new(const char *name);
 
-memdb_tree_entry_t *memdb_tree_entry_copy(
-	memdb_tree_entry_t *te, 
+memdb_tree_entry_t *
+memdb_tree_entry_copy(
+	memdb_tree_entry_t *te,
 	gboolean with_data);
 
-void memdb_tree_entry_free(
-	memdb_tree_entry_t *te);
+void
+memdb_tree_entry_free(memdb_tree_entry_t *te);
 
-int memdb_delete(
-	memdb_t *memdb, 
-	const char *path, 
-	guint32 writer, 
+int
+memdb_delete(
+	memdb_t *memdb,
+	const char *path,
+	guint32 writer,
 	guint32 mtime);
 
-int memdb_read(
-	memdb_t *memdb, 
-	const char *path, 
+int
+memdb_read(
+	memdb_t *memdb,
+	const char *path,
 	gpointer *data_ret);
 
-int memdb_create(
-	memdb_t *memdb, 
+int
+memdb_create(
+	memdb_t *memdb,
 	const char *path,
 	guint32 writer,
 	guint32 mtime);
 
-int memdb_write(
-	memdb_t *memdb, 
-	const char *path, 
-	guint32 writer, 
+int
+memdb_write(
+	memdb_t *memdb,
+	const char *path,
+	guint32 writer,
 	guint32 mtime,
-	gconstpointer data, 
-	size_t count, 
-	off_t offset, 
+	gconstpointer data,
+	size_t count,
+	off_t offset,
 	gboolean truncate);
 
-memdb_tree_entry_t *memdb_getattr(
-	memdb_t *memdb, 
+memdb_tree_entry_t *
+memdb_getattr(
+	memdb_t *memdb,
 	const char *path);
 
-int memdb_rename(
-	memdb_t *memdb, 
-	const char *from, 
-	const char *to, 
-	guint32 writer, 
+int
+memdb_rename(
+	memdb_t *memdb,
+	const char *from,
+	const char *to,
+	guint32 writer,
 	guint32 mtime);
 
-void memdb_dump (
+void
+memdb_dump (
 	memdb_t *memdb);
 
-gboolean memdb_compute_checksum(
-	GHashTable *index, 
-	memdb_tree_entry_t *root, 
-	guchar *csum, 
+gboolean
+memdb_compute_checksum(
+	GHashTable *index,
+	memdb_tree_entry_t *root,
+	guchar *csum,
 	size_t csum_len);
 
-memdb_index_t *memdb_encode_index(
-	GHashTable *index, 
+memdb_index_t *
+memdb_encode_index(
+	GHashTable *index,
 	memdb_tree_entry_t *root);
 
-void memdb_dump_index (
-	memdb_index_t *idx);
+void
+memdb_dump_index (memdb_index_t *idx);
 
-memdb_index_t *memdb_index_copy(
-	memdb_index_t *idx);
+memdb_index_t *
+memdb_index_copy(memdb_index_t *idx);
 
-db_backend_t *bdb_backend_open(
+gboolean
+memdb_tree_entry_csum(
+	memdb_tree_entry_t *te,
+	guchar csum[32]);
+
+db_backend_t *
+bdb_backend_open(
 	const char *filename,
 	memdb_tree_entry_t *root,
 	GHashTable *index);
 
-void bdb_backend_close(
-	db_backend_t *bdb);
+void
+bdb_backend_close(db_backend_t *bdb);
 
-int bdb_backend_write(
+int
+bdb_backend_write(
 	db_backend_t *bdb,
-	guint64 inode, 
-	guint64 parent, 
-	guint64 version, 
+	guint64 inode,
+	guint64 parent,
+	guint64 version,
 	guint32 writer,
 	guint32 mtime,
-	guint32 size, 
-	char type, 
+	guint32 size,
+	char type,
 	char *name,
 	gpointer value,
 	guint64 delete_inode);
 
-gboolean bdb_backend_commit_update(
-	memdb_t *memdb, 
-	memdb_index_t *master, 
-	memdb_index_t *slave, 
+gboolean
+bdb_backend_commit_update(
+	memdb_t *memdb,
+	memdb_index_t *master,
+	memdb_index_t *slave,
 	GList *inodes);
 
 




More information about the pve-devel mailing list