[sheepdog-users] [PATCH 2/3] collie: use hash for collie check

MORITA Kazutaka morita.kazutaka at gmail.com
Fri May 10 07:28:32 CEST 2013


From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>

This patch checks the hash values of the target objects and skips check and
repair when there is no difference between them.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 collie/Makefile.am |    2 +-
 collie/vdi.c       |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/collie/Makefile.am b/collie/Makefile.am
index 386aa49..3fba2dd 100644
--- a/collie/Makefile.am
+++ b/collie/Makefile.am
@@ -30,7 +30,7 @@ collie_SOURCES          += debug.c
 override CFLAGS         := $(subst -pg -gstabs,,$(CFLAGS))
 endif
 
-collie_LDADD	  	= ../lib/libsheepdog.a
+collie_LDADD	  	= ../lib/libsheepdog.a -lpthread
 collie_DEPENDENCIES	= ../lib/libsheepdog.a
 
 noinst_HEADERS		= treeview.h collie.h
diff --git a/collie/vdi.c b/collie/vdi.c
index 91ed671..5b793d4 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -16,6 +16,7 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
+#include <pthread.h>
 
 #include "collie.h"
 #include "treeview.h"
@@ -1439,6 +1440,71 @@ static void write_object_to(const struct sd_vnode *vnode, uint64_t oid,
 	}
 }
 
+struct vdi_hash_info {
+	pthread_t thread;
+	uint64_t oid;
+	struct node_id nid;
+	bool success;
+	uint8_t hash[SHA1_LEN];
+};
+
+static void *get_hash(void *arg)
+{
+	struct vdi_hash_info *info = arg;
+	int ret;
+	char host[HOST_NAME_MAX];
+	struct sd_req hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+
+	sd_init_req(&hdr, SD_OP_GET_HASH);
+	hdr.obj.oid = info->oid;
+	hdr.obj.tgt_epoch = sd_epoch;
+
+	addr_to_str(host, sizeof(host), info->nid.addr, 0);
+	ret = collie_exec_req(host, info->nid.port, &hdr, NULL);
+
+	memcpy(info->hash, rsp->hash.digest, sizeof(info->hash));
+	info->success = (ret == 0);
+
+	return NULL;
+}
+
+/* check the need of repair with hash */
+static bool need_repair(uint64_t oid, const struct sd_vnode **vnodes,
+			int nr_copies)
+{
+	struct vdi_hash_info info[SD_MAX_COPIES];
+	bool success = true;
+
+	for (int i = 0; i < nr_copies; i++) {
+		int ret;
+
+		info[i].oid = oid;
+		info[i].nid = vnodes[i]->nid;
+		ret = pthread_create(&info[i].thread, NULL, get_hash, info + i);
+		if (ret != 0) {
+			fprintf(stderr, "failed to create thread\n");
+			success = false;
+		}
+	}
+
+	for (int i = 0; i < nr_copies; i++) {
+		pthread_join(info[i].thread, NULL);
+		success = success && info[i].success;
+	}
+
+	if (!success)
+		return true;
+
+	for (int i = 1; i < nr_copies; i++) {
+		if (memcmp(info[0].hash, info[i].hash, sizeof(info[0].hash)) != 0)
+			return true;
+	}
+
+	/* all the replicas have the same contents */
+	return false;
+}
+
 /*
  * Fix consistency of the replica of oid.
  *
@@ -1449,16 +1515,21 @@ static void do_check_repair(uint64_t oid, int nr_copies)
 {
 	const struct sd_vnode *tgt_vnodes[SD_MAX_COPIES];
 	size_t size = get_objsize(oid);
-	void *buf = xmalloc(size), *buf_cmp;
+	void *buf, *buf_cmp;
 	int i, ret;
 
+	oid_to_vnodes(sd_vnodes, sd_vnodes_nr, oid, nr_copies, tgt_vnodes);
+
+	if (!need_repair(oid, tgt_vnodes, nr_copies))
+		return;
+
+	buf = xmalloc(size);
 	ret = sd_read_object(oid, buf, size, 0, true);
 	if (ret != SD_RES_SUCCESS) {
 		fprintf(stderr, "FATAL: read %"PRIx64" failed\n", oid);
 		exit(EXIT_FAILURE);
 	}
 
-	oid_to_vnodes(sd_vnodes, sd_vnodes_nr, oid, nr_copies, tgt_vnodes);
 	for (i = 0; i < nr_copies; i++) {
 		buf_cmp = read_object_from(tgt_vnodes[i], oid);
 		if (!buf_cmp) {
-- 
1.7.9.5




More information about the sheepdog-users mailing list