[sheepdog] [PATCH] sheep: remove sha1_from_buffer()

Liu Yuan namei.unix at gmail.com
Tue Dec 17 14:28:25 CET 2013


This function is buggy yet tricky to debug. For now we can't pass following
script:

for i in `seq 0 2`; do
	sheep/sheep -D -n -z $i -p $((7000+$i)) -c local store/$i
done
sleep 1
dog/dog cluster format -c 3
qemu-img convert linux-0.2.img sheepdog:test
dog/dog vdi snapshot test -s snap
dog/dog cluster snapshot save snap1 snapshot
md5sum /tmp/store/0/obj/{007c2b2500000000,007c2b2500000001,007c2b2500000002,007c2b2500000003,007c2b2500000004}
dog/dog cluster snapshot load snap1 snapshot
md5sum /tmp/store/0/obj/{007c2b2500000000,007c2b2500000001,007c2b2500000002,007c2b2500000003,007c2b2500000004}
dog/dog vdi read test | md5sum
md5sum linux-0.2.img

-----------------------------------------

Instead of debugging of it, this patch tries to remove it since the speedup
from sha1_from_buffer is very limited because we don't have many zero filled
objects.

Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
 dog/farm/sha1_file.c |   22 ++++++++++++++++++++--
 include/sha1.h       |    1 -
 lib/sha1.c           |   29 -----------------------------
 sheep/plain_store.c  |    5 ++++-
 4 files changed, 24 insertions(+), 33 deletions(-)

diff --git a/dog/farm/sha1_file.c b/dog/farm/sha1_file.c
index 3ba2519..ffc475c 100644
--- a/dog/farm/sha1_file.c
+++ b/dog/farm/sha1_file.c
@@ -27,6 +27,24 @@
 #include "farm.h"
 #include "util.h"
 
+static void get_sha1(unsigned char *buf, unsigned len, unsigned char *sha1)
+{
+	struct sha1_ctx c;
+	uint64_t offset = 0;
+	uint32_t length = len;
+	void *tmp = valloc(length);
+
+	memcpy(tmp, buf, len);
+	trim_zero_blocks(tmp, &offset, &length);
+
+	sha1_init(&c);
+	sha1_update(&c, (uint8_t *)&offset, sizeof(offset));
+	sha1_update(&c, (uint8_t *)&length, sizeof(length));
+	sha1_update(&c, tmp, length);
+	sha1_final(&c, sha1);
+	free(tmp);
+}
+
 static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
 {
 	int i;
@@ -88,7 +106,7 @@ int sha1_file_write(void *buf, size_t len, unsigned char *outsha1)
 {
 	unsigned char sha1[SHA1_DIGEST_SIZE];
 
-	sha1_from_buffer(buf, len, sha1);
+	get_sha1(buf, len, sha1);
 	if (sha1_buffer_write(sha1, buf, len) < 0)
 		return -1;
 	if (outsha1)
@@ -101,7 +119,7 @@ static int verify_sha1_file(const unsigned char *sha1,
 {
 	unsigned char tmp[SHA1_DIGEST_SIZE];
 
-	sha1_from_buffer(buf, len, tmp);
+	get_sha1(buf, len, tmp);
 	if (memcmp((char *)tmp, (char *)sha1, SHA1_DIGEST_SIZE) != 0) {
 		sd_err("failed, %s != %s", sha1_to_hex(sha1), sha1_to_hex(tmp));
 		return -1;
diff --git a/include/sha1.h b/include/sha1.h
index 9ae70b5..395b176 100644
--- a/include/sha1.h
+++ b/include/sha1.h
@@ -32,6 +32,5 @@ sha1_update_func_t sha1_update;
 sha1_final_func_t sha1_final;
 
 const char *sha1_to_hex(const unsigned char *sha1);
-void sha1_from_buffer(const void *buf, size_t size, unsigned char *sha1);
 
 #endif
diff --git a/lib/sha1.c b/lib/sha1.c
index 9da0518..46dc493 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -334,35 +334,6 @@ const char *sha1_to_hex(const unsigned char *sha1)
 	return buffer;
 }
 
-/*
- * Calculate a sha1 message digest based on the content of 'buf'
- *
- * We can uniquely generate the original buffer from
- * - the trimmed buffer
- * - the orignal buffer length
- * - the trimmed buffer length
- * - the trimmed buffer offset
- *
- * This calculates a unique sha1 digest faster than the naive calculation when
- * the content of 'buf' is sparse.  The result will be set in 'sha1'.
- */
-void sha1_from_buffer(const void *buf, size_t size, unsigned char *sha1)
-{
-	struct sha1_ctx c;
-	uint64_t offset = 0;
-	uint32_t length = size;
-
-	sha1_init(&c);
-	sha1_update(&c, (uint8_t *)&length, sizeof(length));
-
-	find_zero_blocks(buf, &offset, &length);
-
-	sha1_update(&c, (uint8_t *)&length, sizeof(length));
-	sha1_update(&c, (uint8_t *)&offset, sizeof(offset));
-	sha1_update(&c, buf, length);
-	sha1_final(&c, sha1);
-}
-
 static void __attribute__((constructor)) __sha1_init(void)
 {
 	sha1_init = generic_sha1_init;
diff --git a/sheep/plain_store.c b/sheep/plain_store.c
index f0e2c20..a178883 100644
--- a/sheep/plain_store.c
+++ b/sheep/plain_store.c
@@ -611,6 +611,7 @@ int default_get_hash(uint64_t oid, uint32_t epoch, uint8_t *sha1)
 	uint32_t length;
 	bool is_readonly_obj = oid_is_readonly(oid);
 	char path[PATH_MAX];
+	struct sha1_ctx c;
 
 	ret = get_object_path(oid, epoch, path, sizeof(path));
 	if (ret != SD_RES_SUCCESS)
@@ -639,7 +640,9 @@ int default_get_hash(uint64_t oid, uint32_t epoch, uint8_t *sha1)
 		return ret;
 	}
 
-	sha1_from_buffer(buf, length, sha1);
+	sha1_init(&c);
+	sha1_update(&c, buf, length);
+	sha1_final(&c, sha1);
 	free(buf);
 
 	sd_debug("the message digest of %"PRIx64" at epoch %d is %s", oid,
-- 
1.7.9.5




More information about the sheepdog mailing list