[sheepdog] [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
mailing list