diff options
-rw-r--r-- | tests/basic/afr/arbiter-add-brick.t | 10 | ||||
-rw-r--r-- | tests/bugs/glusterd/bug-1406411-fail-add-brick-on-replica-count-change.t | 40 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 19 |
3 files changed, 66 insertions, 3 deletions
diff --git a/tests/basic/afr/arbiter-add-brick.t b/tests/basic/afr/arbiter-add-brick.t index 357f59b0852..69e13267ccd 100644 --- a/tests/basic/afr/arbiter-add-brick.t +++ b/tests/basic/afr/arbiter-add-brick.t @@ -10,6 +10,7 @@ TEST pidof glusterd TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1} TEST $CLI volume set $V0 performance.stat-prefetch off TEST $CLI volume start $V0 +TEST $CLI volume set $V0 self-heal-daemon off TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0; TEST mkdir $M0/dir1 TEST dd if=/dev/urandom of=$M0/file1 bs=1024 count=1 @@ -20,21 +21,24 @@ TEST mkdir $M0/dir2 TEST dd if=/dev/urandom of=$M0/file1 bs=1024 count=1024 +#convert replica 2 to arbiter volume +TEST $CLI volume start $V0 force +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}1 + #syntax check for add-brick. TEST ! $CLI volume add-brick $V0 replica 2 arbiter 1 $H0:$B0/${V0}2 TEST ! $CLI volume add-brick $V0 replica 3 arbiter 2 $H0:$B0/${V0}2 -#convert replica 2 to arbiter volume TEST $CLI volume add-brick $V0 replica 3 arbiter 1 $H0:$B0/${V0}2 EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}2 #Heal files -TEST $CLI volume start $V0 force -EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}1 +TEST $CLI volume set $V0 self-heal-daemon on EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" glustershd_up_status EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0 EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1 EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 2 +TEST $CLI volume heal $V0 EXPECT_WITHIN $HEAL_TIMEOUT "0" get_pending_heal_count $V0 #Perform I/O after add-brick diff --git a/tests/bugs/glusterd/bug-1406411-fail-add-brick-on-replica-count-change.t b/tests/bugs/glusterd/bug-1406411-fail-add-brick-on-replica-count-change.t new file mode 100644 index 00000000000..bbd2d4cc948 --- /dev/null +++ b/tests/bugs/glusterd/bug-1406411-fail-add-brick-on-replica-count-change.t @@ -0,0 +1,40 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd; +TEST pidof glusterd + +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2}; +TEST $CLI volume start $V0 + +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}2 +TEST kill_brick $V0 $H0 $B0/${V0}1 + +#add-brick should fail +TEST ! $CLI volume add-brick $V0 replica 3 $H0:$B0/${V0}3 + +TEST $CLI volume start $V0 force +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}2 +TEST $CLI volume add-brick $V0 replica 3 $H0:$B0/${V0}3 + +TEST $CLI volume create $V1 $H0:$B0/${V1}{1,2}; +TEST $CLI volume start $V1 + +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V1 $H0 $B0/${V1}1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V1 $H0 $B0/${V1}2 +TEST kill_brick $V1 $H0 $B0/${V1}1 + +#add-brick should fail +TEST ! $CLI volume add-brick $V1 replica 2 $H0:$B0/${V1}{3,4} + +TEST $CLI volume start $V1 force +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V1 $H0 $B0/${V1}1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V1 $H0 $B0/${V1}2 +TEST $CLI volume add-brick $V1 replica 2 $H0:$B0/${V1}{3,4} +cleanup; diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c index 19db03a5201..c2c4cf4606f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c @@ -1724,6 +1724,25 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, dict_t *rsp_dict) } } + if (volinfo->replica_count < replica_count) { + cds_list_for_each_entry (brickinfo, &volinfo->bricks, + brick_list) { + if (gf_uuid_compare (brickinfo->uuid, MY_UUID)) + continue; + if (brickinfo->status == GF_BRICK_STOPPED) { + ret = -1; + snprintf (msg, sizeof (msg), "Brick %s is down," + " changing replica count needs all " + "the bricks to be up to avoid data " + "loss", brickinfo->path); + gf_msg (THIS->name, GF_LOG_ERROR, 0, + GD_MSG_BRICK_ADD_FAIL, "%s", msg); + *op_errstr = gf_strdup (msg); + goto out; + } + } + } + if (conf->op_version > GD_OP_VERSION_3_7_5 && is_origin_glusterd (dict)) { ret = glusterd_validate_quorum (this, GD_OP_ADD_BRICK, dict, |