diff options
-rw-r--r-- | tests/bugs/bug-884455.t | 76 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 3 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-layout.c | 13 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-selfheal.c | 46 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht.c | 1 |
5 files changed, 131 insertions, 8 deletions
diff --git a/tests/bugs/bug-884455.t b/tests/bugs/bug-884455.t new file mode 100644 index 000000000..e5b782267 --- /dev/null +++ b/tests/bugs/bug-884455.t @@ -0,0 +1,76 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc + +cleanup; + +function layout_compare() +{ + res=0 + + if [ "$1" == "$2" ] + then + res=1 + fi + if [ "$1" == "$3" ] + then + res=1 + fi + if [ "$2" == "$3" ] + then + res=1 + fi + + echo $res +} + +function get_layout() +{ + layout1=`getfattr -n trusted.glusterfs.dht -e hex $1 2>&1|grep dht |cut -d = -f2` + layout2=`getfattr -n trusted.glusterfs.dht -e hex $2 2>&1|grep dht |cut -d = -f2` + layout3=`getfattr -n trusted.glusterfs.dht -e hex $3 2>&1|grep dht |cut -d = -f2` + + ret=$(layout_compare $layout1 $layout2 $layout3) + + if [ $ret -ne 0 ] + then + echo 1 + else + echo 0 + fi + +} + +BRICK_COUNT=3 + +TEST glusterd +TEST pidof glusterd + +TEST $CLI volume create $V0 $H0:$B0/${V0}0 $H0:$B0/${V0}1 +## set subvols-per-dir option +TEST $CLI volume set $V0 subvols-per-directory 2 +TEST $CLI volume start $V0 + +## Mount FUSE +TEST glusterfs -s $H0 --volfile-id $V0 $M0; + +TEST mkdir $M0/dir{1..10}; + +## Add-brick n run rebalance to force re-write of layout +TEST $CLI volume add-brick $V0 $H0:$B0/${V0}2 +sleep 5; +TEST $CLI volume rebalance $V0 start force +sleep 30; + +## check for layout overlaps. +EXPECT "0" get_layout $B0/${V0}0 $B0/${V0}1 $B0/${V0}2 +EXPECT "0" get_layout $B0/${V0}0/dir1 $B0/${V0}1/dir1 $B0/${V0}2/dir1 +EXPECT "0" get_layout $B0/${V0}0/dir2 $B0/${V0}1/dir2 $B0/${V0}2/dir2 +EXPECT "0" get_layout $B0/${V0}0/dir3 $B0/${V0}1/dir3 $B0/${V0}2/dir3 +EXPECT "0" get_layout $B0/${V0}0/dir4 $B0/${V0}1/dir4 $B0/${V0}2/dir4 +EXPECT "0" get_layout $B0/${V0}0/dir5 $B0/${V0}1/dir5 $B0/${V0}2/dir5 +EXPECT "0" get_layout $B0/${V0}0/dir6 $B0/${V0}1/dir6 $B0/${V0}2/dir6 +EXPECT "0" get_layout $B0/${V0}0/dir7 $B0/${V0}1/dir7 $B0/${V0}2/dir7 +EXPECT "0" get_layout $B0/${V0}0/dir8 $B0/${V0}1/dir8 $B0/${V0}2/dir8 +EXPECT "0" get_layout $B0/${V0}0/dir9 $B0/${V0}1/dir9 $B0/${V0}2/dir9 +EXPECT "0" get_layout $B0/${V0}0/dir10 $B0/${V0}1/dir10 $B0/${V0}2/dir10 diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 1f3ccc1cd..83ec345d6 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -263,6 +263,7 @@ struct dht_conf { /* to keep track of nodes which are decomissioned */ xlator_t **decommissioned_bricks; int decommission_in_progress; + int decommission_subvols_cnt; /* defrag related */ gf_defrag_info_t *defrag; @@ -721,4 +722,6 @@ int dht_dir_attr_heal_done (int ret, call_frame_t *sync_frame, void *data); int dht_dir_has_layout (dict_t *xattr); +gf_boolean_t +dht_is_subvol_in_layout (dht_layout_t *layout, xlator_t *xlator); #endif/* _DHT_H */ diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c index ef728209f..8cae52653 100644 --- a/xlators/cluster/dht/src/dht-layout.c +++ b/xlators/cluster/dht/src/dht-layout.c @@ -419,6 +419,19 @@ dht_layout_entry_cmp_volname (dht_layout_t *layout, int i, int j) layout->list[j].xlator->name)); } + +gf_boolean_t +dht_is_subvol_in_layout (dht_layout_t *layout, xlator_t *xlator) +{ + int i = 0; + + for (i = 0; i < layout->cnt; i++) { + if (!strcmp (layout->list[i].xlator->name, xlator->name)) + return _gf_true; + } + return _gf_false; +} + int64_t dht_layout_entry_cmp (dht_layout_t *layout, int i, int j) { diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c index 4840034a9..fbe4cab3e 100644 --- a/xlators/cluster/dht/src/dht-selfheal.c +++ b/xlators/cluster/dht/src/dht-selfheal.c @@ -101,7 +101,8 @@ dht_selfheal_dir_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc, - dht_layout_t *layout, int i) + dht_layout_t *layout, int i, + xlator_t *req_subvol) { xlator_t *subvol = NULL; dict_t *xattr = NULL; @@ -112,7 +113,10 @@ dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc, local = frame->local; - subvol = layout->list[i].xlator; + if (req_subvol) + subvol = req_subvol; + else + subvol = layout->list[i].xlator; this = frame->this; GF_VALIDATE_OR_GOTO ("", this, err); @@ -179,21 +183,42 @@ dht_fix_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout) int i = 0; int count = 0; xlator_t *this = NULL; + dht_conf_t *conf = NULL; + dht_layout_t *dummy = NULL; local = frame->local; this = frame->this; + conf = this->private; gf_log (this->name, GF_LOG_DEBUG, "writing the new range for all subvolumes"); - local->call_cnt = count = layout->cnt; + local->call_cnt = count = conf->subvolume_cnt; for (i = 0; i < layout->cnt; i++) { - dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i); + dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i, NULL); if (--count == 0) - break; + goto out; } + /* if we are here, subvolcount > layout_count. subvols-per-directory + * option might be set here. We need to clear out layout from the + * non-participating subvolumes, else it will result in overlaps */ + dummy = dht_layout_new (this, 1); + if (!dummy) + goto out; + for (i = 0; i < conf->subvolume_cnt; i++) { + if (_gf_false == + dht_is_subvol_in_layout (layout, conf->subvolumes[i])) { + dht_selfheal_dir_xattr_persubvol (frame, loc, dummy, 0, + conf->subvolumes[i]); + if (--count == 0) + break; + } + } + + dht_layout_unref (this, dummy); +out: return 0; } @@ -235,7 +260,7 @@ dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout) if (layout->list[i].err != -1 || !layout->list[i].stop) continue; - dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i); + dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i, NULL); if (--missing_xattr == 0) break; @@ -524,8 +549,13 @@ dht_get_layout_count (xlator_t *this, dht_layout_t *layout, int new_layout) } } - count = ((layout->spread_cnt) ? layout->spread_cnt : - ((count) ? count : 1)); + /* if layout->spread_cnt is set, check if it is <= available + * subvolumes (excluding bricks that are being decommissioned). Else + * return count */ + count = ((layout->spread_cnt && + (layout->spread_cnt <= + (conf->subvolume_cnt - conf->decommission_subvols_cnt))) ? + layout->spread_cnt : ((count) ? count : 1)); return count; } diff --git a/xlators/cluster/dht/src/dht.c b/xlators/cluster/dht/src/dht.c index d7b1e9655..d70d713ac 100644 --- a/xlators/cluster/dht/src/dht.c +++ b/xlators/cluster/dht/src/dht.c @@ -262,6 +262,7 @@ dht_parse_decommissioned_bricks (xlator_t *this, dht_conf_t *conf, if (!strcmp (conf->subvolumes[i]->name, node)) { conf->decommissioned_bricks[i] = conf->subvolumes[i]; + conf->decommission_subvols_cnt++; gf_log (this->name, GF_LOG_INFO, "decommissioning subvolume %s", conf->subvolumes[i]->name); |