[sheepdog] [PATCH v3] dog/vdi: bug fix for voting majority, add test case to test it
Ruoyu
liangry at ucweb.com
Fri Apr 4 07:55:14 CEST 2014
There is a critical error in the function vote_majority_object.
When all the three copies are different, the original logic still
choose the last one as majority.
---
dog/vdi.c | 21 ++++++++++++--
tests/functional/091 | 72 ++++++++++++++++++++++++++++++++++++++++++++++++
tests/functional/091.out | 57 ++++++++++++++++++++++++++++++++++++++
tests/functional/group | 1 +
4 files changed, 148 insertions(+), 3 deletions(-)
create mode 100755 tests/functional/091
create mode 100644 tests/functional/091.out
diff --git a/dog/vdi.c b/dog/vdi.c
index 999d4be..a9b3c79 100644
--- a/dog/vdi.c
+++ b/dog/vdi.c
@@ -1578,6 +1578,7 @@ static void vote_majority_object(struct vdi_check_info *info)
int count = 0, nr_live_copies = 0;
struct vdi_check_work *majority = NULL;
+ /* step 1 */
for (int i = 0; i < info->nr_copies; i++) {
struct vdi_check_work *vcw = &info->vcw[i];
@@ -1594,14 +1595,28 @@ static void vote_majority_object(struct vdi_check_info *info)
count--;
}
+ /* step 2 */
+ if (count > 0 && count <= nr_live_copies / 2) {
+ count = 0;
+ for (int i = 0; i < info->nr_copies; i++) {
+ struct vdi_check_work *vcw = &info->vcw[i];
+
+ if (!vcw->object_found)
+ continue;
+ if (!memcmp(majority->hash, vcw->hash, sizeof(vcw->hash)))
+ count++;
+ }
+ }
+
if (!majority)
info->result = VDI_CHECK_NO_OBJ_FOUND;
- else if (count < nr_live_copies / 2) {
+ else if (count > nr_live_copies / 2)
+ info->result = VDI_CHECK_SUCCESS;
+ else {
/* no majority found */
majority = NULL;
info->result = VDI_CHECK_NO_MAJORITY_FOUND;
- } else
- info->result = VDI_CHECK_SUCCESS;
+ }
info->majority = majority;
}
diff --git a/tests/functional/091 b/tests/functional/091
new file mode 100755
index 0000000..a98de1b
--- /dev/null
+++ b/tests/functional/091
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+# Test vote majority
+
+. ./common
+
+read_vdi_from_nodes()
+{
+ for i in `seq 0 $(($1-1))`; do
+ $DOG vdi read test 0 12 -p $((7000+$i))
+ echo ""
+ done
+}
+
+check_vdi_consistance()
+{
+ read_vdi_from_nodes $1
+ $DOG vdi check test
+ read_vdi_from_nodes $1
+}
+
+for i in 0 1 2; do
+ _start_sheep $i
+done
+_wait_for_sheep 3
+
+$DOG cluster format -c 3
+$DOG vdi create test 4M
+echo "hello, copy0" | $DOG vdi write test 0 12
+cp $STORE/0/obj/007c2b2500000000 $STORE/copy0
+echo "hello, copy1" | $DOG vdi write test 0 12
+cp $STORE/1/obj/007c2b2500000000 $STORE/copy1
+echo "hello, copy2" | $DOG vdi write test 0 12
+cp $STORE/2/obj/007c2b2500000000 $STORE/copy2
+
+echo ""
+echo "----- 3 copies, ABB -----"
+cp $STORE/copy0 $STORE/0/obj/007c2b2500000000
+check_vdi_consistance 3
+
+echo ""
+echo "----- 3 copies, ABC -----"
+cp $STORE/copy0 $STORE/0/obj/007c2b2500000000
+cp $STORE/copy1 $STORE/1/obj/007c2b2500000000
+check_vdi_consistance 3
+
+for i in 3 4; do
+ _start_sheep $i
+done
+_wait_for_sheep 5
+
+echo "yes" | $DOG cluster format -c 5
+$DOG vdi create test 4M
+echo "hello, copy0" | $DOG vdi write test 0 12
+cp $STORE/0/obj/007c2b2500000000 $STORE/copy0
+echo "hello, copy1" | $DOG vdi write test 0 12
+cp $STORE/1/obj/007c2b2500000000 $STORE/copy1
+
+echo ""
+echo "----- 5 copies, AABBB -----"
+cp $STORE/copy0 $STORE/0/obj/007c2b2500000000
+cp $STORE/copy0 $STORE/1/obj/007c2b2500000000
+check_vdi_consistance 5
+
+echo ""
+echo "----- 5 copies, BABAB -----"
+cp $STORE/copy0 $STORE/1/obj/007c2b2500000000
+cp $STORE/copy0 $STORE/3/obj/007c2b2500000000
+check_vdi_consistance 5
+
+$DOG cluster shutdown
+
diff --git a/tests/functional/091.out b/tests/functional/091.out
new file mode 100644
index 0000000..570a3c6
--- /dev/null
+++ b/tests/functional/091.out
@@ -0,0 +1,57 @@
+QA output created by 091
+using backend plain store
+
+----- 3 copies, ABB -----
+hello, copy0
+hello, copy2
+hello, copy2
+fixed replica 7c2b2500000000
+finish check&repair test
+hello, copy2
+hello, copy2
+hello, copy2
+
+----- 3 copies, ABC -----
+hello, copy0
+hello, copy1
+hello, copy2
+no majority of 7c2b2500000000
+finish check&repair test
+hello, copy0
+hello, copy1
+hello, copy2
+ __
+ ()'`;
+ /\|`
+ / | Caution! The cluster is not empty.
+(/_)_|_ Are you sure you want to continue? [yes/no]: using backend plain store
+
+----- 5 copies, AABBB -----
+hello, copy0
+hello, copy0
+hello, copy1
+hello, copy1
+hello, copy1
+fixed replica 7c2b2500000000
+fixed replica 7c2b2500000000
+finish check&repair test
+hello, copy1
+hello, copy1
+hello, copy1
+hello, copy1
+hello, copy1
+
+----- 5 copies, BABAB -----
+hello, copy1
+hello, copy0
+hello, copy1
+hello, copy0
+hello, copy1
+fixed replica 7c2b2500000000
+fixed replica 7c2b2500000000
+finish check&repair test
+hello, copy1
+hello, copy1
+hello, copy1
+hello, copy1
+hello, copy1
diff --git a/tests/functional/group b/tests/functional/group
index 36c2cf4..329f9fc 100644
--- a/tests/functional/group
+++ b/tests/functional/group
@@ -105,3 +105,4 @@
088 auto quick cluster
089 auto quick sheepfs
090 auto quick vdi md
+091 auto quick vdi
--
1.8.1.2
More information about the sheepdog
mailing list